basic provider model selector

This commit is contained in:
miloschwartz
2026-08-10 12:32:00 -04:00
parent 211d3a53f5
commit 93dea0525e
9 changed files with 209 additions and 27 deletions
@@ -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
View File
@@ -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,