Add reusable tools and assistant bindings

- Introduce a new `Tool` model and `AssistantToolBinding` for managing reusable tools within the application.
- Implement CRUD operations for tools in the new `tools` route, allowing for the creation, retrieval, updating, and deletion of tools.
- Update the `Assistant` model to include a list of tool IDs, enabling assistants to utilize these tools.
- Enhance the backend routes to synchronize tool bindings with assistants, ensuring proper management of tool associations.
- Add frontend components for tool management, including a tool picker in the assistant configuration, improving user experience in tool selection.
- Create a mobile call page to facilitate video calls, integrating camera and microphone selection for enhanced communication capabilities.
- Update API definitions to include tool-related types and operations, ensuring consistency across the application.
- Add a migration script to create the necessary database tables for tools and bindings, supporting the new functionality.
This commit is contained in:
Xin Wang
2026-07-10 10:05:41 +08:00
parent 919325505a
commit 3ed9e1b388
14 changed files with 1815 additions and 22 deletions

View File

@@ -159,6 +159,7 @@ export type Assistant = {
visionModelResourceId: string | null;
modelResourceIds: Partial<Record<ModelType, string>>;
knowledgeBaseId: string | null;
toolIds: string[];
prompt: string;
apiUrl: string;
apiKey: string;
@@ -189,6 +190,69 @@ export const assistantsApi = {
request<{ ok: boolean }>(`/api/assistants/${id}`, { method: "DELETE" }),
};
// ---------- 工具 ----------
export type ToolStatus = "active" | "archived" | "draft";
export type ToolParameter = {
name: string;
type: "string" | "number" | "integer" | "boolean" | "object" | "array";
location: "path" | "query" | "body" | "header";
description: string;
required: boolean;
};
export type EndCallToolDefinition = {
schemaVersion: number;
type: "end_call";
config: {
messageType: "none" | "custom";
customMessage: string;
captureReason: boolean;
};
};
export type HttpToolDefinition = {
schemaVersion: number;
type: "http";
config: {
method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
url: string;
timeoutSeconds: number;
headers: Record<string, string>;
parameters: ToolParameter[];
body: Record<string, unknown>;
};
};
export type Tool = {
id: string;
name: string;
functionName: string;
type: "end_call" | "http";
description: string;
definition: EndCallToolDefinition | HttpToolDefinition;
secrets: Record<string, unknown>;
status: ToolStatus;
updatedAt?: string | null;
};
export type ToolUpsert = Omit<Tool, "id" | "type" | "updatedAt">;
export const toolsApi = {
list: () => request<Tool[]>("/api/tools"),
create: (body: ToolUpsert) =>
request<Tool>("/api/tools", {
method: "POST",
body: JSON.stringify(body),
}),
update: (id: string, body: ToolUpsert) =>
request<Tool>(`/api/tools/${id}`, {
method: "PUT",
body: JSON.stringify(body),
}),
remove: (id: string) =>
request<{ ok: boolean }>(`/api/tools/${id}`, { method: "DELETE" }),
};
// ---------- 知识库 ----------
export type KnowledgeBase = {
id: string;