mirror of
https://github.com/fosrl/pangolin.git
synced 2026-08-13 16:00:02 +02:00
basic provider model selector
This commit is contained in:
@@ -20,7 +20,7 @@ import { createApiClient, formatAxiosError } from "@app/lib/api";
|
||||
import { aiProviderQueries } from "@app/lib/queries";
|
||||
import { useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
|
||||
type ModelListType = "allow" | "block";
|
||||
|
||||
@@ -43,6 +43,18 @@ export default function AiProviderModelsPage() {
|
||||
const modelsQuery = useQuery(
|
||||
aiProviderQueries.providerModels({ providerId: provider.providerId })
|
||||
);
|
||||
const catalogQuery = useQuery(
|
||||
aiProviderQueries.catalogModels({ providerId: provider.providerId })
|
||||
);
|
||||
|
||||
const catalogTags = useMemo(
|
||||
() =>
|
||||
(catalogQuery.data ?? []).map((entry) => ({
|
||||
id: entry.model,
|
||||
text: entry.model
|
||||
})),
|
||||
[catalogQuery.data]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (!modelsQuery.data) return;
|
||||
@@ -165,6 +177,8 @@ export default function AiProviderModelsPage() {
|
||||
}
|
||||
}
|
||||
|
||||
const inputsDisabled = modelsQuery.isLoading || saveLoading;
|
||||
|
||||
return (
|
||||
<SettingsContainer>
|
||||
<SettingsSection>
|
||||
@@ -196,10 +210,12 @@ export default function AiProviderModelsPage() {
|
||||
: newTags;
|
||||
setAllowTags(next as Tag[]);
|
||||
}}
|
||||
enableAutocomplete={catalogTags.length > 0}
|
||||
autocompleteOptions={catalogTags}
|
||||
allowDuplicates={false}
|
||||
sortTags
|
||||
delimiterList={[",", "Enter"]}
|
||||
disabled={modelsQuery.isLoading || saveLoading}
|
||||
disabled={inputsDisabled}
|
||||
/>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
{t("aiProviderModelsAllowDescription")}
|
||||
@@ -223,10 +239,12 @@ export default function AiProviderModelsPage() {
|
||||
: newTags;
|
||||
setBlockTags(next as Tag[]);
|
||||
}}
|
||||
enableAutocomplete={catalogTags.length > 0}
|
||||
autocompleteOptions={catalogTags}
|
||||
allowDuplicates={false}
|
||||
sortTags
|
||||
delimiterList={[",", "Enter"]}
|
||||
disabled={modelsQuery.isLoading || saveLoading}
|
||||
disabled={inputsDisabled}
|
||||
/>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
{t("aiProviderModelsBlockDescription")}
|
||||
|
||||
+12
-1
@@ -61,7 +61,8 @@ import type { GetSiteResourceResponse } from "@server/routers/siteResource/getSi
|
||||
import type { ListTargetsResponse } from "@server/routers/target";
|
||||
import type {
|
||||
ListAiModelsResponse,
|
||||
ListAiProvidersResponse
|
||||
ListAiProvidersResponse,
|
||||
ListCatalogModelsResponse
|
||||
} from "@server/routers/aiProvider/types";
|
||||
import type { ListAiBudgetsByScopeResponse } from "@server/routers/aiBudget/types";
|
||||
import {
|
||||
@@ -1199,6 +1200,16 @@ export const aiProviderQueries = {
|
||||
return res.data.data.models;
|
||||
}
|
||||
}),
|
||||
catalogModels: ({ providerId }: { providerId: number }) =>
|
||||
queryOptions({
|
||||
queryKey: ["AI_PROVIDERS", providerId, "CATALOG_MODELS"] as const,
|
||||
queryFn: async ({ signal, meta }) => {
|
||||
const res = await meta!.api.get<
|
||||
AxiosResponse<ListCatalogModelsResponse>
|
||||
>(`/ai-provider/${providerId}/catalog-models`, { signal });
|
||||
return res.data.data.models;
|
||||
}
|
||||
}),
|
||||
orgProviders: ({ orgId, query }: { orgId: string; query?: string }) =>
|
||||
queryOptions({
|
||||
queryKey: ["AI_PROVIDERS", orgId, "LIST", query ?? ""] as const,
|
||||
|
||||
Reference in New Issue
Block a user