feat: Unify the 'Add Model Provider' modal (#15768)

### What problem does this PR solve?

feat:Unify the 'Add Model Provider' modal

### Type of change

- [x] New Feature (non-breaking change which adds functionality)
- [x] Refactoring
This commit is contained in:
chanx
2026-06-08 16:46:52 +08:00
committed by GitHub
parent 4bbd59823a
commit 144abbe2eb
40 changed files with 3706 additions and 3840 deletions

View File

@@ -14,7 +14,9 @@ import {
IAddProviderRequestBody,
IDeleteProviderInstanceRequestBody,
IListAllModelsRequestParams,
IListProviderModelsRequestBody,
IListProvidersRequestParams,
IModelInfo,
ISetDefaultModelRequestBody,
IUpdateModelStatusRequestBody,
} from '@/interfaces/request/llm';
@@ -33,6 +35,7 @@ export const enum LLMApiAction {
AddProvider = 'addProvider',
AddProviderInstance = 'addProviderInstance',
VerifyProviderConnection = 'verifyProviderConnection',
ListProviderModels = 'listProviderModels',
AddInstanceModel = 'addInstanceModel',
DeleteProviderInstance = 'deleteProviderInstance',
ListDefaultModels = 'listDefaultModels',
@@ -46,6 +49,13 @@ export const LlmKeys = {
[LLMApiAction.AllModels, modelType] as const,
providerInstances: (providerName: string) =>
[LLMApiAction.AddedProviders, providerName, 'instances'] as const,
providerInstance: (providerName: string, instanceName: string) =>
[
LLMApiAction.AddedProviders,
providerName,
instanceName,
'instance',
] as const,
instanceModels: (providerName: string, instanceName: string) =>
[
LLMApiAction.AddedProviders,
@@ -141,6 +151,31 @@ export const useFetchProviderInstances = (providerName: string) => {
return { data, loading };
};
/**
* Fetch full details of a single provider instance (used in viewMode to
* retrieve fields like `baseUrl` that the list endpoint does not return).
* Disabled by default; call from an event handler (e.g. onClick) and
* rely on the returned `refetch` to actually trigger the request.
*/
export const useFetchProviderInstance = (
providerName: string,
instanceName: string,
) => {
return useQuery<IProviderInstance>({
queryKey: LlmKeys.providerInstance(providerName, instanceName),
initialData: undefined as unknown as IProviderInstance,
gcTime: 0,
enabled: false,
queryFn: async () => {
const { data } = await llmService.showProviderInstance(
{ provider_name: providerName, instance_name: instanceName },
true,
);
return (data?.data ?? {}) as IProviderInstance;
},
});
};
export const useFetchInstanceModels = (
providerName: string,
instanceName: string,
@@ -251,6 +286,7 @@ export const useVerifyProviderConnection = () => {
api_key: string;
base_url?: string;
region?: string;
model_info?: IModelInfo[];
}) => {
const { data } = await llmService.verifyProviderConnection(params);
return data;
@@ -260,6 +296,34 @@ export const useVerifyProviderConnection = () => {
return { data, loading, verifyProviderConnection: mutateAsync };
};
export const useListProviderModels = () => {
const { isPending: loading, mutateAsync } = useMutation({
mutationKey: [LLMApiAction.ListProviderModels],
mutationFn: async (params: IListProviderModelsRequestBody) => {
const { provider_name, api_key, base_url } = params;
// GET /api/v1/providers/<provider_name>/models
// The API accepts api_key and base_url as optional query parameters.
// api_key is expected as a string; values in {} object form must be
// JSON-stringified before being sent.
const queryParams: Record<string, string> = {};
if (api_key) {
queryParams.api_key =
typeof api_key === 'string' ? api_key : JSON.stringify(api_key);
}
if (base_url) {
queryParams.base_url = base_url;
}
const { data } = await llmService.listProviderModels(
{ provider_name, params: queryParams },
true,
);
return data;
},
});
return { loading, listProviderModels: mutateAsync };
};
export const useAddInstanceModel = () => {
const queryClient = useQueryClient();
const {