@cicctencent/agent-core 1.0.16 → 1.0.18

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 (71) hide show
  1. package/dist/cjs/agent/compaction.d.ts +26 -0
  2. package/dist/cjs/agent/compaction.d.ts.map +1 -0
  3. package/dist/cjs/agent/compaction.js +95 -0
  4. package/dist/cjs/agent/compaction.js.map +1 -0
  5. package/dist/cjs/agent/engine.d.ts +8 -9
  6. package/dist/cjs/agent/engine.d.ts.map +1 -1
  7. package/dist/cjs/agent/engine.js +62 -78
  8. package/dist/cjs/agent/engine.js.map +1 -1
  9. package/dist/cjs/agent/history-manager.d.ts.map +1 -1
  10. package/dist/cjs/agent/history-manager.js +1 -4
  11. package/dist/cjs/agent/history-manager.js.map +1 -1
  12. package/dist/cjs/agent/types.d.ts +2 -0
  13. package/dist/cjs/agent/types.d.ts.map +1 -1
  14. package/dist/cjs/agent/types.js.map +1 -1
  15. package/dist/cjs/index.d.ts +3 -1
  16. package/dist/cjs/index.d.ts.map +1 -1
  17. package/dist/cjs/index.js +9 -4
  18. package/dist/cjs/index.js.map +1 -1
  19. package/dist/cjs/skill/frontmatter.d.ts +18 -0
  20. package/dist/cjs/skill/frontmatter.d.ts.map +1 -0
  21. package/dist/cjs/skill/frontmatter.js +332 -0
  22. package/dist/cjs/skill/frontmatter.js.map +1 -0
  23. package/dist/cjs/skill/manager.d.ts +33 -6
  24. package/dist/cjs/skill/manager.d.ts.map +1 -1
  25. package/dist/cjs/skill/manager.js +234 -81
  26. package/dist/cjs/skill/manager.js.map +1 -1
  27. package/dist/cjs/skill/types.d.ts +26 -0
  28. package/dist/cjs/skill/types.d.ts.map +1 -1
  29. package/dist/cjs/store/file-tool-result-store.d.ts +5 -0
  30. package/dist/cjs/store/file-tool-result-store.d.ts.map +1 -1
  31. package/dist/cjs/store/file-tool-result-store.js +14 -0
  32. package/dist/cjs/store/file-tool-result-store.js.map +1 -1
  33. package/dist/cjs/utils/token-counter.d.ts.map +1 -1
  34. package/dist/cjs/utils/token-counter.js +20 -16
  35. package/dist/cjs/utils/token-counter.js.map +1 -1
  36. package/dist/esm/agent/compaction.d.ts +26 -0
  37. package/dist/esm/agent/compaction.d.ts.map +1 -0
  38. package/dist/esm/agent/compaction.js +91 -0
  39. package/dist/esm/agent/compaction.js.map +1 -0
  40. package/dist/esm/agent/engine.d.ts +8 -9
  41. package/dist/esm/agent/engine.d.ts.map +1 -1
  42. package/dist/esm/agent/engine.js +61 -77
  43. package/dist/esm/agent/engine.js.map +1 -1
  44. package/dist/esm/agent/history-manager.d.ts.map +1 -1
  45. package/dist/esm/agent/history-manager.js +1 -4
  46. package/dist/esm/agent/history-manager.js.map +1 -1
  47. package/dist/esm/agent/types.d.ts +2 -0
  48. package/dist/esm/agent/types.d.ts.map +1 -1
  49. package/dist/esm/agent/types.js.map +1 -1
  50. package/dist/esm/index.d.ts +3 -1
  51. package/dist/esm/index.d.ts.map +1 -1
  52. package/dist/esm/index.js +1 -0
  53. package/dist/esm/index.js.map +1 -1
  54. package/dist/esm/skill/frontmatter.d.ts +18 -0
  55. package/dist/esm/skill/frontmatter.d.ts.map +1 -0
  56. package/dist/esm/skill/frontmatter.js +326 -0
  57. package/dist/esm/skill/frontmatter.js.map +1 -0
  58. package/dist/esm/skill/manager.d.ts +33 -6
  59. package/dist/esm/skill/manager.d.ts.map +1 -1
  60. package/dist/esm/skill/manager.js +234 -81
  61. package/dist/esm/skill/manager.js.map +1 -1
  62. package/dist/esm/skill/types.d.ts +26 -0
  63. package/dist/esm/skill/types.d.ts.map +1 -1
  64. package/dist/esm/store/file-tool-result-store.d.ts +5 -0
  65. package/dist/esm/store/file-tool-result-store.d.ts.map +1 -1
  66. package/dist/esm/store/file-tool-result-store.js +14 -0
  67. package/dist/esm/store/file-tool-result-store.js.map +1 -1
  68. package/dist/esm/utils/token-counter.d.ts.map +1 -1
  69. package/dist/esm/utils/token-counter.js +20 -16
  70. package/dist/esm/utils/token-counter.js.map +1 -1
  71. package/package.json +7 -4
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  // ============================================================
3
- // Token 计数器 — 基于 tiktoken 的精确 token 计数
3
+ // Token 计数器 - 基于 tiktoken 的精确 token 计数
4
4
  // ============================================================
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.countTokens = countTokens;
@@ -9,15 +9,21 @@ exports.estimateTokens = estimateTokens;
9
9
  const js_tiktoken_1 = require("js-tiktoken");
