Files
metona-ai-desktop/src/types/global.d.ts
T
thzxx ceb8ee644d feat: 升级至 v0.3.7 — 前后端状态同步与错误处理全量修复
核心引擎修复:
- CE-1: 上下文压缩摘要 role 从 system 改为 user,避免被 adapter 过滤
- CE-2: 工具失败时优先使用 error 字段(engine/openai-format/ollama 三处)
- P0-1: DeadLoopError 终止时正确传 error 参数,前端可见 ERROR 事件
- MT-1: 新增 waitForAbort 方法,abortSession 等待 run 结束再返回
- MT-2: TERMINATED 状态到达时标记步骤完成,避免 Trace Viewer 转圈
- MT-3: 压缩边界检测孤立 tool 消息,避免 API 400 错误
- isRetryableError 与 catch 分支统一 toLowerCase

IPC 与主进程修复:
- P0-2: createAdapter 配置缺失返回 null,FALLBACK_ADAPTER 兜底
- P0-3: reloadAdapter 失败返回 success:false 通知前端
- P1-5: 校验失败发 ERROR+DONE 流事件,防止 isStreaming 卡死
- P1-6: configLoaded 标志,配置加载前禁用发送按钮
- P1-7: MCP initialize 移到 agentLoop 后,完成后同步工具
- P2-11: beforeLoad 在 loadURL 前注册 IPC handler
- P2-12: provider 切换竞态保护

前端状态同步修复:
- clearSessions 后同步清空前端会话与消息状态
- clearMemories 通过 memoryVersion 触发 MemoryViewer 重新加载
- ContextMenu 4 个 session 操作补全 IPC 调用与 try/catch
- useConfig 配置保存失败回滚 UI 并提示
- handleToggle 工具切换失败回滚单个工具状态

错误处理全量补全:
- 所有 await window.metona 调用补全 try/catch 与 toast 反馈
- MCP addServer/toggleServer/removeServer 检查返回值
- showItemInFolder 检查返回值(handleOpen/handleOpenInFolder)
- sse-stream/ollama NDJSON 解析失败改为 log.warn
- adapter throwHttpError 带 status 属性供 isRetryableError 判断
2026-07-16 22:40:32 +08:00

