@saber2pr/ai-agent 0.0.64 → 0.0.65

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.
@@ -1,6 +1,6 @@
1
- import { AIMessage, BaseMessage } from '@langchain/core/messages';
2
- import { GraphAgentOptions } from '../types/type';
3
- import { AgentGraphModel } from '../model/AgentGraphModel';
1
+ import { AIMessage, BaseMessage } from "@langchain/core/messages";
2
+ import { GraphAgentOptions } from "../types/type";
3
+ import { AgentGraphModel } from "../model/AgentGraphModel";
4
4
  interface TokenUsage {
5
5
  total: number;
6
6
  }
@@ -30,7 +30,7 @@ export default class McpGraphAgent<T extends AgentGraphModel = any> {
30
30
  * 设置外部流式输出回调(如 VS Code Webview)。
31
31
  * 设置后,callModel 的流式输出将通过回调发送而非写入 stdout。
32
32
  */
33
- setStreamOutput(callback: (chunk: string, type: 'think' | 'text') => void): void;
33
+ setStreamOutput(callback: (chunk: string, type: "think" | "text") => void): void;
34
34
  /**
35
35
  * 清除外部流式输出回调,恢复默认的 stdout 输出。
36
36
  */
@@ -76,11 +76,11 @@ class McpGraphAgent {
76
76
  const cleanup = async () => {
77
77
  this.stopLoading();
78
78
  await this.closeMcpClients(); // 清理 MCP 连接
79
- process.stdout.write('\u001B[?25h');
79
+ process.stdout.write("\u001B[?25h");
80
80
  process.exit(0);
81
81
  };
82
- process.on('SIGINT', cleanup);
83
- process.on('SIGTERM', cleanup);
82
+ process.on("SIGINT", cleanup);
83
+ process.on("SIGTERM", cleanup);
84
84
  }
85
85
  /**
86
86
  * 设置外部流式输出回调(如 VS Code Webview)。
@@ -96,7 +96,7 @@ class McpGraphAgent {
96
96
  this.streamOutputCallback = null;
97
97
  }
98
98
  printLoadedTools() {
99
- console.log('\n🛠️ [Graph] 正在加载工具节点...');
99
+ console.log("\n🛠️ [Graph] 正在加载工具节点...");
100
100
  this.langchainTools.forEach((tool) => {
101
101
  // 工具名称
102
102
  console.log(`\n🧰 工具名: ${tool.name}`);
@@ -120,12 +120,12 @@ class McpGraphAgent {
120
120
  loadMcpConfigs() {
121
121
  const combined = { mcpServers: {} };
122
122
  const paths = [
123
- path_1.default.join(os_1.default.homedir(), '.cursor', 'mcp.json'),
124
- path_1.default.join(os_1.default.homedir(), '.vscode', 'mcp.json'),
123
+ path_1.default.join(os_1.default.homedir(), ".cursor", "mcp.json"),
124
+ path_1.default.join(os_1.default.homedir(), ".vscode", "mcp.json"),
125
125
  ];
126
- paths.forEach(p => {
126
+ paths.forEach((p) => {
127
127
  if (fs_1.default.existsSync(p)) {
128
- const content = JSON.parse(fs_1.default.readFileSync(p, 'utf-8'));
128
+ const content = JSON.parse(fs_1.default.readFileSync(p, "utf-8"));
129
129
  Object.assign(combined.mcpServers, content.mcpServers);
130
130
  }
131
131
  });
@@ -142,13 +142,13 @@ class McpGraphAgent {
142
142
  args: config.args,
143
143
  env: { ...process.env, ...(config.env || {}) },
144
144
  });
145
- const client = new index_js_1.Client({ name: 'mcp-graph-client', version: '1.0.0' }, { capabilities: {} });
145
+ const client = new index_js_1.Client({ name: "mcp-graph-client", version: "1.0.0" }, { capabilities: {} });
146
146
  await client.connect(transport);
147
147
  this.mcpClients.push(client);
148
148
  const { tools } = await client.listTools();
149
- tools.forEach(tool => {
149
+ tools.forEach((tool) => {
150
150
  mcpToolInfos.push({
151
- type: 'function',
151
+ type: "function",
152
152
  function: {
153
153
  name: tool.name,
154
154
  description: tool.description,
@@ -172,11 +172,20 @@ class McpGraphAgent {
172
172
  return mcpToolInfos;
173
173
  }
174
174
  async prepareTools() {
175
- const builtinToolInfos = (0, builtin_1.createDefaultBuiltinTools)({ options: this.options });
175
+ const builtinToolInfos = (0, builtin_1.createDefaultBuiltinTools)({
176
+ options: this.options,
177
+ });
176
178
  const mcpToolInfos = await this.initMcpTools();
177
179
  // 合并内置、手动传入和 MCP 工具
178
- const allToolInfos = [...builtinToolInfos, ...(this.options.tools || []), ...mcpToolInfos];
179
- this.langchainTools = allToolInfos.map(t => (0, convertToLangChainTool_1.convertToLangChainTool)(t, { allTools: allToolInfos }));
180
+ let allToolInfos = [
181
+ ...builtinToolInfos,
182
+ ...(this.options.tools || []),
183
+ ...mcpToolInfos,
184
+ ];
185
+ if (this.options.filterTools) {
186
+ allToolInfos = allToolInfos.filter(this.options.filterTools);
187
+ }
188
+ this.langchainTools = allToolInfos.map((t) => (0, convertToLangChainTool_1.convertToLangChainTool)(t, { allTools: allToolInfos }));
180
189
  this.toolNode = new prebuilt_1.ToolNode(this.langchainTools);
181
190
  return {
182
191
  builtinToolInfos,
@@ -190,7 +199,6 @@ class McpGraphAgent {
190
199
  if (this.model && this.langchainTools.length > 0) {
191
200
  return this.getModel();
192
201
  }
193
- ;
194
202
  // 1. 加载所有工具(含 MCP)
195
203
  const toolsInfo = await this.prepareTools();
196
204
  // 2. 初始化模型
@@ -213,17 +221,17 @@ class McpGraphAgent {
213
221
  this.mcpClients = [];
214
222
  }
215
223
  showLoading(text) {
216
- const chars = ['', '', '', '', '', '', '', '', '', ''];
224
+ const chars = ["", "", "", "", "", "", "", "", "", ""];
217
225
  let i = 0;
218
- process.stdout.write('\u001B[?25l');
226
+ process.stdout.write("\u001B[?25l");
219
227
  const timer = setInterval(() => {
220
228
  process.stdout.write(`\r\x1b[36m${chars[i]}\x1b[0m ${text}`);
221
229
  i = (i + 1) % chars.length;
222
230
  }, 80);
223
231
  return () => {
224
232
  clearInterval(timer);
225
- process.stdout.write('\r\x1b[K');
226
- process.stdout.write('\u001B[?25h');
233
+ process.stdout.write("\r\x1b[K");
234
+ process.stdout.write("\u001B[?25h");
227
235
  };
228
236
  }
229
237
  startLoading(text) {
@@ -260,29 +268,33 @@ class McpGraphAgent {
260
268
  let config = {};
261
269
  if (fs_1.default.existsSync(config_1.CONFIG_FILE)) {
262
270
  try {
263
- config = JSON.parse(fs_1.default.readFileSync(config_1.CONFIG_FILE, 'utf-8'));
271
+ config = JSON.parse(fs_1.default.readFileSync(config_1.CONFIG_FILE, "utf-8"));
264
272
  }
265
273
  catch (e) { }
266
274
  }
267
275
  if (!config.baseURL || !config.apiKey) {
268
- const rl = readline_1.default.createInterface({ input: process.stdin, output: process.stdout });
269
- const question = (q) => new Promise(res => rl.question(q, res));
276
+ const rl = readline_1.default.createInterface({
277
+ input: process.stdin,
278
+ output: process.stdout,
279
+ });
280
+ const question = (q) => new Promise((res) => rl.question(q, res));
270
281
  config.baseURL = config.baseURL || (await question(`? API Base URL: `));
271
282
  config.apiKey = config.apiKey || (await question(`? API Key: `));
272
- config.model = config.model || (await question(`? Model Name: `)) || 'gpt-4o';
283
+ config.model =
284
+ config.model || (await question(`? Model Name: `)) || "gpt-4o";
273
285
  fs_1.default.writeFileSync(config_1.CONFIG_FILE, JSON.stringify(config, null, 2));
274
286
  rl.close();
275
287
  }
276
288
  return config;
277
289
  }
278
- async chat(query = '开始代码审计') {
290
+ async chat(query = "开始代码审计") {
279
291
  try {
280
292
  await this.ensureInitialized();
281
293
  const app = await this.createGraph();
282
294
  const graphStream = await app.stream({
283
295
  messages: [new messages_1.HumanMessage(query)],
284
296
  }, {
285
- configurable: { thread_id: 'auto_worker' },
297
+ configurable: { thread_id: "auto_worker" },
286
298
  recursionLimit: this.recursionLimit,
287
299
  debug: this.verbose,
288
300
  });
@@ -290,7 +302,7 @@ class McpGraphAgent {
290
302
  this.renderOutput(output, this.streamEnabled);
291
303
  }
292
304
  catch (error) {
293
- console.error('\n❌ Chat 过程中发生错误:', error);
305
+ console.error("\n❌ Chat 过程中发生错误:", error);
294
306
  }
295
307
  finally {
296
308
  await this.closeMcpClients();
@@ -300,7 +312,7 @@ class McpGraphAgent {
300
312
  * 流式执行单次查询(编程式 API)。
301
313
  * 无论 options.stream 是否开启,此方法始终以流式方式输出。
302
314
  */
303
- async stream(query = '开始代码审计') {
315
+ async stream(query = "开始代码审计") {
304
316
  const prevStream = this.streamEnabled;
305
317
  this.streamEnabled = true;
306
318
  try {
@@ -309,7 +321,7 @@ class McpGraphAgent {
309
321
  const graphStream = await app.stream({
310
322
  messages: [new messages_1.HumanMessage(query)],
311
323
  }, {
312
- configurable: { thread_id: 'stream_worker' },
324
+ configurable: { thread_id: "stream_worker" },
313
325
  recursionLimit: this.recursionLimit,
314
326
  debug: this.verbose,
315
327
  });
@@ -317,7 +329,7 @@ class McpGraphAgent {
317
329
  this.renderOutput(output, true);
318
330
  }
319
331
  catch (error) {
320
- console.error('\n❌ Stream 过程中发生错误:', error);
332
+ console.error("\n❌ Stream 过程中发生错误:", error);
321
333
  }
322
334
  finally {
323
335
  this.streamEnabled = prevStream;
@@ -327,21 +339,24 @@ class McpGraphAgent {
327
339
  async start() {
328
340
  await this.ensureInitialized();
329
341
  const app = await this.createGraph();
330
- const rl = readline_1.default.createInterface({ input: process.stdin, output: process.stdout });
331
- rl.on('SIGINT', () => {
342
+ const rl = readline_1.default.createInterface({
343
+ input: process.stdin,
344
+ output: process.stdout,
345
+ });
346
+ rl.on("SIGINT", () => {
332
347
  this.stopLoading();
333
348
  rl.close();
334
- process.stdout.write('\u001B[?25h');
349
+ process.stdout.write("\u001B[?25h");
335
350
  process.exit(0);
336
351
  });
337
352
  const ask = () => {
338
- rl.question('> ', async (input) => {
339
- if (input.toLowerCase() === 'exit') {
353
+ rl.question("> ", async (input) => {
354
+ if (input.toLowerCase() === "exit") {
340
355
  rl.close();
341
356
  return;
342
357
  }
343
358
  const graphStream = await app.stream({ messages: [new messages_1.HumanMessage(input)] }, {
344
- configurable: { thread_id: 'session' },
359
+ configurable: { thread_id: "session" },
345
360
  recursionLimit: this.recursionLimit,
346
361
  debug: this.verbose,
347
362
  });
@@ -358,7 +373,9 @@ class McpGraphAgent {
358
373
  // ✅ 打印工具执行结果(tools 节点的输出)
359
374
  const toolsNode = output.tools;
360
375
  if (toolsNode && toolsNode.messages) {
361
- const toolMessages = Array.isArray(toolsNode.messages) ? toolsNode.messages : [];
376
+ const toolMessages = Array.isArray(toolsNode.messages)
377
+ ? toolsNode.messages
378
+ : [];
362
379
  // 获取最近的 AI 消息以匹配 tool_call_id
363
380
  const lastAiMsg = agentNode?.messages?.[agentNode.messages.length - 1];
364
381
  const toolCallMap = new Map();
@@ -372,10 +389,12 @@ class McpGraphAgent {
372
389
  // ToolMessage 有 tool_call_id 字段
373
390
  const toolCallId = msg.tool_call_id || msg.id;
374
391
  if (toolCallId) {
375
- const toolName = toolCallMap.get(toolCallId) || msg.name || 'unknown';
376
- const content = typeof msg.content === 'string' ? msg.content : JSON.stringify(msg.content);
392
+ const toolName = toolCallMap.get(toolCallId) || msg.name || "unknown";
393
+ const content = typeof msg.content === "string"
394
+ ? msg.content
395
+ : JSON.stringify(msg.content);
377
396
  // 如果内容太长,截断显示
378
- const displayContent = content.length > 500 ? content.substring(0, 500) + '...' : content;
397
+ const displayContent = content.length > 500 ? content.substring(0, 500) + "..." : content;
379
398
  console.log(`✅ [工具结果] ${toolName}: ${displayContent}`);
380
399
  }
381
400
  });
@@ -402,7 +421,7 @@ class McpGraphAgent {
402
421
  }
403
422
  // 4. 打印工具调用情况
404
423
  if (msg.tool_calls?.length) {
405
- msg.tool_calls.forEach(call => {
424
+ msg.tool_calls.forEach((call) => {
406
425
  console.log(`🛠️ [调用工具]: ${call.name} 📦 参数: ${JSON.stringify(call.args)}`);
407
426
  });
408
427
  }
@@ -412,9 +431,9 @@ class McpGraphAgent {
412
431
  const recentToolCalls = this.getRecentToolCalls(state.messages);
413
432
  const recentToolCallsStr = recentToolCalls.length > 0
414
433
  ? `\n\n⚠️ 最近调用的工具(避免重复调用相同工具和参数):\n${recentToolCalls
415
- .map(tc => ` - ${tc.name}(${JSON.stringify(tc.args)})`)
416
- .join('\n')}`
417
- : '';
434
+ .map((tc) => ` - ${tc.name}(${JSON.stringify(tc.args)})`)
435
+ .join("\n")}`
436
+ : "";
418
437
  // 1. 构建当前的系统提示词模板
419
438
  const systemPromptTemplate = `
420
439
  ${(0, getSystemPromptTemplate_1.getSystemPromptTemplate)(this.targetDir)}
@@ -425,32 +444,32 @@ ${(0, getSystemPromptTemplate_1.getSystemPromptTemplate)(this.targetDir)}
425
444
  // ✅ 检查 options 中的 alwaysSystem 参数 (默认为 true 或根据你的需求设置)
426
445
  // 如果不希望每次都携带(即只在首轮携带),则过滤掉历史消息里的 SystemMessage
427
446
  if (this.options.alwaysSystem === false) {
428
- inputMessages = state.messages.filter(msg => msg._getType() !== 'system');
447
+ inputMessages = state.messages.filter((msg) => msg._getType() !== "system");
429
448
  }
430
449
  else {
431
450
  // 默认模式:保持干净,由 PromptTemplate 重新生成最新的 System 状态
432
- inputMessages = state.messages.filter(msg => msg._getType() !== 'system');
451
+ inputMessages = state.messages.filter((msg) => msg._getType() !== "system");
433
452
  }
434
453
  const prompt = prompts_1.ChatPromptTemplate.fromMessages([
435
- ['system', systemPromptTemplate],
436
- new prompts_1.MessagesPlaceholder('messages'),
454
+ ["system", systemPromptTemplate],
455
+ new prompts_1.MessagesPlaceholder("messages"),
437
456
  ]);
438
- this.startLoading('AI 正在分析并思考中');
457
+ this.startLoading("AI 正在分析并思考中");
439
458
  try {
440
459
  const promptParams = {
441
460
  messages: inputMessages,
442
461
  recentToolCalls: recentToolCallsStr,
443
- extraPrompt: this.options.extraSystemPrompt || '',
462
+ extraPrompt: this.options.extraSystemPrompt || "",
444
463
  };
445
464
  if (this.streamEnabled) {
446
465
  // ✅ 流式模式:通过 AgentGraphModel.streamGenerate 进行流式输出
447
466
  const formattedMessages = await prompt.formatMessages(promptParams);
448
467
  this.stopLoading();
449
468
  // --- 流式 <think> 标签实时过滤 + 流式打印思考内容 ---
450
- const THINK_OPEN = '<think>';
451
- const THINK_CLOSE = '</think>';
469
+ const THINK_OPEN = "<think>";
470
+ const THINK_CLOSE = "</think>";
452
471
  let inThink = false;
453
- let textBuffer = '';
472
+ let textBuffer = "";
454
473
  let aiHeaderPrinted = false;
455
474
  let thinkHeaderPrinted = false;
456
475
  const hasExternalHandler = !!this.streamOutputCallback;
@@ -458,11 +477,11 @@ ${(0, getSystemPromptTemplate_1.getSystemPromptTemplate)(this.targetDir)}
458
477
  if (!text)
459
478
  return;
460
479
  if (hasExternalHandler) {
461
- this.streamOutputCallback(text, 'text');
480
+ this.streamOutputCallback(text, "text");
462
481
  }
463
482
  else {
464
483
  if (!aiHeaderPrinted) {
465
- process.stdout.write('🤖 [AI]: ');
484
+ process.stdout.write("🤖 [AI]: ");
466
485
  aiHeaderPrinted = true;
467
486
  }
468
487
  process.stdout.write(text);
@@ -472,11 +491,11 @@ ${(0, getSystemPromptTemplate_1.getSystemPromptTemplate)(this.targetDir)}
472
491
  if (!text)
473
492
  return;
474
493
  if (hasExternalHandler) {
475
- this.streamOutputCallback(text, 'think');
494
+ this.streamOutputCallback(text, "think");
476
495
  }
477
496
  else {
478
497
  if (!thinkHeaderPrinted) {
479
- process.stdout.write('\x1b[2m🧠 [思考]: ');
498
+ process.stdout.write("\x1b[2m🧠 [思考]: ");
480
499
  thinkHeaderPrinted = true;
481
500
  }
482
501
  process.stdout.write(text);
@@ -496,7 +515,7 @@ ${(0, getSystemPromptTemplate_1.getSystemPromptTemplate)(this.targetDir)}
496
515
  inThink = false;
497
516
  // 思考块结束:stdout 模式下换行 + 重置样式
498
517
  if (!hasExternalHandler && thinkHeaderPrinted) {
499
- process.stdout.write('\x1b[0m\n');
518
+ process.stdout.write("\x1b[0m\n");
500
519
  thinkHeaderPrinted = false;
501
520
  }
502
521
  }
@@ -539,10 +558,10 @@ ${(0, getSystemPromptTemplate_1.getSystemPromptTemplate)(this.targetDir)}
539
558
  // 收尾:stdout 模式下关闭样式和换行
540
559
  if (!hasExternalHandler) {
541
560
  if (thinkHeaderPrinted) {
542
- process.stdout.write('\x1b[0m\n');
561
+ process.stdout.write("\x1b[0m\n");
543
562
  }
544
563
  if (aiHeaderPrinted)
545
- process.stdout.write('\n');
564
+ process.stdout.write("\n");
546
565
  }
547
566
  const aiMsg = result.generations[0].message;
548
567
  const meta = aiMsg.response_metadata || {};
@@ -591,57 +610,49 @@ ${(0, getSystemPromptTemplate_1.getSystemPromptTemplate)(this.targetDir)}
591
610
  const totalTokens = state.tokenUsage?.total || 0;
592
611
  const totalMs = state.totalDuration || 0;
593
612
  if (totalTokens > 0 || totalMs > 0) {
594
- console.log('\n' + ''.repeat(50));
613
+ console.log("\n" + "".repeat(50));
595
614
  console.log(`🏁 \x1b[32;1m[审计任务全量结算]\x1b[0m`);
596
615
  console.log(` - 累计消耗总额: \x1b[33m${totalTokens}\x1b[0m Tokens`);
597
616
  console.log(` - 累计执行耗时: \x1b[36m${(totalMs / 1000).toFixed(2)}\x1b[0m s`);
598
- console.log(''.repeat(50) + '\n');
617
+ console.log("".repeat(50) + "\n");
599
618
  }
600
619
  }
601
620
  async createGraph() {
602
621
  const workflow = new langgraph_1.StateGraph(AgentState)
603
- .addNode('agent', state => this.callModel(state))
604
- .addNode('tools', this.toolNode)
605
- .addNode('interrupt', state => {
622
+ .addNode("agent", (state) => this.callModel(state))
623
+ .addNode("tools", this.toolNode)
624
+ .addNode("interrupt", (state) => {
606
625
  return {
607
- messages: [new messages_1.AIMessage({
608
- content: `Final Answer:\n💡 **嘿,我们已经聊了很多了!**
609
-
610
- 为了保证服务质量,我通常会在 50 步操作后停下来和您确认一下。这样可以避免我产生“幻觉”或者做一些无用功。
611
-
612
- **任务还没完成吗?** 没关系,只要您回复“继续”,我马上就回来接着干!或者您有什么新的想法要告诉我?`
613
- })]
626
+ messages: [
627
+ new messages_1.AIMessage({
628
+ content: `Final Answer:\n💡 ⚠️ 抱歉,当前任务消耗的 Token 已达上限 ${this.options.maxTokens}。为了防止无限循环,我已停止执行。你可以尝试分步骤指令,继续发送指令,直到任务完成。`,
629
+ }),
630
+ ],
614
631
  };
615
632
  })
616
- .addEdge(langgraph_1.START, 'agent')
617
- .addConditionalEdges('agent', state => {
633
+ .addEdge(langgraph_1.START, "agent")
634
+ .addConditionalEdges("agent", (state) => {
618
635
  const { messages } = state;
619
636
  const lastMsg = messages[messages.length - 1];
620
- const content = lastMsg.content || '';
637
+ const content = lastMsg.content || "";
621
638
  // 🛑 新增:全局 Token 熔断保护
622
639
  // 如果已消耗 Token 超过了 options 中设置的 maxTokens (假设是总限额)
623
- if (this.options.maxTokens && state.tokenUsage.total >= this.options.maxTokens) {
624
- console.warn('⚠️ [警告] 已达到最大 Token 限制,强制结束任务。');
625
- state.messages.push(new messages_1.AIMessage({
626
- content: `⚠️ 抱歉,当前任务消耗的 Token 已达上限 ${this.options.maxTokens}。为了防止无限循环,我已停止执行。你可以尝试分步骤指令,继续发送指令,直到任务完成。`
627
- }));
628
- this.printFinalSummary(state);
629
- return langgraph_1.END;
640
+ if (this.options.maxTokens &&
641
+ state.tokenUsage.total >= this.options.maxTokens) {
642
+ return "interrupt";
630
643
  }
631
644
  // 1. 如果 AI 想要调用工具,去 tools 节点
632
645
  if (lastMsg.tool_calls && lastMsg.tool_calls.length > 0) {
633
- return 'tools';
646
+ return "tools";
634
647
  }
635
- const isFinalAnswer = content.includes('Final Answer');
648
+ const isFinalAnswer = content.includes("Final Answer");
636
649
  if (isFinalAnswer) {
637
650
  this.printFinalSummary(state);
638
651
  return langgraph_1.END;
639
652
  }
640
- if (messages.length > 50) {
641
- return 'interrupt';
642
- }
643
653
  return langgraph_1.END;
644
- }).addEdge('tools', 'agent');
654
+ })
655
+ .addEdge("tools", "agent");
645
656
  return workflow.compile({ checkpointer: this.checkpointer });
646
657
  }
647
658
  }
@@ -1,13 +1,13 @@
1
- import { z } from 'zod';
2
- import { Client } from '@modelcontextprotocol/sdk/client/index';
3
- import { AgentGraphModel } from '../model/AgentGraphModel';
1
+ import { z } from "zod";
2
+ import { Client } from "@modelcontextprotocol/sdk/client/index";
3
+ import { AgentGraphModel } from "../model/AgentGraphModel";
4
4
  export interface ApiConfig {
5
5
  baseURL: string;
6
6
  apiKey: string;
7
7
  model: string;
8
8
  }
9
9
  export interface ToolInfo {
10
- type: 'function';
10
+ type: "function";
11
11
  function: {
12
12
  name: string;
13
13
  description?: string;
@@ -42,6 +42,7 @@ export interface GraphAgentOptions<T extends AgentGraphModel = any> extends Agen
42
42
  recursionLimit?: number;
43
43
  /** 是否启用流式输出,默认 false */
44
44
  stream?: boolean;
45
+ filterTools?: (tool: ToolInfo) => boolean;
45
46
  }
46
47
  export interface CreateAgentOptions {
47
48
  apiKey: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@saber2pr/ai-agent",
3
- "version": "0.0.64",
3
+ "version": "0.0.65",
4
4
  "description": "AI Assistant CLI.",
5
5
  "author": "saber2pr",
6
6
  "license": "ISC",