Files
xianren_studio/ui/src/api.ts
T

669 lines
18 KiB
TypeScript

import { invoke as rawInvoke } from "@tauri-apps/api/core";
import { listen } from "@tauri-apps/api/event";
/** 统一命令包装:失败时自动上报错误到本地日志,再抛出给界面。 */
async function invoke<T>(command: string, args?: Record<string, unknown>): Promise<T> {
try {
return await rawInvoke<T>(command, args);
} catch (error) {
try {
await rawInvoke("report_error", {
source: command,
message: String(error),
});
} catch {
// 上报失败不影响主流程
}
throw error;
}
}
export interface AppInfo {
version: string;
platform: string;
models_dir: string;
logs_dir: string;
engine_bin: string | null;
engine_exists: boolean;
db_path: string;
}
export interface ModelInfo {
id: string;
repo_id: string;
source: string;
kind: string;
enabled: boolean;
file_name: string;
file_path: string;
file_size: number;
quant: string | null;
family: string | null;
status: string;
sha256: string | null;
base_url: string | null;
api_key: string | null;
api_model: string | null;
meta: Record<string, unknown>;
created_at: string;
}
export interface RepoSummary {
repo_id: string;
author: string;
name: string;
downloads: number | null;
likes: number | null;
tags: string[];
}
export interface ModelFile {
path: string;
size: number;
sha256: string | null;
}
export interface Skill {
id: string;
name: string;
description: string;
content: string;
enabled: boolean;
created_at: string;
}
export interface Agent {
id: string;
kind: string;
name: string;
icon: string;
description: string;
system_prompt: string;
model_id: string | null;
enabled: boolean;
created_at: string;
updated_at: string;
}
export interface AgentInput {
name: string;
icon: string;
description: string;
system_prompt: string;
model_id: string | null;
enabled: boolean;
}
export interface WorkflowNodePosition {
x: number;
y: number;
}
export interface WorkflowNode {
id: string;
type: string;
label: string;
position: WorkflowNodePosition;
data: {
prompt?: string;
content?: string;
template?: string;
model_id?: string | null;
temperature?: number;
max_tokens?: number;
note?: string;
favorite?: boolean;
};
}
export interface WorkflowEdge {
id: string;
from: string;
to: string;
}
export interface Workflow {
id: string;
kind: string;
name: string;
icon: string;
description: string;
nodes: WorkflowNode[];
edges: WorkflowEdge[];
model_id: string | null;
enabled: boolean;
created_at: string;
updated_at: string;
}
export interface WorkflowInput {
name: string;
icon: string;
description: string;
nodes: WorkflowNode[];
edges: WorkflowEdge[];
model_id: string | null;
enabled: boolean;
}
export interface WorkflowRunResult {
workflow_id: string;
results: Record<string, string>;
final: string;
}
export interface WorkflowNodeStatusEvent {
workflow_id: string;
node_id: string;
label: string;
status: string;
text: string | null;
}
export interface ScheduledTask {
id: string;
name: string;
agent_id: string | null;
prompt: string;
interval_minutes: number;
enabled: boolean;
email_enabled: boolean;
email_to: string;
email_mode: string;
email_subject: string;
email_body: string;
next_run_at: string | null;
last_run_at: string | null;
last_status: string;
last_result: string | null;
last_error: string | null;
created_at: string;
updated_at: string;
}
export interface ScheduledTaskInput {
name: string;
agent_id: string | null;
prompt: string;
interval_minutes: number;
enabled: boolean;
email_enabled: boolean;
email_to: string;
email_mode: string;
email_subject: string;
email_body: string;
}
export interface KnowledgeBase {
id: string;
name: string;
description: string;
chunk_size: number;
chunk_overlap: number;
doc_count: number;
chunk_count: number;
created_at: string;
updated_at: string;
}
export interface KnowledgeBaseInput {
name: string;
description: string;
chunk_size: number;
chunk_overlap: number;
}
export interface KbDocument {
id: string;
kb_id: string;
name: string;
file_type: string;
file_size: number;
char_count: number;
chunk_count: number;
created_at: string;
updated_at: string;
}
export interface KbDocumentDetail extends KbDocument {
content: string;
}
export interface KbSearchHit {
chunk_id: string;
document_id: string;
document_name: string;
seq: number;
content: string;
}
export interface KbImportResult {
name: string;
ok: boolean;
char_count: number;
chunk_count: number;
error: string | null;
}
export interface KbSource {
id: string;
kb_id: string;
path: string;
extensions: string;
recursive: boolean;
created_at: string;
}
export interface KbSourceInput {
kb_id: string;
path: string;
extensions: string;
recursive: boolean;
}
export interface KbSourceScanResult {
imported: number;
ignored: number;
errors: string[];
}
export interface McpServer {
id: string;
name: string;
description: string;
url: string;
auth_token: string;
enabled: boolean;
created_at: string;
}
export interface McpToolInfo {
name: string;
description: string;
input_schema: Record<string, unknown>;
}
export interface RecommendedFile {
path: string;
quant: string | null;
size_gb: number | null;
size: string | null;
links: string[];
}
export interface RecommendedModel {
id: string;
source: string | null;
params: string | null;
architecture: string | null;
vision: boolean | null;
description: string | null;
files: RecommendedFile[];
}
export interface EngineStatus {
running: boolean;
port: number | null;
pid: number | null;
model: string | null;
backend: string | null;
ctx_size: number | null;
ngl: number | null;
uptime_secs: number | null;
}
export interface Conversation {
id: string;
title: string;
model_id: string | null;
system_prompt: string | null;
agent_id: string | null;
pinned: boolean;
favorite: boolean;
tools: string[];
created_at: string;
updated_at: string;
}
export interface Message {
id: string;
conversation_id: string;
role: string;
model_id: string | null;
content: string;
tokens_in: number | null;
tokens_out: number | null;
elapsed_ms: number | null;
first_token_ms: number | null;
images: string[];
created_at: string;
}
export interface ChatParams {
temperature: number;
top_p: number;
max_tokens: number;
ctx_size: number;
ngl: number;
}
export interface ChatSendPayload {
conversation_id: string;
model_id: string;
content: string;
params: ChatParams;
images: string[];
}
export interface ChatTokenEvent {
conversation_id: string;
text: string;
}
export interface ChatReasoningEvent {
conversation_id: string;
text: string;
}
export interface ChatDoneEvent {
conversation_id: string;
message_id: string;
model_id: string;
content: string;
reasoning: string;
stopped: boolean;
tokens_in: number | null;
tokens_out: number | null;
tokens_estimated: boolean;
elapsed_ms: number;
first_token_ms: number | null;
}
export interface ChatSuggestionsEvent {
conversation_id: string;
message_id: string;
suggestions: string[];
}
export interface ChatToolStatusEvent {
conversation_id: string;
label: string;
status: string;
}
export interface ChatErrorEvent {
conversation_id: string;
message: string;
}
export interface ChatMessageUpdatedEvent {
conversation_id: string;
message: Message;
}
export interface ChatTitleUpdatedEvent {
conversation_id: string;
title: string;
}
export interface MessageVersion {
id: string;
message_id: string;
content: string;
tokens_out: number | null;
elapsed_ms: number | null;
first_token_ms: number | null;
seq: number;
created_at: string;
}
export interface EngineDeployEvent {
model_id: string;
file_name: string;
state: string;
message: string | null;
}
export interface EngineDeployProgressEvent {
model_id: string;
file_name: string;
percent: number;
stage: string;
}
export interface DownloadProgressEvent {
id: string;
url: string;
file_name: string;
downloaded: number;
total: number | null;
percent: number | null;
speed_bps: number;
status: string;
}
export interface ServerStatus {
running: boolean;
port: number | null;
}
export const api = {
appInfo: () => invoke<AppInfo>("app_info"),
autostartStatus: () => invoke<boolean>("autostart_status"),
autostartSet: (enabled: boolean) => invoke<boolean>("autostart_set", { enabled }),
listAgents: () => invoke<Agent[]>("list_agents"),
addAgent: (input: AgentInput) => invoke<Agent>("add_agent", { input }),
updateAgent: (id: string, input: AgentInput) =>
invoke<void>("update_agent", { id, input }),
removeAgent: (id: string) => invoke<void>("remove_agent", { id }),
setAgentEnabled: (id: string, enabled: boolean) =>
invoke<void>("set_agent_enabled", { id, enabled }),
restorePresetAgents: () => invoke<number>("restore_preset_agents"),
listWorkflows: () => invoke<Workflow[]>("list_workflows"),
addWorkflow: (input: WorkflowInput) => invoke<Workflow>("add_workflow", { input }),
updateWorkflow: (id: string, input: WorkflowInput) =>
invoke<void>("update_workflow", { id, input }),
removeWorkflow: (id: string) => invoke<void>("remove_workflow", { id }),
setWorkflowEnabled: (id: string, enabled: boolean) =>
invoke<void>("set_workflow_enabled", { id, enabled }),
restorePresetWorkflows: () => invoke<number>("restore_preset_workflows"),
runWorkflow: (payload: {
workflow_id: string;
input: string;
model_id: string | null;
}) => invoke<WorkflowRunResult>("run_workflow", { payload }),
listScheduledTasks: () => invoke<ScheduledTask[]>("list_scheduled_tasks"),
addScheduledTask: (input: ScheduledTaskInput) =>
invoke<ScheduledTask>("add_scheduled_task", { input }),
updateScheduledTask: (id: string, input: ScheduledTaskInput) =>
invoke<void>("update_scheduled_task", { id, input }),
removeScheduledTask: (id: string) =>
invoke<void>("remove_scheduled_task", { id }),
setScheduledTaskEnabled: (id: string, enabled: boolean) =>
invoke<void>("set_scheduled_task_enabled", { id, enabled }),
runScheduledTaskNow: (id: string) =>
invoke<void>("run_scheduled_task_now", { id }),
mailTest: (to: string) => invoke<void>("mail_test", { to }),
listKnowledgeBases: () => invoke<KnowledgeBase[]>("list_knowledge_bases"),
addKnowledgeBase: (input: KnowledgeBaseInput) =>
invoke<KnowledgeBase>("add_knowledge_base", { input }),
updateKnowledgeBase: (id: string, input: KnowledgeBaseInput) =>
invoke<void>("update_knowledge_base", { id, input }),
removeKnowledgeBase: (id: string) =>
invoke<void>("remove_knowledge_base", { id }),
listKbDocuments: (kbId: string) =>
invoke<KbDocument[]>("list_kb_documents", { kbId }),
getKbDocument: (documentId: string) =>
invoke<KbDocumentDetail>("get_kb_document", { documentId }),
kbImportDocuments: (
kbId: string,
files: { name: string; data_base64: string }[],
) => invoke<KbImportResult[]>("kb_import_documents", { kbId, files }),
removeKbDocument: (documentId: string) =>
invoke<void>("remove_kb_document", { documentId }),
kbRechunkDocument: (documentId: string) =>
invoke<number>("kb_rechunk_document", { documentId }),
kbSearch: (kbId: string | null, query: string, limit?: number) =>
invoke<KbSearchHit[]>("kb_search", { kbId, query, limit: limit ?? 10 }),
kbListSources: (kbId: string) => invoke<KbSource[]>("kb_list_sources", { kbId }),
kbAddSource: (input: KbSourceInput) =>
invoke<KbSourceScanResult>("kb_add_source", { input }),
kbScanSources: (kbId: string) =>
invoke<KbSourceScanResult>("kb_scan_sources", { kbId }),
kbRemoveSource: (sourceId: string) =>
invoke<number>("kb_remove_source", { sourceId }),
listModels: () => invoke<ModelInfo[]>("list_models"),
importModel: (path: string) => invoke<ModelInfo>("import_model", { path }),
removeModel: (id: string) => invoke<void>("remove_model", { id }),
setModelEnabled: (id: string, enabled: boolean) =>
invoke<void>("set_model_enabled", { id, enabled }),
scanModels: () => invoke<ModelInfo[]>("scan_models"),
addRemoteModel: (name: string, baseUrl: string, apiKey: string, apiModel: string) =>
invoke<ModelInfo>("add_remote_model", { name, baseUrl, apiKey, apiModel }),
listSkills: () => invoke<Skill[]>("list_skills"),
addSkill: (name: string, description: string, content: string, enabled: boolean) =>
invoke<Skill>("add_skill", { name, description, content, enabled }),
updateSkill: (
id: string,
name: string,
description: string,
content: string,
enabled: boolean,
) => invoke<void>("update_skill", { id, name, description, content, enabled }),
removeSkill: (id: string) => invoke<void>("remove_skill", { id }),
setSkillEnabled: (id: string, enabled: boolean) =>
invoke<void>("set_skill_enabled", { id, enabled }),
testSkill: (id: string) => invoke<string>("test_skill", { id }),
listMcpServers: () => invoke<McpServer[]>("list_mcp_servers"),
addMcpServer: (
name: string,
description: string,
url: string,
authToken: string,
enabled: boolean,
) => invoke<McpServer>("add_mcp_server", { name, description, url, authToken, enabled }),
updateMcpServer: (
id: string,
name: string,
description: string,
url: string,
authToken: string,
enabled: boolean,
) => invoke<void>("update_mcp_server", { id, name, description, url, authToken, enabled }),
removeMcpServer: (id: string) => invoke<void>("remove_mcp_server", { id }),
setMcpServerEnabled: (id: string, enabled: boolean) =>
invoke<void>("set_mcp_server_enabled", { id, enabled }),
mcpTestServer: (id: string) => invoke<string>("mcp_test_server", { id }),
mcpListTools: (id: string) => invoke<McpToolInfo[]>("mcp_list_tools", { id }),
mcpCallTool: (id: string, toolName: string, args: string) =>
invoke<string>("mcp_call_tool", { id, toolName, args }),
searchModels: (query: string, source: string) =>
invoke<RepoSummary[]>("search_models", { query, source }),
listModelFiles: (repoId: string, source: string) =>
invoke<ModelFile[]>("list_model_files", { repoId, source }),
listRecommendedModels: () => invoke<RecommendedModel[]>("list_recommended_models"),
importRecommendations: (fileName: string, content: string) =>
invoke<void>("import_recommendations", { fileName, content }),
fetchModelPage: (repoId: string, source: string) =>
invoke<string>("fetch_model_page", { repoId, source }),
settingsGet: () => invoke<Record<string, string>>("settings_get"),
settingsSet: (key: string, value: string) =>
invoke<void>("settings_set", { key, value }),
listConversations: (agentId?: string) =>
invoke<Conversation[]>("list_conversations", { agentId: agentId ?? null }),
createConversation: (title: string, modelId?: string, agentId?: string) =>
invoke<Conversation>("create_conversation", {
title,
modelId: modelId ?? null,
agentId: agentId ?? null,
}),
renameConversation: (id: string, title: string) =>
invoke<void>("rename_conversation", { id, title }),
setConversationPinned: (id: string, pinned: boolean) =>
invoke<void>("set_conversation_pinned", { id, pinned }),
setConversationFavorite: (id: string, favorite: boolean) =>
invoke<void>("set_conversation_favorite", { id, favorite }),
importConversation: (payload: {
title: string;
model_id: string | null;
messages: {
role: string;
content: string;
images: string[];
created_at: string | null;
}[];
}) => invoke<Conversation>("import_conversation", { payload }),
setConversationTools: (id: string, tools: string[]) =>
invoke<void>("set_conversation_tools", { id, tools }),
webSearch: (query: string) =>
invoke<{ title: string; url: string; content: string }[]>("web_search", { query }),
deleteConversation: (id: string) =>
invoke<void>("delete_conversation", { id }),
getMessages: (conversationId: string) =>
invoke<Message[]>("get_messages", { conversationId }),
engineStart: (modelId: string, params: ChatParams) =>
invoke<EngineStatus>("engine_start", { modelId, params }),
deployModel: (modelId: string, params: ChatParams) =>
invoke<void>("deploy_model", { modelId, params }),
engineStop: () => invoke<void>("engine_stop"),
engineStatus: () => invoke<EngineStatus>("engine_status"),
chatSend: (payload: ChatSendPayload) =>
invoke<{ conversation_id: string; message_id: string }>("chat_send", { payload }),
chatStop: (conversationId: string) =>
invoke<void>("chat_stop", { conversationId }),
regenerateMessage: (
conversationId: string,
messageId: string,
params: ChatParams,
) =>
invoke<void>("regenerate_message", {
payload: { conversation_id: conversationId, message_id: messageId, params },
}),
editMessage: (
conversationId: string,
messageId: string,
content: string,
params: ChatParams,
) =>
invoke<void>("edit_message", {
payload: {
conversation_id: conversationId,
message_id: messageId,
content,
params,
},
}),
listMessageVersions: (messageId: string) =>
invoke<MessageVersion[]>("list_message_versions", { messageId }),
applyMessageVersion: (
conversationId: string,
messageId: string,
versionId: string,
) => invoke<void>("apply_message_version", { conversationId, messageId, versionId }),
downloadEnqueue: (
url: string,
fileName: string,
sha256?: string,
repoId?: string,
source?: string,
) =>
invoke<string>("download_enqueue", {
payload: {
url,
file_name: fileName,
sha256: sha256 ?? null,
repo_id: repoId ?? null,
source: source ?? null,
},
}),
serverStart: (port: number, apiKey: string) =>
invoke<ServerStatus>("server_start", { port, apiKey }),
serverStop: () => invoke<void>("server_stop"),
serverStatus: () => invoke<ServerStatus>("server_status"),
openPath: (path: string) => invoke<void>("open_path", { path }),
};
export function onEvent<T>(channel: string, handler: (payload: T) => void) {
return listen<T>(channel, (event) => handler(event.payload));
}