10
10
  /** 默认编码器(cl100k_base,兼容 GPT-4 / Claude 等主流模型) */
11
11
  let encoder = null;
12
+ /** 字符估算伪编码器(tiktoken 不可用时兜底,约 4 字符 ≈ 1 token) */
13
+ function createFallbackEncoder() {
14
+ return { encode: (text) => new Array(Math.ceil(text.length / 4)) };
15
+ }
12
16
  /**
13
17
  * LRU 缓存:避免对相同文本重复计算 token
14
18
  * 缓存容量 2000 条,命中率高时可显著减少 encode 调用
19
+ * lastInsertedKey 追踪最近写入的 key,命中时若为同 key 则跳过 delete+set
15
20
  */
16
21
  const TOKEN_CACHE_MAX = 2000;
17
22
  const tokenCache = new Map();
23
+ let lastInsertedKey;
18
24
  /**
19
25
  * 获取 tiktoken 编码器实例(延迟初始化)
20
- * P2 #13: 兼容 ESM 环境 — require 可能未定义,回退到字符估算
26
+ * 兼容 ESM 环境 - require 可能未定义,回退到字符估算
21
27
  */
22
28
  function getEncoder() {
23
29
  if (encoder)
@@ -27,21 +33,13 @@ function getEncoder() {
27
33
  }
28
34
  catch {
29
35
  try {
30
- // P2 #13: ESM 兼容 — 尝试 require,失败则回退到字符估算
31
36
  const ranks = (typeof require !== 'undefined')
32
37
  ? require('js-tiktoken/ranks/cl100k_base')
33
38
  : undefined;
34
- if (ranks) {
35
- encoder = new js_tiktoken_1.Tiktoken(ranks);
36
- }
37
- else {
38
- // ESM 环境无法加载 ranks — 使用伪 encoder 走字符估算
39
- encoder = { encode: (text) => new Array(Math.ceil(text.length / 4)) };
40
- }
39
+ encoder = ranks ? new js_tiktoken_1.Tiktoken(ranks) : createFallbackEncoder();
41
40
  }
42
41
  catch {
43
- // 完全无法加载 tiktoken — 使用伪 encoder 走字符估算
44
- encoder = { encode: (text) => new Array(Math.ceil(text.length / 4)) };
42
+ encoder = createFallbackEncoder();
45
43
  }
46
44
  }
47
45
  return encoder;
@@ -57,9 +55,12 @@ function countTokens(text) {
57
55
  // 缓存查找
58
56
  const cached = tokenCache.get(text);
59
57
  if (cached !== undefined) {
60
- // LRU: 删除旧位置并在末尾重新插入
61
- tokenCache.delete(text);
62
- tokenCache.set(text, cached);
58
+ // LRU: 仅当不是最近插入的条目时才移动到末尾(O(1) 判断,避免展开全部 keys)
59
+ if (lastInsertedKey !== text) {
60
+ tokenCache.delete(text);
61
+ tokenCache.set(text, cached);
62
+ lastInsertedKey = text;
63
+ }
63
64
  return cached;
64
65
  }
65
66
  const count = getEncoder().encode(text).length;
@@ -71,6 +72,7 @@ function countTokens(text) {
71
72
  tokenCache.delete(oldestKey);
72
73
  }
73
74
  tokenCache.set(text, count);
75
+ lastInsertedKey = text;
74
76
  return count;
75
77
  }
76
78
  /**
@@ -80,6 +82,8 @@ function countTokens(text) {
80
82
  * @returns 总 token 数量
81
83
  */
82
84
  function countMessageTokens(messages) {
85
+ if (!messages || messages.length === 0)
86
+ return 0;
83
87
  let total = 0;
84
88
  for (const msg of messages) {
85
89
  // 每条消息 overhead: role + content 分隔
@@ -119,7 +123,7 @@ function countMessageTokens(messages) {
119
123
  * - TextPart: 精确计数
120
124
  * - ImagePart: 按详情级别估算(参考 OpenAI Vision 定价)
121
125
  * - low: ~85 tokens(512x512 固定)
122
- * - high: ~170 tokens/tile(最多 4 tiles → ~680)
126
+ * - high: ~170 tokens/tile(最多 4 tiles -> ~680)
123
127
  * - auto: 默认按 low 估算
124
128
  * - FilePart: 计数文本内容
125
129
  */
@@ -1 +1 @@
1
- {"version":3,"file":"token-counter.js","sourceRoot":"","sources":["../../../src/utils/token-counter.ts"],"names":[],"mappings":";AAAA,+DAA+D;AAC/D,uCAAuC;AACvC,+DAA+D;;AAgD/D,kCAuBC;AAQD,gDAiCC;AAgCD,wCAGC;AAjJD,6CAAyD;AAGzD,iDAAiD;AACjD,IAAI,OAAO,GAAoB,IAAI,CAAC;AAEpC;;;GAGG;AACH,MAAM,eAAe,GAAG,IAAI,CAAC;AAC7B,MAAM,UAAU,GAAG,IAAI,GAAG,EAAkB,CAAC;AAE7C;;;GAGG;AACH,SAAS,UAAU;IACjB,IAAI,OAAO;QAAE,OAAO,OAAO,CAAC;IAC5B,IAAI,CAAC;QACH,OAAO,GAAG,IAAA,8BAAgB,EAAC,OAAO,CAAC,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,IAAI,CAAC;YACH,yCAAyC;YACzC,MAAM,KAAK,GAAG,CAAC,OAAO,OAAO,KAAK,WAAW,CAAC;gBAC5C,CAAC,CAAC,OAAO,CAAC,+BAA+B,CAAC;gBAC1C,CAAC,CAAC,SAAS,CAAC;YACd,IAAI,KAAK,EAAE,CAAC;gBACV,OAAO,GAAG,IAAI,sBAAQ,CAAC,KAAK,CAAC,CAAC;YAChC,CAAC;iBAAM,CAAC;gBACN,uCAAuC;gBACvC,OAAO,GAAG,EAAE,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAyB,CAAC;YACvG,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,sCAAsC;YACtC,OAAO,GAAG,EAAE,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAyB,CAAC;QACvG,CAAC;IACH,CAAC;IACD,OAAO,OAAQ,CAAC;AAClB,CAAC;AAED;;;;GAIG;AACH,SAAgB,WAAW,CAAC,IAAY;IACtC,IAAI,CAAC,IAAI;QAAE,OAAO,CAAC,CAAC;IAEpB,OAAO;IACP,MAAM,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACpC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,qBAAqB;QACrB,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACxB,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAC7B,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,MAAM,KAAK,GAAG,UAAU,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;IAE/C,cAAc;IACd,IAAI,UAAU,CAAC,IAAI,IAAI,eAAe,EAAE,CAAC;QACvC,2BAA2B;QAC3B,MAAM,SAAS,GAAG,UAAU,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC;QACjD,IAAI,SAAS,KAAK,SAAS;YAAE,UAAU,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAC5D,CAAC;IACD,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAE5B,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;GAKG;AACH,SAAgB,kBAAkB,CAAC,QAAmB;IACpD,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC3B,mCAAmC;QACnC,KAAK,IAAI,CAAC,CAAC;QACX,OAAO;QACP,KAAK,IAAI,WAAW,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;QACrC,UAAU;QACV,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;YAChB,IAAI,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;gBACpC,KAAK,IAAI,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YACpC,CAAC;iBAAM,CAAC;gBACN,sBAAsB;gBACtB,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;oBAC/B,KAAK,IAAI,sBAAsB,CAAC,IAAI,CAAC,CAAC;gBACxC,CAAC;YACH,CAAC;QACH,CAAC;QACD,6BAA6B;QAC7B,IAAI,GAAG,CAAC,UAAU,EAAE,CAAC;YACnB,KAAK,MAAM,EAAE,IAAI,GAAG,CAAC,UAAU,EAAE,CAAC;gBAChC,KAAK,IAAI,WAAW,CAAC,EAAE,CAAC,QAAQ,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC;gBAC9C,KAAK,IAAI,WAAW,CAAC,EAAE,CAAC,QAAQ,EAAE,SAAS,IAAI,EAAE,CAAC,CAAC;YACrD,CAAC;QACH,CAAC;QACD,+BAA+B;QAC/B,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC;YACb,KAAK,IAAI,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACjC,CAAC;IACH,CAAC;IACD,2BAA2B;IAC3B,KAAK,IAAI,CAAC,CAAC;IACX,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,sBAAsB,CAAC,IAAiB;IAC/C,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;QAClB,KAAK,MAAM;YACT,OAAO,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChC,KAAK,OAAO;YACV,sDAAsD;YACtD,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM;gBAAE,OAAO,GAAG,CAAC;YACvC,OAAO,EAAE,CAAC;QACZ,KAAK,MAAM;YACT,OAAO,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAChE;YACE,OAAO,CAAC,CAAC;IACb,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,SAAgB,cAAc,CAAC,IAAY;IACzC,IAAI,CAAC,IAAI;QAAE,OAAO,CAAC,CAAC;IACpB,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AACpC,CAAC"}
1
+ {"version":3,"file":"token-counter.js","sourceRoot":"","sources":["../../../src/utils/token-counter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import type { ToolDefinition } from '../tool/types.js';
2
+ /**
3
+ * 生成工具调用的简短摘要(用于历史摘要)。
4
+ * 保留工具名和关键参数,让 LLM 在后续轮次中能复用之前的调用参数。
5
+ *
6
+ * @param name 工具名
7
+ * @param args 工具参数
8
+ */
9
+ export declare function summarizeToolCall(name: string, args: Record<string, unknown>): string;
10
+ /** 工具定义摘要选项 */
11
+ export interface SummarizeToolDefOptions {
12
+ /** 摘要范围:'mcp'=仅 MCP 工具摘要, 'all'=所有传入工具摘要, null=保持原样 */
13
+ scope: 'mcp' | 'all' | null;
14
+ /** 最大描述长度(默认 100) */
15
+ maxDesc?: number;
16
+ /** 判断工具分类的回调(由调用方注入 ToolRegistry 依赖,保持此处无硬依赖) */
17
+ getCategory?: (name: string) => string | undefined;
18
+ }
19
+ /**
20
+ * 将工具定义转为摘要形式(截断 description + 清空 parameters)。
21
+ *
22
+ * @param def 原始工具定义
23
+ * @param options 摘要选项(含 category 查询注入)
24
+ */
25
+ export declare function summarizeToolDef(def: ToolDefinition, options: SummarizeToolDefOptions): ToolDefinition;
26
+ //# sourceMappingURL=compaction.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compaction.d.ts","sourceRoot":"","sources":["../../../src/agent/compaction.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAkBvD;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CA0BrF;AAED,eAAe;AACf,MAAM,WAAW,uBAAuB;IACtC,uDAAuD;IACvD,KAAK,EAAE,KAAK,GAAG,KAAK,GAAG,IAAI,CAAC;IAC5B,qBAAqB;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iDAAiD;IACjD,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;CACpD;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,cAAc,EACnB,OAAO,EAAE,uBAAuB,GAC/B,cAAc,CAoBhB"}
@@ -0,0 +1,91 @@
1
+ // ============================================================
2
+ // Compaction — 历史压缩纯逻辑(从 engine.ts 抽离)
3
+ // ============================================================
4
+ //
5
+ // 本文件承载 AgentEngine 历史压缩相关的「纯函数」部分,与运行时/LLM 调用解耦,
6
+ // 以便独立单元测试。拆分目标:在重构 engine.ts(~2000 行)前,先锁定这些
7
+ // 可被精确断言的纯逻辑行为,避免拆分引入隐性回归。
8
+ //
9
+ // 依赖说明:
10
+ // - summarizeToolCall: 无外部依赖,纯字符串变换
11
+ // - summarizeToolDef: 需要 ToolRegistry 判断 category(保留轻量依赖)
12
+ /**
13
+ * 安全序列化值为字符串(处理 JSON.stringify 的边界情况)。
14
+ * - undefined / function / Symbol → String(v)
15
+ * - 循环引用 → '[Circular]'
16
+ */
17
+ function safeSerialize(v) {
18
+ if (v === undefined || typeof v === 'function' || typeof v === 'symbol') {
19
+ return String(v);
20
+ }
21
+ try {
22
+ return JSON.stringify(v) ?? String(v);
23
+ }
24
+ catch {
25
+ return '[Circular]';
26
+ }
27
+ }
28
+ /**
29
+ * 生成工具调用的简短摘要(用于历史摘要)。
30
+ * 保留工具名和关键参数,让 LLM 在后续轮次中能复用之前的调用参数。
31
+ *
32
+ * @param name 工具名
33
+ * @param args 工具参数
34
+ */
35
+ export function summarizeToolCall(name, args) {
36
+ switch (name) {
37
+ case 'delegate_task': {
38
+ const agent = args.agent || '';
39
+ const task = typeof args.task === 'string' ? args.task.slice(0, 80) : '';
40
+ return `delegate_task(agent=${agent}, task="${task}...")`;
41
+ }
42
+ case 'create_report':
43
+ case 'create_presentation':
44
+ case 'create_document':
45
+ case 'create_pdf':
46
+ case 'save_artifact': {
47
+ const filename = (args.filename || args.title || '').slice(0, 60);
48
+ return `${name}(filename="${filename}")`;
49
+ }
50
+ default: {
51
+ // 通用:展示前 3 个参数的键名和值摘要
52
+ const keys = Object.keys(args).slice(0, 3);
53
+ const parts = keys.map(k => {
54
+ const v = args[k];
55
+ const s = typeof v === 'string' ? v.slice(0, 50) : safeSerialize(v).slice(0, 50);
56
+ return `${k}=${s}`;
57
+ });
58
+ return `${name}(${parts.join(', ')})`;
59
+ }
60
+ }
61
+ }
62
+ /**
63
+ * 将工具定义转为摘要形式(截断 description + 清空 parameters)。
64
+ *
65
+ * @param def 原始工具定义
66
+ * @param options 摘要选项(含 category 查询注入)
67
+ */
68
+ export function summarizeToolDef(def, options) {
69
+ const { scope, maxDesc = 100, getCategory } = options;
70
+ if (scope === null)
71
+ return def;
72
+ if (scope === 'mcp' && getCategory?.(def.function.name) !== 'mcp')
73
+ return def;
74
+ const desc = def.function.description.length > maxDesc
75
+ ? def.function.description.slice(0, maxDesc) + '...'
76
+ : def.function.description;
77
+ return {
78
+ ...def,
79
+ type: 'function',
80
+ function: {
81
+ name: def.function.name,
82
+ description: desc + ` (use read_tool_doc to get full schema before calling; use read_tool_doc(tool_name="list") to see all available tools)`,
83
+ parameters: {
84
+ type: 'object',
85
+ properties: {},
86
+ required: [],
87
+ },
88
+ },
89
+ };
90
+ }
91
+ //# sourceMappingURL=compaction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compaction.js","sourceRoot":"","sources":["../../../src/agent/compaction.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,uCAAuC;AACvC,+DAA+D;AAC/D,EAAE;AACF,kDAAkD;AAClD,8CAA8C;AAC9C,2BAA2B;AAC3B,EAAE;AACF,QAAQ;AACR,oCAAoC;AACpC,0DAA0D;AAI1D;;;;GAIG;AACH,SAAS,aAAa,CAAC,CAAU;IAC/B,IAAI,CAAC,KAAK,SAAS,IAAI,OAAO,CAAC,KAAK,UAAU,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE,CAAC;QACxE,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC;IACnB,CAAC;IACD,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC;IACxC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,YAAY,CAAC;IACtB,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAY,EAAE,IAA6B;IAC3E,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,eAAe,CAAC,CAAC,CAAC;YACrB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAe,IAAI,EAAE,CAAC;YACzC,MAAM,IAAI,GAAG,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACzE,OAAO,uBAAuB,KAAK,WAAW,IAAI,OAAO,CAAC;QAC5D,CAAC;QACD,KAAK,eAAe,CAAC;QACrB,KAAK,qBAAqB,CAAC;QAC3B,KAAK,iBAAiB,CAAC;QACvB,KAAK,YAAY,CAAC;QAClB,KAAK,eAAe,CAAC,CAAC,CAAC;YACrB,MAAM,QAAQ,GAAG,CAAC,IAAI,CAAC,QAAkB,IAAI,IAAI,CAAC,KAAe,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACtF,OAAO,GAAG,IAAI,cAAc,QAAQ,IAAI,CAAC;QAC3C,CAAC;QACD,OAAO,CAAC,CAAC,CAAC;YACR,sBAAsB;YACtB,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAC3C,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;gBACzB,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;gBAClB,MAAM,CAAC,GAAG,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBACjF,OAAO,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACrB,CAAC,CAAC,CAAC;YACH,OAAO,GAAG,IAAI,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;QACxC,CAAC;IACH,CAAC;AACH,CAAC;AAYD;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAC9B,GAAmB,EACnB,OAAgC;IAEhC,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,GAAG,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC;IACtD,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,GAAG,CAAC;IAC/B,IAAI,KAAK,KAAK,KAAK,IAAI,WAAW,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,KAAK;QAAE,OAAO,GAAG,CAAC;IAC9E,MAAM,IAAI,GAAG,GAAG,CAAC,QAAQ,CAAC,WAAW,CAAC,MAAM,GAAG,OAAO;QACpD,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,KAAK;QACpD,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,WAAW,CAAC;IAC7B,OAAO;QACL,GAAG,GAAG;QACN,IAAI,EAAE,UAAmB;QACzB,QAAQ,EAAE;YACR,IAAI,EAAE,GAAG,CAAC,QAAQ,CAAC,IAAI;YACvB,WAAW,EAAE,IAAI,GAAG,wHAAwH;YAC5I,UAAU,EAAE;gBACV,IAAI,EAAE,QAAiB;gBACvB,UAAU,EAAE,EAAE;gBACd,QAAQ,EAAE,EAAE;aACb;SACF;KACF,CAAC;AACJ,CAAC"}
@@ -140,8 +140,7 @@ export declare class AgentEngine {
140
140
  private resolveToolDefs;
141
141
  /**
142
142
  * 将工具定义转为摘要形式(截断 description + 清空 parameters)。
143
- * @param def 原始工具定义
144
- * @param scope 摘要范围:'mcp'=仅MCP工具摘要, 'all'=所有传入工具摘要, null=保持原样
143
+ * 实现抽离至 ./compaction.ts,保持单一来源。
145
144
  */
146
145
  private summarizeToolDef;
147
146
  /** 构建 ToolContext */
@@ -167,16 +166,16 @@ export declare class AgentEngine {
167
166
  * - 且这些调用**全部失败** → 最终产出的数据必然来自模型记忆(真实历史或编造,执行层无法区分);
168
167
  * - → 追加「未经实时核验」声明。
169
168
  *
170
- * 不触发(正确放行):
171
- * - 从未调用外部数据工具(纯本地/推理任务)→ 无需水印;
172
- * - 外部数据工具**有成功** → 数据已核验,无需水印。
173
- *
174
- * @returns 需要追加的声明文本;无需水印时返回空串
175
- */
176
- private buildProvenanceNotice;
177
169
  /**
178
170
  * 对最终回复应用数据出处水印(幂等)。
179
171
  * 仅当有实际文本内容、需要水印、且尚未包含水印标记时追加。
172
+ *
173
+ * 触发(添加水印):
174
+ * - 本轮调用过外部数据获取工具且全部失败 → 最终回复中的数据必然来自记忆 → 需要声明;
175
+ *
176
+ * 不触发(正确放行):
177
+ * - 从未调用外部数据工具(纯本地/推理任务)→ 无需水印;
178
+ * - 外部数据工具**有成功** → 数据已核验,无需水印。
180
179
  */
181
180
  private applyProvenanceNotice;
182
181
  /**
@@ -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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"}
@@ -9,6 +9,7 @@ import { LLMCaller } from "./llm-caller.js";
9
9
  import { AgentToolExecutor } from "./tool-executor.js";
10
10
  import { logEvent } from "../observability/logger.js";
11
11
  import { rateLimitManager } from "./rate-limit-manager.js";
12
+ import { summarizeToolCall, summarizeToolDef } from "./compaction.js";
12
13
  /** 默认系统提示词 */
13
14
  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.`;
14
15
  /**
@@ -46,7 +47,7 @@ When using tools, you MUST provide brief visible narration for the user:
46
47
  - When the task is complete, always end with a clear summary of what was accomplished.
47
48
  - DO NOT output tool calls without accompanying text narration.
48
49
  - **delegate_task / sub-agent output**: When a delegated sub-agent completes, its full output has ALREADY been streamed to the user in real-time. Do NOT repeat or re-output the sub-agent's content. Only write ONE brief sentence summarizing the outcome, then continue with next steps or conclude.
49
- - **Reusing delegate_task results**: When you need data from a previous delegate_task call in later turns, use \`read_tool_result(call_id="...")\` to retrieve the saved result instead of re-running delegate_task. Re-running delegate_task is expensive (a full sub-agent execution) and may produce inconsistent results. The call_id is the tool_call_id of the delegate_task's tool result message. If the result has been compressed to a placeholder or offload tag, the call_id is included in the tag text.
50
+ - **Reusing delegate_task results (CRITICAL)**: When the conversation history contains a section marked "[delegate_task 完整分析结果]", **use that data directly** — do NOT re-run delegate_task. Re-running delegate_task is expensive (a full sub-agent execution), may produce inconsistent results, and is strictly prohibited when the analysis data is already available in the conversation history. If the result has been compressed to a placeholder, use \`read_tool_result(call_id="...")\` to retrieve it.
50
51
  `;
51
52
  /** 数据出处水印标记(隐藏 HTML 注释,用于幂等判定,避免重复注入) */
52
53
  const PROVENANCE_MARKER = '<!--provenance-unverified-->';
@@ -68,42 +69,27 @@ function buildSkillCatalog(skillManager) {
68
69
  const manifests = skillManager.getAllManifests();
69
70
  if (manifests.length === 0)
70
71
  return null;
72
+ let hasResources = false;
71
73
  const lines = manifests.map(m => {
72
74
  const aliases = m.aliases?.length ? ` (also known as: ${m.aliases.join(', ')})` : '';
73
- return `- \`${m.id}\`: ${m.name}${aliases} — ${m.description || '(no description)'}`;
75
+ // 标注标准目录包资源(脚本/参考文档/静态资源),引导 agent 按需访问
76
+ const res = m.resources;
77
+ const badges = [];
78
+ if (res?.scripts?.length)
79
+ badges.push(`${res.scripts.length} scripts`);
80
+ if (res?.references?.length)
81
+ badges.push(`${res.references.length} refs`);
82
+ if (res?.assets?.length)
83
+ badges.push(`${res.assets.length} assets`);
84
+ if (badges.length)
85
+ hasResources = true;
86
+ const resBadge = badges.length ? ` [resources: ${badges.join(', ')}]` : '';
87
+ return `- \`${m.id}\`: ${m.name}${aliases} — ${m.description || '(no description)'}${resBadge}`;
74
88
  });
75
- return `## Available Skills\n\nYou have access to the following skills. **Before using any tools, ALWAYS check if the user's request matches one of these skills first.** If a skill is relevant, call \`load_skill(skill_id="<id>")\` to load its full instructions, then follow those instructions. Skill names and aliases may not exactly match the user's wording - use semantic judgment to identify matches.\n\n${lines.join('\n')}`;
76
- }
77
- /**
78
- * 生成工具调用的简短摘要(用于历史摘要)。
79
- * 保留工具名和关键参数,让 LLM 在后续轮次中能复用之前的调用参数。
80
- */
81
- function summarizeToolCall(name, args) {
82
- switch (name) {
83
- case 'delegate_task': {
84
- const agent = args.agent || '';
85
- const task = typeof args.task === 'string' ? args.task.slice(0, 80) : '';
86
- return `delegate_task(agent=${agent}, task="${task}...")`;
87
- }
88
- case 'create_report':
89
- case 'create_presentation':
90
- case 'create_document':
91
- case 'create_pdf':
92
- case 'save_artifact': {
93
- const filename = (args.filename || args.title || '').slice(0, 60);
94
- return `${name}(filename="${filename}")`;
95
- }
96
- default: {
97
- // 通用:展示前 3 个参数的键名和值摘要
98
- const keys = Object.keys(args).slice(0, 3);
99
- const parts = keys.map(k => {
100
- const v = args[k];
101
- const s = typeof v === 'string' ? v.slice(0, 50) : JSON.stringify(v)?.slice(0, 50);
102
- return `${k}=${s}`;
103
- });
104
- return `${name}(${parts.join(', ')})`;
105
- }
106
- }
89
+ const resourceGuide = hasResources
90
+ ? `\n\nSkills marked with [resources: ...] are standard packages bundling docs and scripts. After loading such a skill with load_skill, read bundled reference docs on demand via \`read_skill_reference(skill_id, path)\` and execute bundled scripts via \`run_skill_script(skill_id, script, args)\` — do NOT read all resources upfront.`
91
+ : '';
92
+ return `## Available Skills\n\nYou have access to the following skills. **Before using any tools, ALWAYS check if the user's request matches one of these skills first.** If a skill is relevant, call \`load_skill(skill_id="<id>")\` to load its full instructions, then follow those instructions. Skill names and aliases may not exactly match the user's wording - use semantic judgment to identify matches.\n\n${lines.join('\n')}${resourceGuide}`;
107
93
  }
108
94
  export class AgentEngine {
109
95
  config;
@@ -511,6 +497,8 @@ export class AgentEngine {
511
497
  }
512
498
  if (effectiveHistory.length === 0)
513
499
  return [];
500
+ // 收集 delegate_task 完整结果(在 800 字摘要之外单独追加,避免被截断)
501
+ const delegateTaskResults = [];
514
502
  // 提取纯文本用于摘要(包含工具调用和工具结果,否则 LLM 丢失关键上下文)
515
503
  const textHistory = effectiveHistory
516
504
  .map(m => {
@@ -522,9 +510,23 @@ export class AgentEngine {
522
510
  // 保留 artifact URL(关键!否则后续引用已生成的报告/文件时丢失链接)
523
511
  const urlMatch = text.match(/(?:URL|url|artifact)[::]\s*(\/api\/[^\s"']+)/i);
524
512
  const urlInfo = urlMatch ? ` [artifact_url: ${urlMatch[1]}]` : '';
525
- // delegate_task 结果保留更多上下文(500 字符),因为重新生成成本极高,
526
- // 摘要中保留更多分析数据可减少 LLM 因"看不到数据"而重跑 delegate_task 的倾向
527
513
  const toolName = HistoryManager.findToolNameForCallId(m.tool_call_id || '', effectiveHistory);
514
+ const callIdMatch = text.match(/\[call_id:\s*"([^"]+)"\]/);
515
+ const extractedCallId = callIdMatch?.[1] || m.tool_call_id || '';
516
+ // delegate_task 结果:在 textHistory 中仅保留短占位符,
517
+ // 完整结果在摘要构建后单独追加(不受 800 字摘要截断影响)
518
+ if (toolName === 'delegate_task' && extractedCallId && this.config.toolResultStore) {
519
+ const fullResult = this.config.toolResultStore.read(extractedCallId);
520
+ if (fullResult) {
521
+ const MAX_DELEGATE_INJECT = 4000;
522
+ const injected = fullResult.length > MAX_DELEGATE_INJECT
523
+ ? fullResult.slice(0, MAX_DELEGATE_INJECT) + '\n...(已截断,完整结果可用 read_tool_result 检索)'
524
+ : fullResult;
525
+ delegateTaskResults.push(`[delegate_task 完整分析结果]:\n${injected}`);
526
+ return `[工具结果] [delegate_task] 分析完成,完整结果见下方 [delegate_task 完整分析结果] 部分`;
527
+ }
528
+ }
529
+ // 其他工具结果保留截断摘要
528
530
  const toolResultLimit = toolName === 'delegate_task' ? 500 : 150;
529
531
  const truncated = text.length > toolResultLimit
530
532
  ? text.slice(0, toolResultLimit) + '...' + urlInfo
@@ -583,6 +585,12 @@ export class AgentEngine {
583
585
  }
584
586
  }
585
587
  }
588
+ // 在 800 字摘要之后追加 delegate_task 完整分析结果(不受摘要截断影响)。
589
+ // 这是确保后续轮次能直接复用分析数据的关键机制,
590
+ // 避免 LLM 因"看不到数据"而重新调用 delegate_task。
591
+ if (delegateTaskResults.length > 0) {
592
+ summary += `\n\n${delegateTaskResults.join('\n\n---\n\n')}`;
593
+ }
586
594
  // 确保 delegate_task 的 call_id 始终可见(不受摘要截断/LLM压缩影响)。
587
595
  // 从 effectiveHistory 的 tool 消息中直接提取 tool_call_id(OpenAI 元数据,始终存在),
588
596
  // 不依赖 processToolOutput 的 [call_id:...] 前缀或摘要保留。
@@ -704,31 +712,14 @@ ${textHistory.join('\n')}`;
704
712
  }
705
713
  /**
706
714
  * 将工具定义转为摘要形式(截断 description + 清空 parameters)。
707
- * @param def 原始工具定义
708
- * @param scope 摘要范围:'mcp'=仅MCP工具摘要, 'all'=所有传入工具摘要, null=保持原样
715
+ * 实现抽离至 ./compaction.ts,保持单一来源。
709
716
  */
710
717
  summarizeToolDef(def, scope) {
711
- if (scope === null)
712
- return def;
713
- const tool = this.config.toolRegistry.get(def.function.name);
714
- if (scope === 'mcp' && tool?.category !== 'mcp')
715
- return def;
716
- const maxDesc = this.config.toolSummaryMaxDesc ?? 100;
717
- const desc = def.function.description.length > maxDesc
718
- ? def.function.description.slice(0, maxDesc) + '...'
719
- : def.function.description;
720
- return {
721
- type: 'function',
722
- function: {
723
- name: def.function.name,
724
- description: desc + ` (use read_tool_doc to get full schema before calling; use read_tool_doc(tool_name="list") to see all available tools)`,
725
- parameters: {
726
- type: 'object',
727
- properties: {},
728
- required: [],
729
- },
730
- },
731
- };
718
+ return summarizeToolDef(def, {
719
+ scope,
720
+ maxDesc: this.config.toolSummaryMaxDesc ?? 100,
721
+ getCategory: (name) => this.config.toolRegistry.get(name)?.category,
722
+ });
732
723
  }
733
724
  // ---- 准备阶段(续) ----
734
725
  /** 构建 ToolContext */
@@ -1161,32 +1152,25 @@ ${textHistory.join('\n')}`;
1161
1152
  * - 且这些调用**全部失败** → 最终产出的数据必然来自模型记忆(真实历史或编造,执行层无法区分);
1162
1153
  * - → 追加「未经实时核验」声明。
1163
1154
  *
1164
- * 不触发(正确放行):
1165
- * - 从未调用外部数据工具(纯本地/推理任务)→ 无需水印;
1166
- * - 外部数据工具**有成功** → 数据已核验,无需水印。
1167
- *
1168
- * @returns 需要追加的声明文本;无需水印时返回空串
1169
- */
1170
- buildProvenanceNotice(state) {
1171
- const externalCalls = state.toolCallRecords.filter(r => this.externalDataFetchTools.has(r.tool));
1172
- if (externalCalls.length === 0)
1173
- return ''; // 未尝试外部数据源 → 不判定
1174
- if (externalCalls.some(r => !r.isError))
1175
- return ''; // 有成功获取 → 视为已核验
1176
- return PROVENANCE_UNVERIFIED_NOTICE; // 尝试过但全失败 → 数据来自记忆
1177
- }
1178
1155
  /**
1179
1156
  * 对最终回复应用数据出处水印(幂等)。
1180
1157
  * 仅当有实际文本内容、需要水印、且尚未包含水印标记时追加。
1158
+ *
1159
+ * 触发(添加水印):
1160
+ * - 本轮调用过外部数据获取工具且全部失败 → 最终回复中的数据必然来自记忆 → 需要声明;
1161
+ *
1162
+ * 不触发(正确放行):
1163
+ * - 从未调用外部数据工具(纯本地/推理任务)→ 无需水印;
1164
+ * - 外部数据工具**有成功** → 数据已核验,无需水印。
1181
1165
  */
1182
1166
  applyProvenanceNotice(state, content) {
1183
1167
  if (!content || content.includes(PROVENANCE_MARKER))
1184
1168
  return content;
1185
- const notice = this.buildProvenanceNotice(state);
1186
- if (!notice)
1169
+ const externalCalls = state.toolCallRecords.filter(r => this.externalDataFetchTools.has(r.tool));
1170
+ if (externalCalls.length === 0 || externalCalls.some(r => !r.isError))
1187
1171
  return content;
1188
- logEvent({ event: 'engine.provenance_notice', sessionId: state.sessionId, level: 'warn', data: { iteration: state.iteration, externalCalls: state.toolCallRecords.filter(r => this.externalDataFetchTools.has(r.tool)).length } });
1189
- return content + notice;
1172
+ logEvent({ event: 'engine.provenance_notice', sessionId: state.sessionId, level: 'warn', data: { iteration: state.iteration, externalCalls: externalCalls.length } });
1173
+ return content + PROVENANCE_UNVERIFIED_NOTICE;
1190
1174
  }
1191
1175
  /**
1192
1176
  * 生成兜底总结(当 LLM 调用失败或无内容输出时使用)。