@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.
Files changed (75) hide show
  1. package/dist/cjs/a2a/rest-runner.d.ts +16 -0
  2. package/dist/cjs/a2a/rest-runner.d.ts.map +1 -1
  3. package/dist/cjs/a2a/rest-runner.js +71 -4
  4. package/dist/cjs/a2a/rest-runner.js.map +1 -1
  5. package/dist/cjs/agent/engine.d.ts +57 -0
  6. package/dist/cjs/agent/engine.d.ts.map +1 -1
  7. package/dist/cjs/agent/engine.js +191 -1
  8. package/dist/cjs/agent/engine.js.map +1 -1
  9. package/dist/cjs/agent/llm-caller.d.ts.map +1 -1
  10. package/dist/cjs/agent/llm-caller.js +8 -0
  11. package/dist/cjs/agent/llm-caller.js.map +1 -1
  12. package/dist/cjs/agent/rate-limit-manager.d.ts +127 -0
  13. package/dist/cjs/agent/rate-limit-manager.d.ts.map +1 -0
  14. package/dist/cjs/agent/rate-limit-manager.js +465 -0
  15. package/dist/cjs/agent/rate-limit-manager.js.map +1 -0
  16. package/dist/cjs/agent/tool-executor.d.ts +11 -0
  17. package/dist/cjs/agent/tool-executor.d.ts.map +1 -1
  18. package/dist/cjs/agent/tool-executor.js +95 -4
  19. package/dist/cjs/agent/tool-executor.js.map +1 -1
  20. package/dist/cjs/agent/types.d.ts +59 -0
  21. package/dist/cjs/agent/types.d.ts.map +1 -1
  22. package/dist/cjs/agent/types.js.map +1 -1
  23. package/dist/cjs/index.d.ts +3 -2
  24. package/dist/cjs/index.d.ts.map +1 -1
  25. package/dist/cjs/index.js +7 -3
  26. package/dist/cjs/index.js.map +1 -1
  27. package/dist/cjs/runtime/run-registry.d.ts +2 -0
  28. package/dist/cjs/runtime/run-registry.d.ts.map +1 -1
  29. package/dist/cjs/runtime/run-registry.js +24 -1
  30. package/dist/cjs/runtime/run-registry.js.map +1 -1
  31. package/dist/cjs/tool/delegate.d.ts +9 -0
  32. package/dist/cjs/tool/delegate.d.ts.map +1 -1
  33. package/dist/cjs/tool/delegate.js.map +1 -1
  34. package/dist/cjs/utils/dsml-parser.d.ts +1 -1
  35. package/dist/cjs/utils/dsml-parser.d.ts.map +1 -1
  36. package/dist/cjs/utils/dsml-parser.js +16 -3
  37. package/dist/cjs/utils/dsml-parser.js.map +1 -1
  38. package/dist/esm/a2a/rest-runner.d.ts +16 -0
  39. package/dist/esm/a2a/rest-runner.d.ts.map +1 -1
  40. package/dist/esm/a2a/rest-runner.js +71 -4
  41. package/dist/esm/a2a/rest-runner.js.map +1 -1
  42. package/dist/esm/agent/engine.d.ts +57 -0
  43. package/dist/esm/agent/engine.d.ts.map +1 -1
  44. package/dist/esm/agent/engine.js +191 -1
  45. package/dist/esm/agent/engine.js.map +1 -1
  46. package/dist/esm/agent/llm-caller.d.ts.map +1 -1
  47. package/dist/esm/agent/llm-caller.js +8 -0
  48. package/dist/esm/agent/llm-caller.js.map +1 -1
  49. package/dist/esm/agent/rate-limit-manager.d.ts +127 -0
  50. package/dist/esm/agent/rate-limit-manager.d.ts.map +1 -0
  51. package/dist/esm/agent/rate-limit-manager.js +463 -0
  52. package/dist/esm/agent/rate-limit-manager.js.map +1 -0
  53. package/dist/esm/agent/tool-executor.d.ts +11 -0
  54. package/dist/esm/agent/tool-executor.d.ts.map +1 -1
  55. package/dist/esm/agent/tool-executor.js +95 -4
  56. package/dist/esm/agent/tool-executor.js.map +1 -1
  57. package/dist/esm/agent/types.d.ts +59 -0
  58. package/dist/esm/agent/types.d.ts.map +1 -1
  59. package/dist/esm/agent/types.js.map +1 -1
  60. package/dist/esm/index.d.ts +3 -2
  61. package/dist/esm/index.d.ts.map +1 -1
  62. package/dist/esm/index.js +1 -0
  63. package/dist/esm/index.js.map +1 -1
  64. package/dist/esm/runtime/run-registry.d.ts +2 -0
  65. package/dist/esm/runtime/run-registry.d.ts.map +1 -1
  66. package/dist/esm/runtime/run-registry.js +24 -1
  67. package/dist/esm/runtime/run-registry.js.map +1 -1
  68. package/dist/esm/tool/delegate.d.ts +9 -0
  69. package/dist/esm/tool/delegate.d.ts.map +1 -1
  70. package/dist/esm/tool/delegate.js.map +1 -1
  71. package/dist/esm/utils/dsml-parser.d.ts +1 -1
  72. package/dist/esm/utils/dsml-parser.d.ts.map +1 -1
  73. package/dist/esm/utils/dsml-parser.js +16 -3
  74. package/dist/esm/utils/dsml-parser.js.map +1 -1
  75. 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,CA8F3F"}
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
- /** 将 task 字符串构建为请求输入 */
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, [taskField]: task };
29
- console.log(`[REST-A2A] '${runnerName}' buildInput:\n baseUrl: ${baseUrl}\n capabilityId: ${capabilityId}\n taskField: ${taskField}\n task (value): ${JSON.stringify(task)}\n staticFields: ${JSON.stringify(staticFields)}\n => final input: ${JSON.stringify(input, null, 2)}`);
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":"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"}
1
+ {"version":3,"file":"rest-runner.js","sourceRoot":"","sources":["../../../src/a2a/rest-runner.ts"],"names":[],"mappings":"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"}
@@ -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":"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"}
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../../src/agent/engine.ts"],"names":[],"mappings":"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"}
@@ -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: `Token budget exceeded (${budgetCheck.currentTokens}/${budgetCheck.maxTokens} tokens). Task aborted to prevent cost overrun.`,
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 };