@saber2pr/ai-agent 0.0.50 → 0.0.51
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/lib/core/agent-graph.d.ts +1 -20
- package/lib/core/agent-graph.js +17 -55
- package/lib/types/type.d.ts +1 -2
- package/package.json +1 -1
|
@@ -6,9 +6,6 @@ interface TokenUsage {
|
|
|
6
6
|
}
|
|
7
7
|
declare const AgentState: import("@langchain/langgraph").AnnotationRoot<{
|
|
8
8
|
messages: import("@langchain/langgraph").BinaryOperatorAggregate<BaseMessage[], BaseMessage[]>;
|
|
9
|
-
auditedFiles: import("@langchain/langgraph").BinaryOperatorAggregate<string[], string[]>;
|
|
10
|
-
targetCount: import("@langchain/langgraph").BinaryOperatorAggregate<number, number>;
|
|
11
|
-
mode: import("@langchain/langgraph").BinaryOperatorAggregate<"chat" | "auto", "chat" | "auto">;
|
|
12
9
|
tokenUsage: import("@langchain/langgraph").BinaryOperatorAggregate<TokenUsage, TokenUsage>;
|
|
13
10
|
totalDuration: import("@langchain/langgraph").BinaryOperatorAggregate<number, number>;
|
|
14
11
|
}>;
|
|
@@ -24,7 +21,6 @@ export default class McpGraphAgent<T extends AgentGraphModel = any> {
|
|
|
24
21
|
private alwaysSystem;
|
|
25
22
|
private recursionLimit;
|
|
26
23
|
private apiConfig;
|
|
27
|
-
private maxTargetCount;
|
|
28
24
|
private maxTokens;
|
|
29
25
|
private mcpClients;
|
|
30
26
|
private streamEnabled;
|
|
@@ -66,36 +62,21 @@ export default class McpGraphAgent<T extends AgentGraphModel = any> {
|
|
|
66
62
|
totalDuration: number;
|
|
67
63
|
}>;
|
|
68
64
|
private getRecentToolCalls;
|
|
69
|
-
trackProgress(state: typeof AgentState.State): Promise<{
|
|
70
|
-
auditedFiles: string[];
|
|
71
|
-
}>;
|
|
72
65
|
private printFinalSummary;
|
|
73
66
|
createGraph(): Promise<import("@langchain/langgraph").CompiledStateGraph<import("@langchain/langgraph").StateType<{
|
|
74
67
|
messages: import("@langchain/langgraph").BinaryOperatorAggregate<BaseMessage[], BaseMessage[]>;
|
|
75
|
-
auditedFiles: import("@langchain/langgraph").BinaryOperatorAggregate<string[], string[]>;
|
|
76
|
-
targetCount: import("@langchain/langgraph").BinaryOperatorAggregate<number, number>;
|
|
77
|
-
mode: import("@langchain/langgraph").BinaryOperatorAggregate<"chat" | "auto", "chat" | "auto">;
|
|
78
68
|
tokenUsage: import("@langchain/langgraph").BinaryOperatorAggregate<TokenUsage, TokenUsage>;
|
|
79
69
|
totalDuration: import("@langchain/langgraph").BinaryOperatorAggregate<number, number>;
|
|
80
70
|
}>, import("@langchain/langgraph").UpdateType<{
|
|
81
71
|
messages: import("@langchain/langgraph").BinaryOperatorAggregate<BaseMessage[], BaseMessage[]>;
|
|
82
|
-
auditedFiles: import("@langchain/langgraph").BinaryOperatorAggregate<string[], string[]>;
|
|
83
|
-
targetCount: import("@langchain/langgraph").BinaryOperatorAggregate<number, number>;
|
|
84
|
-
mode: import("@langchain/langgraph").BinaryOperatorAggregate<"chat" | "auto", "chat" | "auto">;
|
|
85
72
|
tokenUsage: import("@langchain/langgraph").BinaryOperatorAggregate<TokenUsage, TokenUsage>;
|
|
86
73
|
totalDuration: import("@langchain/langgraph").BinaryOperatorAggregate<number, number>;
|
|
87
|
-
}>, "tools" | "__start__" | "agent"
|
|
74
|
+
}>, "tools" | "__start__" | "agent", {
|
|
88
75
|
messages: import("@langchain/langgraph").BinaryOperatorAggregate<BaseMessage[], BaseMessage[]>;
|
|
89
|
-
auditedFiles: import("@langchain/langgraph").BinaryOperatorAggregate<string[], string[]>;
|
|
90
|
-
targetCount: import("@langchain/langgraph").BinaryOperatorAggregate<number, number>;
|
|
91
|
-
mode: import("@langchain/langgraph").BinaryOperatorAggregate<"chat" | "auto", "chat" | "auto">;
|
|
92
76
|
tokenUsage: import("@langchain/langgraph").BinaryOperatorAggregate<TokenUsage, TokenUsage>;
|
|
93
77
|
totalDuration: import("@langchain/langgraph").BinaryOperatorAggregate<number, number>;
|
|
94
78
|
}, {
|
|
95
79
|
messages: import("@langchain/langgraph").BinaryOperatorAggregate<BaseMessage[], BaseMessage[]>;
|
|
96
|
-
auditedFiles: import("@langchain/langgraph").BinaryOperatorAggregate<string[], string[]>;
|
|
97
|
-
targetCount: import("@langchain/langgraph").BinaryOperatorAggregate<number, number>;
|
|
98
|
-
mode: import("@langchain/langgraph").BinaryOperatorAggregate<"chat" | "auto", "chat" | "auto">;
|
|
99
80
|
tokenUsage: import("@langchain/langgraph").BinaryOperatorAggregate<TokenUsage, TokenUsage>;
|
|
100
81
|
totalDuration: import("@langchain/langgraph").BinaryOperatorAggregate<number, number>;
|
|
101
82
|
}, import("@langchain/langgraph").StateDefinition>>;
|
package/lib/core/agent-graph.js
CHANGED
|
@@ -29,18 +29,6 @@ const AgentState = langgraph_1.Annotation.Root({
|
|
|
29
29
|
reducer: (x, y) => x.concat(y),
|
|
30
30
|
default: () => [],
|
|
31
31
|
}),
|
|
32
|
-
auditedFiles: (0, langgraph_1.Annotation)({
|
|
33
|
-
reducer: (x, y) => Array.from(new Set([...x, ...y])),
|
|
34
|
-
default: () => [],
|
|
35
|
-
}),
|
|
36
|
-
targetCount: (0, langgraph_1.Annotation)({
|
|
37
|
-
reducer: (x, y) => y !== null && y !== void 0 ? y : x,
|
|
38
|
-
default: () => 4,
|
|
39
|
-
}),
|
|
40
|
-
mode: (0, langgraph_1.Annotation)({
|
|
41
|
-
reducer: (x, y) => y !== null && y !== void 0 ? y : x,
|
|
42
|
-
default: () => 'chat',
|
|
43
|
-
}),
|
|
44
32
|
// ✅ Token 累加器
|
|
45
33
|
tokenUsage: (0, langgraph_1.Annotation)({
|
|
46
34
|
reducer: (x, y) => ({
|
|
@@ -67,8 +55,7 @@ class McpGraphAgent {
|
|
|
67
55
|
this.targetDir = options.targetDir || process.cwd();
|
|
68
56
|
this.recursionLimit = options.recursionLimit || 80;
|
|
69
57
|
this.apiConfig = options.apiConfig;
|
|
70
|
-
this.
|
|
71
|
-
this.maxTokens = options.maxTokens || 8000;
|
|
58
|
+
this.maxTokens = options.maxTokens || 100000;
|
|
72
59
|
this.streamEnabled = options.stream || false;
|
|
73
60
|
process.setMaxListeners(100);
|
|
74
61
|
// ✅ 修复 AbortSignal 监听器数量警告
|
|
@@ -283,8 +270,6 @@ class McpGraphAgent {
|
|
|
283
270
|
const app = await this.createGraph();
|
|
284
271
|
const graphStream = await app.stream({
|
|
285
272
|
messages: [new messages_1.HumanMessage(query)],
|
|
286
|
-
mode: 'auto',
|
|
287
|
-
targetCount: this.maxTargetCount,
|
|
288
273
|
}, {
|
|
289
274
|
configurable: { thread_id: 'auto_worker' },
|
|
290
275
|
recursionLimit: this.recursionLimit,
|
|
@@ -312,8 +297,6 @@ class McpGraphAgent {
|
|
|
312
297
|
const app = await this.createGraph();
|
|
313
298
|
const graphStream = await app.stream({
|
|
314
299
|
messages: [new messages_1.HumanMessage(query)],
|
|
315
|
-
mode: 'auto',
|
|
316
|
-
targetCount: this.maxTargetCount,
|
|
317
300
|
}, {
|
|
318
301
|
configurable: { thread_id: 'stream_worker' },
|
|
319
302
|
recursionLimit: this.recursionLimit,
|
|
@@ -346,7 +329,7 @@ class McpGraphAgent {
|
|
|
346
329
|
rl.close();
|
|
347
330
|
return;
|
|
348
331
|
}
|
|
349
|
-
const graphStream = await app.stream({ messages: [new messages_1.HumanMessage(input)]
|
|
332
|
+
const graphStream = await app.stream({ messages: [new messages_1.HumanMessage(input)] }, {
|
|
350
333
|
configurable: { thread_id: 'session' },
|
|
351
334
|
recursionLimit: this.recursionLimit,
|
|
352
335
|
debug: this.verbose,
|
|
@@ -416,7 +399,6 @@ class McpGraphAgent {
|
|
|
416
399
|
}
|
|
417
400
|
}
|
|
418
401
|
async callModel(state) {
|
|
419
|
-
const auditedListStr = state.auditedFiles.length > 0 ? state.auditedFiles.map(f => `\n - ${f}`).join('') : '暂无';
|
|
420
402
|
const recentToolCalls = this.getRecentToolCalls(state.messages);
|
|
421
403
|
const recentToolCallsStr = recentToolCalls.length > 0
|
|
422
404
|
? `\n\n⚠️ 最近调用的工具(避免重复调用相同工具和参数):\n${recentToolCalls
|
|
@@ -425,9 +407,6 @@ class McpGraphAgent {
|
|
|
425
407
|
: '';
|
|
426
408
|
// 1. 构建当前的系统提示词模板
|
|
427
409
|
const systemPromptTemplate = `你是一个代码专家。工作目录:${this.targetDir}。
|
|
428
|
-
当前模式:{mode}
|
|
429
|
-
进度:{doneCount}/{targetCount}
|
|
430
|
-
已审计文件:{auditedList}
|
|
431
410
|
|
|
432
411
|
# 🛠️ 工具调用规范
|
|
433
412
|
1. Arguments 必须是纯粹的 JSON 对象,严禁将其作为字符串放入引号中。
|
|
@@ -458,10 +437,6 @@ class McpGraphAgent {
|
|
|
458
437
|
try {
|
|
459
438
|
const promptParams = {
|
|
460
439
|
messages: inputMessages,
|
|
461
|
-
mode: state.mode,
|
|
462
|
-
targetCount: state.targetCount,
|
|
463
|
-
doneCount: state.auditedFiles.length,
|
|
464
|
-
auditedList: auditedListStr,
|
|
465
440
|
recentToolCalls: recentToolCallsStr,
|
|
466
441
|
extraPrompt: this.options.extraSystemPrompt || '',
|
|
467
442
|
};
|
|
@@ -611,21 +586,6 @@ class McpGraphAgent {
|
|
|
611
586
|
}
|
|
612
587
|
return toolCalls;
|
|
613
588
|
}
|
|
614
|
-
async trackProgress(state) {
|
|
615
|
-
var _a;
|
|
616
|
-
const lastAiMsg = state.messages[state.messages.length - 1];
|
|
617
|
-
const currentAudited = new Set(state.auditedFiles);
|
|
618
|
-
if ((_a = lastAiMsg === null || lastAiMsg === void 0 ? void 0 : lastAiMsg.tool_calls) === null || _a === void 0 ? void 0 : _a.length) {
|
|
619
|
-
for (const tc of lastAiMsg.tool_calls) {
|
|
620
|
-
// 兼容所有可能的路径参数字段
|
|
621
|
-
const file = tc.args.path || tc.args.filePath || tc.args.file || tc.args.file_path;
|
|
622
|
-
if (file && typeof file === 'string') {
|
|
623
|
-
currentAudited.add(file);
|
|
624
|
-
}
|
|
625
|
-
}
|
|
626
|
-
}
|
|
627
|
-
return { auditedFiles: Array.from(currentAudited) };
|
|
628
|
-
}
|
|
629
589
|
printFinalSummary(state) {
|
|
630
590
|
var _a;
|
|
631
591
|
const totalTokens = ((_a = state.tokenUsage) === null || _a === void 0 ? void 0 : _a.total) || 0;
|
|
@@ -635,7 +595,6 @@ class McpGraphAgent {
|
|
|
635
595
|
console.log(`🏁 \x1b[32;1m[审计任务全量结算]\x1b[0m`);
|
|
636
596
|
console.log(` - 累计消耗总额: \x1b[33m${totalTokens}\x1b[0m Tokens`);
|
|
637
597
|
console.log(` - 累计执行耗时: \x1b[36m${(totalMs / 1000).toFixed(2)}\x1b[0m s`);
|
|
638
|
-
console.log(` - 审计文件总数: ${state.auditedFiles.length} 个`);
|
|
639
598
|
console.log('═'.repeat(50) + '\n');
|
|
640
599
|
}
|
|
641
600
|
}
|
|
@@ -643,7 +602,6 @@ class McpGraphAgent {
|
|
|
643
602
|
const workflow = new langgraph_1.StateGraph(AgentState)
|
|
644
603
|
.addNode('agent', state => this.callModel(state))
|
|
645
604
|
.addNode('tools', this.toolNode)
|
|
646
|
-
.addNode('progress', state => this.trackProgress(state))
|
|
647
605
|
.addEdge(langgraph_1.START, 'agent')
|
|
648
606
|
.addConditionalEdges('agent', state => {
|
|
649
607
|
const { messages } = state;
|
|
@@ -653,6 +611,9 @@ class McpGraphAgent {
|
|
|
653
611
|
// 如果已消耗 Token 超过了 options 中设置的 maxTokens (假设是总限额)
|
|
654
612
|
if (this.options.maxTokens && state.tokenUsage.total >= this.options.maxTokens) {
|
|
655
613
|
console.warn('⚠️ [警告] 已达到最大 Token 限制,强制结束任务。');
|
|
614
|
+
state.messages.push(new messages_1.AIMessage({
|
|
615
|
+
content: `⚠️ 抱歉,当前任务消耗的 Token 已达上限 ${this.options.maxTokens}。为了防止无限循环,我已停止执行。你可以尝试分步骤指令,继续发送指令,直到任务完成。`
|
|
616
|
+
}));
|
|
656
617
|
this.printFinalSummary(state);
|
|
657
618
|
return langgraph_1.END;
|
|
658
619
|
}
|
|
@@ -660,22 +621,23 @@ class McpGraphAgent {
|
|
|
660
621
|
if (lastMsg.tool_calls && lastMsg.tool_calls.length > 0) {
|
|
661
622
|
return 'tools';
|
|
662
623
|
}
|
|
663
|
-
// 2. 判定结束的条件:
|
|
664
|
-
// - 模式是 auto 且审计完成
|
|
665
|
-
// - 或者 AI 明确输出了结束语
|
|
666
|
-
// - 或者 AI 输出了普通内容且没有工具调用(针对问答模式)
|
|
667
|
-
const isAutoFinished = state.mode === 'auto' && state.auditedFiles.length > state.targetCount;
|
|
668
624
|
const isFinalAnswer = content.includes('Final Answer');
|
|
669
|
-
|
|
670
|
-
if (isAutoFinished || isFinalAnswer || state.mode === 'chat') {
|
|
625
|
+
if (isFinalAnswer) {
|
|
671
626
|
this.printFinalSummary(state);
|
|
672
627
|
return langgraph_1.END;
|
|
673
628
|
}
|
|
674
|
-
|
|
629
|
+
if (messages.length > 50) {
|
|
630
|
+
state.messages.push(new messages_1.AIMessage({
|
|
631
|
+
content: `💡 **嘿,我们已经聊了很多了!**
|
|
632
|
+
|
|
633
|
+
为了保证服务质量,我通常会在 50 步操作后停下来和您确认一下。这样可以避免我产生“幻觉”或者做一些无用功。
|
|
634
|
+
|
|
635
|
+
**任务还没完成吗?** 没关系,只要您回复“继续”,我马上就回来接着干!或者您有什么新的想法要告诉我?`
|
|
636
|
+
}));
|
|
637
|
+
return langgraph_1.END;
|
|
638
|
+
}
|
|
675
639
|
return langgraph_1.END;
|
|
676
|
-
})
|
|
677
|
-
.addEdge('tools', 'progress')
|
|
678
|
-
.addEdge('progress', 'agent');
|
|
640
|
+
}).addEdge('tools', 'agent');
|
|
679
641
|
return workflow.compile({ checkpointer: this.checkpointer });
|
|
680
642
|
}
|
|
681
643
|
}
|
package/lib/types/type.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ export interface ApiConfig {
|
|
|
7
7
|
model: string;
|
|
8
8
|
}
|
|
9
9
|
export interface ToolInfo {
|
|
10
|
-
type:
|
|
10
|
+
type: 'function';
|
|
11
11
|
function: {
|
|
12
12
|
name: string;
|
|
13
13
|
description?: string;
|
|
@@ -38,7 +38,6 @@ export interface GraphAgentOptions<T extends AgentGraphModel = any> extends Agen
|
|
|
38
38
|
apiModel?: T;
|
|
39
39
|
alwaysSystem?: boolean;
|
|
40
40
|
recursionLimit?: number;
|
|
41
|
-
maxTargetCount?: number;
|
|
42
41
|
/** 是否启用流式输出,默认 false */
|
|
43
42
|
stream?: boolean;
|
|
44
43
|
}
|