@huyooo/ai-chat-core 0.3.6 → 0.3.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapter/index.d.ts +0 -1
- package/dist/adapter/model-adapter.d.ts +0 -1
- package/dist/adapter/model-options.d.ts +0 -1
- package/dist/adapter/types.d.ts +0 -1
- package/dist/chat-runtime.d.ts +0 -1
- package/dist/constants.d.ts +0 -1
- package/dist/events.d.ts +0 -1
- package/dist/extension/index.d.ts +0 -1
- package/dist/extension/types.d.ts +0 -1
- package/dist/families/index.d.ts +0 -1
- package/dist/families/presets.d.ts +0 -1
- package/dist/families/resolver.d.ts +0 -1
- package/dist/families/types.d.ts +0 -1
- package/dist/governance/command-safety.d.ts +0 -1
- package/dist/governance/governance.d.ts +0 -1
- package/dist/governance/index.d.ts +0 -1
- package/dist/governance/types.d.ts +0 -1
- package/dist/index.d.ts +0 -1
- package/dist/internal/management-args.d.ts +0 -1
- package/dist/internal/management-results.d.ts +0 -1
- package/dist/llm-config.d.ts +0 -1
- package/dist/logger/core.d.ts +0 -1
- package/dist/logger/index.d.ts +0 -1
- package/dist/orchestrator/compression-handler.d.ts +0 -1
- package/dist/orchestrator/context-compressor.d.ts +0 -1
- package/dist/orchestrator/context-summarizer.d.ts +0 -1
- package/dist/orchestrator/index.d.ts +0 -1
- package/dist/orchestrator/orchestrator.d.ts +0 -1
- package/dist/orchestrator/types.d.ts +0 -1
- package/dist/parts/index.d.ts +0 -1
- package/dist/parts/registry.d.ts +0 -1
- package/dist/parts/summaries.d.ts +0 -1
- package/dist/parts/types.d.ts +0 -1
- package/dist/platform.d.ts +0 -1
- package/dist/protocols/anthropic.d.ts +0 -1
- package/dist/protocols/ark.d.ts +0 -1
- package/dist/protocols/deepseek.d.ts +0 -1
- package/dist/protocols/error-utils.d.ts +0 -1
- package/dist/protocols/gemini.d.ts +0 -1
- package/dist/protocols/glm.d.ts +0 -1
- package/dist/protocols/grok.d.ts +0 -1
- package/dist/protocols/index.d.ts +0 -1
- package/dist/protocols/minimax.d.ts +0 -1
- package/dist/protocols/moonshot.d.ts +0 -1
- package/dist/protocols/openai-sse.d.ts +0 -1
- package/dist/protocols/openai.d.ts +0 -1
- package/dist/protocols/qwen.d.ts +0 -1
- package/dist/protocols/responses-sse.d.ts +0 -1
- package/dist/protocols/sse-reader.d.ts +0 -1
- package/dist/protocols/tool-arguments.d.ts +0 -1
- package/dist/protocols/types.d.ts +0 -1
- package/dist/protocols/vercel-gateway.d.ts +0 -1
- package/dist/runtime.d.ts +0 -1
- package/dist/skills/index.d.ts +0 -1
- package/dist/skills/management/admin.d.ts +0 -1
- package/dist/skills/management/index.d.ts +0 -1
- package/dist/skills/management/inputs.d.ts +0 -1
- package/dist/skills/management/operations.d.ts +0 -1
- package/dist/skills/management/types.d.ts +0 -1
- package/dist/skills/registry.d.ts +0 -1
- package/dist/skills/summaries.d.ts +0 -1
- package/dist/skills/types.d.ts +0 -1
- package/dist/test-utils/mock-sse.d.ts +0 -1
- package/dist/tool-manager/define-tool.d.ts +0 -1
- package/dist/tool-manager/formats.d.ts +0 -1
- package/dist/tool-manager/identity.d.ts +0 -1
- package/dist/tool-manager/in-process-provider.d.ts +0 -1
- package/dist/tool-manager/index.d.ts +0 -1
- package/dist/tool-manager/manager.d.ts +0 -1
- package/dist/tool-manager/mcp-provider.d.ts +0 -1
- package/dist/tool-manager/summaries.d.ts +0 -1
- package/dist/tool-manager/types.d.ts +0 -1
- package/dist/types.d.ts +0 -1
- package/package.json +2 -3
- package/dist/adapter/index.d.ts.map +0 -1
- package/dist/adapter/model-adapter.d.ts.map +0 -1
- package/dist/adapter/model-options.d.ts.map +0 -1
- package/dist/adapter/types.d.ts.map +0 -1
- package/dist/chat-runtime.d.ts.map +0 -1
- package/dist/constants.d.ts.map +0 -1
- package/dist/events.d.ts.map +0 -1
- package/dist/extension/index.d.ts.map +0 -1
- package/dist/extension/types.d.ts.map +0 -1
- package/dist/families/index.d.ts.map +0 -1
- package/dist/families/presets.d.ts.map +0 -1
- package/dist/families/resolver.d.ts.map +0 -1
- package/dist/families/types.d.ts.map +0 -1
- package/dist/governance/command-safety.d.ts.map +0 -1
- package/dist/governance/governance.d.ts.map +0 -1
- package/dist/governance/index.d.ts.map +0 -1
- package/dist/governance/types.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/internal/management-args.d.ts.map +0 -1
- package/dist/internal/management-results.d.ts.map +0 -1
- package/dist/llm-config.d.ts.map +0 -1
- package/dist/logger/core.d.ts.map +0 -1
- package/dist/logger/index.d.ts.map +0 -1
- package/dist/orchestrator/compression-handler.d.ts.map +0 -1
- package/dist/orchestrator/context-compressor.d.ts.map +0 -1
- package/dist/orchestrator/context-summarizer.d.ts.map +0 -1
- package/dist/orchestrator/index.d.ts.map +0 -1
- package/dist/orchestrator/orchestrator.d.ts.map +0 -1
- package/dist/orchestrator/types.d.ts.map +0 -1
- package/dist/parts/index.d.ts.map +0 -1
- package/dist/parts/registry.d.ts.map +0 -1
- package/dist/parts/summaries.d.ts.map +0 -1
- package/dist/parts/types.d.ts.map +0 -1
- package/dist/platform.d.ts.map +0 -1
- package/dist/protocols/anthropic.d.ts.map +0 -1
- package/dist/protocols/ark.d.ts.map +0 -1
- package/dist/protocols/deepseek.d.ts.map +0 -1
- package/dist/protocols/error-utils.d.ts.map +0 -1
- package/dist/protocols/gemini.d.ts.map +0 -1
- package/dist/protocols/glm.d.ts.map +0 -1
- package/dist/protocols/grok.d.ts.map +0 -1
- package/dist/protocols/index.d.ts.map +0 -1
- package/dist/protocols/minimax.d.ts.map +0 -1
- package/dist/protocols/moonshot.d.ts.map +0 -1
- package/dist/protocols/openai-sse.d.ts.map +0 -1
- package/dist/protocols/openai.d.ts.map +0 -1
- package/dist/protocols/qwen.d.ts.map +0 -1
- package/dist/protocols/responses-sse.d.ts.map +0 -1
- package/dist/protocols/sse-reader.d.ts.map +0 -1
- package/dist/protocols/tool-arguments.d.ts.map +0 -1
- package/dist/protocols/types.d.ts.map +0 -1
- package/dist/protocols/vercel-gateway.d.ts.map +0 -1
- package/dist/runtime.d.ts.map +0 -1
- package/dist/skills/index.d.ts.map +0 -1
- package/dist/skills/management/admin.d.ts.map +0 -1
- package/dist/skills/management/index.d.ts.map +0 -1
- package/dist/skills/management/inputs.d.ts.map +0 -1
- package/dist/skills/management/operations.d.ts.map +0 -1
- package/dist/skills/management/types.d.ts.map +0 -1
- package/dist/skills/registry.d.ts.map +0 -1
- package/dist/skills/summaries.d.ts.map +0 -1
- package/dist/skills/types.d.ts.map +0 -1
- package/dist/test-utils/mock-sse.d.ts.map +0 -1
- package/dist/tool-manager/define-tool.d.ts.map +0 -1
- package/dist/tool-manager/formats.d.ts.map +0 -1
- package/dist/tool-manager/identity.d.ts.map +0 -1
- package/dist/tool-manager/in-process-provider.d.ts.map +0 -1
- package/dist/tool-manager/index.d.ts.map +0 -1
- package/dist/tool-manager/manager.d.ts.map +0 -1
- package/dist/tool-manager/mcp-provider.d.ts.map +0 -1
- package/dist/tool-manager/summaries.d.ts.map +0 -1
- package/dist/tool-manager/types.d.ts.map +0 -1
- package/dist/types.d.ts.map +0 -1
- package/src/adapter/index.ts +0 -25
- package/src/adapter/model-adapter.ts +0 -196
- package/src/adapter/model-options.ts +0 -143
- package/src/adapter/types.ts +0 -41
- package/src/chat-runtime.ts +0 -515
- package/src/constants.ts +0 -32
- package/src/events.ts +0 -1084
- package/src/extension/index.ts +0 -24
- package/src/extension/types.ts +0 -49
- package/src/families/index.ts +0 -28
- package/src/families/presets.ts +0 -124
- package/src/families/resolver.ts +0 -22
- package/src/families/types.ts +0 -55
- package/src/governance/command-safety.ts +0 -224
- package/src/governance/governance.ts +0 -125
- package/src/governance/index.ts +0 -38
- package/src/governance/types.ts +0 -44
- package/src/index.ts +0 -426
- package/src/internal/management-args.ts +0 -39
- package/src/internal/management-results.ts +0 -60
- package/src/llm-config.ts +0 -137
- package/src/logger/core.ts +0 -96
- package/src/logger/index.ts +0 -8
- package/src/orchestrator/compression-handler.ts +0 -137
- package/src/orchestrator/context-compressor.ts +0 -249
- package/src/orchestrator/context-summarizer.ts +0 -123
- package/src/orchestrator/index.ts +0 -20
- package/src/orchestrator/orchestrator.ts +0 -1002
- package/src/orchestrator/types.ts +0 -70
- package/src/parts/index.ts +0 -20
- package/src/parts/registry.ts +0 -95
- package/src/parts/summaries.ts +0 -40
- package/src/parts/types.ts +0 -63
- package/src/platform.ts +0 -73
- package/src/protocols/anthropic.ts +0 -377
- package/src/protocols/ark.ts +0 -300
- package/src/protocols/deepseek.ts +0 -192
- package/src/protocols/error-utils.ts +0 -71
- package/src/protocols/gemini.ts +0 -352
- package/src/protocols/glm.ts +0 -212
- package/src/protocols/grok.ts +0 -98
- package/src/protocols/index.ts +0 -48
- package/src/protocols/minimax.ts +0 -308
- package/src/protocols/moonshot.ts +0 -186
- package/src/protocols/openai-sse.ts +0 -156
- package/src/protocols/openai.ts +0 -97
- package/src/protocols/qwen.ts +0 -358
- package/src/protocols/responses-sse.ts +0 -224
- package/src/protocols/sse-reader.ts +0 -54
- package/src/protocols/tool-arguments.ts +0 -32
- package/src/protocols/types.ts +0 -198
- package/src/protocols/vercel-gateway.ts +0 -391
- package/src/runtime.ts +0 -167
- package/src/skills/index.ts +0 -29
- package/src/skills/management/admin.ts +0 -170
- package/src/skills/management/index.ts +0 -27
- package/src/skills/management/inputs.ts +0 -79
- package/src/skills/management/operations.ts +0 -256
- package/src/skills/management/types.ts +0 -57
- package/src/skills/registry.ts +0 -120
- package/src/skills/summaries.ts +0 -48
- package/src/skills/types.ts +0 -65
- package/src/test-utils/mock-sse.ts +0 -32
- package/src/tool-manager/define-tool.ts +0 -201
- package/src/tool-manager/formats.ts +0 -146
- package/src/tool-manager/identity.ts +0 -80
- package/src/tool-manager/in-process-provider.ts +0 -164
- package/src/tool-manager/index.ts +0 -63
- package/src/tool-manager/manager.ts +0 -562
- package/src/tool-manager/mcp-provider.ts +0 -509
- package/src/tool-manager/summaries.ts +0 -136
- package/src/tool-manager/types.ts +0 -389
- package/src/types.ts +0 -1142
package/src/types.ts
DELETED
|
@@ -1,1142 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* AI Chat Core 公共类型定义
|
|
3
|
-
*
|
|
4
|
-
* - Agent / Chat 配置、消息与工具契约(含 JSON Schema、ToolResult 信封)
|
|
5
|
-
* - 与治理、MCP、Skills 等模块共享的跨层类型入口
|
|
6
|
-
* - 不包含协议层与编排器专用类型(见 protocols/、orchestrator/types)
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import type {
|
|
10
|
-
AssetApprovalPolicy,
|
|
11
|
-
AssetHostDependency,
|
|
12
|
-
AssetSideEffectLevel,
|
|
13
|
-
AssetSource,
|
|
14
|
-
} from './governance/types';
|
|
15
|
-
import type { McpServerConfig } from './tool-manager/types';
|
|
16
|
-
import { Kind, Type, type TSchema } from '@sinclair/typebox';
|
|
17
|
-
|
|
18
|
-
// ==================== 模式与模型 ====================
|
|
19
|
-
|
|
20
|
-
/** 对话模式 */
|
|
21
|
-
export type ChatMode = 'agent' | 'ask';
|
|
22
|
-
|
|
23
|
-
export type { ModelFamilyId, ModelFamilyConfig } from './families';
|
|
24
|
-
import type { ProtocolId } from './protocols';
|
|
25
|
-
export type { ProtocolId } from './protocols';
|
|
26
|
-
|
|
27
|
-
export type { ModelOption } from './adapter';
|
|
28
|
-
|
|
29
|
-
// ==================== 配置 ====================
|
|
30
|
-
|
|
31
|
-
/** 工具批准回调函数 */
|
|
32
|
-
export type ToolApprovalCallback = (toolCall: {
|
|
33
|
-
id: string;
|
|
34
|
-
name: string;
|
|
35
|
-
toolName?: string;
|
|
36
|
-
extensionId?: string;
|
|
37
|
-
alias?: string;
|
|
38
|
-
displayName?: string;
|
|
39
|
-
args: Record<string, unknown>;
|
|
40
|
-
}) => Promise<boolean>;
|
|
41
|
-
|
|
42
|
-
/** 宿主应用注入的工具执行审计钩子 */
|
|
43
|
-
export interface ToolExecutionAuditHooks {
|
|
44
|
-
startToolCall(input: {
|
|
45
|
-
id?: string | null;
|
|
46
|
-
traceId: string;
|
|
47
|
-
extensionId?: string | null;
|
|
48
|
-
toolName: string;
|
|
49
|
-
displayName?: string | null;
|
|
50
|
-
source?: AssetSource | string | null;
|
|
51
|
-
cwd?: string | null;
|
|
52
|
-
args?: unknown;
|
|
53
|
-
approvalPolicy?: AssetApprovalPolicy | string | null;
|
|
54
|
-
sideEffectLevel?: AssetSideEffectLevel | string | null;
|
|
55
|
-
hostDependency?: AssetHostDependency | string | null;
|
|
56
|
-
metadata?: Record<string, unknown>;
|
|
57
|
-
}): string;
|
|
58
|
-
finishToolCall(input: {
|
|
59
|
-
toolCallId: string;
|
|
60
|
-
traceId: string;
|
|
61
|
-
result?: unknown;
|
|
62
|
-
completedAt?: string;
|
|
63
|
-
}): void;
|
|
64
|
-
failToolCall(input: {
|
|
65
|
-
toolCallId: string;
|
|
66
|
-
traceId: string;
|
|
67
|
-
error: unknown;
|
|
68
|
-
completedAt?: string;
|
|
69
|
-
}): void;
|
|
70
|
-
runWithContext<T>(
|
|
71
|
-
context: {
|
|
72
|
-
conversationId?: string | null;
|
|
73
|
-
turnId?: string | null;
|
|
74
|
-
toolCallId?: string | null;
|
|
75
|
-
traceId?: string | null;
|
|
76
|
-
},
|
|
77
|
-
fn: () => T,
|
|
78
|
-
): T;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/** Agent 配置 */
|
|
82
|
-
export interface AgentConfig {
|
|
83
|
-
/** 统一 LLM 配置(endpoints + models 降级链) */
|
|
84
|
-
llmConfig: import('./llm-config').LLMConfig;
|
|
85
|
-
/** 当前工作目录(必传,浏览器安全:不使用 process.cwd()) */
|
|
86
|
-
cwd: string;
|
|
87
|
-
/** 最大模型轮次(可选,默认不限制) */
|
|
88
|
-
maxIterations?: number;
|
|
89
|
-
/** 最大总执行时长,单位毫秒(可选,默认不限制) */
|
|
90
|
-
maxDurationMs?: number;
|
|
91
|
-
/** 最大工具调用次数(可选,默认不限制) */
|
|
92
|
-
maxToolCalls?: number;
|
|
93
|
-
/** 最大累计 token 数(可选,默认不限制) */
|
|
94
|
-
maxTotalTokens?: number;
|
|
95
|
-
/**
|
|
96
|
-
* 工具列表(Vite 插件风格)
|
|
97
|
-
*
|
|
98
|
-
* 支持多种形式:
|
|
99
|
-
* - 单个工具:getEnvironmentTool()
|
|
100
|
-
* - 工具插件:searchPlugin({ dataDir, workspace })
|
|
101
|
-
* - Promise:await asyncPlugin()
|
|
102
|
-
*/
|
|
103
|
-
tools?: ToolConfigItem[];
|
|
104
|
-
/**
|
|
105
|
-
* 工具批准回调(manual 模式使用)
|
|
106
|
-
* 返回 true 表示批准执行,false 表示跳过
|
|
107
|
-
*/
|
|
108
|
-
onToolApprovalRequest?: ToolApprovalCallback;
|
|
109
|
-
/**
|
|
110
|
-
* 动态获取自动运行配置回调
|
|
111
|
-
* 每次检查工具批准时调用,获取最新配置
|
|
112
|
-
*/
|
|
113
|
-
getAutoRunConfig?: () => Promise<AutoRunConfig | undefined>;
|
|
114
|
-
/**
|
|
115
|
-
* MCP Server 配置列表
|
|
116
|
-
*
|
|
117
|
-
* 初始化时自动连接所有 MCP Server,发现工具并注册到 Agent。
|
|
118
|
-
*/
|
|
119
|
-
mcpServers?: McpServerConfig[];
|
|
120
|
-
/**
|
|
121
|
-
* 宿主应用注入的数据引擎接口(可选)。
|
|
122
|
-
* 传递给 ToolContext.dataEngine,使所有工具可访问平台数据能力。
|
|
123
|
-
*/
|
|
124
|
-
dataEngine?: DataEngineContext;
|
|
125
|
-
/**
|
|
126
|
-
* 宿主应用注入的工具执行审计钩子。
|
|
127
|
-
* 位于 ChatRuntime.executeTool 根入口,覆盖 in-process、MCP 和未来 provider。
|
|
128
|
-
*/
|
|
129
|
-
audit?: ToolExecutionAuditHooks;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
/** 深度思考模式 */
|
|
133
|
-
export type ThinkingMode = 'enabled' | 'disabled';
|
|
134
|
-
|
|
135
|
-
/** 自动运行模式 */
|
|
136
|
-
export type AutoRunMode = 'run-everything' | 'manual';
|
|
137
|
-
|
|
138
|
-
/** 自动运行配置 */
|
|
139
|
-
export interface AutoRunConfig {
|
|
140
|
-
/**
|
|
141
|
-
* 自动运行模式
|
|
142
|
-
* - 'run-everything': 运行所有内容(自动执行)
|
|
143
|
-
* - 'manual': 手动批准(每次执行前询问)
|
|
144
|
-
*/
|
|
145
|
-
mode?: AutoRunMode;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
/**
|
|
149
|
-
* 用户工具定义(透传模式)
|
|
150
|
-
*
|
|
151
|
-
* 只包含 schema,不包含 execute 函数
|
|
152
|
-
* 由客户端执行,服务端透传 tool_call_request 事件
|
|
153
|
-
*/
|
|
154
|
-
export interface UserToolDefinition {
|
|
155
|
-
/** 工具名称 */
|
|
156
|
-
name: string;
|
|
157
|
-
/** 工具描述(供 AI 理解) */
|
|
158
|
-
description: string;
|
|
159
|
-
/** 参数定义(JSON Schema,支持嵌套) */
|
|
160
|
-
parameters: JsonSchemaObject;
|
|
161
|
-
/** 成功时 data 内的业务结构(JSON Schema,可选) */
|
|
162
|
-
outputSchema?: JsonSchemaObject;
|
|
163
|
-
/** 成功返回标准信封结构(JSON Schema,可选,由 outputSchema 自动生成) */
|
|
164
|
-
resolvedOutputSchema?: JsonSchemaObject;
|
|
165
|
-
/** 标准错误返回结构(JSON Schema,可选;不传则使用平台默认错误结构) */
|
|
166
|
-
errorSchema?: JsonSchemaObject;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
/** 聊天配置(每次聊天可变的选项) */
|
|
170
|
-
export interface ChatOptions {
|
|
171
|
-
/** 对话模式 */
|
|
172
|
-
mode?: ChatMode;
|
|
173
|
-
/** 使用的模型 */
|
|
174
|
-
model?: string;
|
|
175
|
-
/** 模型提供商 */
|
|
176
|
-
provider?: ProtocolId;
|
|
177
|
-
/** 是否启用联网搜索 */
|
|
178
|
-
enableWebSearch?: boolean;
|
|
179
|
-
/**
|
|
180
|
-
* 深度思考模式
|
|
181
|
-
* - 'enabled': 强制开启深度思考
|
|
182
|
-
* - 'disabled': 强制关闭深度思考
|
|
183
|
-
*/
|
|
184
|
-
thinkingMode?: ThinkingMode;
|
|
185
|
-
/** 启用的工具名称列表(agent 模式有效,ask 模式强制禁用) */
|
|
186
|
-
enabledTools?: string[];
|
|
187
|
-
/**
|
|
188
|
-
* 宿主侧动态工具选择解析器。
|
|
189
|
-
* 每次模型迭代前调用,用于让 tool_enable 这类管理工具在同一轮 agent loop 的下一次模型请求生效。
|
|
190
|
-
*/
|
|
191
|
-
resolveEnabledTools?: () => Promise<string[] | undefined>;
|
|
192
|
-
/** 自动运行配置 */
|
|
193
|
-
autoRunConfig?: AutoRunConfig;
|
|
194
|
-
/** 单次运行最大模型轮次;不传则使用运行时默认值 */
|
|
195
|
-
maxIterations?: number;
|
|
196
|
-
/** 单次运行最大时长(毫秒);不传则使用运行时默认值 */
|
|
197
|
-
maxDurationMs?: number;
|
|
198
|
-
/** 单次运行最大工具调用次数;不传则使用运行时默认值 */
|
|
199
|
-
maxToolCalls?: number;
|
|
200
|
-
/** 单次运行最大累计 Token;不传则使用运行时默认值 */
|
|
201
|
-
maxTotalTokens?: number;
|
|
202
|
-
/** 对话历史(从数据库加载,无状态架构,需包含完整 tool_calls / tool_call_id) */
|
|
203
|
-
history?: ChatMessage[];
|
|
204
|
-
/**
|
|
205
|
-
* 用户自定义工具(透传模式)
|
|
206
|
-
*
|
|
207
|
-
* 这些工具不在服务端执行,而是:
|
|
208
|
-
* 1. 传递给 AI 模型
|
|
209
|
-
* 2. AI 返回 tool_call 时,发送 tool_call_request 事件给客户端
|
|
210
|
-
* 3. 客户端执行后,发新请求继续对话
|
|
211
|
-
*/
|
|
212
|
-
userTools?: UserToolDefinition[];
|
|
213
|
-
/**
|
|
214
|
-
* 上次请求的计划快照(可选,仅用于断点续传)
|
|
215
|
-
*
|
|
216
|
-
* 正常流程不需要传:AI 会在单次请求内自主创建和管理计划。
|
|
217
|
-
*
|
|
218
|
-
* 仅在请求被中断后需要恢复时使用:
|
|
219
|
-
* - 客户端工具透传模式(请求中断,等客户端执行后重新发请求)
|
|
220
|
-
* - 用户 abort 后想继续
|
|
221
|
-
*/
|
|
222
|
-
/**
|
|
223
|
-
* 宿主平台提示词(可选)
|
|
224
|
-
*
|
|
225
|
-
* 由宿主应用(如 SuperX)注入的平台特定 system prompt 扩展。
|
|
226
|
-
* 用于描述平台特有的能力、工具编排、记忆管理等,避免在核心库中硬编码具体工具名。
|
|
227
|
-
*
|
|
228
|
-
* 注入位置:基础 prompt 之后、Skills 内容之前。
|
|
229
|
-
*/
|
|
230
|
-
platformPrompt?: string;
|
|
231
|
-
/**
|
|
232
|
-
* Skills 内容(启用的 Skills 的 content 数组,由前端/服务端拼好传入)
|
|
233
|
-
*
|
|
234
|
-
* 自动注入到 system prompt 的【用户指令】段落。
|
|
235
|
-
* 前端合并「默认启用的 skills + @ 手动选的 skills」后传入。
|
|
236
|
-
*/
|
|
237
|
-
skillContents?: string[];
|
|
238
|
-
// 注意:每个 provider 内部使用自己的最优参数
|
|
239
|
-
// - ARK: reasoning.effort = 'high'
|
|
240
|
-
// - Qwen: thinking_budget = 38400
|
|
241
|
-
// - Gemini: thinkingLevel = 'high'
|
|
242
|
-
// 外部只需关心 thinkingMode 开关即可
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
// ==================== 工具相关 ====================
|
|
246
|
-
|
|
247
|
-
/** 前端渲染组件类型:内置若干枚举,扩展 Part 使用与 `parts/<name>` 一致的任意字符串 */
|
|
248
|
-
export type RenderType = 'weather' | 'chart' | 'browser' | 'plan' | string;
|
|
249
|
-
|
|
250
|
-
/** 前端动作类型(可扩展) */
|
|
251
|
-
export type ActionType = 'toast' | 'notification' | 'reload' | string;
|
|
252
|
-
|
|
253
|
-
/**
|
|
254
|
-
* 工具 UI 声明(互斥)
|
|
255
|
-
* - render: 在对话流中渲染自定义组件
|
|
256
|
-
* - action: 触发前端动作(通知、刷新等)
|
|
257
|
-
*/
|
|
258
|
-
export type ToolUI =
|
|
259
|
-
| {
|
|
260
|
-
type: 'render';
|
|
261
|
-
name: RenderType;
|
|
262
|
-
props?: Record<string, unknown>;
|
|
263
|
-
/**
|
|
264
|
-
* 仅在 tool_call_result 成功后再创建 render Part。
|
|
265
|
-
*
|
|
266
|
-
* 适用于“结果导向”的卡片:
|
|
267
|
-
* - 运行中没有稳定可展示内容
|
|
268
|
-
* - 最终结果可能被动态抑制(例如 no-op)
|
|
269
|
-
*/
|
|
270
|
-
renderOnResultOnly?: boolean;
|
|
271
|
-
/**
|
|
272
|
-
* 消息内唯一实例(如 plan 进度面板)
|
|
273
|
-
*
|
|
274
|
-
* - true: 同类型 Part 在一条消息中只存在一个,多次调用同一工具时就地更新
|
|
275
|
-
* - false/undefined: 每次调用创建独立 Part(如天气卡片、搜索结果)
|
|
276
|
-
*/
|
|
277
|
-
singleton?: boolean;
|
|
278
|
-
}
|
|
279
|
-
| { type: 'action'; name: ActionType };
|
|
280
|
-
|
|
281
|
-
/** Shell 命令执行结果 */
|
|
282
|
-
export interface ExecResult {
|
|
283
|
-
stdout: string;
|
|
284
|
-
stderr: string;
|
|
285
|
-
exitCode: number;
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
export interface ExecOptions {
|
|
289
|
-
timeout?: number;
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
/** 工具执行上下文 */
|
|
293
|
-
export interface ToolContext {
|
|
294
|
-
/** 当前模型工具调用 ID(由编排器注入,供宿主审计/关联使用) */
|
|
295
|
-
toolCallId?: string;
|
|
296
|
-
/** 当前模型工具调用名称(由编排器注入,供宿主审计/关联使用) */
|
|
297
|
-
toolName?: string;
|
|
298
|
-
/** 当前工作目录(可选,工具需要时由框架注入) */
|
|
299
|
-
cwd?: string;
|
|
300
|
-
/**
|
|
301
|
-
* 当前模型回合允许调用的工具名。
|
|
302
|
-
* 管理类工具必须用它约束搜索、查看和启用范围,避免绕过会话能力选择。
|
|
303
|
-
*/
|
|
304
|
-
allowedToolNames?: readonly string[];
|
|
305
|
-
/** 执行 Shell 命令(可选,工具需要时由框架注入) */
|
|
306
|
-
exec?: (cmd: string, args?: string[], options?: ExecOptions) => Promise<ExecResult>;
|
|
307
|
-
/** 中断信号(用于取消长时间操作) */
|
|
308
|
-
signal?: AbortSignal;
|
|
309
|
-
/** 向对话流推送 stdout 增量(可选) */
|
|
310
|
-
onStdout?: (chunk: string) => void;
|
|
311
|
-
/** 向对话流推送 stderr 增量(可选) */
|
|
312
|
-
onStderr?: (chunk: string) => void;
|
|
313
|
-
/**
|
|
314
|
-
* 宿主应用注入的数据引擎接口(可选)。
|
|
315
|
-
* 市场扩展工具可通过此接口访问数据库、搜索引擎等平台能力。
|
|
316
|
-
*/
|
|
317
|
-
dataEngine?: DataEngineContext;
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
/** 数据引擎上下文 — 宿主应用按需注入 */
|
|
321
|
-
export interface DataEngineContext {
|
|
322
|
-
/** 按名称获取 SQLite 只读连接,用于查询已注册数据库 */
|
|
323
|
-
queryDb: (dbName: string, sql: string, params?: unknown[]) => { columns: string[]; rows: Record<string, unknown>[] };
|
|
324
|
-
/** 列出所有可用数据集(SQLite + Vector + FullText) */
|
|
325
|
-
listDatasets: () => Array<{
|
|
326
|
-
id?: string
|
|
327
|
-
name: string
|
|
328
|
-
storageKind: string
|
|
329
|
-
owner: { ownerType: string; ownerKey: string }
|
|
330
|
-
workspaceKey?: string | null
|
|
331
|
-
customScope?: Record<string, unknown> | null
|
|
332
|
-
description: string
|
|
333
|
-
queryHint?: string
|
|
334
|
-
path?: string
|
|
335
|
-
capabilities?: {
|
|
336
|
-
readable: boolean
|
|
337
|
-
writable: boolean
|
|
338
|
-
queryable: boolean
|
|
339
|
-
searchable?: boolean
|
|
340
|
-
recoverable: boolean
|
|
341
|
-
}
|
|
342
|
-
}>;
|
|
343
|
-
/** 跨数据库关键词搜索 */
|
|
344
|
-
searchAll: (
|
|
345
|
-
keyword: string,
|
|
346
|
-
opts?: {
|
|
347
|
-
ownerType?: string
|
|
348
|
-
ownerKey?: string
|
|
349
|
-
workspaceKey?: string
|
|
350
|
-
storageKind?: string
|
|
351
|
-
mode?: 'exact' | 'semantic' | 'fulltext' | 'hybrid'
|
|
352
|
-
limit?: number
|
|
353
|
-
},
|
|
354
|
-
) => Array<{
|
|
355
|
-
database: string
|
|
356
|
-
table: string
|
|
357
|
-
row: Record<string, unknown>
|
|
358
|
-
resourceName?: string
|
|
359
|
-
storageKind?: string
|
|
360
|
-
matchType?: string
|
|
361
|
-
score?: number
|
|
362
|
-
path?: string
|
|
363
|
-
snippet?: string
|
|
364
|
-
}> | Promise<Array<{
|
|
365
|
-
database: string
|
|
366
|
-
table: string
|
|
367
|
-
row: Record<string, unknown>
|
|
368
|
-
resourceName?: string
|
|
369
|
-
storageKind?: string
|
|
370
|
-
matchType?: string
|
|
371
|
-
score?: number
|
|
372
|
-
path?: string
|
|
373
|
-
snippet?: string
|
|
374
|
-
}>>;
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
// ==================== 工具结果 ====================
|
|
378
|
-
|
|
379
|
-
/** 统一工具结果信封 */
|
|
380
|
-
export interface ToolResult {
|
|
381
|
-
/** 结构化业务数据。序列化后固定放在 data 字段内。 */
|
|
382
|
-
data?: Record<string, unknown>;
|
|
383
|
-
/** 给用户和模型看的简短说明。序列化后固定放在 message 字段内。 */
|
|
384
|
-
message?: string;
|
|
385
|
-
/** @deprecated 使用 message。保留给旧内部调用,序列化时会映射到 message。 */
|
|
386
|
-
text?: string;
|
|
387
|
-
/** 精简摘要,帮助模型快速理解工具结果 */
|
|
388
|
-
_summary?: string;
|
|
389
|
-
/** 附加元数据(调试/埋点/来源信息) */
|
|
390
|
-
metadata?: Record<string, unknown>;
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
export type ToolSuccess<TData extends Record<string, unknown> = Record<string, unknown>> = {
|
|
394
|
-
status: 'ok';
|
|
395
|
-
data: TData;
|
|
396
|
-
message?: string;
|
|
397
|
-
};
|
|
398
|
-
|
|
399
|
-
export function toolOk<TData extends Record<string, unknown>>(
|
|
400
|
-
data: TData,
|
|
401
|
-
message?: string,
|
|
402
|
-
): ToolResult {
|
|
403
|
-
return {
|
|
404
|
-
data,
|
|
405
|
-
message,
|
|
406
|
-
};
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
export function textToolResult(
|
|
410
|
-
text: string,
|
|
411
|
-
options: { summary?: string; metadata?: Record<string, unknown> } = {},
|
|
412
|
-
): ToolResult {
|
|
413
|
-
return {
|
|
414
|
-
message: text,
|
|
415
|
-
_summary: options.summary,
|
|
416
|
-
metadata: options.metadata,
|
|
417
|
-
};
|
|
418
|
-
}
|
|
419
|
-
|
|
420
|
-
export function dataToolResult(
|
|
421
|
-
data: Record<string, unknown>,
|
|
422
|
-
options: { text?: string; summary?: string; metadata?: Record<string, unknown> } = {},
|
|
423
|
-
): ToolResult {
|
|
424
|
-
return {
|
|
425
|
-
data,
|
|
426
|
-
message: options.text,
|
|
427
|
-
_summary: options.summary,
|
|
428
|
-
metadata: options.metadata,
|
|
429
|
-
};
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
export function emptyToolResult(
|
|
433
|
-
options: { summary?: string; metadata?: Record<string, unknown> } = {},
|
|
434
|
-
): ToolResult {
|
|
435
|
-
return {
|
|
436
|
-
text: undefined,
|
|
437
|
-
_summary: options.summary,
|
|
438
|
-
metadata: options.metadata,
|
|
439
|
-
};
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
export interface ToolGovernanceSnapshot {
|
|
443
|
-
approvalPolicy?: AssetApprovalPolicy;
|
|
444
|
-
sideEffectLevel?: AssetSideEffectLevel;
|
|
445
|
-
hostDependency?: AssetHostDependency;
|
|
446
|
-
riskSummary?: string;
|
|
447
|
-
riskTags?: string[];
|
|
448
|
-
riskSignals?: string[];
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
/** 工具执行允许返回的值 */
|
|
452
|
-
export type ToolExecuteResult = ToolResult | Record<string, unknown>;
|
|
453
|
-
|
|
454
|
-
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
455
|
-
return typeof value === 'object' && value !== null;
|
|
456
|
-
}
|
|
457
|
-
|
|
458
|
-
/** 判断对象是否已经是 ToolResult 信封 */
|
|
459
|
-
export function isToolResult(value: unknown): value is ToolResult {
|
|
460
|
-
if (!isRecord(value)) return false;
|
|
461
|
-
return (
|
|
462
|
-
'data' in value ||
|
|
463
|
-
'message' in value ||
|
|
464
|
-
'text' in value ||
|
|
465
|
-
'_summary' in value ||
|
|
466
|
-
'metadata' in value
|
|
467
|
-
);
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
/** 规范化工具结果为统一信封 */
|
|
471
|
-
export function normalizeToolResult(value: ToolExecuteResult | undefined): ToolResult {
|
|
472
|
-
if (!value) return { data: {} };
|
|
473
|
-
if (isToolResult(value)) return value;
|
|
474
|
-
return { data: value };
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
/**
|
|
478
|
-
* 将 ToolResult 序列化为给 LLM / 事件系统使用的最终对象。
|
|
479
|
-
*
|
|
480
|
-
* 设计原则:
|
|
481
|
-
* - 成功结果统一返回 status/data/message envelope。
|
|
482
|
-
* - 业务字段一律位于 data 内,避免与平台协议字段冲突。
|
|
483
|
-
*/
|
|
484
|
-
export function serializeToolResult(result: ToolResult): Record<string, unknown> {
|
|
485
|
-
const output: Record<string, unknown> = {
|
|
486
|
-
status: 'ok',
|
|
487
|
-
data: result.data ?? {},
|
|
488
|
-
};
|
|
489
|
-
const message = result.message ?? result.text;
|
|
490
|
-
if (message !== undefined) output.message = message;
|
|
491
|
-
if (result._summary !== undefined) output._summary = result._summary;
|
|
492
|
-
if (result.metadata !== undefined) output._meta = result.metadata;
|
|
493
|
-
return output;
|
|
494
|
-
}
|
|
495
|
-
|
|
496
|
-
function isToolUi(value: unknown): value is ToolUI {
|
|
497
|
-
if (!isRecord(value)) return false;
|
|
498
|
-
if (value.type === 'action') {
|
|
499
|
-
return typeof value.name === 'string';
|
|
500
|
-
}
|
|
501
|
-
if (value.type === 'render') {
|
|
502
|
-
return typeof value.name === 'string';
|
|
503
|
-
}
|
|
504
|
-
return false;
|
|
505
|
-
}
|
|
506
|
-
|
|
507
|
-
/**
|
|
508
|
-
* 解析单次工具执行最终应使用的 UI。
|
|
509
|
-
*
|
|
510
|
-
* 规则:
|
|
511
|
-
* - 默认沿用工具静态声明的 ui
|
|
512
|
-
* - result.metadata.ui 可覆盖静态 ui
|
|
513
|
-
* - result.metadata.ui === null 表示这次显式不渲染任何 render/action ui
|
|
514
|
-
*/
|
|
515
|
-
export function resolveToolResultUi(
|
|
516
|
-
result: ToolResult,
|
|
517
|
-
fallback?: ToolUI,
|
|
518
|
-
): ToolUI | undefined {
|
|
519
|
-
const metadata = result.metadata;
|
|
520
|
-
if (!metadata || !Object.prototype.hasOwnProperty.call(metadata, 'ui')) {
|
|
521
|
-
return fallback;
|
|
522
|
-
}
|
|
523
|
-
|
|
524
|
-
const override = metadata.ui;
|
|
525
|
-
if (override == null) {
|
|
526
|
-
return undefined;
|
|
527
|
-
}
|
|
528
|
-
|
|
529
|
-
return isToolUi(override) ? override : fallback;
|
|
530
|
-
}
|
|
531
|
-
|
|
532
|
-
function mergeApprovalPolicy(
|
|
533
|
-
left?: AssetApprovalPolicy,
|
|
534
|
-
right?: AssetApprovalPolicy,
|
|
535
|
-
) {
|
|
536
|
-
const order: Record<NonNullable<typeof left>, number> = {
|
|
537
|
-
auto: 0,
|
|
538
|
-
'destructive-only': 1,
|
|
539
|
-
manual: 2,
|
|
540
|
-
};
|
|
541
|
-
if (!left) return right;
|
|
542
|
-
if (!right) return left;
|
|
543
|
-
return order[left] >= order[right] ? left : right;
|
|
544
|
-
}
|
|
545
|
-
|
|
546
|
-
function mergeSideEffectLevel(
|
|
547
|
-
left?: AssetSideEffectLevel,
|
|
548
|
-
right?: AssetSideEffectLevel,
|
|
549
|
-
) {
|
|
550
|
-
const order: Record<NonNullable<typeof left>, number> = {
|
|
551
|
-
read: 0,
|
|
552
|
-
write: 1,
|
|
553
|
-
destructive: 2,
|
|
554
|
-
};
|
|
555
|
-
if (!left) return right;
|
|
556
|
-
if (!right) return left;
|
|
557
|
-
return order[left] >= order[right] ? left : right;
|
|
558
|
-
}
|
|
559
|
-
|
|
560
|
-
function mergeHostDependency(
|
|
561
|
-
left?: AssetHostDependency,
|
|
562
|
-
right?: AssetHostDependency,
|
|
563
|
-
) {
|
|
564
|
-
const order: Record<NonNullable<typeof left>, number> = {
|
|
565
|
-
none: 0,
|
|
566
|
-
'local-app': 1,
|
|
567
|
-
'os-service': 2,
|
|
568
|
-
'remote-service': 3,
|
|
569
|
-
};
|
|
570
|
-
if (!left) return right;
|
|
571
|
-
if (!right) return left;
|
|
572
|
-
return order[left] >= order[right] ? left : right;
|
|
573
|
-
}
|
|
574
|
-
|
|
575
|
-
/** 合并静态治理与基于输入参数的动态治理,始终选择更严格的一侧。 */
|
|
576
|
-
export function mergeToolGovernance(
|
|
577
|
-
base?: ToolGovernanceSnapshot,
|
|
578
|
-
override?: ToolGovernanceSnapshot,
|
|
579
|
-
): ToolGovernanceSnapshot {
|
|
580
|
-
return {
|
|
581
|
-
approvalPolicy: mergeApprovalPolicy(base?.approvalPolicy, override?.approvalPolicy),
|
|
582
|
-
sideEffectLevel: mergeSideEffectLevel(base?.sideEffectLevel, override?.sideEffectLevel),
|
|
583
|
-
hostDependency: mergeHostDependency(base?.hostDependency, override?.hostDependency),
|
|
584
|
-
riskSummary: override?.riskSummary ?? base?.riskSummary,
|
|
585
|
-
riskTags: override?.riskTags ?? base?.riskTags,
|
|
586
|
-
riskSignals: override?.riskSignals ?? base?.riskSignals,
|
|
587
|
-
};
|
|
588
|
-
}
|
|
589
|
-
|
|
590
|
-
/**
|
|
591
|
-
* 基于工具静态声明和本次输入参数,解析执行前应展示/判断的治理信息。
|
|
592
|
-
*/
|
|
593
|
-
export async function resolveToolGovernanceSnapshot(
|
|
594
|
-
tool: Pick<Tool, 'approvalPolicy' | 'sideEffectLevel' | 'hostDependency' | 'assessInputGovernance'> | undefined,
|
|
595
|
-
args: Record<string, unknown>,
|
|
596
|
-
): Promise<ToolGovernanceSnapshot> {
|
|
597
|
-
const staticGovernance: ToolGovernanceSnapshot = tool
|
|
598
|
-
? {
|
|
599
|
-
approvalPolicy: tool.approvalPolicy,
|
|
600
|
-
sideEffectLevel: tool.sideEffectLevel,
|
|
601
|
-
hostDependency: tool.hostDependency,
|
|
602
|
-
}
|
|
603
|
-
: {};
|
|
604
|
-
const dynamicGovernance = tool?.assessInputGovernance
|
|
605
|
-
? await tool.assessInputGovernance(args)
|
|
606
|
-
: undefined;
|
|
607
|
-
return mergeToolGovernance(staticGovernance, dynamicGovernance);
|
|
608
|
-
}
|
|
609
|
-
|
|
610
|
-
// ==================== 工具错误 ====================
|
|
611
|
-
|
|
612
|
-
/** 工具错误码(预定义 + 可扩展) */
|
|
613
|
-
export type ToolErrorCode =
|
|
614
|
-
| 'INVALID_PARAMS'
|
|
615
|
-
| 'NOT_FOUND'
|
|
616
|
-
| 'PERMISSION_DENIED'
|
|
617
|
-
| 'OPERATION_FAILED'
|
|
618
|
-
| 'TIMEOUT'
|
|
619
|
-
| 'NETWORK_ERROR'
|
|
620
|
-
| (string & {});
|
|
621
|
-
|
|
622
|
-
/** 标准工具错误分类 */
|
|
623
|
-
export type ToolErrorCategory =
|
|
624
|
-
| 'validation'
|
|
625
|
-
| 'permission'
|
|
626
|
-
| 'network'
|
|
627
|
-
| 'not_found'
|
|
628
|
-
| 'conflict'
|
|
629
|
-
| 'runtime'
|
|
630
|
-
| 'external'
|
|
631
|
-
| (string & {});
|
|
632
|
-
|
|
633
|
-
/** 工具错误结构 */
|
|
634
|
-
export interface ToolError {
|
|
635
|
-
message: string;
|
|
636
|
-
code?: ToolErrorCode;
|
|
637
|
-
category?: ToolErrorCategory;
|
|
638
|
-
suggestion?: string;
|
|
639
|
-
retryable?: boolean;
|
|
640
|
-
details?: Record<string, unknown>;
|
|
641
|
-
}
|
|
642
|
-
|
|
643
|
-
/** 结构化工具异常 */
|
|
644
|
-
export class ToolException extends Error {
|
|
645
|
-
readonly toolError: ToolError;
|
|
646
|
-
|
|
647
|
-
constructor(toolError: ToolError) {
|
|
648
|
-
super(toolError.message);
|
|
649
|
-
this.name = 'ToolException';
|
|
650
|
-
this.toolError = toolError;
|
|
651
|
-
}
|
|
652
|
-
}
|
|
653
|
-
|
|
654
|
-
/** 判断是否为结构化工具错误 */
|
|
655
|
-
export function isToolError(e: unknown): e is ToolException {
|
|
656
|
-
return e instanceof ToolException;
|
|
657
|
-
}
|
|
658
|
-
|
|
659
|
-
/**
|
|
660
|
-
* 抛出结构化工具错误
|
|
661
|
-
*
|
|
662
|
-
* @example
|
|
663
|
-
* throwToolError('文件不存在')
|
|
664
|
-
* throwToolError({ message: '网络超时', code: 'NETWORK_ERROR', retryable: true })
|
|
665
|
-
*/
|
|
666
|
-
export function throwToolError(message: string): never;
|
|
667
|
-
export function throwToolError(error: ToolError): never;
|
|
668
|
-
export function throwToolError(input: string | ToolError): never {
|
|
669
|
-
throw new ToolException(typeof input === 'string' ? { message: input, code: 'OPERATION_FAILED' } : input);
|
|
670
|
-
}
|
|
671
|
-
|
|
672
|
-
/** JSON Schema 属性定义(支持嵌套,符合 JSON Schema 规范) */
|
|
673
|
-
export interface JsonSchemaProperty {
|
|
674
|
-
type?: string;
|
|
675
|
-
const?: unknown;
|
|
676
|
-
description?: string;
|
|
677
|
-
format?: string;
|
|
678
|
-
enum?: unknown[];
|
|
679
|
-
items?: JsonSchemaProperty;
|
|
680
|
-
properties?: Record<string, JsonSchemaProperty>;
|
|
681
|
-
required?: string[];
|
|
682
|
-
default?: unknown;
|
|
683
|
-
additionalProperties?: boolean | JsonSchemaProperty;
|
|
684
|
-
anyOf?: JsonSchemaProperty[];
|
|
685
|
-
oneOf?: JsonSchemaProperty[];
|
|
686
|
-
}
|
|
687
|
-
|
|
688
|
-
/** JSON Schema 对象类型(工具参数的根类型) */
|
|
689
|
-
export interface JsonSchemaObject {
|
|
690
|
-
type: 'object';
|
|
691
|
-
properties: Record<string, JsonSchemaProperty>;
|
|
692
|
-
required?: string[];
|
|
693
|
-
description?: string;
|
|
694
|
-
additionalProperties?: boolean | JsonSchemaProperty;
|
|
695
|
-
}
|
|
696
|
-
|
|
697
|
-
/** 平台标准工具错误返回结构 */
|
|
698
|
-
export const STANDARD_TOOL_ERROR_SCHEMA: JsonSchemaObject = {
|
|
699
|
-
type: 'object',
|
|
700
|
-
description: '工具失败时的平台标准错误结构。成功结果使用工具自己的 resolvedOutputSchema。',
|
|
701
|
-
properties: {
|
|
702
|
-
status: {
|
|
703
|
-
type: 'string',
|
|
704
|
-
enum: ['error'],
|
|
705
|
-
description: '固定为 error,表示工具执行失败。',
|
|
706
|
-
},
|
|
707
|
-
failureReason: {
|
|
708
|
-
type: 'string',
|
|
709
|
-
description: '执行层失败原因,例如 parse_error、denied、timeout、execution_error。',
|
|
710
|
-
},
|
|
711
|
-
error: {
|
|
712
|
-
type: 'object',
|
|
713
|
-
description: '结构化错误信息。',
|
|
714
|
-
properties: {
|
|
715
|
-
code: {
|
|
716
|
-
type: 'string',
|
|
717
|
-
description: '稳定错误码,例如 INVALID_PARAMS、NETWORK_ERROR、NOT_FOUND。',
|
|
718
|
-
},
|
|
719
|
-
message: {
|
|
720
|
-
type: 'string',
|
|
721
|
-
description: '给用户和模型看的错误说明。',
|
|
722
|
-
},
|
|
723
|
-
category: {
|
|
724
|
-
type: 'string',
|
|
725
|
-
enum: ['validation', 'permission', 'network', 'not_found', 'conflict', 'runtime', 'external'],
|
|
726
|
-
description: '错误分类,用于判断是否换参数、重试、申请权限或停止。',
|
|
727
|
-
},
|
|
728
|
-
retryable: {
|
|
729
|
-
type: 'boolean',
|
|
730
|
-
description: '是否建议用相同目标稍后重试。',
|
|
731
|
-
},
|
|
732
|
-
suggestion: {
|
|
733
|
-
type: 'string',
|
|
734
|
-
description: '可选修复建议。',
|
|
735
|
-
},
|
|
736
|
-
details: {
|
|
737
|
-
type: 'object',
|
|
738
|
-
description: '可选调试详情,字段随错误码变化。',
|
|
739
|
-
additionalProperties: true,
|
|
740
|
-
},
|
|
741
|
-
},
|
|
742
|
-
required: ['message'],
|
|
743
|
-
additionalProperties: false,
|
|
744
|
-
},
|
|
745
|
-
},
|
|
746
|
-
required: ['status', 'failureReason', 'error'],
|
|
747
|
-
additionalProperties: false,
|
|
748
|
-
};
|
|
749
|
-
|
|
750
|
-
function isTypeBoxSchema(schema: Record<string, unknown>): schema is TSchema {
|
|
751
|
-
return Object.prototype.hasOwnProperty.call(schema, Kind);
|
|
752
|
-
}
|
|
753
|
-
|
|
754
|
-
function toSchemaOptions(schema: Record<string, unknown>): Record<string, unknown> {
|
|
755
|
-
const options: Record<string, unknown> = {};
|
|
756
|
-
const optionKeys = [
|
|
757
|
-
'description',
|
|
758
|
-
'default',
|
|
759
|
-
'title',
|
|
760
|
-
'format',
|
|
761
|
-
'pattern',
|
|
762
|
-
'minLength',
|
|
763
|
-
'maxLength',
|
|
764
|
-
'minimum',
|
|
765
|
-
'maximum',
|
|
766
|
-
'exclusiveMinimum',
|
|
767
|
-
'exclusiveMaximum',
|
|
768
|
-
'multipleOf',
|
|
769
|
-
'minItems',
|
|
770
|
-
'maxItems',
|
|
771
|
-
'uniqueItems',
|
|
772
|
-
];
|
|
773
|
-
|
|
774
|
-
for (const key of optionKeys) {
|
|
775
|
-
const value = schema[key];
|
|
776
|
-
if (value !== undefined) {
|
|
777
|
-
options[key] = value;
|
|
778
|
-
}
|
|
779
|
-
}
|
|
780
|
-
|
|
781
|
-
const additionalProperties = schema.additionalProperties;
|
|
782
|
-
if (typeof additionalProperties === 'boolean') {
|
|
783
|
-
options.additionalProperties = additionalProperties;
|
|
784
|
-
} else if (additionalProperties && typeof additionalProperties === 'object') {
|
|
785
|
-
options.additionalProperties = jsonSchemaToTypeBoxSchema(additionalProperties as Record<string, unknown>);
|
|
786
|
-
}
|
|
787
|
-
|
|
788
|
-
return options;
|
|
789
|
-
}
|
|
790
|
-
|
|
791
|
-
function toTypeBoxLiteral(value: unknown, options: Record<string, unknown>): TSchema {
|
|
792
|
-
if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
|
|
793
|
-
return Type.Literal(value, options);
|
|
794
|
-
}
|
|
795
|
-
if (value === null) {
|
|
796
|
-
return Type.Null(options);
|
|
797
|
-
}
|
|
798
|
-
return Type.Any(options);
|
|
799
|
-
}
|
|
800
|
-
|
|
801
|
-
function toTypeBoxEnumSchema(
|
|
802
|
-
enumValues: readonly unknown[],
|
|
803
|
-
schema: Record<string, unknown>,
|
|
804
|
-
): TSchema {
|
|
805
|
-
const options = toSchemaOptions(schema);
|
|
806
|
-
const literals = enumValues.map(value => toTypeBoxLiteral(value, {}));
|
|
807
|
-
if (literals.length === 1) {
|
|
808
|
-
return toTypeBoxLiteral(enumValues[0], options);
|
|
809
|
-
}
|
|
810
|
-
return Type.Union(literals, options);
|
|
811
|
-
}
|
|
812
|
-
|
|
813
|
-
export function jsonSchemaToTypeBoxSchema(schema: Record<string, unknown>): TSchema {
|
|
814
|
-
if (isTypeBoxSchema(schema)) return schema;
|
|
815
|
-
|
|
816
|
-
if (Object.prototype.hasOwnProperty.call(schema, 'const')) {
|
|
817
|
-
return toTypeBoxLiteral(schema.const, toSchemaOptions(schema));
|
|
818
|
-
}
|
|
819
|
-
|
|
820
|
-
const enumValues = Array.isArray(schema.enum) ? schema.enum : undefined;
|
|
821
|
-
if (enumValues && enumValues.length > 0) {
|
|
822
|
-
return toTypeBoxEnumSchema(enumValues, schema);
|
|
823
|
-
}
|
|
824
|
-
|
|
825
|
-
const unionSchemas = Array.isArray(schema.oneOf)
|
|
826
|
-
? schema.oneOf
|
|
827
|
-
: Array.isArray(schema.anyOf)
|
|
828
|
-
? schema.anyOf
|
|
829
|
-
: undefined;
|
|
830
|
-
if (unionSchemas && unionSchemas.length > 0) {
|
|
831
|
-
return Type.Union(
|
|
832
|
-
unionSchemas.map(value => value && typeof value === 'object'
|
|
833
|
-
? jsonSchemaToTypeBoxSchema(value as Record<string, unknown>)
|
|
834
|
-
: Type.Any()),
|
|
835
|
-
toSchemaOptions(schema),
|
|
836
|
-
);
|
|
837
|
-
}
|
|
838
|
-
|
|
839
|
-
const type = schema.type;
|
|
840
|
-
if (Array.isArray(type)) {
|
|
841
|
-
return Type.Union(
|
|
842
|
-
type.map(value => jsonSchemaToTypeBoxSchema({ ...schema, type: value, oneOf: undefined, anyOf: undefined })),
|
|
843
|
-
toSchemaOptions(schema),
|
|
844
|
-
);
|
|
845
|
-
}
|
|
846
|
-
|
|
847
|
-
const options = toSchemaOptions(schema);
|
|
848
|
-
|
|
849
|
-
if (type === 'string') {
|
|
850
|
-
return Type.String(options);
|
|
851
|
-
}
|
|
852
|
-
if (type === 'number') {
|
|
853
|
-
return Type.Number(options);
|
|
854
|
-
}
|
|
855
|
-
if (type === 'integer') {
|
|
856
|
-
return Type.Integer(options);
|
|
857
|
-
}
|
|
858
|
-
if (type === 'boolean') {
|
|
859
|
-
return Type.Boolean(options);
|
|
860
|
-
}
|
|
861
|
-
if (type === 'null') {
|
|
862
|
-
return Type.Null(options);
|
|
863
|
-
}
|
|
864
|
-
if (type === 'array') {
|
|
865
|
-
const items = schema.items;
|
|
866
|
-
const itemSchema = items && typeof items === 'object'
|
|
867
|
-
? jsonSchemaToTypeBoxSchema(items as Record<string, unknown>)
|
|
868
|
-
: Type.Any();
|
|
869
|
-
return Type.Array(itemSchema, options);
|
|
870
|
-
}
|
|
871
|
-
if (type === 'object' || typeof schema.properties === 'object') {
|
|
872
|
-
const properties = schema.properties;
|
|
873
|
-
const required = Array.isArray(schema.required) ? new Set(schema.required.filter(value => typeof value === 'string')) : new Set<string>();
|
|
874
|
-
const entries = properties && typeof properties === 'object'
|
|
875
|
-
? Object.entries(properties)
|
|
876
|
-
: [];
|
|
877
|
-
const mappedProperties: Record<string, TSchema> = {};
|
|
878
|
-
|
|
879
|
-
for (const [key, value] of entries) {
|
|
880
|
-
const propertySchema = value && typeof value === 'object'
|
|
881
|
-
? jsonSchemaToTypeBoxSchema(value as Record<string, unknown>)
|
|
882
|
-
: Type.Any();
|
|
883
|
-
mappedProperties[key] = required.has(key) ? propertySchema : Type.Optional(propertySchema);
|
|
884
|
-
}
|
|
885
|
-
|
|
886
|
-
return Type.Object(mappedProperties, options);
|
|
887
|
-
}
|
|
888
|
-
|
|
889
|
-
return Type.Any(options);
|
|
890
|
-
}
|
|
891
|
-
|
|
892
|
-
export function createResolvedOutputSchema(dataSchema: JsonSchemaObject): JsonSchemaObject {
|
|
893
|
-
const dataWithDescription = dataSchema.description
|
|
894
|
-
? dataSchema
|
|
895
|
-
: { ...dataSchema, description: '工具成功时的业务数据。' };
|
|
896
|
-
|
|
897
|
-
return Type.Object({
|
|
898
|
-
status: Type.Literal('ok', { description: '固定为 ok,表示工具执行成功。' }),
|
|
899
|
-
data: jsonSchemaToTypeBoxSchema(dataWithDescription as unknown as Record<string, unknown>),
|
|
900
|
-
message: Type.Optional(Type.String({ description: '可选。给用户和模型看的简短说明,不承载业务数据。' })),
|
|
901
|
-
}, {
|
|
902
|
-
description: '工具成功时的平台标准返回结构。业务字段固定放在 data 内。',
|
|
903
|
-
}) as unknown as JsonSchemaObject;
|
|
904
|
-
}
|
|
905
|
-
|
|
906
|
-
/**
|
|
907
|
-
* 工具接口
|
|
908
|
-
*
|
|
909
|
-
* @example
|
|
910
|
-
* ```typescript
|
|
911
|
-
* const myTool: Tool = {
|
|
912
|
-
* name: 'my_tool',
|
|
913
|
-
* description: '我的自定义工具',
|
|
914
|
-
* parameters: { type: 'object', properties: { query: { type: 'string' } }, required: ['query'] },
|
|
915
|
-
* execute: async (args) => ({ result: args.query })
|
|
916
|
-
* };
|
|
917
|
-
* ```
|
|
918
|
-
*/
|
|
919
|
-
export interface Tool {
|
|
920
|
-
/** 工具全局唯一 ID(可选,不传则由 provider 生成) */
|
|
921
|
-
id?: string;
|
|
922
|
-
/**
|
|
923
|
-
* 工具集 ID(scope 命名空间)
|
|
924
|
-
*
|
|
925
|
-
* 设置后表示此工具属于某个 scoped 工具集:
|
|
926
|
-
* - identity: `source:assetId:name`
|
|
927
|
-
* - alias: `assetId__name`
|
|
928
|
-
*
|
|
929
|
-
* 不设置则 name 同时作为 assetId(独立工具):
|
|
930
|
-
* - identity: `source:name`
|
|
931
|
-
* - alias: `name`
|
|
932
|
-
*/
|
|
933
|
-
assetId?: string;
|
|
934
|
-
/** scope 内的工具名(即 assetId/name 两段式中的 name) */
|
|
935
|
-
name: string;
|
|
936
|
-
/** 对模型暴露的别名(可选,不传则由 provider 生成) */
|
|
937
|
-
alias?: string;
|
|
938
|
-
/** UI 展示名称(可选) */
|
|
939
|
-
displayName?: string;
|
|
940
|
-
/** 工具描述(供 AI 理解) */
|
|
941
|
-
description: string;
|
|
942
|
-
/** 参数定义(JSON Schema) */
|
|
943
|
-
parameters: JsonSchemaObject;
|
|
944
|
-
/** 成功时 data 内的业务结构(JSON Schema,可选) */
|
|
945
|
-
outputSchema?: JsonSchemaObject;
|
|
946
|
-
/** 成功返回标准信封结构(JSON Schema,可选,由 outputSchema 自动生成) */
|
|
947
|
-
resolvedOutputSchema?: JsonSchemaObject;
|
|
948
|
-
/** 失败返回结构(JSON Schema;不传时描述符层使用平台标准错误结构) */
|
|
949
|
-
errorSchema?: JsonSchemaObject;
|
|
950
|
-
/**
|
|
951
|
-
* UI 声明(可选)
|
|
952
|
-
* - render: 在对话流中渲染自定义组件
|
|
953
|
-
* - action: 执行成功后触发前端动作
|
|
954
|
-
*/
|
|
955
|
-
ui?: ToolUI;
|
|
956
|
-
/**
|
|
957
|
-
* 是否需要用户手动批准(覆盖全局 autoRunMode)
|
|
958
|
-
*
|
|
959
|
-
* 设为 true 时无论全局配置如何,该工具必须用户确认才执行
|
|
960
|
-
*/
|
|
961
|
-
requiresApproval?: boolean;
|
|
962
|
-
/** 审批策略。`destructive-only` 表示仅 destructive 工具需要批准。 */
|
|
963
|
-
approvalPolicy?: AssetApprovalPolicy;
|
|
964
|
-
/** 副作用等级。用于审批和风险展示。 */
|
|
965
|
-
sideEffectLevel?: AssetSideEffectLevel;
|
|
966
|
-
/** 宿主依赖类型。用于治理和展示。 */
|
|
967
|
-
hostDependency?: AssetHostDependency;
|
|
968
|
-
/**
|
|
969
|
-
* 基于本次输入参数预判治理信息(可选)。
|
|
970
|
-
*
|
|
971
|
-
* 设计约束:
|
|
972
|
-
* - 用于执行前的动态风险评估
|
|
973
|
-
* - Orchestrator 只会将其与静态治理做“更严格”的合并,不会放宽静态治理
|
|
974
|
-
*/
|
|
975
|
-
assessInputGovernance?: (
|
|
976
|
-
args: Record<string, unknown>,
|
|
977
|
-
) => ToolGovernanceSnapshot | Promise<ToolGovernanceSnapshot | undefined> | undefined;
|
|
978
|
-
/** 分发来源(注册时如设置则覆盖 provider 默认值) */
|
|
979
|
-
source?: import('./governance/types').AssetSource;
|
|
980
|
-
/** 工具分类(供 ToolRegistry 发现使用) */
|
|
981
|
-
category?: string;
|
|
982
|
-
/** 工具标签(供 ToolRegistry 搜索使用) */
|
|
983
|
-
tags?: string[];
|
|
984
|
-
/** 超时时间(毫秒),由框架通过 AbortSignal 强制执行 */
|
|
985
|
-
timeout?: number;
|
|
986
|
-
/**
|
|
987
|
-
* 执行函数
|
|
988
|
-
*
|
|
989
|
-
* 成功返回 ToolResult 或普通对象,框架会统一规范化后再传给 LLM。
|
|
990
|
-
* 失败统一 throw(推荐使用 throwToolError())。
|
|
991
|
-
*/
|
|
992
|
-
execute: (args: Record<string, unknown>, context: ToolContext) => Promise<ToolExecuteResult>;
|
|
993
|
-
}
|
|
994
|
-
|
|
995
|
-
/** 工具执行器接口(供 Agent 内部使用,自定义命令执行环境) */
|
|
996
|
-
export interface ToolExecutor {
|
|
997
|
-
/** 执行 Shell 命令 */
|
|
998
|
-
executeCommand(
|
|
999
|
-
command: string,
|
|
1000
|
-
cwd?: string,
|
|
1001
|
-
signal?: AbortSignal,
|
|
1002
|
-
hooks?: {
|
|
1003
|
-
onStdout?: (chunk: string) => void;
|
|
1004
|
-
onStderr?: (chunk: string) => void;
|
|
1005
|
-
},
|
|
1006
|
-
timeout?: number,
|
|
1007
|
-
): Promise<{ success: boolean; output?: string; error?: string }>;
|
|
1008
|
-
}
|
|
1009
|
-
|
|
1010
|
-
// ==================== 工具插件(Vite 插件风格) ====================
|
|
1011
|
-
|
|
1012
|
-
/**
|
|
1013
|
-
* 工具插件实例
|
|
1014
|
-
*
|
|
1015
|
-
* 由 createXxxPlugin() 返回,可直接在 tools 数组中展开使用
|
|
1016
|
-
*/
|
|
1017
|
-
export interface ToolPlugin {
|
|
1018
|
-
/** 插件提供的工具数组 */
|
|
1019
|
-
tools: Tool[];
|
|
1020
|
-
/** 插件控制方法(可选,由各插件自定义) */
|
|
1021
|
-
[key: string]: unknown;
|
|
1022
|
-
}
|
|
1023
|
-
|
|
1024
|
-
/**
|
|
1025
|
-
* 创建单个工具插件(辅助函数)
|
|
1026
|
-
*
|
|
1027
|
-
* @example
|
|
1028
|
-
* ```typescript
|
|
1029
|
-
* export function getEnvironmentTool(): ToolPlugin {
|
|
1030
|
-
* return tool({
|
|
1031
|
-
* name: 'get_environment',
|
|
1032
|
-
* description: '...',
|
|
1033
|
-
* parameters: { ... },
|
|
1034
|
-
* execute: async (args, context) => { ... }
|
|
1035
|
-
* });
|
|
1036
|
-
* }
|
|
1037
|
-
* ```
|
|
1038
|
-
*/
|
|
1039
|
-
export function tool(t: Tool): ToolPlugin {
|
|
1040
|
-
return { tools: [t] };
|
|
1041
|
-
}
|
|
1042
|
-
|
|
1043
|
-
/**
|
|
1044
|
-
* 创建多个工具插件(辅助函数)
|
|
1045
|
-
*
|
|
1046
|
-
* @example
|
|
1047
|
-
* ```typescript
|
|
1048
|
-
* export function myPlugin(): ToolPlugin {
|
|
1049
|
-
* return tools([
|
|
1050
|
-
* { name: 'tool1', ... },
|
|
1051
|
-
* { name: 'tool2', ... },
|
|
1052
|
-
* ]);
|
|
1053
|
-
* }
|
|
1054
|
-
* ```
|
|
1055
|
-
*/
|
|
1056
|
-
export function tools(ts: Tool[]): ToolPlugin {
|
|
1057
|
-
return { tools: ts };
|
|
1058
|
-
}
|
|
1059
|
-
|
|
1060
|
-
/**
|
|
1061
|
-
* 工具配置项(Vite 插件风格,只支持插件形式)
|
|
1062
|
-
*
|
|
1063
|
-
* @example
|
|
1064
|
-
* ```typescript
|
|
1065
|
-
* tools: [
|
|
1066
|
-
* getEnvironmentTool(), // 工具插件(函数调用)
|
|
1067
|
-
* searchPlugin({ dataDir, workspace }), // 异步插件(返回 Promise<ToolPlugin>)
|
|
1068
|
-
* ]
|
|
1069
|
-
* ```
|
|
1070
|
-
*/
|
|
1071
|
-
export type ToolConfigItem = Tool | ToolPlugin | Promise<Tool | ToolPlugin>;
|
|
1072
|
-
|
|
1073
|
-
/**
|
|
1074
|
-
* 解析工具配置,统一转换为 Tool[]
|
|
1075
|
-
*
|
|
1076
|
-
* 支持三种形式:
|
|
1077
|
-
* - Tool: 单个工具(直接使用)
|
|
1078
|
-
* - ToolPlugin: 工具插件(展开 .tools 数组)
|
|
1079
|
-
* - Promise<Tool | ToolPlugin>: 异步工具/插件
|
|
1080
|
-
*/
|
|
1081
|
-
export async function resolveTools(items: ToolConfigItem[]): Promise<Tool[]> {
|
|
1082
|
-
const tools: Tool[] = [];
|
|
1083
|
-
|
|
1084
|
-
for (const item of items) {
|
|
1085
|
-
const resolved = await item;
|
|
1086
|
-
|
|
1087
|
-
if ('tools' in resolved && Array.isArray(resolved.tools)) {
|
|
1088
|
-
// ToolPlugin
|
|
1089
|
-
tools.push(...resolved.tools);
|
|
1090
|
-
} else if ('name' in resolved && 'execute' in resolved) {
|
|
1091
|
-
// Tool
|
|
1092
|
-
tools.push(resolved as Tool);
|
|
1093
|
-
} else {
|
|
1094
|
-
console.warn('无法识别的工具配置项:', resolved);
|
|
1095
|
-
}
|
|
1096
|
-
}
|
|
1097
|
-
|
|
1098
|
-
return tools;
|
|
1099
|
-
}
|
|
1100
|
-
|
|
1101
|
-
/** 工具定义(OpenAI 格式,内部使用) */
|
|
1102
|
-
export interface ToolDefinition {
|
|
1103
|
-
type: 'function';
|
|
1104
|
-
function: {
|
|
1105
|
-
name: string;
|
|
1106
|
-
description: string;
|
|
1107
|
-
parameters: JsonSchemaObject;
|
|
1108
|
-
};
|
|
1109
|
-
}
|
|
1110
|
-
|
|
1111
|
-
// ==================== 消息相关 ====================
|
|
1112
|
-
|
|
1113
|
-
/** 聊天消息(内部格式) */
|
|
1114
|
-
export interface ChatMessage {
|
|
1115
|
-
/** 消息 ID */
|
|
1116
|
-
id?: string;
|
|
1117
|
-
role: 'system' | 'user' | 'assistant' | 'tool';
|
|
1118
|
-
content: string;
|
|
1119
|
-
/** 深度思考内容 */
|
|
1120
|
-
reasoning_content?: string;
|
|
1121
|
-
tool_call_id?: string;
|
|
1122
|
-
tool_calls?: Array<{
|
|
1123
|
-
id: string;
|
|
1124
|
-
type: 'function';
|
|
1125
|
-
function: {
|
|
1126
|
-
name: string;
|
|
1127
|
-
arguments: string;
|
|
1128
|
-
};
|
|
1129
|
-
/** Gemini 模型需要的 thought_signature(用于工具调用循环) */
|
|
1130
|
-
thought_signature?: string;
|
|
1131
|
-
}>;
|
|
1132
|
-
}
|
|
1133
|
-
|
|
1134
|
-
// ==================== API 特定类型 ====================
|
|
1135
|
-
|
|
1136
|
-
/** 火山引擎 Responses API 工具定义 */
|
|
1137
|
-
export interface ResponsesApiTool {
|
|
1138
|
-
type: 'function';
|
|
1139
|
-
name?: string;
|
|
1140
|
-
description?: string;
|
|
1141
|
-
parameters?: Record<string, unknown>;
|
|
1142
|
-
}
|