@scenemesh/entity-engine-aimodule 1.0.0
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/LICENSE +21 -0
- package/README.md +854 -0
- package/dist/ai-core-LBGYFGOK.mjs +17 -0
- package/dist/ai-core-LBGYFGOK.mjs.map +1 -0
- package/dist/ai-core-UGJWSCQN.js +17 -0
- package/dist/ai-core-UGJWSCQN.js.map +1 -0
- package/dist/ai-core-manager-B3Z34RHA.mjs +9 -0
- package/dist/ai-core-manager-B3Z34RHA.mjs.map +1 -0
- package/dist/ai-core-manager-W7SSDCG5.js +9 -0
- package/dist/ai-core-manager-W7SSDCG5.js.map +1 -0
- package/dist/ai-embeddings-5ED5LDXX.mjs +17 -0
- package/dist/ai-embeddings-5ED5LDXX.mjs.map +1 -0
- package/dist/ai-embeddings-WCXZMMTZ.js +17 -0
- package/dist/ai-embeddings-WCXZMMTZ.js.map +1 -0
- package/dist/ai-form-renderer-24IWNMX5.js +233 -0
- package/dist/ai-form-renderer-24IWNMX5.js.map +1 -0
- package/dist/ai-form-renderer-BORQABF2.mjs +233 -0
- package/dist/ai-form-renderer-BORQABF2.mjs.map +1 -0
- package/dist/ai-provider-3PSCVEEN.mjs +17 -0
- package/dist/ai-provider-3PSCVEEN.mjs.map +1 -0
- package/dist/ai-provider-WMPMVZFL.js +17 -0
- package/dist/ai-provider-WMPMVZFL.js.map +1 -0
- package/dist/ai-renderer-7WGGWH5D.mjs +134 -0
- package/dist/ai-renderer-7WGGWH5D.mjs.map +1 -0
- package/dist/ai-renderer-OILYWAJV.js +134 -0
- package/dist/ai-renderer-OILYWAJV.js.map +1 -0
- package/dist/ai-settings-DGCFPK3U.js +15 -0
- package/dist/ai-settings-DGCFPK3U.js.map +1 -0
- package/dist/ai-settings-DTXEAB64.mjs +15 -0
- package/dist/ai-settings-DTXEAB64.mjs.map +1 -0
- package/dist/ai-structured-EGZ26ZS4.mjs +13 -0
- package/dist/ai-structured-EGZ26ZS4.mjs.map +1 -0
- package/dist/ai-structured-N2FZLO4A.js +13 -0
- package/dist/ai-structured-N2FZLO4A.js.map +1 -0
- package/dist/ai-tools-B3R77HZ3.js +19 -0
- package/dist/ai-tools-B3R77HZ3.js.map +1 -0
- package/dist/ai-tools-JAPVYQGE.mjs +19 -0
- package/dist/ai-tools-JAPVYQGE.mjs.map +1 -0
- package/dist/ai.module-GAHVCBTP.js +7 -0
- package/dist/ai.module-GAHVCBTP.js.map +1 -0
- package/dist/ai.module-TTPMTPB3.mjs +7 -0
- package/dist/ai.module-TTPMTPB3.mjs.map +1 -0
- package/dist/chunk-25C2NRSD.mjs +611 -0
- package/dist/chunk-25C2NRSD.mjs.map +1 -0
- package/dist/chunk-4JQ7UOXH.js +427 -0
- package/dist/chunk-4JQ7UOXH.js.map +1 -0
- package/dist/chunk-6IUKES2L.js +290 -0
- package/dist/chunk-6IUKES2L.js.map +1 -0
- package/dist/chunk-COWPK7XN.mjs +834 -0
- package/dist/chunk-COWPK7XN.mjs.map +1 -0
- package/dist/chunk-CTEXPMVZ.js +512 -0
- package/dist/chunk-CTEXPMVZ.js.map +1 -0
- package/dist/chunk-DXQTHA75.js +573 -0
- package/dist/chunk-DXQTHA75.js.map +1 -0
- package/dist/chunk-DZFQ6I23.js +72 -0
- package/dist/chunk-DZFQ6I23.js.map +1 -0
- package/dist/chunk-J323UTPE.mjs +650 -0
- package/dist/chunk-J323UTPE.mjs.map +1 -0
- package/dist/chunk-LHNNALVF.js +834 -0
- package/dist/chunk-LHNNALVF.js.map +1 -0
- package/dist/chunk-O7SZSMXV.js +1621 -0
- package/dist/chunk-O7SZSMXV.js.map +1 -0
- package/dist/chunk-OTNOFOVW.js +650 -0
- package/dist/chunk-OTNOFOVW.js.map +1 -0
- package/dist/chunk-PRIGZEI4.mjs +72 -0
- package/dist/chunk-PRIGZEI4.mjs.map +1 -0
- package/dist/chunk-SBSZ3IPB.mjs +573 -0
- package/dist/chunk-SBSZ3IPB.mjs.map +1 -0
- package/dist/chunk-SXPA6SSD.mjs +1621 -0
- package/dist/chunk-SXPA6SSD.mjs.map +1 -0
- package/dist/chunk-T5A4KAVS.mjs +512 -0
- package/dist/chunk-T5A4KAVS.mjs.map +1 -0
- package/dist/chunk-TDRKKUNT.mjs +357 -0
- package/dist/chunk-TDRKKUNT.mjs.map +1 -0
- package/dist/chunk-TJFNODPE.js +357 -0
- package/dist/chunk-TJFNODPE.js.map +1 -0
- package/dist/chunk-V2SSI3SL.mjs +427 -0
- package/dist/chunk-V2SSI3SL.mjs.map +1 -0
- package/dist/chunk-X42L6MTY.mjs +290 -0
- package/dist/chunk-X42L6MTY.mjs.map +1 -0
- package/dist/chunk-YSVMY77H.js +611 -0
- package/dist/chunk-YSVMY77H.js.map +1 -0
- package/dist/core-ANYRS6EF.mjs +73 -0
- package/dist/core-ANYRS6EF.mjs.map +1 -0
- package/dist/core-K5K34DCS.js +73 -0
- package/dist/core-K5K34DCS.js.map +1 -0
- package/dist/core-index.d.mts +1668 -0
- package/dist/core-index.d.ts +1668 -0
- package/dist/core-index.js +101 -0
- package/dist/core-index.js.map +1 -0
- package/dist/core-index.mjs +101 -0
- package/dist/core-index.mjs.map +1 -0
- package/dist/index.d.mts +2911 -0
- package/dist/index.d.ts +2911 -0
- package/dist/index.js +1177 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +1177 -0
- package/dist/index.mjs.map +1 -0
- package/dist/tools-352X7A6X.mjs +366 -0
- package/dist/tools-352X7A6X.mjs.map +1 -0
- package/dist/tools-YLEX6GNO.js +366 -0
- package/dist/tools-YLEX6GNO.js.map +1 -0
- package/dist/ui-index.d.mts +627 -0
- package/dist/ui-index.d.ts +627 -0
- package/dist/ui-index.js +2354 -0
- package/dist/ui-index.js.map +1 -0
- package/dist/ui-index.mjs +2353 -0
- package/dist/ui-index.mjs.map +1 -0
- package/package.json +105 -0
|
@@ -0,0 +1,611 @@
|
|
|
1
|
+
// src/core/ai-tools.ts
|
|
2
|
+
import { EventEmitter } from "events";
|
|
3
|
+
import {
|
|
4
|
+
tool,
|
|
5
|
+
dynamicTool,
|
|
6
|
+
stepCountIs,
|
|
7
|
+
NoSuchToolError,
|
|
8
|
+
InvalidToolInputError
|
|
9
|
+
} from "ai";
|
|
10
|
+
var AIToolsIntegration = class extends EventEmitter {
|
|
11
|
+
constructor() {
|
|
12
|
+
super();
|
|
13
|
+
this.initialized = false;
|
|
14
|
+
this.requestCounter = 0;
|
|
15
|
+
this.registeredTools = /* @__PURE__ */ new Map();
|
|
16
|
+
this.dynamicTools = /* @__PURE__ */ new Map();
|
|
17
|
+
this.mcpClients = /* @__PURE__ */ new Map();
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* 初始化
|
|
21
|
+
*/
|
|
22
|
+
async initialize() {
|
|
23
|
+
if (this.initialized) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
try {
|
|
27
|
+
this.emit("ai_tools:initializing");
|
|
28
|
+
this.initialized = true;
|
|
29
|
+
this.emit("ai_tools:initialized");
|
|
30
|
+
} catch (error) {
|
|
31
|
+
this.emit("ai_tools:initialization_failed", { error });
|
|
32
|
+
throw error;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* 生成请求ID
|
|
37
|
+
*/
|
|
38
|
+
generateRequestId() {
|
|
39
|
+
return `ai-tools-${Date.now()}-${++this.requestCounter}`;
|
|
40
|
+
}
|
|
41
|
+
// Tool Management
|
|
42
|
+
/**
|
|
43
|
+
* Create tool - following official specifications
|
|
44
|
+
*/
|
|
45
|
+
createTool(description, inputSchema, execute) {
|
|
46
|
+
if (execute) {
|
|
47
|
+
return tool({
|
|
48
|
+
description,
|
|
49
|
+
inputSchema,
|
|
50
|
+
execute: async (params) => execute(params, {
|
|
51
|
+
// 传递标准的AI SDK执行选项
|
|
52
|
+
toolCallId: "tool-call-" + Date.now(),
|
|
53
|
+
messages: [],
|
|
54
|
+
abortSignal: void 0,
|
|
55
|
+
experimental_context: void 0
|
|
56
|
+
})
|
|
57
|
+
});
|
|
58
|
+
} else {
|
|
59
|
+
return tool({
|
|
60
|
+
description,
|
|
61
|
+
inputSchema
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* 创建动态工具 - 完全基于 AI SDK 的 dynamicTool
|
|
67
|
+
*/
|
|
68
|
+
createDynamicTool(description, inputSchema, execute) {
|
|
69
|
+
return dynamicTool({
|
|
70
|
+
description,
|
|
71
|
+
inputSchema,
|
|
72
|
+
execute: execute ? async (input, options) => {
|
|
73
|
+
const toolOptions = {
|
|
74
|
+
toolCallId: options.toolCallId || "unknown",
|
|
75
|
+
messages: options.messages || [],
|
|
76
|
+
abortSignal: options.abortSignal,
|
|
77
|
+
experimental_context: options.experimental_context
|
|
78
|
+
};
|
|
79
|
+
return execute(input, toolOptions);
|
|
80
|
+
} : async (input, options) => (
|
|
81
|
+
// 默认实现:返回输入参数
|
|
82
|
+
input
|
|
83
|
+
)
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* 注册工具到集成器
|
|
88
|
+
*/
|
|
89
|
+
registerTool(name, toolInstance) {
|
|
90
|
+
this.registeredTools.set(name, toolInstance);
|
|
91
|
+
this.emit("ai_tools:tool_registered", { name, tool: toolInstance });
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* 获取已注册的工具
|
|
95
|
+
*/
|
|
96
|
+
getRegisteredTools() {
|
|
97
|
+
const tools = {};
|
|
98
|
+
this.registeredTools.forEach((registeredTool, name) => {
|
|
99
|
+
tools[name] = registeredTool;
|
|
100
|
+
});
|
|
101
|
+
return tools;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* 注册动态工具
|
|
105
|
+
*/
|
|
106
|
+
registerDynamicTool(name, dynamicToolInstance) {
|
|
107
|
+
this.dynamicTools.set(name, dynamicToolInstance);
|
|
108
|
+
this.emit("ai_tools:dynamic_tool_registered", { name, tool: dynamicToolInstance });
|
|
109
|
+
}
|
|
110
|
+
// ================================
|
|
111
|
+
// 🔄 多步调用系统 - 按照官方文档规范实现
|
|
112
|
+
// ================================
|
|
113
|
+
/**
|
|
114
|
+
* 使用工具执行文本生成 - 遵循官方 generateText + tools 模式
|
|
115
|
+
* 这是 AI SDK 工具调用的标准方式
|
|
116
|
+
*/
|
|
117
|
+
async generateTextWithTools(options) {
|
|
118
|
+
const { generateText } = await import("ai");
|
|
119
|
+
const requestId = this.generateRequestId();
|
|
120
|
+
const startTime = Date.now();
|
|
121
|
+
try {
|
|
122
|
+
this.emit("ai_tools:multi_step_started", {
|
|
123
|
+
requestId,
|
|
124
|
+
model: typeof options.model === "string" ? options.model : "unknown",
|
|
125
|
+
hasTools: !!options.tools,
|
|
126
|
+
stopWhen: !!options.stopWhen,
|
|
127
|
+
maxSteps: options.maxSteps || 5
|
|
128
|
+
});
|
|
129
|
+
const generateOptions = {
|
|
130
|
+
model: options.model,
|
|
131
|
+
system: options.system,
|
|
132
|
+
prompt: options.prompt,
|
|
133
|
+
messages: options.messages,
|
|
134
|
+
tools: options.tools,
|
|
135
|
+
toolChoice: options.toolChoice,
|
|
136
|
+
activeTools: options.activeTools,
|
|
137
|
+
maxOutputTokens: options.maxOutputTokens,
|
|
138
|
+
temperature: options.temperature,
|
|
139
|
+
topP: options.topP,
|
|
140
|
+
topK: options.topK,
|
|
141
|
+
presencePenalty: options.presencePenalty,
|
|
142
|
+
frequencyPenalty: options.frequencyPenalty,
|
|
143
|
+
seed: options.seed,
|
|
144
|
+
maxRetries: options.maxRetries,
|
|
145
|
+
abortSignal: options.abortSignal,
|
|
146
|
+
headers: options.headers,
|
|
147
|
+
experimental_context: options.experimental_context,
|
|
148
|
+
experimental_telemetry: options.experimental_telemetry,
|
|
149
|
+
experimental_repairToolCall: options.experimental_repairToolCall,
|
|
150
|
+
onStepFinish: options.onStepFinish,
|
|
151
|
+
prepareStep: options.prepareStep
|
|
152
|
+
};
|
|
153
|
+
if (options.stopWhen) {
|
|
154
|
+
generateOptions.stopWhen = Array.isArray(options.stopWhen) ? options.stopWhen.map((cond) => this.parseStopCondition(cond)) : this.parseStopCondition(options.stopWhen);
|
|
155
|
+
} else if (options.maxSteps) {
|
|
156
|
+
generateOptions.stopWhen = stepCountIs(options.maxSteps);
|
|
157
|
+
}
|
|
158
|
+
const result = await generateText(generateOptions);
|
|
159
|
+
this.emit("ai_tools:multi_step_completed", {
|
|
160
|
+
requestId,
|
|
161
|
+
latency: Date.now() - startTime,
|
|
162
|
+
steps: result.steps?.length || 1,
|
|
163
|
+
toolCalls: result.toolCalls?.length || 0,
|
|
164
|
+
toolResults: result.toolResults?.length || 0,
|
|
165
|
+
finishReason: result.finishReason,
|
|
166
|
+
usage: result.usage
|
|
167
|
+
});
|
|
168
|
+
return {
|
|
169
|
+
text: result.text,
|
|
170
|
+
steps: result.steps || [],
|
|
171
|
+
toolCalls: result.toolCalls || [],
|
|
172
|
+
toolResults: result.toolResults || [],
|
|
173
|
+
finishReason: result.finishReason,
|
|
174
|
+
usage: result.usage,
|
|
175
|
+
totalUsage: result.totalUsage || result.usage,
|
|
176
|
+
content: result.content || [],
|
|
177
|
+
reasoning: result.reasoning || [],
|
|
178
|
+
reasoningText: result.reasoningText,
|
|
179
|
+
sources: result.sources || [],
|
|
180
|
+
files: result.files || [],
|
|
181
|
+
warnings: result.warnings,
|
|
182
|
+
response: result.response,
|
|
183
|
+
providerMetadata: result.providerMetadata
|
|
184
|
+
};
|
|
185
|
+
} catch (error) {
|
|
186
|
+
this.emit("ai_tools:generate_text_with_tools_failed", {
|
|
187
|
+
requestId,
|
|
188
|
+
error: error.message,
|
|
189
|
+
latency: Date.now() - startTime,
|
|
190
|
+
errorType: error.constructor.name
|
|
191
|
+
});
|
|
192
|
+
throw error;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* 使用工具执行流式文本生成 - 遵循官方 streamText + tools 模式
|
|
197
|
+
*/
|
|
198
|
+
async streamTextWithTools(options) {
|
|
199
|
+
const { streamText } = await import("ai");
|
|
200
|
+
const requestId = this.generateRequestId();
|
|
201
|
+
this.emit("ai_tools:multi_step_stream_started", {
|
|
202
|
+
requestId,
|
|
203
|
+
model: typeof options.model === "string" ? options.model : "unknown",
|
|
204
|
+
hasTools: !!options.tools,
|
|
205
|
+
stopWhen: !!options.stopWhen
|
|
206
|
+
});
|
|
207
|
+
const wrappedOptions = {
|
|
208
|
+
...options,
|
|
209
|
+
onStepFinish: (result) => {
|
|
210
|
+
this.emit("ai_tools:step_finished", {
|
|
211
|
+
requestId,
|
|
212
|
+
stepType: result.stepType,
|
|
213
|
+
stepNumber: result.stepNumber || 0,
|
|
214
|
+
toolCalls: result.toolCalls?.length || 0,
|
|
215
|
+
toolResults: result.toolResults?.length || 0,
|
|
216
|
+
finishReason: result.finishReason
|
|
217
|
+
});
|
|
218
|
+
if (options.onStepFinish) {
|
|
219
|
+
options.onStepFinish(result);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
};
|
|
223
|
+
const streamOptions = { ...wrappedOptions };
|
|
224
|
+
if (options.stopWhen) {
|
|
225
|
+
streamOptions.stopWhen = Array.isArray(options.stopWhen) ? options.stopWhen.map((cond) => this.parseStopCondition(cond)) : this.parseStopCondition(options.stopWhen);
|
|
226
|
+
}
|
|
227
|
+
const streamResult = streamText(streamOptions);
|
|
228
|
+
const enhancedStreamResult = {
|
|
229
|
+
...streamResult,
|
|
230
|
+
// 工具调用分析方法
|
|
231
|
+
analyzeToolUsage: async () => {
|
|
232
|
+
const steps = await streamResult.steps;
|
|
233
|
+
return this.analyzeToolUsage(steps);
|
|
234
|
+
},
|
|
235
|
+
// 提取所有工具调用
|
|
236
|
+
getAllToolCalls: async () => {
|
|
237
|
+
const steps = await streamResult.steps;
|
|
238
|
+
return this.extractToolCallsFromSteps(steps);
|
|
239
|
+
},
|
|
240
|
+
// 提取所有工具结果
|
|
241
|
+
getAllToolResults: async () => {
|
|
242
|
+
const steps = await streamResult.steps;
|
|
243
|
+
return this.extractToolResultsFromSteps(steps);
|
|
244
|
+
},
|
|
245
|
+
// 获取响应消息 - 官方文档重点功能
|
|
246
|
+
getResponseMessages: async () => {
|
|
247
|
+
const response = await streamResult.response;
|
|
248
|
+
return this.extractResponseMessages({ response });
|
|
249
|
+
}
|
|
250
|
+
};
|
|
251
|
+
return enhancedStreamResult;
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* 创建步骤计数停止条件
|
|
255
|
+
*/
|
|
256
|
+
createStepCountCondition(maxSteps) {
|
|
257
|
+
return { type: "stepCount", value: maxSteps };
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* 创建自定义停止条件
|
|
261
|
+
*/
|
|
262
|
+
createCustomStopCondition(condition) {
|
|
263
|
+
return condition;
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* 解析停止条件
|
|
267
|
+
*/
|
|
268
|
+
parseStopCondition(condition) {
|
|
269
|
+
if (typeof condition === "function") {
|
|
270
|
+
return condition;
|
|
271
|
+
}
|
|
272
|
+
if (condition.type === "stepCount") {
|
|
273
|
+
return stepCountIs(condition.value);
|
|
274
|
+
}
|
|
275
|
+
if (condition.type === "custom") {
|
|
276
|
+
return condition.condition;
|
|
277
|
+
}
|
|
278
|
+
return stepCountIs(5);
|
|
279
|
+
}
|
|
280
|
+
// ================================
|
|
281
|
+
// Tool repair system
|
|
282
|
+
// ================================
|
|
283
|
+
/**
|
|
284
|
+
* 创建结构化输出修复器
|
|
285
|
+
*/
|
|
286
|
+
createStructuredRepairFunction(repairModel) {
|
|
287
|
+
return async (options) => {
|
|
288
|
+
if (NoSuchToolError.isInstance(options.error)) {
|
|
289
|
+
return null;
|
|
290
|
+
}
|
|
291
|
+
try {
|
|
292
|
+
const { generateObject } = await import("ai");
|
|
293
|
+
const toolDef = options.tools[options.toolCall.toolName];
|
|
294
|
+
if (!toolDef) return null;
|
|
295
|
+
const { object: repairedArgs } = await generateObject({
|
|
296
|
+
model: repairModel,
|
|
297
|
+
schema: toolDef.parameters || toolDef.schema,
|
|
298
|
+
prompt: [
|
|
299
|
+
`The model tried to call the tool "${options.toolCall.toolName}" with the following inputs:`,
|
|
300
|
+
JSON.stringify(options.toolCall.input),
|
|
301
|
+
`The tool accepts the following schema:`,
|
|
302
|
+
JSON.stringify(options.inputSchema(options.toolCall)),
|
|
303
|
+
"Please fix the inputs to match the schema."
|
|
304
|
+
].join("\n")
|
|
305
|
+
});
|
|
306
|
+
return {
|
|
307
|
+
...options.toolCall,
|
|
308
|
+
input: JSON.stringify(repairedArgs)
|
|
309
|
+
};
|
|
310
|
+
} catch (repairError) {
|
|
311
|
+
this.emit("ai_tools:repair_failed", {
|
|
312
|
+
originalError: options.error,
|
|
313
|
+
repairError,
|
|
314
|
+
toolCall: options.toolCall
|
|
315
|
+
});
|
|
316
|
+
return null;
|
|
317
|
+
}
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* 创建重新询问修复器
|
|
322
|
+
*/
|
|
323
|
+
createReaskRepairFunction(repairModel) {
|
|
324
|
+
return async (options) => {
|
|
325
|
+
try {
|
|
326
|
+
const { generateText } = await import("ai");
|
|
327
|
+
const result = await generateText({
|
|
328
|
+
model: repairModel,
|
|
329
|
+
system: options.system,
|
|
330
|
+
messages: [
|
|
331
|
+
...options.messages,
|
|
332
|
+
{
|
|
333
|
+
role: "assistant",
|
|
334
|
+
content: [{
|
|
335
|
+
type: "tool-call",
|
|
336
|
+
toolCallId: options.toolCall.toolCallId,
|
|
337
|
+
toolName: options.toolCall.toolName,
|
|
338
|
+
input: options.toolCall.input
|
|
339
|
+
}]
|
|
340
|
+
},
|
|
341
|
+
{
|
|
342
|
+
role: "tool",
|
|
343
|
+
content: [{
|
|
344
|
+
type: "tool-result",
|
|
345
|
+
toolCallId: options.toolCall.toolCallId,
|
|
346
|
+
toolName: options.toolCall.toolName,
|
|
347
|
+
output: options.error.message
|
|
348
|
+
}]
|
|
349
|
+
}
|
|
350
|
+
],
|
|
351
|
+
tools: options.tools
|
|
352
|
+
});
|
|
353
|
+
const newToolCall = result.toolCalls.find(
|
|
354
|
+
(newCall) => newCall.toolName === options.toolCall.toolName
|
|
355
|
+
);
|
|
356
|
+
return newToolCall ? {
|
|
357
|
+
toolCallType: "function",
|
|
358
|
+
toolCallId: options.toolCall.toolCallId,
|
|
359
|
+
toolName: options.toolCall.toolName,
|
|
360
|
+
input: JSON.stringify(newToolCall.input)
|
|
361
|
+
} : null;
|
|
362
|
+
} catch (repairError) {
|
|
363
|
+
this.emit("ai_tools:reask_repair_failed", {
|
|
364
|
+
originalError: options.error,
|
|
365
|
+
repairError,
|
|
366
|
+
toolCall: options.toolCall
|
|
367
|
+
});
|
|
368
|
+
return null;
|
|
369
|
+
}
|
|
370
|
+
};
|
|
371
|
+
}
|
|
372
|
+
// ================================
|
|
373
|
+
// 🔗 MCP集成系统
|
|
374
|
+
// ================================
|
|
375
|
+
/**
|
|
376
|
+
* 创建MCP客户端
|
|
377
|
+
*/
|
|
378
|
+
async createMCPClient(config) {
|
|
379
|
+
const { experimental_createMCPClient } = await import("ai");
|
|
380
|
+
let transportConfig;
|
|
381
|
+
switch (config.transport.type) {
|
|
382
|
+
case "sse":
|
|
383
|
+
transportConfig = {
|
|
384
|
+
transport: {
|
|
385
|
+
type: "sse",
|
|
386
|
+
url: config.transport.url,
|
|
387
|
+
headers: config.transport.headers
|
|
388
|
+
}
|
|
389
|
+
};
|
|
390
|
+
break;
|
|
391
|
+
case "stdio":
|
|
392
|
+
if (typeof window === "undefined" && typeof process !== "undefined") {
|
|
393
|
+
try {
|
|
394
|
+
const { Experimental_StdioMCPTransport } = await import("ai/mcp-stdio");
|
|
395
|
+
transportConfig = {
|
|
396
|
+
transport: new Experimental_StdioMCPTransport({
|
|
397
|
+
command: config.transport.command,
|
|
398
|
+
args: config.transport.args
|
|
399
|
+
})
|
|
400
|
+
};
|
|
401
|
+
} catch (error) {
|
|
402
|
+
throw new Error("stdio transport requires Node.js environment and ai/mcp-stdio package");
|
|
403
|
+
}
|
|
404
|
+
} else {
|
|
405
|
+
throw new Error("stdio transport is only available in Node.js environment");
|
|
406
|
+
}
|
|
407
|
+
break;
|
|
408
|
+
case "custom":
|
|
409
|
+
transportConfig = {
|
|
410
|
+
transport: config.transport.transport
|
|
411
|
+
};
|
|
412
|
+
break;
|
|
413
|
+
default:
|
|
414
|
+
throw new Error(`Unsupported MCP transport type: ${config.transport.type}`);
|
|
415
|
+
}
|
|
416
|
+
const mcpClient = await experimental_createMCPClient(transportConfig);
|
|
417
|
+
const clientId = `mcp-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
418
|
+
const wrappedClient = {
|
|
419
|
+
async tools(toolConfig) {
|
|
420
|
+
if (config.schemas || toolConfig?.schemas) {
|
|
421
|
+
return mcpClient.tools({ schemas: config.schemas || toolConfig?.schemas });
|
|
422
|
+
} else {
|
|
423
|
+
return mcpClient.tools();
|
|
424
|
+
}
|
|
425
|
+
},
|
|
426
|
+
async close() {
|
|
427
|
+
await mcpClient.close();
|
|
428
|
+
this.mcpClients.delete(clientId);
|
|
429
|
+
this.emit("ai_tools:mcp_client_closed", { clientId });
|
|
430
|
+
}
|
|
431
|
+
};
|
|
432
|
+
this.mcpClients.set(clientId, wrappedClient);
|
|
433
|
+
this.emit("ai_tools:mcp_client_created", { clientId, config });
|
|
434
|
+
return wrappedClient;
|
|
435
|
+
}
|
|
436
|
+
/**
|
|
437
|
+
* 关闭所有MCP客户端
|
|
438
|
+
*/
|
|
439
|
+
async closeAllMCPClients() {
|
|
440
|
+
const closePromises = Array.from(this.mcpClients.values()).map((client) => client.close());
|
|
441
|
+
await Promise.all(closePromises);
|
|
442
|
+
this.mcpClients.clear();
|
|
443
|
+
}
|
|
444
|
+
// Utility methods
|
|
445
|
+
/**
|
|
446
|
+
* Create simple tool call configuration
|
|
447
|
+
*/
|
|
448
|
+
createSimpleToolCall(model, tools, prompt, options) {
|
|
449
|
+
return {
|
|
450
|
+
model,
|
|
451
|
+
tools,
|
|
452
|
+
prompt,
|
|
453
|
+
...options
|
|
454
|
+
};
|
|
455
|
+
}
|
|
456
|
+
/**
|
|
457
|
+
* 创建多步工具调用配置 - 使用 stopWhen 参数
|
|
458
|
+
*/
|
|
459
|
+
createMultiStepToolCall(model, tools, prompt, maxSteps = 5, options) {
|
|
460
|
+
return {
|
|
461
|
+
model,
|
|
462
|
+
tools,
|
|
463
|
+
prompt,
|
|
464
|
+
stopWhen: this.createStepCountCondition(maxSteps),
|
|
465
|
+
...options
|
|
466
|
+
};
|
|
467
|
+
}
|
|
468
|
+
/**
|
|
469
|
+
* 直接执行单个工具 - 用于测试或直接调用
|
|
470
|
+
*/
|
|
471
|
+
async executeSingleTool(toolName, input, tools, options) {
|
|
472
|
+
const selectedTool = tools[toolName];
|
|
473
|
+
if (!selectedTool || !selectedTool.execute) {
|
|
474
|
+
throw new Error(`Tool '${String(toolName)}' not found or not executable`);
|
|
475
|
+
}
|
|
476
|
+
const toolOptions = {
|
|
477
|
+
toolCallId: `direct-${Date.now()}`,
|
|
478
|
+
messages: options?.messages || [],
|
|
479
|
+
abortSignal: options?.abortSignal,
|
|
480
|
+
experimental_context: options?.experimental_context
|
|
481
|
+
};
|
|
482
|
+
return selectedTool.execute(input, toolOptions);
|
|
483
|
+
}
|
|
484
|
+
/**
|
|
485
|
+
* 获取响应消息 - 官方文档重点推荐的功能
|
|
486
|
+
* 用于将助手和工具消息添加到对话历史
|
|
487
|
+
*/
|
|
488
|
+
extractResponseMessages(result) {
|
|
489
|
+
return result.response?.messages || [];
|
|
490
|
+
}
|
|
491
|
+
/**
|
|
492
|
+
* 将响应消息添加到对话历史 - 官方文档示例
|
|
493
|
+
*/
|
|
494
|
+
addResponseMessagesToHistory(messages, result) {
|
|
495
|
+
const responseMessages = this.extractResponseMessages(result);
|
|
496
|
+
return [...messages, ...responseMessages];
|
|
497
|
+
}
|
|
498
|
+
/**
|
|
499
|
+
* 批量工具调用验证
|
|
500
|
+
*/
|
|
501
|
+
validateBatchToolCalls(toolCalls, tools) {
|
|
502
|
+
return toolCalls.map((toolCall) => ({
|
|
503
|
+
toolCall,
|
|
504
|
+
...this.validateToolCall(toolCall, tools)
|
|
505
|
+
}));
|
|
506
|
+
}
|
|
507
|
+
/**
|
|
508
|
+
* 工具调用结果验证
|
|
509
|
+
*/
|
|
510
|
+
validateToolCall(toolCall, tools) {
|
|
511
|
+
const toolName = toolCall.toolName;
|
|
512
|
+
const targetTool = tools[toolName];
|
|
513
|
+
if (!targetTool) {
|
|
514
|
+
return { valid: false, error: `Tool '${String(toolName)}' not found` };
|
|
515
|
+
}
|
|
516
|
+
try {
|
|
517
|
+
if (targetTool.inputSchema || targetTool.parameters) {
|
|
518
|
+
const schema = targetTool.inputSchema || targetTool.parameters;
|
|
519
|
+
schema.parse(toolCall.input);
|
|
520
|
+
}
|
|
521
|
+
return { valid: true };
|
|
522
|
+
} catch (validationError) {
|
|
523
|
+
return {
|
|
524
|
+
valid: false,
|
|
525
|
+
error: `Invalid tool input: ${validationError.message}`
|
|
526
|
+
};
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
/**
|
|
530
|
+
* 工具调用统计分析
|
|
531
|
+
*/
|
|
532
|
+
analyzeToolUsage(steps) {
|
|
533
|
+
const allToolCalls = this.extractToolCallsFromSteps(steps);
|
|
534
|
+
const allToolResults = this.extractToolResultsFromSteps(steps);
|
|
535
|
+
const toolUsageByName = {};
|
|
536
|
+
allToolCalls.forEach((call) => {
|
|
537
|
+
const toolName = String(call.toolName);
|
|
538
|
+
toolUsageByName[toolName] = (toolUsageByName[toolName] || 0) + 1;
|
|
539
|
+
});
|
|
540
|
+
const stepTypes = {};
|
|
541
|
+
steps.forEach((step) => {
|
|
542
|
+
stepTypes[step.stepType] = (stepTypes[step.stepType] || 0) + 1;
|
|
543
|
+
});
|
|
544
|
+
return {
|
|
545
|
+
totalToolCalls: allToolCalls.length,
|
|
546
|
+
totalToolResults: allToolResults.length,
|
|
547
|
+
toolUsageByName,
|
|
548
|
+
avgToolCallsPerStep: steps.length > 0 ? allToolCalls.length / steps.length : 0,
|
|
549
|
+
stepTypes
|
|
550
|
+
};
|
|
551
|
+
}
|
|
552
|
+
/**
|
|
553
|
+
* 提取步骤中的所有工具调用
|
|
554
|
+
*/
|
|
555
|
+
extractToolCallsFromSteps(steps) {
|
|
556
|
+
return steps.flatMap((step) => step.toolCalls);
|
|
557
|
+
}
|
|
558
|
+
/**
|
|
559
|
+
* 提取步骤中的所有工具结果
|
|
560
|
+
*/
|
|
561
|
+
extractToolResultsFromSteps(steps) {
|
|
562
|
+
return steps.flatMap((step) => step.toolResults);
|
|
563
|
+
}
|
|
564
|
+
/**
|
|
565
|
+
* 检查初始化状态
|
|
566
|
+
*/
|
|
567
|
+
isInitialized() {
|
|
568
|
+
return this.initialized;
|
|
569
|
+
}
|
|
570
|
+
/**
|
|
571
|
+
* 获取统计信息
|
|
572
|
+
*/
|
|
573
|
+
getStats() {
|
|
574
|
+
return {
|
|
575
|
+
requestCount: this.requestCounter,
|
|
576
|
+
isInitialized: this.initialized,
|
|
577
|
+
registeredTools: this.registeredTools.size,
|
|
578
|
+
dynamicTools: this.dynamicTools.size,
|
|
579
|
+
mcpClients: this.mcpClients.size
|
|
580
|
+
};
|
|
581
|
+
}
|
|
582
|
+
/**
|
|
583
|
+
* 重置统计信息
|
|
584
|
+
*/
|
|
585
|
+
resetStats() {
|
|
586
|
+
this.requestCounter = 0;
|
|
587
|
+
}
|
|
588
|
+
/**
|
|
589
|
+
* 销毁实例
|
|
590
|
+
*/
|
|
591
|
+
async destroy() {
|
|
592
|
+
await this.closeAllMCPClients();
|
|
593
|
+
this.registeredTools.clear();
|
|
594
|
+
this.dynamicTools.clear();
|
|
595
|
+
this.removeAllListeners();
|
|
596
|
+
this.initialized = false;
|
|
597
|
+
this.requestCounter = 0;
|
|
598
|
+
}
|
|
599
|
+
};
|
|
600
|
+
var ai_tools_default = AIToolsIntegration;
|
|
601
|
+
|
|
602
|
+
export {
|
|
603
|
+
tool,
|
|
604
|
+
dynamicTool,
|
|
605
|
+
stepCountIs,
|
|
606
|
+
NoSuchToolError,
|
|
607
|
+
InvalidToolInputError,
|
|
608
|
+
AIToolsIntegration,
|
|
609
|
+
ai_tools_default
|
|
610
|
+
};
|
|
611
|
+
//# sourceMappingURL=chunk-25C2NRSD.mjs.map
|