@cicctencent/agent-core 0.1.27 → 0.1.30
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 +5 -1
- package/dist/cjs/agent/engine.d.ts.map +1 -1
- package/dist/cjs/agent/engine.js +78 -49
- package/dist/cjs/agent/engine.js.map +1 -1
- package/dist/cjs/agent/history-manager.d.ts.map +1 -1
- package/dist/cjs/agent/history-manager.js +17 -2
- package/dist/cjs/agent/history-manager.js.map +1 -1
- package/dist/cjs/agent/llm-caller.d.ts +2 -7
- package/dist/cjs/agent/llm-caller.d.ts.map +1 -1
- package/dist/cjs/agent/llm-caller.js +19 -18
- package/dist/cjs/agent/llm-caller.js.map +1 -1
- package/dist/cjs/agent/tool-executor.d.ts +9 -6
- package/dist/cjs/agent/tool-executor.d.ts.map +1 -1
- package/dist/cjs/agent/tool-executor.js +53 -59
- package/dist/cjs/agent/tool-executor.js.map +1 -1
- package/dist/cjs/agent/types.d.ts +50 -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 +2 -2
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/runtime/run-registry.d.ts +15 -2
- package/dist/cjs/runtime/run-registry.d.ts.map +1 -1
- package/dist/cjs/runtime/run-registry.js +87 -25
- 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/token-counter.d.ts.map +1 -1
- package/dist/cjs/utils/token-counter.js +20 -4
- package/dist/cjs/utils/token-counter.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 +5 -1
- package/dist/esm/agent/engine.d.ts.map +1 -1
- package/dist/esm/agent/engine.js +78 -49
- package/dist/esm/agent/engine.js.map +1 -1
- package/dist/esm/agent/history-manager.d.ts.map +1 -1
- package/dist/esm/agent/history-manager.js +17 -2
- package/dist/esm/agent/history-manager.js.map +1 -1
- package/dist/esm/agent/llm-caller.d.ts +2 -7
- package/dist/esm/agent/llm-caller.d.ts.map +1 -1
- package/dist/esm/agent/llm-caller.js +19 -18
- package/dist/esm/agent/llm-caller.js.map +1 -1
- package/dist/esm/agent/tool-executor.d.ts +9 -6
- package/dist/esm/agent/tool-executor.d.ts.map +1 -1
- package/dist/esm/agent/tool-executor.js +53 -59
- package/dist/esm/agent/tool-executor.js.map +1 -1
- package/dist/esm/agent/types.d.ts +50 -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 +2 -2
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/runtime/run-registry.d.ts +15 -2
- package/dist/esm/runtime/run-registry.d.ts.map +1 -1
- package/dist/esm/runtime/run-registry.js +87 -25
- 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/token-counter.d.ts.map +1 -1
- package/dist/esm/utils/token-counter.js +20 -4
- package/dist/esm/utils/token-counter.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":"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"}
|
|
@@ -16,12 +16,16 @@ export declare class AgentEngine {
|
|
|
16
16
|
private llmCaller;
|
|
17
17
|
/** 子模块:工具执行器 */
|
|
18
18
|
private toolExecutor;
|
|
19
|
-
/** 历史摘要缓存:sessionId → { summary, lastSummarizedCount } */
|
|
19
|
+
/** 历史摘要缓存:sessionId → { summary, lastSummarizedCount }(LRU 限制防止内存泄漏) */
|
|
20
20
|
private summaryCache;
|
|
21
|
+
/** 摘要缓存上限 */
|
|
22
|
+
private static readonly SUMMARY_CACHE_MAX;
|
|
21
23
|
/** 数据获取类工具集合(用于循环检测) */
|
|
22
24
|
private dataFetchTools;
|
|
23
25
|
/** 产出型工具集合(有这些调用时不触发数据获取循环检测) */
|
|
24
26
|
private outputTools;
|
|
27
|
+
/** Guard 策略配置(阈值可注入,不硬编码业务逻辑) */
|
|
28
|
+
private guardConfig;
|
|
25
29
|
constructor(config: AgentConfig);
|
|
26
30
|
/** 获取当前 Agent 的 ToolRegistry(供 read_tool_doc 等内置工具使用) */
|
|
27
31
|
getToolRegistry(): ToolRegistry;
|
|
@@ -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,EAAe,MAAM,YAAY,CAAC;AAEvE,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;
|
|
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
|
@@ -10,10 +10,11 @@ const types_ts_1 = require("../types.js");
|
|
|
10
10
|
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
|
+
const logger_ts_1 = require("../observability/logger.js");
|
|
13
14
|
/** 默认系统提示词 */
|
|
14
15
|
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.`;
|
|
15
|
-
/** 进度叙述规则(追加到 system prompt,引导 LLM
|
|
16
|
-
const
|
|
16
|
+
/** 进度叙述规则(追加到 system prompt,引导 LLM 在工具调用间输出可见文本)— 可通过 AgentConfig.progressNarrationRules 覆盖 */
|
|
17
|
+
const DEFAULT_PROGRESS_NARRATION_RULES = `
|
|
17
18
|
|
|
18
19
|
## Progress Narration Rules
|
|
19
20
|
|
|
@@ -90,12 +91,16 @@ class AgentEngine {
|
|
|
90
91
|
llmCaller;
|
|
91
92
|
/** 子模块:工具执行器 */
|
|
92
93
|
toolExecutor;
|
|
93
|
-
/** 历史摘要缓存:sessionId → { summary, lastSummarizedCount } */
|
|
94
|
+
/** 历史摘要缓存:sessionId → { summary, lastSummarizedCount }(LRU 限制防止内存泄漏) */
|
|
94
95
|
summaryCache = new Map();
|
|
96
|
+
/** 摘要缓存上限 */
|
|
97
|
+
static SUMMARY_CACHE_MAX = 100;
|
|
95
98
|
/** 数据获取类工具集合(用于循环检测) */
|
|
96
99
|
dataFetchTools;
|
|
97
100
|
/** 产出型工具集合(有这些调用时不触发数据获取循环检测) */
|
|
98
101
|
outputTools;
|
|
102
|
+
/** Guard 策略配置(阈值可注入,不硬编码业务逻辑) */
|
|
103
|
+
guardConfig;
|
|
99
104
|
constructor(config) {
|
|
100
105
|
this.config = {
|
|
101
106
|
...config,
|
|
@@ -141,6 +146,19 @@ class AgentEngine {
|
|
|
141
146
|
'delegate_task', 'create_presentation', 'create_document',
|
|
142
147
|
'create_pdf', 'show_widget', 'save_artifact',
|
|
143
148
|
]);
|
|
149
|
+
// 初始化 Guard 策略配置(阈值可注入,不硬编码业务逻辑)
|
|
150
|
+
const gc = config.guardConfig ?? {};
|
|
151
|
+
this.guardConfig = {
|
|
152
|
+
iterationGuardThreshold: gc.iterationGuardThreshold ?? 0.35,
|
|
153
|
+
maxContinuationNudges: gc.maxContinuationNudges ?? 2,
|
|
154
|
+
consecutiveSilentThreshold: gc.consecutiveSilentThreshold ?? 2,
|
|
155
|
+
consecutiveAllFailThreshold: gc.consecutiveAllFailThreshold ?? 3,
|
|
156
|
+
dataFetchLoopMinCount: gc.dataFetchLoopMinCount ?? 3,
|
|
157
|
+
consecutiveFailMinCount: gc.consecutiveFailMinCount ?? 5,
|
|
158
|
+
consecutiveFailErrorThreshold: gc.consecutiveFailErrorThreshold ?? 4,
|
|
159
|
+
delegateTargets: gc.delegateTargets ?? {},
|
|
160
|
+
iterationGuardPrompt: gc.iterationGuardPrompt ?? '',
|
|
161
|
+
};
|
|
144
162
|
}
|
|
145
163
|
/** 获取当前 Agent 的 ToolRegistry(供 read_tool_doc 等内置工具使用) */
|
|
146
164
|
getToolRegistry() {
|
|
@@ -292,11 +310,11 @@ class AgentEngine {
|
|
|
292
310
|
if (options.context?.terminalOutput) {
|
|
293
311
|
systemPrompt += `\n\n## Recent Terminal Output\n\n\`\`\`\n${options.context.terminalOutput}\n\`\`\``;
|
|
294
312
|
}
|
|
295
|
-
//
|
|
313
|
+
// 注入进度叙述规则(仅在有工具可用时)— P1 #6: 可通过 config 覆盖
|
|
296
314
|
if (this.config.toolRegistry) {
|
|
297
315
|
const toolCount = this.config.toolRegistry.getDefinitions().length;
|
|
298
316
|
if (toolCount > 0) {
|
|
299
|
-
systemPrompt +=
|
|
317
|
+
systemPrompt += this.config.progressNarrationRules ?? DEFAULT_PROGRESS_NARRATION_RULES;
|
|
300
318
|
}
|
|
301
319
|
}
|
|
302
320
|
// 去重检测:如果历史最后一条已经是当前用户消息(由 buildThreadHistory 从 DB 恢复),
|
|
@@ -310,7 +328,7 @@ class AgentEngine {
|
|
|
310
328
|
&& typeof lastMsg.content === 'string'
|
|
311
329
|
&& lastMsg.content === actualText;
|
|
312
330
|
if (isDuplicateUserMessage) {
|
|
313
|
-
|
|
331
|
+
(0, logger_ts_1.logEvent)({ event: 'engine.duplicate_user_message', sessionId, data: { action: 'excluded_from_summary' } });
|
|
314
332
|
}
|
|
315
333
|
// 非破坏性上下文投影(Context Collapse):
|
|
316
334
|
// 当历史 token 超过预算时,使用投影而非破坏性压缩,保留原始历史完整
|
|
@@ -480,7 +498,7 @@ ${textHistory.join('\n')}`;
|
|
|
480
498
|
}
|
|
481
499
|
}
|
|
482
500
|
catch (e) {
|
|
483
|
-
|
|
501
|
+
(0, logger_ts_1.logEvent)({ event: 'engine.summarize_failed', level: 'warn', data: { error: e?.message || String(e) } });
|
|
484
502
|
}
|
|
485
503
|
// 回退:简单拼接,截断到 800 字
|
|
486
504
|
const fallback = textHistory.join('\n');
|
|
@@ -495,6 +513,12 @@ ${textHistory.join('\n')}`;
|
|
|
495
513
|
async refreshSummaryCache(sessionId, textHistory) {
|
|
496
514
|
try {
|
|
497
515
|
const summary = await this.summarizeHistory(textHistory);
|
|
516
|
+
// P2 #11: LRU 淘汰 — 超过上限时移除最旧的条目
|
|
517
|
+
if (this.summaryCache.size >= AgentEngine.SUMMARY_CACHE_MAX) {
|
|
518
|
+
const oldestKey = this.summaryCache.keys().next().value;
|
|
519
|
+
if (oldestKey !== undefined)
|
|
520
|
+
this.summaryCache.delete(oldestKey);
|
|
521
|
+
}
|
|
498
522
|
this.summaryCache.set(sessionId, {
|
|
499
523
|
summary,
|
|
500
524
|
lastSummarizedCount: textHistory.length,
|
|
@@ -565,7 +589,7 @@ ${textHistory.join('\n')}`;
|
|
|
565
589
|
async prepareRun(options, internalAbort) {
|
|
566
590
|
const { skillContent, actualMessage, skillMatched } = await this.resolveSkill(options, options.sessionId);
|
|
567
591
|
const toolDefs = this.resolveToolDefs(options);
|
|
568
|
-
|
|
592
|
+
(0, logger_ts_1.logEvent)({ event: 'engine.prepare', sessionId: options.sessionId, data: { toolCount: toolDefs.length, tools: toolDefs.map(t => t.function.name) } });
|
|
569
593
|
return {
|
|
570
594
|
sessionId: options.sessionId,
|
|
571
595
|
messages: await this.buildInitialMessages(options, skillContent, actualMessage, skillMatched),
|
|
@@ -599,7 +623,7 @@ ${textHistory.join('\n')}`;
|
|
|
599
623
|
const budgetCheck = this.config.usageTracker.checkBudget(state.sessionId, this.config.tokenBudget);
|
|
600
624
|
if (budgetCheck.exceeded) {
|
|
601
625
|
if (this.config.tokenBudget.onExceed === 'abort') {
|
|
602
|
-
|
|
626
|
+
(0, logger_ts_1.logEvent)({ event: 'engine.token_budget_exceeded', sessionId: state.sessionId, level: 'warn', data: { current: budgetCheck.currentTokens, max: budgetCheck.maxTokens, action: 'abort' } });
|
|
603
627
|
yield this.createEvent(state.sessionId, {
|
|
604
628
|
type: 'error',
|
|
605
629
|
error: `Token budget exceeded (${budgetCheck.currentTokens}/${budgetCheck.maxTokens} tokens). Task aborted to prevent cost overrun.`,
|
|
@@ -609,7 +633,7 @@ ${textHistory.join('\n')}`;
|
|
|
609
633
|
return;
|
|
610
634
|
}
|
|
611
635
|
else {
|
|
612
|
-
|
|
636
|
+
(0, logger_ts_1.logEvent)({ event: 'engine.token_budget_warning', sessionId: state.sessionId, level: 'warn', data: { current: budgetCheck.currentTokens, max: budgetCheck.maxTokens } });
|
|
613
637
|
}
|
|
614
638
|
}
|
|
615
639
|
}
|
|
@@ -650,7 +674,7 @@ ${textHistory.join('\n')}`;
|
|
|
650
674
|
// 所有 LLM provider 均已失败(callWithRetry 内部已重试+降级),
|
|
651
675
|
// 不再发 done 事件(callWithRetry 已发出带详细错误信息的 error 事件),
|
|
652
676
|
// 仅完成清理,避免 done 事件覆盖前端已展示的错误消息
|
|
653
|
-
|
|
677
|
+
(0, logger_ts_1.logEvent)({ event: 'engine.llm_exhausted', sessionId: state.sessionId, level: 'warn', data: { iteration: state.iteration } });
|
|
654
678
|
this.statusMap.set(state.sessionId, 'idle');
|
|
655
679
|
// 记录 Token 用量到 UsageTracker
|
|
656
680
|
if (this.config.usageTracker && state.totalUsage) {
|
|
@@ -693,10 +717,10 @@ ${textHistory.join('\n')}`;
|
|
|
693
717
|
}
|
|
694
718
|
// 无 tool_calls → 检查是否提前停止(上一轮有工具调用,说明任务可能未完成)
|
|
695
719
|
if (!assistant.tool_calls?.length) {
|
|
696
|
-
if (state.lastIterationHadToolCalls && state.continuationNudges <
|
|
720
|
+
if (state.lastIterationHadToolCalls && state.continuationNudges < this.guardConfig.maxContinuationNudges) {
|
|
697
721
|
state.continuationNudges++;
|
|
698
722
|
state.lastIterationHadToolCalls = false; // 已消费标记,避免重复注入
|
|
699
|
-
|
|
723
|
+
(0, logger_ts_1.logEvent)({ event: 'engine.continuation_nudge', sessionId: state.sessionId, data: { nudge: state.continuationNudges, iteration: state.iteration } });
|
|
700
724
|
this.injectContinuationNudge(state);
|
|
701
725
|
// 不退出,继续下一轮迭代让 LLM 继续执行任务
|
|
702
726
|
continue;
|
|
@@ -709,7 +733,7 @@ ${textHistory.join('\n')}`;
|
|
|
709
733
|
// 检测连续静默迭代(有 tool_calls 但无 content),超过阈值自动注入提醒
|
|
710
734
|
if (!assistant.content) {
|
|
711
735
|
state.consecutiveSilentIterations++;
|
|
712
|
-
if (state.consecutiveSilentIterations >=
|
|
736
|
+
if (state.consecutiveSilentIterations >= this.guardConfig.consecutiveSilentThreshold) {
|
|
713
737
|
this.injectProgressNudge(state);
|
|
714
738
|
state.consecutiveSilentIterations = 0;
|
|
715
739
|
}
|
|
@@ -723,8 +747,8 @@ ${textHistory.join('\n')}`;
|
|
|
723
747
|
const allFailed = newRecords.every(r => r.isError);
|
|
724
748
|
if (allFailed) {
|
|
725
749
|
state.consecutiveAllFailIterations++;
|
|
726
|
-
if (state.consecutiveAllFailIterations >=
|
|
727
|
-
|
|
750
|
+
if (state.consecutiveAllFailIterations >= this.guardConfig.consecutiveAllFailThreshold) {
|
|
751
|
+
(0, logger_ts_1.logEvent)({ event: 'engine.global_fail_breaker', sessionId: state.sessionId, level: 'warn', data: { consecutiveFails: state.consecutiveAllFailIterations, iteration: state.iteration } });
|
|
728
752
|
yield this.emitDone(state);
|
|
729
753
|
return;
|
|
730
754
|
}
|
|
@@ -793,7 +817,7 @@ ${textHistory.join('\n')}`;
|
|
|
793
817
|
};
|
|
794
818
|
state.messages.push(msg);
|
|
795
819
|
this.historyManager.addHistory(state.sessionId, msg);
|
|
796
|
-
|
|
820
|
+
(0, logger_ts_1.logEvent)({ event: 'engine.progress_nudge', sessionId: state.sessionId, data: { iteration: state.iteration } });
|
|
797
821
|
}
|
|
798
822
|
/**
|
|
799
823
|
* 迭代预算提醒
|
|
@@ -807,32 +831,35 @@ ${textHistory.join('\n')}`;
|
|
|
807
831
|
const cur = state.iteration;
|
|
808
832
|
const remaining = max - cur;
|
|
809
833
|
const ratio = cur / max;
|
|
810
|
-
if (ratio >=
|
|
834
|
+
if (ratio >= this.guardConfig.iterationGuardThreshold && remaining > 0) {
|
|
811
835
|
state.iterationGuardInjected = true;
|
|
812
836
|
const toolCallCount = state.toolCallRecords.length;
|
|
813
|
-
const
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
837
|
+
const targets = this.guardConfig.delegateTargets;
|
|
838
|
+
const reportAgent = targets.report ? `"${targets.report}"` : 'the appropriate report agent';
|
|
839
|
+
const docAgent = targets.document ? `"${targets.document}"` : 'the appropriate document agent';
|
|
840
|
+
const pptAgent = targets.presentation ? `"${targets.presentation}"` : docAgent;
|
|
841
|
+
// P1 #6: 使用可配置的提示文本,默认为通用英文提示(不绑定业务 Agent 名称)
|
|
842
|
+
const promptText = this.guardConfig.iterationGuardPrompt || [
|
|
843
|
+
`[SYSTEM ITERATION BUDGET: iteration ${cur}/${max}, ${remaining} remaining]`,
|
|
844
|
+
'',
|
|
845
|
+
`⚠️ You have used ${cur} of ${max} iterations (${toolCallCount} tool calls). Budget is running low.`,
|
|
846
|
+
'',
|
|
847
|
+
'**MANDATORY rules for remaining iterations — violating these will result in task failure:**',
|
|
848
|
+
'1. **STOP all data gathering immediately.** You already have enough data from previous tool calls.',
|
|
849
|
+
'2. **DO NOT call web_fetch, execute_command, write_file, or run_script again.**',
|
|
850
|
+
`3. **NOW delegate remaining work:**`,
|
|
851
|
+
` - For reports/dashboards: call \`delegate_task\` with agent ${reportAgent}.`,
|
|
852
|
+
` - For documents: call \`delegate_task\` with agent ${docAgent}.`,
|
|
853
|
+
` - For PPT: call \`delegate_task\` with agent ${pptAgent}.`,
|
|
854
|
+
' - For direct output: call `create_presentation`/`create_document`/`show_widget` directly.',
|
|
855
|
+
'4. If you cannot delegate, produce the final output NOW with the data you have.',
|
|
856
|
+
'',
|
|
857
|
+
'Do NOT write any more scripts or fetch any more data. Your data collection phase is OVER.',
|
|
858
|
+
].join('\n');
|
|
859
|
+
const msg = { role: 'user', content: promptText };
|
|
833
860
|
state.messages.push(msg);
|
|
834
861
|
this.historyManager.addHistory(state.sessionId, msg);
|
|
835
|
-
|
|
862
|
+
(0, logger_ts_1.logEvent)({ event: 'engine.iteration_guard', sessionId: state.sessionId, data: { iteration: cur, max } });
|
|
836
863
|
}
|
|
837
864
|
}
|
|
838
865
|
/**
|
|
@@ -853,19 +880,21 @@ ${textHistory.join('\n')}`;
|
|
|
853
880
|
if (hasOutput)
|
|
854
881
|
return; // 已调用过产出型工具,不再干预
|
|
855
882
|
const recent = state.toolCallRecords.slice(-6);
|
|
856
|
-
// --- 条件 1:数据获取循环(最近
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
const
|
|
883
|
+
// --- 条件 1:数据获取循环(最近 N+ 条全是数据获取类) ---
|
|
884
|
+
const loopMin = this.guardConfig.dataFetchLoopMinCount;
|
|
885
|
+
if (recent.length >= loopMin) {
|
|
886
|
+
const lastN = recent.slice(-loopMin);
|
|
887
|
+
const allDataFetch = lastN.every(r => DATA_FETCH_TOOLS.has(r.tool));
|
|
860
888
|
if (allDataFetch) {
|
|
861
889
|
this.injectDataFetchGuard(state, recent, 'loop');
|
|
862
890
|
return;
|
|
863
891
|
}
|
|
864
892
|
}
|
|
865
|
-
// --- 条件 2:连续失败熔断(最近
|
|
866
|
-
|
|
893
|
+
// --- 条件 2:连续失败熔断(最近 N+ 条中 M+ 条失败) ---
|
|
894
|
+
const failMin = this.guardConfig.consecutiveFailMinCount;
|
|
895
|
+
if (recent.length >= failMin) {
|
|
867
896
|
const errorCount = recent.filter(r => r.isError).length;
|
|
868
|
-
if (errorCount >=
|
|
897
|
+
if (errorCount >= this.guardConfig.consecutiveFailErrorThreshold) {
|
|
869
898
|
this.injectDataFetchGuard(state, recent, 'failures');
|
|
870
899
|
return;
|
|
871
900
|
}
|
|
@@ -903,7 +932,7 @@ ${textHistory.join('\n')}`;
|
|
|
903
932
|
};
|
|
904
933
|
state.messages.push(msg);
|
|
905
934
|
this.historyManager.addHistory(state.sessionId, msg);
|
|
906
|
-
|
|
935
|
+
(0, logger_ts_1.logEvent)({ event: 'engine.data_fetch_guard', sessionId: state.sessionId, data: { reason, iteration: state.iteration, recent: toolSummary } });
|
|
907
936
|
}
|
|
908
937
|
/**
|
|
909
938
|
* 任务继续提示
|
|
@@ -930,7 +959,7 @@ ${textHistory.join('\n')}`;
|
|
|
930
959
|
};
|
|
931
960
|
state.messages.push(msg);
|
|
932
961
|
this.historyManager.addHistory(state.sessionId, msg);
|
|
933
|
-
|
|
962
|
+
(0, logger_ts_1.logEvent)({ event: 'engine.continuation_nudge_injected', sessionId: state.sessionId, data: { iteration: state.iteration, nudge: state.continuationNudges } });
|
|
934
963
|
}
|
|
935
964
|
/**
|
|
936
965
|
* 渐进式结果交付
|
|
@@ -959,7 +988,7 @@ ${textHistory.join('\n')}`;
|
|
|
959
988
|
};
|
|
960
989
|
state.messages.push(msg);
|
|
961
990
|
this.historyManager.addHistory(state.sessionId, msg);
|
|
962
|
-
|
|
991
|
+
(0, logger_ts_1.logEvent)({ event: 'engine.progressive_nudge', sessionId: state.sessionId, data: { iteration: state.iteration, delegates: delegateCalls.length } });
|
|
963
992
|
}
|
|
964
993
|
// ---- Hooks ----
|
|
965
994
|
/** 执行指定事件类型的所有 Hook */
|