@huyooo/ai-chat-core 0.2.45 → 0.3.3
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 +11 -0
- package/dist/adapter/index.d.ts.map +1 -0
- package/dist/adapter/model-adapter.d.ts +25 -0
- package/dist/adapter/model-adapter.d.ts.map +1 -0
- package/dist/adapter/model-options.d.ts +53 -0
- package/dist/adapter/model-options.d.ts.map +1 -0
- package/dist/adapter/types.d.ts +28 -0
- package/dist/adapter/types.d.ts.map +1 -0
- package/dist/chat-runtime.d.ts +96 -0
- package/dist/chat-runtime.d.ts.map +1 -0
- package/dist/constants.d.ts +12 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/events.d.ts +605 -1
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +1 -1
- package/dist/extension/index.d.ts +9 -0
- package/dist/extension/index.d.ts.map +1 -0
- package/dist/extension/types.d.ts +46 -0
- package/dist/extension/types.d.ts.map +1 -0
- package/dist/families/index.d.ts +11 -0
- package/dist/families/index.d.ts.map +1 -0
- package/dist/families/presets.d.ts +31 -0
- package/dist/families/presets.d.ts.map +1 -0
- package/dist/families/resolver.d.ts +11 -0
- package/dist/families/resolver.d.ts.map +1 -0
- package/dist/families/types.d.ts +29 -0
- package/dist/families/types.d.ts.map +1 -0
- package/dist/governance/command-safety.d.ts +34 -0
- package/dist/governance/command-safety.d.ts.map +1 -0
- package/dist/governance/governance.d.ts +19 -0
- package/dist/governance/governance.d.ts.map +1 -0
- package/dist/governance/index.d.ts +12 -0
- package/dist/governance/index.d.ts.map +1 -0
- package/dist/governance/types.d.ts +29 -0
- package/dist/governance/types.d.ts.map +1 -0
- package/dist/index.d.ts +72 -804
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +51 -1
- package/dist/internal/management-args.d.ts +13 -0
- package/dist/internal/management-args.d.ts.map +1 -0
- package/dist/internal/management-results.d.ts +21 -0
- package/dist/internal/management-results.d.ts.map +1 -0
- package/dist/llm-config.d.ts +108 -0
- package/dist/llm-config.d.ts.map +1 -0
- package/dist/logger/core.d.ts +31 -0
- package/dist/logger/core.d.ts.map +1 -0
- package/dist/logger/index.d.ts +9 -0
- package/dist/logger/index.d.ts.map +1 -0
- package/dist/orchestrator/compression-handler.d.ts +29 -0
- package/dist/orchestrator/compression-handler.d.ts.map +1 -0
- package/dist/orchestrator/context-compressor.d.ts +51 -0
- package/dist/orchestrator/context-compressor.d.ts.map +1 -0
- package/dist/orchestrator/context-summarizer.d.ts +41 -0
- package/dist/orchestrator/context-summarizer.d.ts.map +1 -0
- package/dist/orchestrator/index.d.ts +12 -0
- package/dist/orchestrator/index.d.ts.map +1 -0
- package/dist/orchestrator/orchestrator.d.ts +46 -0
- package/dist/orchestrator/orchestrator.d.ts.map +1 -0
- package/dist/orchestrator/types.d.ts +58 -0
- package/dist/orchestrator/types.d.ts.map +1 -0
- package/dist/parts/index.d.ts +13 -0
- package/dist/parts/index.d.ts.map +1 -0
- package/dist/parts/registry.d.ts +11 -0
- package/dist/parts/registry.d.ts.map +1 -0
- package/dist/parts/summaries.d.ts +9 -0
- package/dist/parts/summaries.d.ts.map +1 -0
- package/dist/parts/types.d.ts +61 -0
- package/dist/parts/types.d.ts.map +1 -0
- package/dist/platform.d.ts +17 -0
- package/dist/platform.d.ts.map +1 -0
- package/dist/platform.js +1 -0
- package/dist/protocols/anthropic.d.ts +20 -0
- package/dist/protocols/anthropic.d.ts.map +1 -0
- package/dist/protocols/ark.d.ts +36 -0
- package/dist/protocols/ark.d.ts.map +1 -0
- package/dist/protocols/deepseek.d.ts +24 -0
- package/dist/protocols/deepseek.d.ts.map +1 -0
- package/dist/protocols/error-utils.d.ts +14 -0
- package/dist/protocols/error-utils.d.ts.map +1 -0
- package/dist/protocols/gemini.d.ts +24 -0
- package/dist/protocols/gemini.d.ts.map +1 -0
- package/dist/protocols/glm.d.ts +20 -0
- package/dist/protocols/glm.d.ts.map +1 -0
- package/dist/protocols/grok.d.ts +20 -0
- package/dist/protocols/grok.d.ts.map +1 -0
- package/dist/protocols/index.d.ts +31 -0
- package/dist/protocols/index.d.ts.map +1 -0
- package/dist/protocols/minimax.d.ts +38 -0
- package/dist/protocols/minimax.d.ts.map +1 -0
- package/dist/protocols/moonshot.d.ts +20 -0
- package/dist/protocols/moonshot.d.ts.map +1 -0
- package/dist/protocols/openai-sse.d.ts +33 -0
- package/dist/protocols/openai-sse.d.ts.map +1 -0
- package/dist/protocols/openai.d.ts +19 -0
- package/dist/protocols/openai.d.ts.map +1 -0
- package/dist/protocols/qwen.d.ts +26 -0
- package/dist/protocols/qwen.d.ts.map +1 -0
- package/dist/protocols/responses-sse.d.ts +30 -0
- package/dist/protocols/responses-sse.d.ts.map +1 -0
- package/dist/protocols/sse-reader.d.ts +23 -0
- package/dist/protocols/sse-reader.d.ts.map +1 -0
- package/dist/protocols/tool-arguments.d.ts +8 -0
- package/dist/protocols/tool-arguments.d.ts.map +1 -0
- package/dist/protocols/types.d.ts +148 -0
- package/dist/protocols/types.d.ts.map +1 -0
- package/dist/protocols/vercel-gateway.d.ts +15 -0
- package/dist/protocols/vercel-gateway.d.ts.map +1 -0
- package/dist/runtime.d.ts +151 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +1 -0
- package/dist/skills/index.d.ts +14 -0
- package/dist/skills/index.d.ts.map +1 -0
- package/dist/skills/management/admin.d.ts +10 -0
- package/dist/skills/management/admin.d.ts.map +1 -0
- package/dist/skills/management/index.d.ts +11 -0
- package/dist/skills/management/index.d.ts.map +1 -0
- package/dist/skills/management/inputs.d.ts +44 -0
- package/dist/skills/management/inputs.d.ts.map +1 -0
- package/dist/skills/management/operations.d.ts +78 -0
- package/dist/skills/management/operations.d.ts.map +1 -0
- package/dist/skills/management/types.d.ts +70 -0
- package/dist/skills/management/types.d.ts.map +1 -0
- package/dist/skills/registry.d.ts +37 -0
- package/dist/skills/registry.d.ts.map +1 -0
- package/dist/skills/summaries.d.ts +9 -0
- package/dist/skills/summaries.d.ts.map +1 -0
- package/dist/skills/types.d.ts +61 -0
- package/dist/skills/types.d.ts.map +1 -0
- package/dist/test-utils/mock-sse.d.ts +13 -0
- package/dist/test-utils/mock-sse.d.ts.map +1 -0
- package/dist/tool-manager/define-tool.d.ts +35 -0
- package/dist/tool-manager/define-tool.d.ts.map +1 -0
- package/dist/tool-manager/formats.d.ts +46 -0
- package/dist/tool-manager/formats.d.ts.map +1 -0
- package/dist/tool-manager/identity.d.ts +18 -0
- package/dist/tool-manager/identity.d.ts.map +1 -0
- package/dist/tool-manager/in-process-provider.d.ts +15 -0
- package/dist/tool-manager/in-process-provider.d.ts.map +1 -0
- package/dist/tool-manager/index.d.ts +18 -0
- package/dist/tool-manager/index.d.ts.map +1 -0
- package/dist/tool-manager/manager.d.ts +18 -0
- package/dist/tool-manager/manager.d.ts.map +1 -0
- package/dist/tool-manager/mcp-provider.d.ts +21 -0
- package/dist/tool-manager/mcp-provider.d.ts.map +1 -0
- package/dist/tool-manager/summaries.d.ts +39 -0
- package/dist/tool-manager/summaries.d.ts.map +1 -0
- package/dist/tool-manager/types.d.ts +314 -0
- package/dist/tool-manager/types.d.ts.map +1 -0
- package/dist/types.d.ts +663 -0
- package/dist/types.d.ts.map +1 -0
- package/package.json +26 -15
- package/src/adapter/index.ts +25 -0
- package/src/adapter/model-adapter.ts +196 -0
- package/src/adapter/model-options.ts +143 -0
- package/src/adapter/types.ts +41 -0
- package/src/chat-runtime.ts +515 -0
- package/src/constants.ts +9 -102
- package/src/events.ts +364 -150
- package/src/extension/index.ts +24 -0
- package/src/extension/types.ts +49 -0
- package/src/families/index.ts +28 -0
- package/src/families/presets.ts +124 -0
- package/src/families/resolver.ts +22 -0
- package/src/families/types.ts +55 -0
- package/src/governance/command-safety.ts +224 -0
- package/src/governance/governance.ts +125 -0
- package/src/governance/index.ts +38 -0
- package/src/governance/types.ts +44 -0
- package/src/index.ts +250 -145
- package/src/internal/management-args.ts +39 -0
- package/src/internal/management-results.ts +60 -0
- package/src/llm-config.ts +137 -0
- package/src/logger/core.ts +96 -0
- package/src/logger/index.ts +8 -0
- package/src/orchestrator/compression-handler.ts +137 -0
- package/src/{providers → orchestrator}/context-compressor.ts +79 -47
- package/src/orchestrator/context-summarizer.ts +123 -0
- package/src/orchestrator/index.ts +20 -0
- package/src/orchestrator/orchestrator.ts +1002 -0
- package/src/orchestrator/types.ts +70 -0
- package/src/parts/index.ts +20 -0
- package/src/parts/registry.ts +95 -0
- package/src/parts/summaries.ts +40 -0
- package/src/parts/types.ts +63 -0
- package/src/platform.ts +73 -0
- package/src/protocols/anthropic.ts +377 -0
- package/src/protocols/ark.ts +300 -0
- package/src/protocols/deepseek.ts +192 -0
- package/src/{providers/protocols → protocols}/error-utils.ts +17 -20
- package/src/protocols/gemini.ts +352 -0
- package/src/protocols/glm.ts +212 -0
- package/src/protocols/grok.ts +98 -0
- package/src/protocols/index.ts +48 -0
- package/src/protocols/minimax.ts +308 -0
- package/src/protocols/moonshot.ts +186 -0
- package/src/protocols/openai-sse.ts +156 -0
- package/src/protocols/openai.ts +97 -0
- package/src/protocols/qwen.ts +358 -0
- package/src/protocols/responses-sse.ts +224 -0
- package/src/protocols/sse-reader.ts +54 -0
- package/src/protocols/tool-arguments.ts +32 -0
- package/src/{providers/protocols → protocols}/types.ts +46 -37
- package/src/protocols/vercel-gateway.ts +391 -0
- package/src/runtime.ts +167 -0
- package/src/skills/index.ts +29 -0
- package/src/skills/management/admin.ts +170 -0
- package/src/skills/management/index.ts +27 -0
- package/src/skills/management/inputs.ts +79 -0
- package/src/skills/management/operations.ts +256 -0
- package/src/skills/management/types.ts +57 -0
- package/src/skills/registry.ts +120 -0
- package/src/skills/summaries.ts +48 -0
- package/src/skills/types.ts +65 -0
- package/src/test-utils/mock-sse.ts +3 -3
- package/src/tool-manager/define-tool.ts +201 -0
- package/src/tool-manager/formats.ts +146 -0
- package/src/tool-manager/identity.ts +80 -0
- package/src/tool-manager/in-process-provider.ts +164 -0
- package/src/tool-manager/index.ts +63 -0
- package/src/tool-manager/manager.ts +562 -0
- package/src/tool-manager/mcp-provider.ts +509 -0
- package/src/tool-manager/summaries.ts +136 -0
- package/src/tool-manager/types.ts +389 -0
- package/src/types.ts +750 -191
- package/dist/events-CU5D5ray.d.ts +0 -1128
- package/src/agent.ts +0 -409
- package/src/internal/update-plan.ts +0 -2
- package/src/internal/web-search.ts +0 -77
- package/src/mcp/client-manager.ts +0 -302
- package/src/mcp/index.ts +0 -2
- package/src/mcp/types.ts +0 -43
- package/src/providers/context-summarizer.ts +0 -70
- package/src/providers/index.ts +0 -125
- package/src/providers/model-registry.ts +0 -466
- package/src/providers/orchestrator.ts +0 -839
- package/src/providers/protocols/anthropic.ts +0 -406
- package/src/providers/protocols/ark.ts +0 -362
- package/src/providers/protocols/deepseek.ts +0 -344
- package/src/providers/protocols/gemini.ts +0 -350
- package/src/providers/protocols/index.ts +0 -36
- package/src/providers/protocols/openai.ts +0 -420
- package/src/providers/protocols/qwen.ts +0 -315
- package/src/providers/types.ts +0 -264
- package/src/providers/unified-adapter.ts +0 -367
- package/src/router.ts +0 -72
- package/src/tools.ts +0 -162
- package/src/utils.ts +0 -86
package/src/types.ts
CHANGED
|
@@ -1,90 +1,30 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* AI Chat Core
|
|
2
|
+
* AI Chat Core 公共类型定义
|
|
3
|
+
*
|
|
4
|
+
* - Agent / Chat 配置、消息与工具契约(含 JSON Schema、ToolResult 信封)
|
|
5
|
+
* - 与治理、MCP、Skills 等模块共享的跨层类型入口
|
|
6
|
+
* - 不包含协议层与编排器专用类型(见 protocols/、orchestrator/types)
|
|
3
7
|
*/
|
|
4
8
|
|
|
5
|
-
import type {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
getModelSearchStrategy,
|
|
14
|
-
type ModelRegistryEntry,
|
|
15
|
-
} from './providers/model-registry';
|
|
16
|
-
import type { ProviderType } from './router';
|
|
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
17
|
|
|
18
18
|
// ==================== 模式与模型 ====================
|
|
19
19
|
|
|
20
20
|
/** 对话模式 */
|
|
21
21
|
export type ChatMode = 'agent' | 'ask';
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
export type {
|
|
26
|
-
export { getModelFamily, getModelEntry, modelSupportsThinking, modelSupportsNativeSearch, getModelSearchStrategy };
|
|
27
|
-
|
|
28
|
-
/** 模型选项(前端显示用) */
|
|
29
|
-
export interface ModelOption {
|
|
30
|
-
/** 模型 ID(发送给 API) */
|
|
31
|
-
modelId: string;
|
|
32
|
-
/** 显示名称 */
|
|
33
|
-
displayName: string;
|
|
34
|
-
/** 是否支持深度思考 */
|
|
35
|
-
supportsThinking: boolean;
|
|
36
|
-
/** 是否支持图片理解 */
|
|
37
|
-
supportsVision: boolean;
|
|
38
|
-
/** 用于模型项 hover 的特性描述(由后端定义,前端只渲染) */
|
|
39
|
-
tooltip?: {
|
|
40
|
-
features?: string[];
|
|
41
|
-
/** 开销信息(数组,分行显示) */
|
|
42
|
-
cost?: string[];
|
|
43
|
-
description?: string;
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/** 生成模型 tooltip 的 features 列表 */
|
|
48
|
-
function buildModelFeatures(entry: ModelRegistryEntry): string[] {
|
|
49
|
-
const family = getModelFamily(entry.id);
|
|
50
|
-
const supportsVision = modelSupportsVision(entry.id);
|
|
51
|
-
const supportsThinking = family?.supportsThinking ?? false;
|
|
52
|
-
const supportsNativeSearch = family?.supportsNativeSearch ?? false;
|
|
53
|
-
|
|
54
|
-
const features: string[] = [];
|
|
55
|
-
// 顺序:多模态 > 深度思考 > 长上下文 > 联网搜索
|
|
56
|
-
if (supportsVision) features.push('多模态');
|
|
57
|
-
if (supportsThinking) features.push('深度思考');
|
|
58
|
-
if (entry.contextWindow) features.push(`长上下文(${entry.contextWindow})`);
|
|
59
|
-
if (supportsNativeSearch) features.push('联网搜索');
|
|
60
|
-
|
|
61
|
-
return features;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* 预定义模型列表
|
|
66
|
-
*/
|
|
67
|
-
export const MODELS: ModelOption[] = getVisibleModels().map(entry => {
|
|
68
|
-
const family = getModelFamily(entry.id);
|
|
69
|
-
const supportsThinking = family?.supportsThinking ?? false;
|
|
70
|
-
const supportsVision = modelSupportsVision(entry.id);
|
|
71
|
-
|
|
72
|
-
return {
|
|
73
|
-
modelId: entry.id,
|
|
74
|
-
displayName: entry.displayName,
|
|
75
|
-
supportsThinking,
|
|
76
|
-
supportsVision,
|
|
77
|
-
tooltip: {
|
|
78
|
-
features: buildModelFeatures(entry),
|
|
79
|
-
cost: entry.pricing,
|
|
80
|
-
},
|
|
81
|
-
};
|
|
82
|
-
});
|
|
23
|
+
export type { ModelFamilyId, ModelFamilyConfig } from './families';
|
|
24
|
+
import type { ProtocolId } from './protocols';
|
|
25
|
+
export type { ProtocolId } from './protocols';
|
|
83
26
|
|
|
84
|
-
|
|
85
|
-
export function getModelByModelId(modelId: string): ModelOption | undefined {
|
|
86
|
-
return MODELS.find(m => m.modelId === modelId);
|
|
87
|
-
}
|
|
27
|
+
export type { ModelOption } from './adapter';
|
|
88
28
|
|
|
89
29
|
// ==================== 配置 ====================
|
|
90
30
|
|
|
@@ -92,47 +32,73 @@ export function getModelByModelId(modelId: string): ModelOption | undefined {
|
|
|
92
32
|
export type ToolApprovalCallback = (toolCall: {
|
|
93
33
|
id: string;
|
|
94
34
|
name: string;
|
|
35
|
+
toolName?: string;
|
|
36
|
+
extensionId?: string;
|
|
37
|
+
alias?: string;
|
|
38
|
+
displayName?: string;
|
|
95
39
|
args: Record<string, unknown>;
|
|
96
40
|
}) => Promise<boolean>;
|
|
97
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
|
+
|
|
98
81
|
/** Agent 配置 */
|
|
99
82
|
export interface AgentConfig {
|
|
100
|
-
/**
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
|
|
112
|
-
/** Vercel API Key(用于 Vercel AI Gateway 访问 Claude) */
|
|
113
|
-
vercelApiKey?: string;
|
|
114
|
-
/** Tavily API Key(用于统一 Web Search) */
|
|
115
|
-
tavilyApiKey?: string;
|
|
116
|
-
/** Gemini API Key (用于图片/视频,注意:中国大陆无法直接访问) */
|
|
117
|
-
geminiApiKey: string;
|
|
118
|
-
/** 当前工作目录(Current Working Directory) */
|
|
119
|
-
cwd?: string;
|
|
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;
|
|
120
95
|
/**
|
|
121
96
|
* 工具列表(Vite 插件风格)
|
|
122
97
|
*
|
|
123
98
|
* 支持多种形式:
|
|
124
|
-
* - 单个工具:
|
|
99
|
+
* - 单个工具:getEnvironmentTool()
|
|
125
100
|
* - 工具插件:searchPlugin({ dataDir, workspace })
|
|
126
101
|
* - Promise:await asyncPlugin()
|
|
127
|
-
*
|
|
128
|
-
* @example
|
|
129
|
-
* ```typescript
|
|
130
|
-
* tools: [
|
|
131
|
-
* getCwdTool,
|
|
132
|
-
* executeCommandTool,
|
|
133
|
-
* searchPlugin({ dataDir: '/path', workspace: '/project' }),
|
|
134
|
-
* ]
|
|
135
|
-
* ```
|
|
136
102
|
*/
|
|
137
103
|
tools?: ToolConfigItem[];
|
|
138
104
|
/**
|
|
@@ -149,28 +115,18 @@ export interface AgentConfig {
|
|
|
149
115
|
* MCP Server 配置列表
|
|
150
116
|
*
|
|
151
117
|
* 初始化时自动连接所有 MCP Server,发现工具并注册到 Agent。
|
|
152
|
-
*
|
|
153
|
-
* @example
|
|
154
|
-
* ```typescript
|
|
155
|
-
* mcpServers: [
|
|
156
|
-
* { name: 'filesystem', transport: 'stdio', command: 'npx', args: ['-y', '@modelcontextprotocol/server-filesystem', '/Users/me'] },
|
|
157
|
-
* { name: 'github', transport: 'stdio', command: 'npx', args: ['-y', '@modelcontextprotocol/server-github'], env: { GITHUB_TOKEN: '...' } },
|
|
158
|
-
* { name: 'remote-db', transport: 'sse', url: 'http://localhost:3001/mcp' },
|
|
159
|
-
* ]
|
|
160
|
-
* ```
|
|
161
118
|
*/
|
|
162
119
|
mcpServers?: McpServerConfig[];
|
|
163
120
|
/**
|
|
164
|
-
*
|
|
165
|
-
*
|
|
166
|
-
* 当对话历史超过模型 context window 时,orchestrator 调用此函数执行 AI 总结。
|
|
167
|
-
* 宿主提供实现(如 smart-finder 的 toolAI),ai-chat-core 不关心具体调用方式。
|
|
168
|
-
*
|
|
169
|
-
* @param systemPrompt 总结指令
|
|
170
|
-
* @param userPrompt 格式化后的中间对话历史
|
|
171
|
-
* @returns 总结后的文本
|
|
121
|
+
* 宿主应用注入的数据引擎接口(可选)。
|
|
122
|
+
* 传递给 ToolContext.dataEngine,使所有工具可访问平台数据能力。
|
|
172
123
|
*/
|
|
173
|
-
|
|
124
|
+
dataEngine?: DataEngineContext;
|
|
125
|
+
/**
|
|
126
|
+
* 宿主应用注入的工具执行审计钩子。
|
|
127
|
+
* 位于 ChatRuntime.executeTool 根入口,覆盖 in-process、MCP 和未来 provider。
|
|
128
|
+
*/
|
|
129
|
+
audit?: ToolExecutionAuditHooks;
|
|
174
130
|
}
|
|
175
131
|
|
|
176
132
|
/** 深度思考模式 */
|
|
@@ -189,12 +145,6 @@ export interface AutoRunConfig {
|
|
|
189
145
|
mode?: AutoRunMode;
|
|
190
146
|
}
|
|
191
147
|
|
|
192
|
-
/** 聊天消息格式(用于传递历史) */
|
|
193
|
-
export interface ChatHistoryMessage {
|
|
194
|
-
role: 'user' | 'assistant' | 'system' | 'tool';
|
|
195
|
-
content: string;
|
|
196
|
-
}
|
|
197
|
-
|
|
198
148
|
/**
|
|
199
149
|
* 用户工具定义(透传模式)
|
|
200
150
|
*
|
|
@@ -208,6 +158,12 @@ export interface UserToolDefinition {
|
|
|
208
158
|
description: string;
|
|
209
159
|
/** 参数定义(JSON Schema,支持嵌套) */
|
|
210
160
|
parameters: JsonSchemaObject;
|
|
161
|
+
/** 成功时 data 内的业务结构(JSON Schema,可选) */
|
|
162
|
+
outputSchema?: JsonSchemaObject;
|
|
163
|
+
/** 成功返回标准信封结构(JSON Schema,可选,由 outputSchema 自动生成) */
|
|
164
|
+
resolvedOutputSchema?: JsonSchemaObject;
|
|
165
|
+
/** 标准错误返回结构(JSON Schema,可选;不传则使用平台默认错误结构) */
|
|
166
|
+
errorSchema?: JsonSchemaObject;
|
|
211
167
|
}
|
|
212
168
|
|
|
213
169
|
/** 聊天配置(每次聊天可变的选项) */
|
|
@@ -217,7 +173,7 @@ export interface ChatOptions {
|
|
|
217
173
|
/** 使用的模型 */
|
|
218
174
|
model?: string;
|
|
219
175
|
/** 模型提供商 */
|
|
220
|
-
provider?:
|
|
176
|
+
provider?: ProtocolId;
|
|
221
177
|
/** 是否启用联网搜索 */
|
|
222
178
|
enableWebSearch?: boolean;
|
|
223
179
|
/**
|
|
@@ -228,10 +184,23 @@ export interface ChatOptions {
|
|
|
228
184
|
thinkingMode?: ThinkingMode;
|
|
229
185
|
/** 启用的工具名称列表(agent 模式有效,ask 模式强制禁用) */
|
|
230
186
|
enabledTools?: string[];
|
|
187
|
+
/**
|
|
188
|
+
* 宿主侧动态工具选择解析器。
|
|
189
|
+
* 每次模型迭代前调用,用于让 tool_enable 这类管理工具在同一轮 agent loop 的下一次模型请求生效。
|
|
190
|
+
*/
|
|
191
|
+
resolveEnabledTools?: () => Promise<string[] | undefined>;
|
|
231
192
|
/** 自动运行配置 */
|
|
232
193
|
autoRunConfig?: AutoRunConfig;
|
|
233
|
-
/**
|
|
234
|
-
|
|
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[];
|
|
235
204
|
/**
|
|
236
205
|
* 用户自定义工具(透传模式)
|
|
237
206
|
*
|
|
@@ -253,7 +222,7 @@ export interface ChatOptions {
|
|
|
253
222
|
/**
|
|
254
223
|
* 宿主平台提示词(可选)
|
|
255
224
|
*
|
|
256
|
-
* 由宿主应用(如
|
|
225
|
+
* 由宿主应用(如 SuperX)注入的平台特定 system prompt 扩展。
|
|
257
226
|
* 用于描述平台特有的能力、工具编排、记忆管理等,避免在核心库中硬编码具体工具名。
|
|
258
227
|
*
|
|
259
228
|
* 注入位置:基础 prompt 之后、Skills 内容之前。
|
|
@@ -275,7 +244,7 @@ export interface ChatOptions {
|
|
|
275
244
|
|
|
276
245
|
// ==================== 工具相关 ====================
|
|
277
246
|
|
|
278
|
-
/**
|
|
247
|
+
/** 前端渲染组件类型:内置若干枚举,扩展 Part 使用与 `parts/<name>` 一致的任意字符串 */
|
|
279
248
|
export type RenderType = 'weather' | 'chart' | 'browser' | 'plan' | string;
|
|
280
249
|
|
|
281
250
|
/** 前端动作类型(可扩展) */
|
|
@@ -287,7 +256,26 @@ export type ActionType = 'toast' | 'notification' | 'reload' | string;
|
|
|
287
256
|
* - action: 触发前端动作(通知、刷新等)
|
|
288
257
|
*/
|
|
289
258
|
export type ToolUI =
|
|
290
|
-
| {
|
|
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
|
+
}
|
|
291
279
|
| { type: 'action'; name: ActionType };
|
|
292
280
|
|
|
293
281
|
/** Shell 命令执行结果 */
|
|
@@ -297,19 +285,331 @@ export interface ExecResult {
|
|
|
297
285
|
exitCode: number;
|
|
298
286
|
}
|
|
299
287
|
|
|
288
|
+
export interface ExecOptions {
|
|
289
|
+
timeout?: number;
|
|
290
|
+
}
|
|
291
|
+
|
|
300
292
|
/** 工具执行上下文 */
|
|
301
293
|
export interface ToolContext {
|
|
294
|
+
/** 当前模型工具调用 ID(由编排器注入,供宿主审计/关联使用) */
|
|
295
|
+
toolCallId?: string;
|
|
296
|
+
/** 当前模型工具调用名称(由编排器注入,供宿主审计/关联使用) */
|
|
297
|
+
toolName?: string;
|
|
302
298
|
/** 当前工作目录(可选,工具需要时由框架注入) */
|
|
303
299
|
cwd?: string;
|
|
300
|
+
/**
|
|
301
|
+
* 当前模型回合允许调用的工具名。
|
|
302
|
+
* 管理类工具必须用它约束搜索、查看和启用范围,避免绕过会话能力选择。
|
|
303
|
+
*/
|
|
304
|
+
allowedToolNames?: readonly string[];
|
|
304
305
|
/** 执行 Shell 命令(可选,工具需要时由框架注入) */
|
|
305
|
-
exec?: (cmd: string, args?: string[]) => Promise<ExecResult>;
|
|
306
|
+
exec?: (cmd: string, args?: string[], options?: ExecOptions) => Promise<ExecResult>;
|
|
306
307
|
/** 中断信号(用于取消长时间操作) */
|
|
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);
|
|
308
608
|
}
|
|
309
609
|
|
|
310
610
|
// ==================== 工具错误 ====================
|
|
311
611
|
|
|
312
|
-
/**
|
|
612
|
+
/** 工具错误码(预定义 + 可扩展) */
|
|
313
613
|
export type ToolErrorCode =
|
|
314
614
|
| 'INVALID_PARAMS'
|
|
315
615
|
| 'NOT_FOUND'
|
|
@@ -317,63 +617,72 @@ export type ToolErrorCode =
|
|
|
317
617
|
| 'OPERATION_FAILED'
|
|
318
618
|
| 'TIMEOUT'
|
|
319
619
|
| 'NETWORK_ERROR'
|
|
320
|
-
| string;
|
|
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 & {});
|
|
321
632
|
|
|
322
633
|
/** 工具错误结构 */
|
|
323
634
|
export interface ToolError {
|
|
324
635
|
message: string;
|
|
325
636
|
code?: ToolErrorCode;
|
|
637
|
+
category?: ToolErrorCategory;
|
|
326
638
|
suggestion?: string;
|
|
327
639
|
retryable?: boolean;
|
|
640
|
+
details?: Record<string, unknown>;
|
|
328
641
|
}
|
|
329
642
|
|
|
330
|
-
/**
|
|
331
|
-
export
|
|
332
|
-
|
|
333
|
-
e instanceof Error &&
|
|
334
|
-
typeof (e as Error & { toolError?: unknown }).toolError === 'object' &&
|
|
335
|
-
(e as Error & { toolError: unknown }).toolError !== null &&
|
|
336
|
-
typeof ((e as Error & { toolError: Record<string, unknown> }).toolError as Record<string, unknown>).message === 'string'
|
|
337
|
-
);
|
|
338
|
-
}
|
|
643
|
+
/** 结构化工具异常 */
|
|
644
|
+
export class ToolException extends Error {
|
|
645
|
+
readonly toolError: ToolError;
|
|
339
646
|
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
): never {
|
|
346
|
-
const toolError: ToolError = { message, code, ...opts };
|
|
347
|
-
const err = new Error(message) as Error & { toolError: ToolError };
|
|
348
|
-
Object.defineProperty(err, 'toolError', { value: toolError, enumerable: true });
|
|
349
|
-
throw err;
|
|
647
|
+
constructor(toolError: ToolError) {
|
|
648
|
+
super(toolError.message);
|
|
649
|
+
this.name = 'ToolException';
|
|
650
|
+
this.toolError = toolError;
|
|
651
|
+
}
|
|
350
652
|
}
|
|
351
653
|
|
|
352
|
-
/**
|
|
353
|
-
export function
|
|
354
|
-
|
|
355
|
-
code?: ToolErrorCode,
|
|
356
|
-
opts?: { suggestion?: string; retryable?: boolean }
|
|
357
|
-
): never {
|
|
358
|
-
if (isToolError(error)) throw error;
|
|
359
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
360
|
-
throwToolError(message, code, opts);
|
|
654
|
+
/** 判断是否为结构化工具错误 */
|
|
655
|
+
export function isToolError(e: unknown): e is ToolException {
|
|
656
|
+
return e instanceof ToolException;
|
|
361
657
|
}
|
|
362
658
|
|
|
363
|
-
/**
|
|
364
|
-
|
|
365
|
-
|
|
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);
|
|
366
670
|
}
|
|
367
671
|
|
|
368
672
|
/** JSON Schema 属性定义(支持嵌套,符合 JSON Schema 规范) */
|
|
369
673
|
export interface JsonSchemaProperty {
|
|
370
674
|
type?: string;
|
|
675
|
+
const?: unknown;
|
|
371
676
|
description?: string;
|
|
677
|
+
format?: string;
|
|
372
678
|
enum?: unknown[];
|
|
373
679
|
items?: JsonSchemaProperty;
|
|
374
680
|
properties?: Record<string, JsonSchemaProperty>;
|
|
375
681
|
required?: string[];
|
|
376
682
|
default?: unknown;
|
|
683
|
+
additionalProperties?: boolean | JsonSchemaProperty;
|
|
684
|
+
anyOf?: JsonSchemaProperty[];
|
|
685
|
+
oneOf?: JsonSchemaProperty[];
|
|
377
686
|
}
|
|
378
687
|
|
|
379
688
|
/** JSON Schema 对象类型(工具参数的根类型) */
|
|
@@ -382,6 +691,216 @@ export interface JsonSchemaObject {
|
|
|
382
691
|
properties: Record<string, JsonSchemaProperty>;
|
|
383
692
|
required?: string[];
|
|
384
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;
|
|
385
904
|
}
|
|
386
905
|
|
|
387
906
|
/**
|
|
@@ -393,17 +912,41 @@ export interface JsonSchemaObject {
|
|
|
393
912
|
* name: 'my_tool',
|
|
394
913
|
* description: '我的自定义工具',
|
|
395
914
|
* parameters: { type: 'object', properties: { query: { type: 'string' } }, required: ['query'] },
|
|
396
|
-
* execute: async (args) => ({ result:
|
|
915
|
+
* execute: async (args) => ({ result: args.query })
|
|
397
916
|
* };
|
|
398
917
|
* ```
|
|
399
918
|
*/
|
|
400
919
|
export interface Tool {
|
|
401
|
-
/**
|
|
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) */
|
|
402
935
|
name: string;
|
|
936
|
+
/** 对模型暴露的别名(可选,不传则由 provider 生成) */
|
|
937
|
+
alias?: string;
|
|
938
|
+
/** UI 展示名称(可选) */
|
|
939
|
+
displayName?: string;
|
|
403
940
|
/** 工具描述(供 AI 理解) */
|
|
404
941
|
description: string;
|
|
405
942
|
/** 参数定义(JSON Schema) */
|
|
406
943
|
parameters: JsonSchemaObject;
|
|
944
|
+
/** 成功时 data 内的业务结构(JSON Schema,可选) */
|
|
945
|
+
outputSchema?: JsonSchemaObject;
|
|
946
|
+
/** 成功返回标准信封结构(JSON Schema,可选,由 outputSchema 自动生成) */
|
|
947
|
+
resolvedOutputSchema?: JsonSchemaObject;
|
|
948
|
+
/** 失败返回结构(JSON Schema;不传时描述符层使用平台标准错误结构) */
|
|
949
|
+
errorSchema?: JsonSchemaObject;
|
|
407
950
|
/**
|
|
408
951
|
* UI 声明(可选)
|
|
409
952
|
* - render: 在对话流中渲染自定义组件
|
|
@@ -416,17 +959,37 @@ export interface Tool {
|
|
|
416
959
|
* 设为 true 时无论全局配置如何,该工具必须用户确认才执行
|
|
417
960
|
*/
|
|
418
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[];
|
|
419
984
|
/** 超时时间(毫秒),由框架通过 AbortSignal 强制执行 */
|
|
420
985
|
timeout?: number;
|
|
421
|
-
/**
|
|
422
|
-
meta?: Record<string, unknown>;
|
|
423
|
-
/**
|
|
986
|
+
/**
|
|
424
987
|
* 执行函数
|
|
425
988
|
*
|
|
426
|
-
* 成功返回
|
|
989
|
+
* 成功返回 ToolResult 或普通对象,框架会统一规范化后再传给 LLM。
|
|
427
990
|
* 失败统一 throw(推荐使用 throwToolError())。
|
|
428
991
|
*/
|
|
429
|
-
execute: (args: Record<string, unknown>, context: ToolContext) => Promise<
|
|
992
|
+
execute: (args: Record<string, unknown>, context: ToolContext) => Promise<ToolExecuteResult>;
|
|
430
993
|
}
|
|
431
994
|
|
|
432
995
|
/** 工具执行器接口(供 Agent 内部使用,自定义命令执行环境) */
|
|
@@ -439,7 +1002,8 @@ export interface ToolExecutor {
|
|
|
439
1002
|
hooks?: {
|
|
440
1003
|
onStdout?: (chunk: string) => void;
|
|
441
1004
|
onStderr?: (chunk: string) => void;
|
|
442
|
-
}
|
|
1005
|
+
},
|
|
1006
|
+
timeout?: number,
|
|
443
1007
|
): Promise<{ success: boolean; output?: string; error?: string }>;
|
|
444
1008
|
}
|
|
445
1009
|
|
|
@@ -462,9 +1026,9 @@ export interface ToolPlugin {
|
|
|
462
1026
|
*
|
|
463
1027
|
* @example
|
|
464
1028
|
* ```typescript
|
|
465
|
-
* export function
|
|
1029
|
+
* export function getEnvironmentTool(): ToolPlugin {
|
|
466
1030
|
* return tool({
|
|
467
|
-
* name: '
|
|
1031
|
+
* name: 'get_environment',
|
|
468
1032
|
* description: '...',
|
|
469
1033
|
* parameters: { ... },
|
|
470
1034
|
* execute: async (args, context) => { ... }
|
|
@@ -499,7 +1063,7 @@ export function tools(ts: Tool[]): ToolPlugin {
|
|
|
499
1063
|
* @example
|
|
500
1064
|
* ```typescript
|
|
501
1065
|
* tools: [
|
|
502
|
-
*
|
|
1066
|
+
* getEnvironmentTool(), // 工具插件(函数调用)
|
|
503
1067
|
* searchPlugin({ dataDir, workspace }), // 异步插件(返回 Promise<ToolPlugin>)
|
|
504
1068
|
* ]
|
|
505
1069
|
* ```
|
|
@@ -516,10 +1080,10 @@ export type ToolConfigItem = Tool | ToolPlugin | Promise<Tool | ToolPlugin>;
|
|
|
516
1080
|
*/
|
|
517
1081
|
export async function resolveTools(items: ToolConfigItem[]): Promise<Tool[]> {
|
|
518
1082
|
const tools: Tool[] = [];
|
|
519
|
-
|
|
1083
|
+
|
|
520
1084
|
for (const item of items) {
|
|
521
1085
|
const resolved = await item;
|
|
522
|
-
|
|
1086
|
+
|
|
523
1087
|
if ('tools' in resolved && Array.isArray(resolved.tools)) {
|
|
524
1088
|
// ToolPlugin
|
|
525
1089
|
tools.push(...resolved.tools);
|
|
@@ -530,7 +1094,7 @@ export async function resolveTools(items: ToolConfigItem[]): Promise<Tool[]> {
|
|
|
530
1094
|
console.warn('无法识别的工具配置项:', resolved);
|
|
531
1095
|
}
|
|
532
1096
|
}
|
|
533
|
-
|
|
1097
|
+
|
|
534
1098
|
return tools;
|
|
535
1099
|
}
|
|
536
1100
|
|
|
@@ -571,13 +1135,8 @@ export interface ChatMessage {
|
|
|
571
1135
|
|
|
572
1136
|
/** 火山引擎 Responses API 工具定义 */
|
|
573
1137
|
export interface ResponsesApiTool {
|
|
574
|
-
type: 'function'
|
|
575
|
-
// Function 类型
|
|
1138
|
+
type: 'function';
|
|
576
1139
|
name?: string;
|
|
577
1140
|
description?: string;
|
|
578
1141
|
parameters?: Record<string, unknown>;
|
|
579
|
-
// Web Search 类型
|
|
580
|
-
max_keyword?: number;
|
|
581
|
-
limit?: number;
|
|
582
|
-
sources?: string[];
|
|
583
1142
|
}
|