669 lines
18 KiB
TypeScript
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));
|
|
}
|