Refactor backend to support interface-definition driven model resources
- Introduce a new model structure for managing interface definitions and model resources, enhancing the backend's capability to handle various service integrations. - Update the Makefile to reflect changes in database seeding and resource management commands. - Remove the deprecated credentials management routes and replace them with a unified model registry API. - Modify existing routes and schemas to align with the new model structure, ensuring seamless integration with the frontend. - Enhance database seeding scripts to populate new model resources and their configurations. - Update README documentation to reflect the new architecture and usage instructions for model resources and interface definitions.
This commit is contained in:
@@ -9,56 +9,6 @@ export const API_BASE =
|
||||
process.env.NEXT_PUBLIC_API_BASE_URL ?? "http://localhost:8000";
|
||||
|
||||
export type ModelType = "LLM" | "ASR" | "TTS" | "Realtime" | "Embedding";
|
||||
export type InterfaceType = "openai" | "xfyun" | "dashscope" | "gemini";
|
||||
|
||||
/** 列表/详情返回(api_key 已打码) */
|
||||
export type Credential = {
|
||||
id: string;
|
||||
name: string;
|
||||
modelId: string;
|
||||
type: ModelType;
|
||||
interfaceType: InterfaceType;
|
||||
apiUrl: string;
|
||||
apiKey: string;
|
||||
voice: string;
|
||||
speed: number;
|
||||
language: string;
|
||||
isDefault: boolean;
|
||||
};
|
||||
|
||||
/** 创建/更新入参。apiKey 留空或打码值 → 后端保留旧 key */
|
||||
export type CredentialUpsert = {
|
||||
name: string;
|
||||
modelId: string;
|
||||
type: ModelType;
|
||||
interfaceType: InterfaceType;
|
||||
apiUrl: string;
|
||||
apiKey: string;
|
||||
voice: string;
|
||||
speed: number;
|
||||
language: string;
|
||||
isDefault: boolean;
|
||||
};
|
||||
|
||||
export type CredentialTestRequest = Pick<
|
||||
CredentialUpsert,
|
||||
| "modelId"
|
||||
| "type"
|
||||
| "interfaceType"
|
||||
| "apiUrl"
|
||||
| "apiKey"
|
||||
| "voice"
|
||||
| "speed"
|
||||
| "language"
|
||||
>;
|
||||
|
||||
export type CredentialTestResult = {
|
||||
ok: boolean;
|
||||
latencyMs: number | null;
|
||||
message: string;
|
||||
detail: string;
|
||||
};
|
||||
|
||||
async function request<T>(path: string, init?: RequestInit): Promise<T> {
|
||||
const res = await fetch(`${API_BASE}${path}`, {
|
||||
headers: { "Content-Type": "application/json" },
|
||||
@@ -79,31 +29,85 @@ async function request<T>(path: string, init?: RequestInit): Promise<T> {
|
||||
return (text ? JSON.parse(text) : undefined) as T;
|
||||
}
|
||||
|
||||
export const credentialsApi = {
|
||||
list: () => request<Credential[]>("/api/credentials"),
|
||||
create: (body: CredentialUpsert) =>
|
||||
request<Credential>("/api/credentials", {
|
||||
// ---------- 接口定义驱动的模型注册表 ----------
|
||||
export type InterfaceField = {
|
||||
key: string;
|
||||
label: string;
|
||||
group: "values" | "secrets";
|
||||
type: "text" | "url" | "password" | "number" | "boolean" | "select";
|
||||
required: boolean;
|
||||
default?: unknown;
|
||||
options?: string[];
|
||||
};
|
||||
|
||||
export type InterfaceDefinition = {
|
||||
interfaceType: string;
|
||||
name: string;
|
||||
capability: ModelType;
|
||||
fieldSchema: { fields: InterfaceField[] };
|
||||
enabled: boolean;
|
||||
version: number;
|
||||
};
|
||||
|
||||
export type ModelResource = {
|
||||
id: string;
|
||||
name: string;
|
||||
capability: ModelType;
|
||||
interfaceType: string;
|
||||
values: Record<string, unknown>;
|
||||
secrets: Record<string, unknown>;
|
||||
enabled: boolean;
|
||||
isDefault: boolean;
|
||||
updatedAt?: string | null;
|
||||
};
|
||||
|
||||
export type ModelResourceUpsert = Omit<
|
||||
ModelResource,
|
||||
"id" | "capability" | "updatedAt"
|
||||
>;
|
||||
|
||||
export type ModelResourceTestResult = {
|
||||
ok: boolean;
|
||||
latencyMs: number | null;
|
||||
message: string;
|
||||
detail: string;
|
||||
};
|
||||
|
||||
export const interfaceDefinitionsApi = {
|
||||
list: (capability?: ModelType) =>
|
||||
request<InterfaceDefinition[]>(
|
||||
`/api/interface-definitions${capability ? `?capability=${capability}` : ""}`,
|
||||
),
|
||||
};
|
||||
|
||||
export const modelResourcesApi = {
|
||||
list: () => request<ModelResource[]>("/api/model-resources"),
|
||||
create: (body: ModelResourceUpsert) =>
|
||||
request<ModelResource>("/api/model-resources", {
|
||||
method: "POST",
|
||||
body: JSON.stringify(body),
|
||||
}),
|
||||
update: (id: string, body: CredentialUpsert) =>
|
||||
request<Credential>(`/api/credentials/${id}`, {
|
||||
update: (id: string, body: ModelResourceUpsert) =>
|
||||
request<ModelResource>(`/api/model-resources/${id}`, {
|
||||
method: "PUT",
|
||||
body: JSON.stringify(body),
|
||||
}),
|
||||
test: (body: CredentialTestRequest, id?: string) =>
|
||||
request<CredentialTestResult>(
|
||||
id ? `/api/credentials/${id}/test` : "/api/credentials/test",
|
||||
test: (body: ModelResourceUpsert, id?: string) =>
|
||||
request<ModelResourceTestResult>(
|
||||
id ? `/api/model-resources/${id}/test` : "/api/model-resources/test",
|
||||
{
|
||||
method: "POST",
|
||||
body: JSON.stringify(body),
|
||||
},
|
||||
),
|
||||
// 服务端整行复制(含真 key,密钥不经浏览器)
|
||||
duplicate: (id: string) =>
|
||||
request<Credential>(`/api/credentials/${id}/duplicate`, { method: "POST" }),
|
||||
request<ModelResource>(`/api/model-resources/${id}/duplicate`, {
|
||||
method: "POST",
|
||||
}),
|
||||
remove: (id: string) =>
|
||||
request<{ ok: boolean }>(`/api/credentials/${id}`, { method: "DELETE" }),
|
||||
request<{ ok: boolean }>(`/api/model-resources/${id}`, {
|
||||
method: "DELETE",
|
||||
}),
|
||||
};
|
||||
|
||||
// ---------- 助手 ----------
|
||||
@@ -123,10 +127,7 @@ export type Assistant = {
|
||||
runtimeMode: RuntimeMode;
|
||||
greeting: string;
|
||||
enableInterrupt: boolean;
|
||||
llmCredentialId: string | null;
|
||||
asrCredentialId: string | null;
|
||||
ttsCredentialId: string | null;
|
||||
realtimeCredentialId: string | null;
|
||||
modelResourceIds: Partial<Record<ModelType, string>>;
|
||||
knowledgeBaseId: string | null;
|
||||
prompt: string;
|
||||
apiUrl: string;
|
||||
@@ -163,7 +164,7 @@ export type KnowledgeBase = {
|
||||
id: string;
|
||||
name: string;
|
||||
description: string;
|
||||
embeddingCredentialId: string | null;
|
||||
embeddingModelResourceId: string | null;
|
||||
status: string;
|
||||
updatedAt?: string | null;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user