379 lines
10 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* MetonaAI Desktop — 全局类型声明
*
* 为渲染进程暴露的 window.metona API 提供类型支持。
* 使用具体类型替代 unknown,确保类型安全。
*/
// ===== Metona IR 类型(渲染进程侧子集) =====
/** MetonaMessage — IR 标准消息类型(渲染进程可构造的部分) */
interface MetonaMessageInput {
role: 'user' | 'assistant' | 'system' | 'tool';
content: string;
reasoningContent?: string;
toolCalls?: Array<{ id: string; name: string; args: Record<string, unknown> }>;
timestamp: number;
iteration?: number;
images?: Array<{ url: string; detail?: 'low' | 'high' | 'auto' }>;
}
// ===== Agent API =====
interface MetonaStreamEventData {
type: string;
requestId?: string;
sessionId?: string;
iteration?: number;
seq?: number;
timestamp?: number;
delta?: string;
content?: string;
toolCall?: {
id: string;
name: string;
args: Record<string, unknown>;
};
toolResult?: {
toolCallId: string;
toolName: string;
success: boolean;
result?: unknown;
error?: string;
durationMs?: number;
};
usage?: {
inputTokens?: number;
outputTokens?: number;
totalTokens?: number;
};
error?: {
code: string;
message: string;
retryable?: boolean;
};
state?: string;
}
interface MetonaAgentAPI {
/** 发送 MetonaMessageIR 类型)+ sessionId 到主进程 */
sendMessage: (message: MetonaMessageInput, sessionId: string) => Promise<{ success: boolean }>;
onStreamEvent: (callback: (event: MetonaStreamEventData) => void) => () => void;
onStateChange: (callback: (state: {
sessionId: string | null;
iteration: number;
state: string;
previous: string;
current: string;
}) => void) => () => void;
abortSession: (sessionId: string) => Promise<{ success: boolean }>;
onProviderSwitched: (callback: (data: { from?: string; to?: string; reason?: string }) => void) => () => void;
}
// ===== Sessions API =====
interface MetonaSessionInfo {
id: string;
title: string;
createdAt: number;
updatedAt: number;
messageCount: number;
pinned: boolean;
archived: boolean;
}
interface MetonaSessionsAPI {
list: () => Promise<MetonaSessionInfo[]>;
create: (title?: string) => Promise<MetonaSessionInfo>;
rename: (sessionId: string, title: string) => Promise<{ success: boolean }>;
delete: (sessionId: string) => Promise<{ success: boolean }>;
getMessages: (sessionId: string) => Promise<Array<{
id: string;
role: string;
content: string;
reasoningContent?: string;
toolCalls?: unknown[];
toolResult?: unknown;
attachments?: Array<{ id: string; name: string; type: string; size: number; preview?: string; textContent?: string }>;
iteration?: number;
timestamp: number;
}>>;
pin: (sessionId: string, pinned: boolean) => Promise<{ success: boolean }>;
archive: (sessionId: string, archived: boolean) => Promise<{ success: boolean }>;
deleteMessage: (messageId: string) => Promise<{ success: boolean }>;
clearMessages: (sessionId: string) => Promise<{ success: boolean }>;
saveTrace: (sessionId: string, data: { traceSteps: unknown[]; tokenUsage: unknown }) => Promise<{ success: boolean }>;
getTrace: (sessionId: string) => Promise<{ traceSteps: unknown[]; tokenUsage: unknown } | null>;
}
// ===== MCP API =====
interface MetonaMCPServerConfig {
name: string;
transport: 'stdio' | 'sse';
command?: string;
args?: string[];
url?: string;
enabled: boolean;
}
interface MetonaMCPServerStatus {
name: string;
status: 'connecting' | 'connected' | 'disconnected' | 'error';
toolCount: number;
error?: string;
}
interface MetonaMCPAPI {
listServers: () => Promise<MetonaMCPServerStatus[]>;
addServer: (config: MetonaMCPServerConfig) => Promise<{ success: boolean }>;
removeServer: (name: string) => Promise<{ success: boolean }>;
toggleServer: (name: string, enabled: boolean) => Promise<{ success: boolean }>;
}
// ===== Memory API =====
interface MetonaMemorySearchResult {
id: string;
type: 'episodic' | 'semantic' | 'working';
content: string;
summary?: string;
importance: number;
relevanceScore: number;
createdAt: number;
}
interface MetonaMemoryAPI {
search: (query: string, options?: {
topK?: number;
type?: 'episodic' | 'semantic' | 'working';
minImportance?: number;
}) => Promise<MetonaMemorySearchResult[]>;
listAll: (options?: { type?: string; limit?: number }) => Promise<{
success: boolean;
data?: { episodic?: unknown[]; semantic?: unknown[]; working?: unknown[] };
error?: string;
}>;
delete: (type: string, id: string) => Promise<{ success: boolean; error?: string }>;
}
// ===== Config API =====
interface MetonaConfigAPI {
get: (key: string) => Promise<unknown>;
set: (key: string, value: unknown) => Promise<{ success: boolean }>;
}
// ===== App API =====
interface MetonaAppAPI {
getVersion: () => Promise<string>;
getAppDataPath: () => Promise<string>;
openExternal: (url: string) => Promise<{ success: boolean; error?: string }>;
showItemInFolder: (path: string) => Promise<{ success: boolean; error?: string }>;
selectFolder: (defaultPath?: string) => Promise<{ canceled: boolean; path: string }>;
restart: () => Promise<{ success: boolean }>;
}
// ===== Workspace API =====
interface MetonaWorkspaceCheckResult {
valid: boolean;
path?: string;
exists?: boolean;
missingFiles?: string[];
isNewWorkspace?: boolean;
reason?: string;
}
interface MetonaWorkspaceInheritResult {
success: boolean;
inherited?: string[];
failed?: Array<{ file: string; error: string }>;
error?: string;
}
interface MetonaWorkspaceFileInfo {
name: string;
path: string;
exists: boolean;
size: number;
mtime: number;
preview: string;
}
interface MetonaWorkspaceDirInfo {
name: string;
path: string;
exists: boolean;
fileCount: number;
}
interface MetonaWorkspaceInfo {
path: string;
files: MetonaWorkspaceFileInfo[];
dirs: MetonaWorkspaceDirInfo[];
}
interface MetonaWorkspaceAPI {
check: (targetPath: string) => Promise<MetonaWorkspaceCheckResult>;
inheritFiles: (params: { targetPath: string; sourcePath: string; files: string[] }) =>
Promise<MetonaWorkspaceInheritResult>;
getInfo: () => Promise<MetonaWorkspaceInfo>;
}
// ===== Toast API =====
interface MetonaToastAPI {
onShow: (callback: (data: {
type: 'success' | 'error' | 'warning' | 'info';
message: string;
options?: Record<string, unknown>;
}) => void) => () => void;
}
// ===== Tools API =====
interface MetonaToolInfo {
name: string;
description: string;
category: string;
riskLevel: string;
requiresPermission: boolean;
enabled: boolean;
}
interface MetonaToolsAPI {
list: () => Promise<MetonaToolInfo[]>;
toggle: (toolName: string, enabled: boolean) => Promise<{ success: boolean }>;
}
// ===== SearXNG API =====
interface MetonaSearXNGTestResult {
success: boolean;
statusCode?: number;
latencyMs?: number;
error?: string;
}
interface MetonaSearXNGAPI {
/** 测试 SearXNG 实例连接可达性与认证有效性 */
testConnection: (url: string, authKey: string, authType: string) => Promise<MetonaSearXNGTestResult>;
}
// ===== Data API =====
interface MetonaDataAPI {
exportData: (sessionId?: string) => Promise<{ success: boolean; data?: unknown; error?: string }>;
clearSessions: () => Promise<{ success: boolean; error?: string }>;
clearMemories: () => Promise<{ success: boolean; error?: string }>;
clearAuditLogs: () => Promise<{ success: boolean; error?: string }>;
}
// ===== v0.2.0: Tasks API =====
interface MetonaTask {
id: string;
session_id: string;
title: string;
description: string;
status: 'pending' | 'in_progress' | 'completed' | 'blocked' | 'cancelled';
priority: 'low' | 'medium' | 'high' | 'critical';
parent_id: string | null;
assigned_to: string | null;
order_idx: number;
created_at: number;
updated_at: number;
completed_at: number | null;
}
interface MetonaTasksAPI {
list: (sessionId?: string) => Promise<{ success: boolean; data: MetonaTask[] }>;
create: (data: {
sessionId: string;
title: string;
description?: string;
priority?: string;
parentId?: string;
}) => Promise<{ success: boolean; id?: string; error?: string }>;
update: (
id: string,
updates: {
title?: string;
description?: string;
status?: string;
priority?: string;
assignedTo?: string;
},
) => Promise<{ success: boolean; error?: string }>;
delete: (id: string) => Promise<{ success: boolean; error?: string }>;
}
// ===== v0.2.0: Audit API =====
interface MetonaAuditVerifyResult {
success: boolean;
valid: boolean;
totalRecords: number;
verifiedRecords: number;
tamperedId: number | null;
error?: string;
}
interface MetonaAuditAPI {
verifyChain: () => Promise<MetonaAuditVerifyResult>;
query: (filters?: { sessionId?: string; eventType?: string; limit?: number }) =>
Promise<{ success: boolean; data?: unknown[]; error?: string }>;
}
// ===== v0.2.0: Tool Confirmation API =====
interface MetonaConfirmationRequest {
toolCallId: string;
toolName: string;
args: Record<string, unknown>;
riskLevel: string;
reason: string;
}
interface MetonaToolAPI {
onConfirmationRequest: (callback: (request: MetonaConfirmationRequest) => void) => () => void;
sendConfirmationResponse: (response: {
toolCallId: string;
approved: boolean;
remember: boolean;
autoExecute?: boolean;
}) => void;
/** 设置/取消工具的持久化自动执行(跨会话不再询问) */
setAutoExecute: (toolName: string, enabled: boolean) => Promise<{ success: boolean; error?: string }>;
/** 获取已设置为自动执行的工具列表 */
getAutoExecuteList: () => Promise<{ success: boolean; data: string[] }>;
}
// ===== Bridge 接口 =====
interface MetonaBridge {
agent: MetonaAgentAPI;
sessions: MetonaSessionsAPI;
mcp: MetonaMCPAPI;
memory: MetonaMemoryAPI;
config: MetonaConfigAPI;
app: MetonaAppAPI;
workspace: MetonaWorkspaceAPI;
toast: MetonaToastAPI;
tools: MetonaToolsAPI;
data: MetonaDataAPI;
searxng: MetonaSearXNGAPI;
tasks: MetonaTasksAPI;
audit: MetonaAuditAPI;
tool: MetonaToolAPI;
}
// ===== 全局 Window 增强 =====
interface Window {
metona: MetonaBridge;
electron: unknown;
}