@cicctencent/agent-core 0.1.28 → 0.1.31
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/cjs/a2a/rest-runner.d.ts +16 -0
- package/dist/cjs/a2a/rest-runner.d.ts.map +1 -1
- package/dist/cjs/a2a/rest-runner.js +71 -4
- package/dist/cjs/a2a/rest-runner.js.map +1 -1
- package/dist/cjs/agent/engine.d.ts +57 -0
- package/dist/cjs/agent/engine.d.ts.map +1 -1
- package/dist/cjs/agent/engine.js +191 -1
- package/dist/cjs/agent/engine.js.map +1 -1
- package/dist/cjs/agent/llm-caller.d.ts.map +1 -1
- package/dist/cjs/agent/llm-caller.js +8 -0
- package/dist/cjs/agent/llm-caller.js.map +1 -1
- package/dist/cjs/agent/rate-limit-manager.d.ts +127 -0
- package/dist/cjs/agent/rate-limit-manager.d.ts.map +1 -0
- package/dist/cjs/agent/rate-limit-manager.js +465 -0
- package/dist/cjs/agent/rate-limit-manager.js.map +1 -0
- package/dist/cjs/agent/tool-executor.d.ts +11 -0
- package/dist/cjs/agent/tool-executor.d.ts.map +1 -1
- package/dist/cjs/agent/tool-executor.js +95 -4
- package/dist/cjs/agent/tool-executor.js.map +1 -1
- package/dist/cjs/agent/types.d.ts +59 -0
- package/dist/cjs/agent/types.d.ts.map +1 -1
- package/dist/cjs/agent/types.js.map +1 -1
- package/dist/cjs/index.d.ts +3 -2
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +7 -3
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/runtime/run-registry.d.ts +2 -0
- package/dist/cjs/runtime/run-registry.d.ts.map +1 -1
- package/dist/cjs/runtime/run-registry.js +24 -1
- package/dist/cjs/runtime/run-registry.js.map +1 -1
- package/dist/cjs/tool/delegate.d.ts +9 -0
- package/dist/cjs/tool/delegate.d.ts.map +1 -1
- package/dist/cjs/tool/delegate.js.map +1 -1
- package/dist/cjs/utils/dsml-parser.d.ts +1 -1
- package/dist/cjs/utils/dsml-parser.d.ts.map +1 -1
- package/dist/cjs/utils/dsml-parser.js +16 -3
- package/dist/cjs/utils/dsml-parser.js.map +1 -1
- package/dist/esm/a2a/rest-runner.d.ts +16 -0
- package/dist/esm/a2a/rest-runner.d.ts.map +1 -1
- package/dist/esm/a2a/rest-runner.js +71 -4
- package/dist/esm/a2a/rest-runner.js.map +1 -1
- package/dist/esm/agent/engine.d.ts +57 -0
- package/dist/esm/agent/engine.d.ts.map +1 -1
- package/dist/esm/agent/engine.js +191 -1
- package/dist/esm/agent/engine.js.map +1 -1
- package/dist/esm/agent/llm-caller.d.ts.map +1 -1
- package/dist/esm/agent/llm-caller.js +8 -0
- package/dist/esm/agent/llm-caller.js.map +1 -1
- package/dist/esm/agent/rate-limit-manager.d.ts +127 -0
- package/dist/esm/agent/rate-limit-manager.d.ts.map +1 -0
- package/dist/esm/agent/rate-limit-manager.js +463 -0
- package/dist/esm/agent/rate-limit-manager.js.map +1 -0
- package/dist/esm/agent/tool-executor.d.ts +11 -0
- package/dist/esm/agent/tool-executor.d.ts.map +1 -1
- package/dist/esm/agent/tool-executor.js +95 -4
- package/dist/esm/agent/tool-executor.js.map +1 -1
- package/dist/esm/agent/types.d.ts +59 -0
- package/dist/esm/agent/types.d.ts.map +1 -1
- package/dist/esm/agent/types.js.map +1 -1
- package/dist/esm/index.d.ts +3 -2
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +1 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/runtime/run-registry.d.ts +2 -0
- package/dist/esm/runtime/run-registry.d.ts.map +1 -1
- package/dist/esm/runtime/run-registry.js +24 -1
- package/dist/esm/runtime/run-registry.js.map +1 -1
- package/dist/esm/tool/delegate.d.ts +9 -0
- package/dist/esm/tool/delegate.d.ts.map +1 -1
- package/dist/esm/tool/delegate.js.map +1 -1
- package/dist/esm/utils/dsml-parser.d.ts +1 -1
- package/dist/esm/utils/dsml-parser.d.ts.map +1 -1
- package/dist/esm/utils/dsml-parser.js +16 -3
- package/dist/esm/utils/dsml-parser.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import type { SubAgentRunner } from '../tool/delegate.js';
|
|
2
2
|
import type { RestA2AClient } from './rest-client.js';
|
|
3
|
+
/** 远程 Capability 的 input_schema 片段(供 runner 拆解 JSON 打包的 task) */
|
|
4
|
+
export interface RestInputSchema {
|
|
5
|
+
type?: string;
|
|
6
|
+
/** input_schema.required 字段名列表 */
|
|
7
|
+
required?: string[];
|
|
8
|
+
/** input_schema.properties,值为各字段的 schema 定义(含 type/description/enum 等) */
|
|
9
|
+
properties?: Record<string, unknown>;
|
|
10
|
+
}
|
|
3
11
|
/** createRestA2ARemoteRunner 配置项 */
|
|
4
12
|
export interface RestA2ARemoteRunnerConfig {
|
|
5
13
|
/** 远程 Agent 的 base URL(如 http://localhost:8000) */
|
|
@@ -16,6 +24,14 @@ export interface RestA2ARemoteRunnerConfig {
|
|
|
16
24
|
staticFields?: Record<string, string>;
|
|
17
25
|
/** 任务字符串映射到的字段名(默认 'analysis_focus') */
|
|
18
26
|
taskField?: string;
|
|
27
|
+
/**
|
|
28
|
+
* 允许 LLM 动态填写的字段名列表(来自 input_schema 的 properties 键)。
|
|
29
|
+
* - 缺省时仅 taskField 为动态,其余走 staticFields(与旧行为一致)。
|
|
30
|
+
* - 配置后,当 LLM 把 task 打包成 JSON 对象时,这些键会被合并进最终 input。
|
|
31
|
+
*/
|
|
32
|
+
dynamicFields?: string[];
|
|
33
|
+
/** 远程 Capability 的 input_schema 片段,用于校验/白名单动态字段及生成 LLM 引导文案 */
|
|
34
|
+
inputSchema?: RestInputSchema;
|
|
19
35
|
/** 是否启用流式(默认 true) */
|
|
20
36
|
streaming?: boolean;
|
|
21
37
|
/** 流式失败时是否自动回退到同步模式,默认 true */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rest-runner.d.ts","sourceRoot":"","sources":["../../../src/a2a/rest-runner.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,OAAO,KAAK,EAAE,aAAa,EAAsC,MAAM,kBAAkB,CAAC;AAE1F,oCAAoC;AACpC,MAAM,WAAW,yBAAyB;IACxC,mDAAmD;IACnD,OAAO,EAAE,MAAM,CAAC;IAChB,4CAA4C;IAC5C,YAAY,EAAE,MAAM,CAAC;IACrB,sBAAsB;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,4BAA4B;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,qBAAqB;IACrB,MAAM,EAAE,aAAa,CAAC;IACtB,0EAA0E;IAC1E,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,wCAAwC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sBAAsB;IACtB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,+BAA+B;IAC/B,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,yBAAyB,GAAG,cAAc,
|
|
1
|
+
{"version":3,"file":"rest-runner.d.ts","sourceRoot":"","sources":["../../../src/a2a/rest-runner.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,OAAO,KAAK,EAAE,aAAa,EAAsC,MAAM,kBAAkB,CAAC;AAE1F,iEAAiE;AACjE,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,kCAAkC;IAClC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,0EAA0E;IAC1E,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED,oCAAoC;AACpC,MAAM,WAAW,yBAAyB;IACxC,mDAAmD;IACnD,OAAO,EAAE,MAAM,CAAC;IAChB,4CAA4C;IAC5C,YAAY,EAAE,MAAM,CAAC;IACrB,sBAAsB;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,4BAA4B;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,qBAAqB;IACrB,MAAM,EAAE,aAAa,CAAC;IACtB,0EAA0E;IAC1E,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,wCAAwC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,+DAA+D;IAC/D,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B,sBAAsB;IACtB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,+BAA+B;IAC/B,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,yBAAyB,GAAG,cAAc,CAsK3F"}
|
|
@@ -22,11 +22,61 @@ exports.createRestA2ARemoteRunner = createRestA2ARemoteRunner;
|
|
|
22
22
|
* - error → error
|
|
23
23
|
*/
|
|
24
24
|
function createRestA2ARemoteRunner(config) {
|
|
25
|
-
const { baseUrl, capabilityId, name: runnerName, description: runnerDesc, client, staticFields = {}, taskField = 'analysis_focus', streaming = true, fallbackToSync = true, } = config;
|
|
26
|
-
/**
|
|
25
|
+
const { baseUrl, capabilityId, name: runnerName, description: runnerDesc, client, staticFields = {}, taskField = 'analysis_focus', dynamicFields, inputSchema, streaming = true, fallbackToSync = true, } = config;
|
|
26
|
+
/**
|
|
27
|
+
* 允许 LLM 动态填写的字段白名单。
|
|
28
|
+
* - 优先用 dynamicFields;
|
|
29
|
+
* - 缺省时退化为 inputSchema 的所有 properties 键;
|
|
30
|
+
* - 都没有则只保留 taskField。
|
|
31
|
+
* taskField 永远视为动态字段。
|
|
32
|
+
*/
|
|
33
|
+
const allowedDynamicFields = Array.from(new Set([
|
|
34
|
+
taskField,
|
|
35
|
+
...(dynamicFields && dynamicFields.length
|
|
36
|
+
? dynamicFields
|
|
37
|
+
: (inputSchema?.properties ? Object.keys(inputSchema.properties) : [])),
|
|
38
|
+
]));
|
|
39
|
+
/**
|
|
40
|
+
* 将 task 字符串构建为请求输入。
|
|
41
|
+
*
|
|
42
|
+
* 支持两种形态:
|
|
43
|
+
* 1. task 为普通字符串 → 映射到 taskField(旧行为,向后兼容)。
|
|
44
|
+
* 2. task 为 JSON 对象字符串(如 '{"analysis_focus":"...","competitors":"..."}')
|
|
45
|
+
* → 解析后把属于 allowedDynamicFields 的键合并进 input(覆盖静态默认值),
|
|
46
|
+
* 其余键忽略,避免污染请求体。
|
|
47
|
+
*
|
|
48
|
+
* 静态字段始终作为基础值先行铺底,动态字段在后覆盖。
|
|
49
|
+
*/
|
|
27
50
|
function buildInput(task) {
|
|
28
|
-
const input = { ...staticFields
|
|
29
|
-
|
|
51
|
+
const input = { ...staticFields };
|
|
52
|
+
const trimmed = (task ?? '').trim();
|
|
53
|
+
const looksLikeJson = trimmed.startsWith('{') && trimmed.endsWith('}');
|
|
54
|
+
let parsedTask = null;
|
|
55
|
+
if (looksLikeJson) {
|
|
56
|
+
try {
|
|
57
|
+
const parsed = JSON.parse(trimmed);
|
|
58
|
+
if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {
|
|
59
|
+
parsedTask = parsed;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
catch { /* 非法 JSON,按纯文本处理 */ }
|
|
63
|
+
}
|
|
64
|
+
if (parsedTask) {
|
|
65
|
+
for (const key of allowedDynamicFields) {
|
|
66
|
+
if (parsedTask[key] !== undefined && parsedTask[key] !== null) {
|
|
67
|
+
input[key] = parsedTask[key];
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
// 若解析出的对象未命中任何动态字段,则把整段原文回填到 taskField,避免丢内容
|
|
71
|
+
const hitAny = allowedDynamicFields.some(k => parsedTask[k] !== undefined && parsedTask[k] !== null);
|
|
72
|
+
if (!hitAny) {
|
|
73
|
+
input[taskField] = task;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
input[taskField] = task;
|
|
78
|
+
}
|
|
79
|
+
console.log(`[REST-A2A] '${runnerName}' buildInput:\n baseUrl: ${baseUrl}\n capabilityId: ${capabilityId}\n taskField: ${taskField}\n dynamicFields: [${allowedDynamicFields.join(', ')}]\n task (value): ${JSON.stringify(task)}\n staticFields: ${JSON.stringify(staticFields)}\n => final input: ${JSON.stringify(input, null, 2)}`);
|
|
30
80
|
return input;
|
|
31
81
|
}
|
|
32
82
|
/** 从 RestCapabilityResult 中提取最终文本 */
|
|
@@ -85,9 +135,26 @@ function createRestA2ARemoteRunner(config) {
|
|
|
85
135
|
return `[REST A2A '${runnerName}'] Error: ${errMsg}`;
|
|
86
136
|
}
|
|
87
137
|
};
|
|
138
|
+
// 暴露给 delegate_task 用于生成 LLM 引导文案的动态字段元数据。
|
|
139
|
+
// 仅当存在多个动态字段(>1,即不止 taskField)时才填充,避免单字段场景产生噪音。
|
|
140
|
+
const inputFields = allowedDynamicFields.length > 1
|
|
141
|
+
? allowedDynamicFields.map(name => {
|
|
142
|
+
const prop = inputSchema?.properties?.[name];
|
|
143
|
+
const propDef = (prop && typeof prop === 'object' ? prop : {});
|
|
144
|
+
const rawType = propDef.type;
|
|
145
|
+
const type = Array.isArray(rawType) ? rawType.filter(Boolean).join('|') : (typeof rawType === 'string' ? rawType : 'string');
|
|
146
|
+
return {
|
|
147
|
+
name,
|
|
148
|
+
required: inputSchema?.required?.includes(name) ?? false,
|
|
149
|
+
description: typeof propDef.description === 'string' ? propDef.description : '',
|
|
150
|
+
type,
|
|
151
|
+
};
|
|
152
|
+
})
|
|
153
|
+
: undefined;
|
|
88
154
|
return {
|
|
89
155
|
name: runnerName,
|
|
90
156
|
description: runnerDesc,
|
|
157
|
+
inputFields,
|
|
91
158
|
run: async (task, ctx, _options) => {
|
|
92
159
|
return streaming && ctx?.emitSubEvent
|
|
93
160
|
? runStreaming(task, ctx)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rest-runner.js","sourceRoot":"","sources":["../../../src/a2a/rest-runner.ts"],"names":[],"mappings":";AAAA,+DAA+D;AAC/D,mEAAmE;AACnE,kDAAkD;AAClD,+DAA+D;;
|
|
1
|
+
{"version":3,"file":"rest-runner.js","sourceRoot":"","sources":["../../../src/a2a/rest-runner.ts"],"names":[],"mappings":";AAAA,+DAA+D;AAC/D,mEAAmE;AACnE,kDAAkD;AAClD,+DAA+D;;AA6D/D,8DAsKC;AAtLD;;;;;;;;;;;;;;;GAeG;AACH,SAAgB,yBAAyB,CAAC,MAAiC;IACzE,MAAM,EACJ,OAAO,EACP,YAAY,EACZ,IAAI,EAAE,UAAU,EAChB,WAAW,EAAE,UAAU,EACvB,MAAM,EACN,YAAY,GAAG,EAAE,EACjB,SAAS,GAAG,gBAAgB,EAC5B,aAAa,EACb,WAAW,EACX,SAAS,GAAG,IAAI,EAChB,cAAc,GAAG,IAAI,GACtB,GAAG,MAAM,CAAC;IAEX;;;;;;OAMG;IACH,MAAM,oBAAoB,GAAa,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAS;QAChE,SAAS;QACT,GAAG,CAAC,aAAa,IAAI,aAAa,CAAC,MAAM;YACvC,CAAC,CAAC,aAAa;YACf,CAAC,CAAC,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;KAC1E,CAAC,CAAC,CAAC;IAEJ;;;;;;;;;;OAUG;IACH,SAAS,UAAU,CAAC,IAAY;QAC9B,MAAM,KAAK,GAA4B,EAAE,GAAG,YAAY,EAAE,CAAC;QAE3D,MAAM,OAAO,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QACpC,MAAM,aAAa,GAAG,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QACvE,IAAI,UAAU,GAAmC,IAAI,CAAC;QACtD,IAAI,aAAa,EAAE,CAAC;YAClB,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;gBACnC,IAAI,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;oBACnE,UAAU,GAAG,MAAiC,CAAC;gBACjD,CAAC;YACH,CAAC;YAAC,MAAM,CAAC,CAAC,oBAAoB,CAAC,CAAC;QAClC,CAAC;QAED,IAAI,UAAU,EAAE,CAAC;YACf,KAAK,MAAM,GAAG,IAAI,oBAAoB,EAAE,CAAC;gBACvC,IAAI,UAAU,CAAC,GAAG,CAAC,KAAK,SAAS,IAAI,UAAU,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC;oBAC9D,KAAK,CAAC,GAAG,CAAC,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;gBAC/B,CAAC;YACH,CAAC;YACD,6CAA6C;YAC7C,MAAM,MAAM,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,UAAW,CAAC,CAAC,CAAC,KAAK,SAAS,IAAI,UAAW,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;YACvG,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,KAAK,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC;YAC1B,CAAC;QACH,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC;QAC1B,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,eAAe,UAAU,6BAA6B,OAAO,qBAAqB,YAAY,kBAAkB,SAAS,uBAAuB,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC,sBAAsB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,qBAAqB,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,uBAAuB,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;QAC/U,OAAO,KAAK,CAAC;IACf,CAAC;IAED,qCAAqC;IACrC,SAAS,iBAAiB,CAAC,MAA4B;QACrD,IAAI,MAAM,CAAC,MAAM,EAAE,UAAU;YAAE,OAAO,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC;QAC/D,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO;YAAE,OAAO,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC;QACzD,uBAAuB;QACvB,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,IAAI,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAC1D,CAAC;IAED,iBAAiB;IACjB,MAAM,OAAO,GAAG,KAAK,EAAE,IAAY,EAAmB,EAAE;QACtD,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,YAAY,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;YAC5E,IAAI,MAAM,CAAC,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;gBAC/C,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,IAAI,eAAe,CAAC;gBAC/C,OAAO,CAAC,KAAK,CAAC,eAAe,UAAU,kBAAkB,MAAM,EAAE,CAAC,CAAC;gBACnE,OAAO,cAAc,UAAU,aAAa,MAAM,EAAE,CAAC;YACvD,CAAC;YACD,OAAO,iBAAiB,CAAC,MAAM,CAAC,CAAC;QACnC,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,OAAO,CAAC,KAAK,CAAC,eAAe,UAAU,iBAAiB,GAAG,EAAE,OAAO,IAAI,GAAG,EAAE,CAAC,CAAC;YAC/E,OAAO,cAAc,UAAU,aAAa,GAAG,CAAC,OAAO,IAAI,GAAG,EAAE,CAAC;QACnE,CAAC;IACH,CAAC,CAAC;IAEF,iBAAiB;IACjB,MAAM,YAAY,GAAG,KAAK,EAAE,IAAY,EAAE,GAAgB,EAAmB,EAAE;QAC7E,MAAM,IAAI,GAAG,GAAG,CAAC,YAAY,CAAC;QAC9B,MAAM,YAAY,GAAG,GAAG,CAAC,iBAAiB,IAAI,YAAY,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;QAEvE,SAAS,CAAC,IAAI,EAAE,YAAY,EAAE,UAAU,EAAE,IAAI,CAAC,CAAC;QAEhD,IAAI,CAAC;YACH,MAAM,WAAW,GAAG,MAAM,MAAM,CAAC,eAAe,CAC9C,OAAO,EACP,YAAY,EACZ,UAAU,CAAC,IAAI,CAAC,EAChB,CAAC,KAAK,EAAE,EAAE,CAAC,mBAAmB,CAAC,IAAI,EAAE,YAAY,EAAE,UAAU,EAAE,KAAK,CAAC,EACrE,GAAG,CAAC,WAAW,CAChB,CAAC;YAEF,IAAI,WAAW,EAAE,MAAM,KAAK,QAAQ,IAAI,WAAW,EAAE,KAAK,EAAE,CAAC;gBAC3D,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,IAAI,6BAA6B,CAAC;gBAClE,OAAO,CAAC,KAAK,CAAC,eAAe,UAAU,aAAa,MAAM,EAAE,CAAC,CAAC;gBAC9D,SAAS,CAAC,IAAI,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC;gBAClD,OAAO,cAAc,UAAU,aAAa,MAAM,EAAE,CAAC;YACvD,CAAC;YAED,MAAM,UAAU,GAAG,WAAW;gBAC5B,CAAC,CAAC,iBAAiB,CAAC,WAAW,CAAC;gBAChC,CAAC,CAAC,gCAAgC,CAAC;YACrC,QAAQ,CAAC,IAAI,EAAE,YAAY,EAAE,UAAU,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;YAC5D,OAAO,UAAU,CAAC;QACpB,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,MAAM,MAAM,GAAG,GAAG,EAAE,OAAO,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC;YAC3C,OAAO,CAAC,KAAK,CAAC,eAAe,UAAU,sBAAsB,MAAM,EAAE,CAAC,CAAC;YACvE,iBAAiB;YACjB,IAAI,cAAc,EAAE,CAAC;gBACnB,OAAO,CAAC,GAAG,CAAC,eAAe,UAAU,wBAAwB,CAAC,CAAC;gBAC/D,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC;YACvB,CAAC;YACD,SAAS,CAAC,IAAI,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC;YAClD,OAAO,cAAc,UAAU,aAAa,MAAM,EAAE,CAAC;QACvD,CAAC;IACH,CAAC,CAAC;IAEF,2CAA2C;IAC3C,gDAAgD;IAChD,MAAM,WAAW,GAAG,oBAAoB,CAAC,MAAM,GAAG,CAAC;QACjD,CAAC,CAAC,oBAAoB,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;YAC9B,MAAM,IAAI,GAAG,WAAW,EAAE,UAAU,EAAE,CAAC,IAAI,CAAC,CAAC;YAC7C,MAAM,OAAO,GAAG,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAA4B,CAAC;YAC1F,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;YAC7B,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;YAC7H,OAAO;gBACL,IAAI;gBACJ,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,KAAK;gBACxD,WAAW,EAAE,OAAO,OAAO,CAAC,WAAW,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE;gBAC/E,IAAI;aACL,CAAC;QACJ,CAAC,CAAC;QACJ,CAAC,CAAC,SAAS,CAAC;IAEd,OAAO;QACL,IAAI,EAAE,UAAU;QAChB,WAAW,EAAE,UAAU;QACvB,WAAW;QACX,GAAG,EAAE,KAAK,EAAE,IAAY,EAAE,GAAG,EAAE,QAAQ,EAAmB,EAAE;YAC1D,OAAO,SAAS,IAAI,GAAG,EAAE,YAAY;gBACnC,CAAC,CAAC,YAAY,CAAC,IAAI,EAAE,GAAG,CAAC;gBACzB,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACpB,CAAC;KACF,CAAC;AACJ,CAAC;AAED,qBAAqB;AAErB,SAAS,SAAS,CAChB,IAAsC,EACtC,YAAoB,EACpB,SAAiB,EACjB,IAAY;IAEZ,IAAI,EAAE,CAAC;QACL,gBAAgB,EAAE,YAAY;QAC9B,SAAS;QACT,SAAS,EAAE,OAAO;QAClB,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,oBAAoB,EAAE;KACxD,CAAC,CAAC;AACL,CAAC;AAED,SAAS,QAAQ,CACf,IAAsC,EACtC,YAAoB,EACpB,SAAiB,EACjB,aAAqB;IAErB,IAAI,EAAE,CAAC;QACL,gBAAgB,EAAE,YAAY;QAC9B,SAAS;QACT,SAAS,EAAE,MAAM;QACjB,IAAI,EAAE,EAAE,aAAa,EAAE;KACxB,CAAC,CAAC;AACL,CAAC;AAED,SAAS,SAAS,CAChB,IAAsC,EACtC,YAAoB,EACpB,SAAiB,EACjB,KAAa;IAEb,IAAI,EAAE,CAAC;QACL,gBAAgB,EAAE,YAAY;QAC9B,SAAS;QACT,SAAS,EAAE,OAAO;QAClB,IAAI,EAAE,EAAE,KAAK,EAAE;KAChB,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;;;;GAWG;AACH,SAAS,mBAAmB,CAC1B,IAAsC,EACtC,YAAoB,EACpB,SAAiB,EACjB,KAAmB;IAEnB,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC;IAEzC,QAAQ,SAAS,EAAE,CAAC;QAClB,KAAK,QAAQ;YACX,+CAA+C;YAC/C,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;gBAC9B,IAAI,EAAE,CAAC;oBACL,gBAAgB,EAAE,YAAY;oBAC9B,SAAS;oBACT,SAAS,EAAE,UAAU;oBACrB,IAAI,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE;iBACrD,CAAC,CAAC;YACL,CAAC;YACD,MAAM;QAER,KAAK,OAAO;YACV,IAAI,EAAE,CAAC;gBACL,gBAAgB,EAAE,YAAY;gBAC9B,SAAS;gBACT,SAAS,EAAE,UAAU;gBACrB,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE;aACrD,CAAC,CAAC;YACH,MAAM;QAER,KAAK,WAAW;YACd,IAAI,EAAE,CAAC;gBACL,gBAAgB,EAAE,YAAY;gBAC9B,SAAS;gBACT,SAAS,EAAE,WAAW;gBACtB,IAAI;aACL,CAAC,CAAC;YACH,MAAM;QAER,KAAK,aAAa;YAChB,IAAI,EAAE,CAAC;gBACL,gBAAgB,EAAE,YAAY;gBAC9B,SAAS;gBACT,SAAS,EAAE,aAAa;gBACxB,IAAI;aACL,CAAC,CAAC;YACH,MAAM;QAER,KAAK,eAAe;YAClB,IAAI,EAAE,CAAC;gBACL,gBAAgB,EAAE,YAAY;gBAC9B,SAAS;gBACT,SAAS,EAAE,SAAS;gBACpB,IAAI,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE;aAChC,CAAC,CAAC;YACH,MAAM;QAER,uDAAuD;QACvD,KAAK,QAAQ,CAAC;QACd,KAAK,OAAO;YACV,MAAM;QAER;YACE,cAAc;YACd,MAAM;IACV,CAAC;AACH,CAAC"}
|
|
@@ -10,6 +10,10 @@ export declare class AgentEngine {
|
|
|
10
10
|
private abortMap;
|
|
11
11
|
/** sessionId → steering messages(实时转向队列) */
|
|
12
12
|
private steeringMap;
|
|
13
|
+
/** parentSessionId → Set<childSessionId>(父子会话关系跟踪,用于级联 abort) */
|
|
14
|
+
private childSessionMap;
|
|
15
|
+
/** childSessionId → parentSessionId(反向索引,用于快速查找父会话) */
|
|
16
|
+
private parentSessionMap;
|
|
13
17
|
/** 子模块:历史管理器 */
|
|
14
18
|
private historyManager;
|
|
15
19
|
/** 子模块:LLM 调用器 */
|
|
@@ -26,6 +30,8 @@ export declare class AgentEngine {
|
|
|
26
30
|
private outputTools;
|
|
27
31
|
/** Guard 策略配置(阈值可注入,不硬编码业务逻辑) */
|
|
28
32
|
private guardConfig;
|
|
33
|
+
/** 错误恢复策略配置 */
|
|
34
|
+
private errorRecovery;
|
|
29
35
|
constructor(config: AgentConfig);
|
|
30
36
|
/** 获取当前 Agent 的 ToolRegistry(供 read_tool_doc 等内置工具使用) */
|
|
31
37
|
getToolRegistry(): ToolRegistry;
|
|
@@ -65,6 +71,29 @@ export declare class AgentEngine {
|
|
|
65
71
|
forkHistory(sourceSessionId: string, targetSessionId: string, fromIndex?: number): number;
|
|
66
72
|
/** 获取会话历史的消息数量 */
|
|
67
73
|
getHistoryLength(sessionId: string): number;
|
|
74
|
+
/**
|
|
75
|
+
* 注册父子会话关系。
|
|
76
|
+
*
|
|
77
|
+
* 典型场景:主 Agent 通过 delegate_task 工具派生子任务时,
|
|
78
|
+
* 上层调用此方法将子会话与父会话关联。当父会话因异常终止时,
|
|
79
|
+
* 如果配置了 `cascadeAbortChildren`,所有子会话也会被自动 abort。
|
|
80
|
+
*
|
|
81
|
+
* @param parentSessionId 父会话 ID
|
|
82
|
+
* @param childSessionId 子会话 ID
|
|
83
|
+
*/
|
|
84
|
+
linkChildSession(parentSessionId: string, childSessionId: string): void;
|
|
85
|
+
/**
|
|
86
|
+
* 解除父子会话关系(子会话完成后调用)。
|
|
87
|
+
*/
|
|
88
|
+
unlinkChildSession(childSessionId: string): void;
|
|
89
|
+
/**
|
|
90
|
+
* 获取指定父会话的所有子会话 ID。
|
|
91
|
+
*/
|
|
92
|
+
getChildSessions(parentSessionId: string): string[];
|
|
93
|
+
/**
|
|
94
|
+
* 获取指定子会话的父会话 ID(如有)。
|
|
95
|
+
*/
|
|
96
|
+
getParentSession(childSessionId: string): string | undefined;
|
|
68
97
|
/**
|
|
69
98
|
* 执行 Agent 任务(流式推送事件)
|
|
70
99
|
* 上层通过 for-await-of 消费事件流
|
|
@@ -161,10 +190,38 @@ export declare class AgentEngine {
|
|
|
161
190
|
private emitDone;
|
|
162
191
|
/** 中断指定会话的 Agent 执行 */
|
|
163
192
|
abort(sessionId: string): void;
|
|
193
|
+
/**
|
|
194
|
+
* 中断指定会话及其所有子会话的 Agent 执行(级联 abort)。
|
|
195
|
+
*
|
|
196
|
+
* 递归遍历子会话树,从叶子节点到根节点依次 abort。
|
|
197
|
+
* 用于确保父会话异常终止时,所有 delegate_task 派生的子任务也被终止。
|
|
198
|
+
*/
|
|
199
|
+
abortCascade(sessionId: string): void;
|
|
164
200
|
/** 查询指定会话的 Agent 状态 */
|
|
165
201
|
getStatus(sessionId: string): AgentStatus;
|
|
166
202
|
/** 销毁引擎,释放所有会话资源 */
|
|
167
203
|
destroy(): void;
|
|
204
|
+
/**
|
|
205
|
+
* 统一的致命错误处理入口。
|
|
206
|
+
*
|
|
207
|
+
* 由引擎内部(agentLoop、catch 块)在遇到不可恢复错误时调用。
|
|
208
|
+
* 按以下顺序执行:
|
|
209
|
+
* 1. 调用 config.errorRecovery.onFatalError 回调(允许上层记录/通知)
|
|
210
|
+
* 2. 如果 config.errorRecovery.autoAbortOnFatal,abort 当前会话
|
|
211
|
+
* 3. 如果 config.errorRecovery.cascadeAbortChildren,级联 abort 所有子会话
|
|
212
|
+
*
|
|
213
|
+
* @param error 致命错误信息(含 sessionId)
|
|
214
|
+
*/
|
|
215
|
+
private handleFatalError;
|
|
216
|
+
/**
|
|
217
|
+
* 清理指定会话的父子关系记录。
|
|
218
|
+
*
|
|
219
|
+
* 在会话自然完成或 abort 后调用,防止内存泄漏。
|
|
220
|
+
* 处理两个方向:
|
|
221
|
+
* - 如果是父会话:移除所有子会话引用(但子会话若仍在运行则保留其关系)
|
|
222
|
+
* - 如果是子会话:从父会话的子集中移除自身
|
|
223
|
+
*/
|
|
224
|
+
private cleanupSessionRelations;
|
|
168
225
|
createEvent(sessionId: string, event: Record<string, unknown>): AgentEvent;
|
|
169
226
|
private createNoopShell;
|
|
170
227
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../../src/agent/engine.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,OAAO,EAAoE,MAAM,aAAa,CAAC;AAItI,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../../src/agent/engine.ts"],"names":[],"mappings":"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"}
|
package/dist/cjs/agent/engine.js
CHANGED
|
@@ -11,6 +11,7 @@ const history_manager_ts_1 = require("./history-manager.js");
|
|
|
11
11
|
const llm_caller_ts_1 = require("./llm-caller.js");
|
|
12
12
|
const tool_executor_ts_1 = require("./tool-executor.js");
|
|
13
13
|
const logger_ts_1 = require("../observability/logger.js");
|
|
14
|
+
const rate_limit_manager_ts_1 = require("./rate-limit-manager.js");
|
|
14
15
|
/** 默认系统提示词 */
|
|
15
16
|
const DEFAULT_BASE_PROMPT = `You are a helpful AI assistant with access to tools. Use tools when needed to accomplish tasks. Always explain your actions clearly.`;
|
|
16
17
|
/** 进度叙述规则(追加到 system prompt,引导 LLM 在工具调用间输出可见文本)— 可通过 AgentConfig.progressNarrationRules 覆盖 */
|
|
@@ -85,6 +86,10 @@ class AgentEngine {
|
|
|
85
86
|
abortMap = new Map();
|
|
86
87
|
/** sessionId → steering messages(实时转向队列) */
|
|
87
88
|
steeringMap = new Map();
|
|
89
|
+
/** parentSessionId → Set<childSessionId>(父子会话关系跟踪,用于级联 abort) */
|
|
90
|
+
childSessionMap = new Map();
|
|
91
|
+
/** childSessionId → parentSessionId(反向索引,用于快速查找父会话) */
|
|
92
|
+
parentSessionMap = new Map();
|
|
88
93
|
/** 子模块:历史管理器 */
|
|
89
94
|
historyManager;
|
|
90
95
|
/** 子模块:LLM 调用器 */
|
|
@@ -101,6 +106,8 @@ class AgentEngine {
|
|
|
101
106
|
outputTools;
|
|
102
107
|
/** Guard 策略配置(阈值可注入,不硬编码业务逻辑) */
|
|
103
108
|
guardConfig;
|
|
109
|
+
/** 错误恢复策略配置 */
|
|
110
|
+
errorRecovery;
|
|
104
111
|
constructor(config) {
|
|
105
112
|
this.config = {
|
|
106
113
|
...config,
|
|
@@ -159,6 +166,13 @@ class AgentEngine {
|
|
|
159
166
|
delegateTargets: gc.delegateTargets ?? {},
|
|
160
167
|
iterationGuardPrompt: gc.iterationGuardPrompt ?? '',
|
|
161
168
|
};
|
|
169
|
+
// 初始化错误恢复策略
|
|
170
|
+
const er = config.errorRecovery ?? {};
|
|
171
|
+
this.errorRecovery = {
|
|
172
|
+
autoAbortOnFatal: er.autoAbortOnFatal ?? true,
|
|
173
|
+
cascadeAbortChildren: er.cascadeAbortChildren ?? false,
|
|
174
|
+
onFatalError: er.onFatalError ?? undefined,
|
|
175
|
+
};
|
|
162
176
|
}
|
|
163
177
|
/** 获取当前 Agent 的 ToolRegistry(供 read_tool_doc 等内置工具使用) */
|
|
164
178
|
getToolRegistry() {
|
|
@@ -216,6 +230,51 @@ class AgentEngine {
|
|
|
216
230
|
getHistoryLength(sessionId) {
|
|
217
231
|
return this.historyManager.getHistoryLength(sessionId);
|
|
218
232
|
}
|
|
233
|
+
// ---- 父子会话关系管理 ----
|
|
234
|
+
/**
|
|
235
|
+
* 注册父子会话关系。
|
|
236
|
+
*
|
|
237
|
+
* 典型场景:主 Agent 通过 delegate_task 工具派生子任务时,
|
|
238
|
+
* 上层调用此方法将子会话与父会话关联。当父会话因异常终止时,
|
|
239
|
+
* 如果配置了 `cascadeAbortChildren`,所有子会话也会被自动 abort。
|
|
240
|
+
*
|
|
241
|
+
* @param parentSessionId 父会话 ID
|
|
242
|
+
* @param childSessionId 子会话 ID
|
|
243
|
+
*/
|
|
244
|
+
linkChildSession(parentSessionId, childSessionId) {
|
|
245
|
+
if (!this.childSessionMap.has(parentSessionId)) {
|
|
246
|
+
this.childSessionMap.set(parentSessionId, new Set());
|
|
247
|
+
}
|
|
248
|
+
this.childSessionMap.get(parentSessionId).add(childSessionId);
|
|
249
|
+
this.parentSessionMap.set(childSessionId, parentSessionId);
|
|
250
|
+
// 通知 RateLimitManager 建立父子映射(用于 429 终止主会话时定位父会话)
|
|
251
|
+
rate_limit_manager_ts_1.rateLimitManager.registerSubSession(childSessionId, parentSessionId);
|
|
252
|
+
(0, logger_ts_1.logEvent)({ event: 'engine.child_linked', sessionId: parentSessionId, data: { childSessionId } });
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* 解除父子会话关系(子会话完成后调用)。
|
|
256
|
+
*/
|
|
257
|
+
unlinkChildSession(childSessionId) {
|
|
258
|
+
const parentId = this.parentSessionMap.get(childSessionId);
|
|
259
|
+
if (parentId) {
|
|
260
|
+
this.childSessionMap.get(parentId)?.delete(childSessionId);
|
|
261
|
+
this.parentSessionMap.delete(childSessionId);
|
|
262
|
+
}
|
|
263
|
+
// 通知 RateLimitManager 注销子会话,释放并发槽位
|
|
264
|
+
rate_limit_manager_ts_1.rateLimitManager.unregisterSubSession(childSessionId);
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* 获取指定父会话的所有子会话 ID。
|
|
268
|
+
*/
|
|
269
|
+
getChildSessions(parentSessionId) {
|
|
270
|
+
return Array.from(this.childSessionMap.get(parentSessionId) ?? []);
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* 获取指定子会话的父会话 ID(如有)。
|
|
274
|
+
*/
|
|
275
|
+
getParentSession(childSessionId) {
|
|
276
|
+
return this.parentSessionMap.get(childSessionId);
|
|
277
|
+
}
|
|
219
278
|
/**
|
|
220
279
|
* 执行 Agent 任务(流式推送事件)
|
|
221
280
|
* 上层通过 for-await-of 消费事件流
|
|
@@ -225,6 +284,8 @@ class AgentEngine {
|
|
|
225
284
|
// ① Abort 控制
|
|
226
285
|
const internalAbort = new AbortController();
|
|
227
286
|
this.abortMap.set(sessionId, internalAbort);
|
|
287
|
+
// 注册到 RateLimitManager,使其能在多轮冷却失败时终止主会话
|
|
288
|
+
rate_limit_manager_ts_1.rateLimitManager.registerMainSession(sessionId, internalAbort);
|
|
228
289
|
const onExternalAbort = () => internalAbort.abort();
|
|
229
290
|
if (abortSignal) {
|
|
230
291
|
if (abortSignal.aborted)
|
|
@@ -246,6 +307,15 @@ class AgentEngine {
|
|
|
246
307
|
error: errorMsg,
|
|
247
308
|
recoverable: false,
|
|
248
309
|
});
|
|
310
|
+
// 致命错误 → 自动 abort + 级联清理
|
|
311
|
+
await this.handleFatalError({
|
|
312
|
+
sessionId,
|
|
313
|
+
errorType: 'unexpected_exception',
|
|
314
|
+
error: errorMsg,
|
|
315
|
+
timestamp: Date.now(),
|
|
316
|
+
iteration: 0,
|
|
317
|
+
rawError: err,
|
|
318
|
+
});
|
|
249
319
|
this.statusMap.set(sessionId, 'idle');
|
|
250
320
|
}
|
|
251
321
|
finally {
|
|
@@ -253,6 +323,8 @@ class AgentEngine {
|
|
|
253
323
|
abortSignal.removeEventListener('abort', onExternalAbort);
|
|
254
324
|
this.abortMap.delete(sessionId);
|
|
255
325
|
this.steeringMap.delete(sessionId);
|
|
326
|
+
// 注销主会话,清理限流状态和子会话映射
|
|
327
|
+
rate_limit_manager_ts_1.rateLimitManager.unregisterMainSession(sessionId);
|
|
256
328
|
}
|
|
257
329
|
}
|
|
258
330
|
// ---- 准备阶段 ----
|
|
@@ -623,12 +695,21 @@ ${textHistory.join('\n')}`;
|
|
|
623
695
|
const budgetCheck = this.config.usageTracker.checkBudget(state.sessionId, this.config.tokenBudget);
|
|
624
696
|
if (budgetCheck.exceeded) {
|
|
625
697
|
if (this.config.tokenBudget.onExceed === 'abort') {
|
|
698
|
+
const budgetErrMsg = `Token budget exceeded (${budgetCheck.currentTokens}/${budgetCheck.maxTokens} tokens). Task aborted to prevent cost overrun.`;
|
|
626
699
|
(0, logger_ts_1.logEvent)({ event: 'engine.token_budget_exceeded', sessionId: state.sessionId, level: 'warn', data: { current: budgetCheck.currentTokens, max: budgetCheck.maxTokens, action: 'abort' } });
|
|
627
700
|
yield this.createEvent(state.sessionId, {
|
|
628
701
|
type: 'error',
|
|
629
|
-
error:
|
|
702
|
+
error: budgetErrMsg,
|
|
630
703
|
recoverable: false,
|
|
631
704
|
});
|
|
705
|
+
// 致命错误 → 自动 abort + 级联清理
|
|
706
|
+
await this.handleFatalError({
|
|
707
|
+
sessionId: state.sessionId,
|
|
708
|
+
errorType: 'token_budget_exceeded',
|
|
709
|
+
error: budgetErrMsg,
|
|
710
|
+
timestamp: Date.now(),
|
|
711
|
+
iteration: state.iteration,
|
|
712
|
+
});
|
|
632
713
|
yield this.emitDone(state);
|
|
633
714
|
return;
|
|
634
715
|
}
|
|
@@ -674,8 +755,17 @@ ${textHistory.join('\n')}`;
|
|
|
674
755
|
// 所有 LLM provider 均已失败(callWithRetry 内部已重试+降级),
|
|
675
756
|
// 不再发 done 事件(callWithRetry 已发出带详细错误信息的 error 事件),
|
|
676
757
|
// 仅完成清理,避免 done 事件覆盖前端已展示的错误消息
|
|
758
|
+
const errorMsg = 'All LLM providers exhausted (all calls failed including retries and fallback)';
|
|
677
759
|
(0, logger_ts_1.logEvent)({ event: 'engine.llm_exhausted', sessionId: state.sessionId, level: 'warn', data: { iteration: state.iteration } });
|
|
678
760
|
this.statusMap.set(state.sessionId, 'idle');
|
|
761
|
+
// 致命错误 → 自动 abort + 级联清理(级联清理子 Agent 运行中的子任务)
|
|
762
|
+
await this.handleFatalError({
|
|
763
|
+
sessionId: state.sessionId,
|
|
764
|
+
errorType: 'llm_exhausted',
|
|
765
|
+
error: errorMsg,
|
|
766
|
+
timestamp: Date.now(),
|
|
767
|
+
iteration: state.iteration,
|
|
768
|
+
});
|
|
679
769
|
// 记录 Token 用量到 UsageTracker
|
|
680
770
|
if (this.config.usageTracker && state.totalUsage) {
|
|
681
771
|
const modelInfo = this.config.llmProvider.getModel();
|
|
@@ -748,7 +838,16 @@ ${textHistory.join('\n')}`;
|
|
|
748
838
|
if (allFailed) {
|
|
749
839
|
state.consecutiveAllFailIterations++;
|
|
750
840
|
if (state.consecutiveAllFailIterations >= this.guardConfig.consecutiveAllFailThreshold) {
|
|
841
|
+
const failMsg = `All tool calls failed for ${state.consecutiveAllFailIterations} consecutive iterations`;
|
|
751
842
|
(0, logger_ts_1.logEvent)({ event: 'engine.global_fail_breaker', sessionId: state.sessionId, level: 'warn', data: { consecutiveFails: state.consecutiveAllFailIterations, iteration: state.iteration } });
|
|
843
|
+
// 致命错误 → 自动 abort + 级联清理
|
|
844
|
+
await this.handleFatalError({
|
|
845
|
+
sessionId: state.sessionId,
|
|
846
|
+
errorType: 'all_tools_failed',
|
|
847
|
+
error: failMsg,
|
|
848
|
+
timestamp: Date.now(),
|
|
849
|
+
iteration: state.iteration,
|
|
850
|
+
});
|
|
752
851
|
yield this.emitDone(state);
|
|
753
852
|
return;
|
|
754
853
|
}
|
|
@@ -1059,6 +1158,8 @@ ${textHistory.join('\n')}`;
|
|
|
1059
1158
|
// ---- 辅助 ----
|
|
1060
1159
|
emitDone(state) {
|
|
1061
1160
|
this.statusMap.set(state.sessionId, 'idle');
|
|
1161
|
+
// 会话正常结束时清理父子关系(不级联 abort,子会话可自行运行完成)
|
|
1162
|
+
this.cleanupSessionRelations(state.sessionId);
|
|
1062
1163
|
// 记录 Token 用量到 UsageTracker
|
|
1063
1164
|
if (this.config.usageTracker && state.totalUsage) {
|
|
1064
1165
|
const modelInfo = this.config.llmProvider.getModel();
|
|
@@ -1089,8 +1190,25 @@ ${textHistory.join('\n')}`;
|
|
|
1089
1190
|
if (controller) {
|
|
1090
1191
|
controller.abort();
|
|
1091
1192
|
this.statusMap.set(sessionId, 'aborting');
|
|
1193
|
+
(0, logger_ts_1.logEvent)({ event: 'engine.abort', sessionId, data: { reason: 'abort() called' } });
|
|
1092
1194
|
}
|
|
1093
1195
|
}
|
|
1196
|
+
/**
|
|
1197
|
+
* 中断指定会话及其所有子会话的 Agent 执行(级联 abort)。
|
|
1198
|
+
*
|
|
1199
|
+
* 递归遍历子会话树,从叶子节点到根节点依次 abort。
|
|
1200
|
+
* 用于确保父会话异常终止时,所有 delegate_task 派生的子任务也被终止。
|
|
1201
|
+
*/
|
|
1202
|
+
abortCascade(sessionId) {
|
|
1203
|
+
this.abort(sessionId);
|
|
1204
|
+
// 遍历直接子会话,递归 abort
|
|
1205
|
+
const children = this.getChildSessions(sessionId);
|
|
1206
|
+
for (const childId of children) {
|
|
1207
|
+
this.abortCascade(childId);
|
|
1208
|
+
}
|
|
1209
|
+
// 清理父子关系
|
|
1210
|
+
this.cleanupSessionRelations(sessionId);
|
|
1211
|
+
}
|
|
1094
1212
|
/** 查询指定会话的 Agent 状态 */
|
|
1095
1213
|
getStatus(sessionId) {
|
|
1096
1214
|
return this.statusMap.get(sessionId) || 'idle';
|
|
@@ -1103,9 +1221,81 @@ ${textHistory.join('\n')}`;
|
|
|
1103
1221
|
this.abortMap.clear();
|
|
1104
1222
|
this.statusMap.clear();
|
|
1105
1223
|
this.steeringMap.clear();
|
|
1224
|
+
this.childSessionMap.clear();
|
|
1225
|
+
this.parentSessionMap.clear();
|
|
1106
1226
|
this.summaryCache.clear();
|
|
1107
1227
|
this.historyManager.clearAll();
|
|
1108
1228
|
}
|
|
1229
|
+
// ---- 致命错误处理 ----
|
|
1230
|
+
/**
|
|
1231
|
+
* 统一的致命错误处理入口。
|
|
1232
|
+
*
|
|
1233
|
+
* 由引擎内部(agentLoop、catch 块)在遇到不可恢复错误时调用。
|
|
1234
|
+
* 按以下顺序执行:
|
|
1235
|
+
* 1. 调用 config.errorRecovery.onFatalError 回调(允许上层记录/通知)
|
|
1236
|
+
* 2. 如果 config.errorRecovery.autoAbortOnFatal,abort 当前会话
|
|
1237
|
+
* 3. 如果 config.errorRecovery.cascadeAbortChildren,级联 abort 所有子会话
|
|
1238
|
+
*
|
|
1239
|
+
* @param error 致命错误信息(含 sessionId)
|
|
1240
|
+
*/
|
|
1241
|
+
async handleFatalError(error) {
|
|
1242
|
+
(0, logger_ts_1.logEvent)({
|
|
1243
|
+
event: 'engine.fatal_error',
|
|
1244
|
+
sessionId: error.sessionId,
|
|
1245
|
+
level: 'error',
|
|
1246
|
+
data: {
|
|
1247
|
+
errorType: error.errorType,
|
|
1248
|
+
error: error.error,
|
|
1249
|
+
iteration: error.iteration,
|
|
1250
|
+
autoAbort: this.errorRecovery.autoAbortOnFatal,
|
|
1251
|
+
cascadeAbort: this.errorRecovery.cascadeAbortChildren,
|
|
1252
|
+
},
|
|
1253
|
+
});
|
|
1254
|
+
// ① 外部回调通知(不阻塞后续清理流程)
|
|
1255
|
+
if (this.errorRecovery.onFatalError) {
|
|
1256
|
+
try {
|
|
1257
|
+
await this.errorRecovery.onFatalError(error);
|
|
1258
|
+
}
|
|
1259
|
+
catch (e) {
|
|
1260
|
+
// 回调异常不影响后续清理流程
|
|
1261
|
+
(0, logger_ts_1.logEvent)({
|
|
1262
|
+
event: 'engine.fatal_error_callback_failed',
|
|
1263
|
+
sessionId: error.sessionId,
|
|
1264
|
+
level: 'warn',
|
|
1265
|
+
data: { error: e?.message || String(e) },
|
|
1266
|
+
});
|
|
1267
|
+
}
|
|
1268
|
+
}
|
|
1269
|
+
// ② 自动 abort 当前会话
|
|
1270
|
+
if (this.errorRecovery.autoAbortOnFatal) {
|
|
1271
|
+
if (this.errorRecovery.cascadeAbortChildren) {
|
|
1272
|
+
// 级联 abort:终止当前会话及其所有子孙会话
|
|
1273
|
+
this.abortCascade(error.sessionId);
|
|
1274
|
+
}
|
|
1275
|
+
else {
|
|
1276
|
+
// 仅 abort 当前会话
|
|
1277
|
+
this.abort(error.sessionId);
|
|
1278
|
+
}
|
|
1279
|
+
}
|
|
1280
|
+
}
|
|
1281
|
+
/**
|
|
1282
|
+
* 清理指定会话的父子关系记录。
|
|
1283
|
+
*
|
|
1284
|
+
* 在会话自然完成或 abort 后调用,防止内存泄漏。
|
|
1285
|
+
* 处理两个方向:
|
|
1286
|
+
* - 如果是父会话:移除所有子会话引用(但子会话若仍在运行则保留其关系)
|
|
1287
|
+
* - 如果是子会话:从父会话的子集中移除自身
|
|
1288
|
+
*/
|
|
1289
|
+
cleanupSessionRelations(sessionId) {
|
|
1290
|
+
// 从父会话的子集中移除自身
|
|
1291
|
+
const parentId = this.parentSessionMap.get(sessionId);
|
|
1292
|
+
if (parentId) {
|
|
1293
|
+
this.childSessionMap.get(parentId)?.delete(sessionId);
|
|
1294
|
+
this.parentSessionMap.delete(sessionId);
|
|
1295
|
+
}
|
|
1296
|
+
// 删除自身作为父会话的所有子关系记录(但保留子会话本身仍在运行)
|
|
1297
|
+
this.childSessionMap.delete(sessionId);
|
|
1298
|
+
}
|
|
1109
1299
|
// ---- 内部辅助 ----
|
|
1110
1300
|
createEvent(sessionId, event) {
|
|
1111
1301
|
return { ...event, timestamp: Date.now(), sessionId };
|