Files
archived-gitea-ai-assistant/frontend/src/services/llmProviderService.ts
jeffusion c45cb34a35 feat(ui): add LLM provider management frontend
Add complete Web UI for LLM provider configuration: provider list with
enable/disable toggles, add/edit dialog, connection testing with result
display, role assignment cards, and model combobox with API/recommended/custom
tags. All labels in Chinese. Add description prop to SelectItem for
Radix Select rendering fix. Register route and nav link.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)
2026-03-24 12:30:13 +08:00

87 lines
2.8 KiB
TypeScript

import api from '@/lib/api';
export type ProviderType = 'openai_compatible' | 'openai_responses' | 'anthropic' | 'gemini';
export interface ProviderDto {
id: string;
name: string;
type: ProviderType;
baseUrl: string | null;
defaultModel: string;
isEnabled: boolean;
hasKey: boolean;
extraConfig: Record<string, unknown>;
createdAt: string;
updatedAt?: string;
}
export interface RoleAssignmentDto {
role: string;
providerId: string | null;
providerName: string | null;
providerType: string | null;
model: string | null;
}
export interface TestResult {
success: boolean;
latencyMs?: number;
model?: string;
message?: string;
error?: string;
}
export const MODEL_SUGGESTIONS: Record<ProviderType, string[]> = {
openai_compatible: ['gpt-4o', 'gpt-4o-mini', 'gpt-4-turbo', 'deepseek-chat', 'qwen-plus'],
openai_responses: ['gpt-4o', 'gpt-4o-mini', 'gpt-4.1', 'gpt-4.1-mini', 'o3-mini'],
anthropic: ['claude-sonnet-4-20250514', 'claude-3-5-haiku-20241022', 'claude-opus-4-20250514'],
gemini: ['gemini-2.5-pro', 'gemini-2.5-flash', 'gemini-2.0-flash'],
};
export const fetchProviders = async (): Promise<ProviderDto[]> => {
const response = await api.get<ProviderDto[]>('/llm/providers');
return response.data;
};
export const createProvider = async (data: Partial<ProviderDto> & { apiKey?: string }): Promise<ProviderDto> => {
const response = await api.post<ProviderDto>('/llm/providers', data);
return response.data;
};
export const updateProvider = async (id: string, data: Partial<ProviderDto>): Promise<ProviderDto> => {
const response = await api.put<ProviderDto>(`/llm/providers/${id}`, data);
return response.data;
};
export const deleteProvider = async (id: string): Promise<void> => {
await api.delete(`/llm/providers/${id}`);
};
export const setApiKey = async (id: string, apiKey: string): Promise<void> => {
await api.put(`/llm/providers/${id}/key`, { apiKey });
};
export const deleteApiKey = async (id: string): Promise<void> => {
await api.delete(`/llm/providers/${id}/key`);
};
export const fetchRoles = async (): Promise<RoleAssignmentDto[]> => {
const response = await api.get<RoleAssignmentDto[]>('/llm/roles');
return response.data;
};
export const setRole = async (role: string, providerId: string | null, model: string | null): Promise<RoleAssignmentDto> => {
const response = await api.put<RoleAssignmentDto>(`/llm/roles/${role}`, { providerId, model });
return response.data;
};
export const testProvider = async (id: string): Promise<TestResult> => {
const response = await api.post<TestResult>(`/llm/providers/${id}/test`);
return response.data;
};
export const fetchModels = async (id: string): Promise<string[]> => {
const response = await api.get<{ models: string[] }>(`/llm/providers/${id}/models`);
return response.data.models;
};