aws-runtime-bridge 1.9.40 → 1.9.41
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/adapter/AcodeSdkAdapter.d.ts +31 -4
- package/dist/adapter/AcodeSdkAdapter.d.ts.map +1 -1
- package/dist/adapter/AcodeSdkAdapter.js +382 -57
- package/dist/adapter/ClaudeSdkAdapter.d.ts.map +1 -1
- package/dist/adapter/ClaudeSdkAdapter.js +1 -0
- package/dist/adapter/OpencodeSdkAdapter.d.ts +19 -0
- package/dist/adapter/OpencodeSdkAdapter.d.ts.map +1 -1
- package/dist/adapter/OpencodeSdkAdapter.js +62 -0
- package/dist/adapter/types.d.ts +21 -6
- package/dist/adapter/types.d.ts.map +1 -1
- package/dist/adapter/types.js +10 -1
- package/dist/index.js +11 -0
- package/dist/routes/ai-sources.js +4 -1
- package/dist/routes/dashboard.d.ts.map +1 -1
- package/dist/routes/dashboard.js +1 -1
- package/dist/routes/runtime-binding.d.ts.map +1 -1
- package/dist/routes/runtime-binding.js +6 -3
- package/dist/routes/sessions.js +89 -4
- package/dist/routes/sub-agents.js +15 -1
- package/dist/routes/terminal.d.ts +3 -0
- package/dist/routes/terminal.d.ts.map +1 -1
- package/dist/routes/terminal.js +122 -5
- package/dist/services/acode-package.d.ts +8 -1
- package/dist/services/acode-package.d.ts.map +1 -1
- package/dist/services/acode-package.js +33 -4
- package/dist/services/aws-client-agent-mcp.d.ts.map +1 -1
- package/dist/services/aws-client-agent-mcp.js +11 -4
- package/dist/services/fileSnapshotStore.js +1 -1
- package/dist/services/legacy-path-migration.d.ts +3 -0
- package/dist/services/legacy-path-migration.d.ts.map +1 -0
- package/dist/services/legacy-path-migration.js +66 -0
- package/dist/services/lifecycle-state.d.ts.map +1 -1
- package/dist/services/lifecycle-state.js +1 -1
- package/dist/services/runtime-binding.d.ts +5 -0
- package/dist/services/runtime-binding.d.ts.map +1 -1
- package/dist/services/runtime-binding.js +33 -1
- package/dist/services/session-output.d.ts +7 -1
- package/dist/services/session-output.d.ts.map +1 -1
- package/dist/services/session-output.js +16 -2
- package/package/acode/dist/built-in-file-tools.d.ts.map +1 -1
- package/package/acode/dist/built-in-file-tools.js +504 -3
- package/package/acode/dist/compaction.d.ts +43 -7
- package/package/acode/dist/compaction.d.ts.map +1 -1
- package/package/acode/dist/compaction.js +286 -31
- package/package/acode/dist/runtime.d.ts +120 -0
- package/package/acode/dist/runtime.d.ts.map +1 -1
- package/package/acode/dist/runtime.js +921 -71
- package/package/acode/dist/sub-agent-manager.d.ts +96 -1
- package/package/acode/dist/sub-agent-manager.d.ts.map +1 -1
- package/package/acode/dist/sub-agent-manager.js +293 -3
- package/package/acode/dist/sub-agent-store.d.ts +8 -1
- package/package/acode/dist/sub-agent-store.d.ts.map +1 -1
- package/package/acode/dist/sub-agent-store.js +55 -0
- package/package/acode/dist/sub-agent-types.d.ts +4 -0
- package/package/acode/dist/sub-agent-types.d.ts.map +1 -1
- package/package/acode/dist/types.d.ts +19 -0
- package/package/acode/dist/types.d.ts.map +1 -1
- package/package/aws-client-agent-mcp/dist/agent-client.d.ts +9 -0
- package/package/aws-client-agent-mcp/dist/agent-client.d.ts.map +1 -1
- package/package/aws-client-agent-mcp/dist/agent-client.js +69 -10
- package/package/aws-client-agent-mcp/dist/agent-client.js.map +1 -1
- package/package/aws-client-agent-mcp/dist/config.d.ts.map +1 -1
- package/package/aws-client-agent-mcp/dist/config.js +4 -0
- package/package/aws-client-agent-mcp/dist/config.js.map +1 -1
- package/package/aws-client-agent-mcp/dist/constants.d.ts +2 -0
- package/package/aws-client-agent-mcp/dist/constants.d.ts.map +1 -1
- package/package/aws-client-agent-mcp/dist/constants.js +3 -1
- package/package/aws-client-agent-mcp/dist/constants.js.map +1 -1
- package/package/aws-client-agent-mcp/dist/context-manager.d.ts +4 -1
- package/package/aws-client-agent-mcp/dist/context-manager.d.ts.map +1 -1
- package/package/aws-client-agent-mcp/dist/context-manager.js +6 -2
- package/package/aws-client-agent-mcp/dist/context-manager.js.map +1 -1
- package/package/aws-client-agent-mcp/dist/context-manager.test.js +5 -0
- package/package/aws-client-agent-mcp/dist/context-manager.test.js.map +1 -1
- package/package/aws-client-agent-mcp/dist/http-client.d.ts +5 -0
- package/package/aws-client-agent-mcp/dist/http-client.d.ts.map +1 -1
- package/package/aws-client-agent-mcp/dist/http-client.js +15 -1
- package/package/aws-client-agent-mcp/dist/http-client.js.map +1 -1
- package/package/aws-client-agent-mcp/dist/mcp-server.d.ts +92 -34
- package/package/aws-client-agent-mcp/dist/mcp-server.d.ts.map +1 -1
- package/package/aws-client-agent-mcp/dist/mcp-server.js +606 -208
- package/package/aws-client-agent-mcp/dist/mcp-server.js.map +1 -1
- package/package/aws-client-agent-mcp/dist/mcp-server.test.js +151 -51
- package/package/aws-client-agent-mcp/dist/mcp-server.test.js.map +1 -1
- package/package/aws-client-agent-mcp/dist/mcp-tools.d.ts +7 -0
- package/package/aws-client-agent-mcp/dist/mcp-tools.d.ts.map +1 -1
- package/package/aws-client-agent-mcp/dist/mcp-tools.js +18 -0
- package/package/aws-client-agent-mcp/dist/mcp-tools.js.map +1 -1
- package/package/aws-client-agent-mcp/dist/memory-store.d.ts +32 -9
- package/package/aws-client-agent-mcp/dist/memory-store.d.ts.map +1 -1
- package/package/aws-client-agent-mcp/dist/memory-store.js +58 -19
- package/package/aws-client-agent-mcp/dist/memory-store.js.map +1 -1
- package/package/aws-client-agent-mcp/dist/memory-tools.js +3 -3
- package/package/aws-client-agent-mcp/dist/memory-tools.js.map +1 -1
- package/package/aws-client-agent-mcp/dist/message-buffer.d.ts +13 -0
- package/package/aws-client-agent-mcp/dist/message-buffer.d.ts.map +1 -1
- package/package/aws-client-agent-mcp/dist/message-buffer.js +23 -0
- package/package/aws-client-agent-mcp/dist/message-buffer.js.map +1 -1
- package/package/aws-client-agent-mcp/dist/server-memory-store.d.ts +13 -0
- package/package/aws-client-agent-mcp/dist/server-memory-store.d.ts.map +1 -1
- package/package/aws-client-agent-mcp/dist/server-memory-store.js +18 -0
- package/package/aws-client-agent-mcp/dist/server-memory-store.js.map +1 -1
- package/package/aws-client-agent-mcp/dist/types.d.ts +9 -0
- package/package/aws-client-agent-mcp/dist/types.d.ts.map +1 -1
- package/package/aws-client-agent-mcp/dist/types.js.map +1 -1
- package/package/aws-client-agent-mcp/dist/websocket-client.d.ts +34 -1
- package/package/aws-client-agent-mcp/dist/websocket-client.d.ts.map +1 -1
- package/package/aws-client-agent-mcp/dist/websocket-client.js +146 -18
- package/package/aws-client-agent-mcp/dist/websocket-client.js.map +1 -1
- package/package.json +1 -1
|
@@ -15,8 +15,39 @@
|
|
|
15
15
|
// ============ 常量(与 OpenCode compaction.ts 对齐) ============
|
|
16
16
|
/** 压缩缓冲区:保留这么多 token 的空闲空间,避免压缩过程中溢出 */
|
|
17
17
|
export const COMPACTION_BUFFER = 20_000;
|
|
18
|
-
/**
|
|
18
|
+
/**
|
|
19
|
+
* 基础压缩触发比例(兜底默认值,仅用于 contextLimit <= 0 的异常场景)。
|
|
20
|
+
* 正常情况下通过 {@link getCompactionTriggerRatio} 按窗口大小动态分级。
|
|
21
|
+
*/
|
|
19
22
|
export const COMPACTION_TRIGGER_RATIO = 0.55;
|
|
23
|
+
/**
|
|
24
|
+
* 压缩触发比例的窗口分级表。
|
|
25
|
+
* 大窗口下压缩成本高(LLM 摘要调用 + 上下文丢失风险),应提高比例充分利用窗口;
|
|
26
|
+
* 小窗口下压缩成本低,可适当降低比例以及时释放空间。
|
|
27
|
+
*
|
|
28
|
+
* | 窗口大小 | 比例 |
|
|
29
|
+
* |---------------|-------|
|
|
30
|
+
* | < 32K | 0.70 |
|
|
31
|
+
* | 32K - 128K | 0.75 |
|
|
32
|
+
* | 128K - 512K | 0.80 |
|
|
33
|
+
* | ≥ 512K | 0.85 |
|
|
34
|
+
*/
|
|
35
|
+
const COMPACTION_TRIGGER_RATIO_TIERS = [
|
|
36
|
+
[32_000, 0.70],
|
|
37
|
+
[128_000, 0.75],
|
|
38
|
+
[512_000, 0.80],
|
|
39
|
+
[Number.POSITIVE_INFINITY, 0.85],
|
|
40
|
+
];
|
|
41
|
+
/** 按上下文窗口大小返回压缩触发比例(大窗口更高,充分利用空间)。 */
|
|
42
|
+
export function getCompactionTriggerRatio(contextLimit) {
|
|
43
|
+
if (contextLimit <= 0)
|
|
44
|
+
return COMPACTION_TRIGGER_RATIO;
|
|
45
|
+
for (const [limit, ratio] of COMPACTION_TRIGGER_RATIO_TIERS) {
|
|
46
|
+
if (contextLimit < limit)
|
|
47
|
+
return ratio;
|
|
48
|
+
}
|
|
49
|
+
return 0.85;
|
|
50
|
+
}
|
|
20
51
|
/** Prune 保护线默认值:保留最近 PRUNE_PROTECT token 的工具输出完整。
|
|
21
52
|
* 注意:实际使用时会按 contextLimit 比例调整(见 pruneToolOutputs),
|
|
22
53
|
* 避免在小上下文窗口(如 60k)下保护线过高导致 prune 永不触发。
|
|
@@ -32,6 +63,57 @@ const PRUNE_PROTECT_RATIO = 0.5;
|
|
|
32
63
|
const PRUNE_MINIMUM_RATIO = 0.1;
|
|
33
64
|
/** Prune 白名单:这些工具的输出永远不会被裁剪 */
|
|
34
65
|
const PRUNE_PROTECTED_TOOLS = new Set(["skill", "todo_write", "todo_read"]);
|
|
66
|
+
/**
|
|
67
|
+
* 工具重要性等级(数字越小越重要,越优先保护)。
|
|
68
|
+
* 用于 prune 时按重要性排序:裁剪时优先移除低重要性的工具输出。
|
|
69
|
+
*/
|
|
70
|
+
const TOOL_IMPORTANCE = {
|
|
71
|
+
// 最高保护:文件读取和搜索类(结果包含关键上下文)
|
|
72
|
+
"read_file": 0,
|
|
73
|
+
"Read": 0,
|
|
74
|
+
"grep": 0,
|
|
75
|
+
"Grep": 0,
|
|
76
|
+
"glob": 0,
|
|
77
|
+
"Glob": 0,
|
|
78
|
+
"contextweaver_codebase-retrieval": 0,
|
|
79
|
+
// 高保护:文件写入和编辑(确认信息)
|
|
80
|
+
"Edit": 1,
|
|
81
|
+
"edit": 1,
|
|
82
|
+
"Write": 1,
|
|
83
|
+
"write": 1,
|
|
84
|
+
"write_file": 1,
|
|
85
|
+
// 中保护:网络请求
|
|
86
|
+
"webfetch": 2,
|
|
87
|
+
"WebFetch": 2,
|
|
88
|
+
"WebSearch": 2,
|
|
89
|
+
"websearch_web_search_exa": 2,
|
|
90
|
+
// 低保护:命令行执行(输出通常可丢弃)
|
|
91
|
+
"bash": 3,
|
|
92
|
+
"Bash": 3,
|
|
93
|
+
"run_terminal_command": 3,
|
|
94
|
+
// 最低保护:UI 操作
|
|
95
|
+
"playwright_browser_": 4,
|
|
96
|
+
};
|
|
97
|
+
/** 默认重要性(不在 TOOL_IMPORTANCE 中的工具) */
|
|
98
|
+
const DEFAULT_TOOL_IMPORTANCE = 2;
|
|
99
|
+
/**
|
|
100
|
+
* 获取工具的重要性等级。
|
|
101
|
+
* 支持前缀匹配(如 "playwright_browser_navigate" 匹配 "playwright_browser_")。
|
|
102
|
+
*/
|
|
103
|
+
function getToolImportance(toolName) {
|
|
104
|
+
if (!toolName)
|
|
105
|
+
return DEFAULT_TOOL_IMPORTANCE;
|
|
106
|
+
if (TOOL_IMPORTANCE[toolName] !== undefined)
|
|
107
|
+
return TOOL_IMPORTANCE[toolName];
|
|
108
|
+
// 前缀匹配(按长度降序)
|
|
109
|
+
const matches = Object.keys(TOOL_IMPORTANCE)
|
|
110
|
+
.filter((key) => toolName.startsWith(key))
|
|
111
|
+
.sort((a, b) => b.length - a.length);
|
|
112
|
+
if (matches.length > 0) {
|
|
113
|
+
return TOOL_IMPORTANCE[matches[0]];
|
|
114
|
+
}
|
|
115
|
+
return DEFAULT_TOOL_IMPORTANCE;
|
|
116
|
+
}
|
|
35
117
|
/** 默认上下文窗口上限(查找不到模型时使用) */
|
|
36
118
|
const DEFAULT_CONTEXT_LIMIT = 128_000;
|
|
37
119
|
/** 默认最大输出 token */
|
|
@@ -76,19 +158,31 @@ export const COMPACTION_LLM_PROMPT_TEMPLATE = [
|
|
|
76
158
|
"",
|
|
77
159
|
"Output only the summary, no preamble.",
|
|
78
160
|
].join("\n");
|
|
79
|
-
/** token 估算系数:约
|
|
80
|
-
const
|
|
161
|
+
/** 中文字符 token 估算系数:约 1.5 字符/token */
|
|
162
|
+
const ESTIMATION_CJK_CHARS_PER_TOKEN = 1.5;
|
|
163
|
+
/** ASCII 字符 token 估算系数:约 4 字符/token */
|
|
164
|
+
const ESTIMATION_ASCII_CHARS_PER_TOKEN = 4;
|
|
165
|
+
/**
|
|
166
|
+
* Token 估算安全填充系数。
|
|
167
|
+
* 参考 Claude Code 的 ×4/3 策略:本地估算始终比实际 token 数偏小,
|
|
168
|
+
* 乘以安全系数确保估算值 >= 实际值,避免在溢出前来不及压缩。
|
|
169
|
+
*/
|
|
170
|
+
const ESTIMATION_SAFE_PADDING = 1.15;
|
|
171
|
+
/** 图片/文档块固定 token 估算值(参考 Claude Code 的 2000 tokens/image) */
|
|
172
|
+
const ESTIMATION_IMAGE_TOKENS = 2000;
|
|
173
|
+
/** 工具调用 JSON 结构附加开销(tool_call_id + role 等) */
|
|
174
|
+
const ESTIMATION_TOOL_OVERHEAD = 8;
|
|
81
175
|
/**
|
|
82
|
-
* 计算压缩触发阈值:取 min(contextLimit ×
|
|
176
|
+
* 计算压缩触发阈值:取 min(contextLimit × 动态比例, hardLimit - reserved)。
|
|
83
177
|
*
|
|
84
|
-
* - ratioBased = contextLimit ×
|
|
178
|
+
* - ratioBased = contextLimit × getCompactionTriggerRatio(contextLimit)(按窗口大小动态分级)
|
|
85
179
|
* - hardLimit = inputLimit ?? contextLimit(provider 显式 inputLimit 优先)
|
|
86
180
|
* - reserved = min(COMPACTION_BUFFER, maxOutput)(buffer 不超过输出上限)
|
|
87
181
|
*
|
|
88
182
|
* 取两者较小者,既避免小窗口下过早触发,又避免接近硬上限时来不及压缩。
|
|
89
183
|
*/
|
|
90
184
|
export function calculateCompactionThreshold(contextLimit, maxOutput, inputLimit) {
|
|
91
|
-
const ratioBased = Math.floor(contextLimit *
|
|
185
|
+
const ratioBased = Math.floor(contextLimit * getCompactionTriggerRatio(contextLimit));
|
|
92
186
|
const hardLimit = inputLimit ?? contextLimit;
|
|
93
187
|
const reserved = Math.min(COMPACTION_BUFFER, maxOutput);
|
|
94
188
|
const hardLimitBased = hardLimit - reserved;
|
|
@@ -172,14 +266,55 @@ export function lookupModelLimits(modelName, configOverrides) {
|
|
|
172
266
|
}
|
|
173
267
|
// ============ Token 估算 ============
|
|
174
268
|
/**
|
|
175
|
-
*
|
|
176
|
-
*
|
|
177
|
-
*
|
|
269
|
+
* 中英文分离的文本 token 估算。
|
|
270
|
+
* 对纯 ASCII 约 4 字符/token,对中文约 1.5 字符/token。
|
|
271
|
+
* 参考:context-manager.ts 的同名方法。
|
|
272
|
+
*/
|
|
273
|
+
export function estimateTextTokens(text) {
|
|
274
|
+
if (!text)
|
|
275
|
+
return 0;
|
|
276
|
+
let cjkCount = 0;
|
|
277
|
+
let asciiCount = 0;
|
|
278
|
+
for (const ch of text) {
|
|
279
|
+
if (ch > "\u00ff") {
|
|
280
|
+
cjkCount++;
|
|
281
|
+
}
|
|
282
|
+
else {
|
|
283
|
+
asciiCount++;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
return Math.ceil(cjkCount / ESTIMATION_CJK_CHARS_PER_TOKEN + asciiCount / ESTIMATION_ASCII_CHARS_PER_TOKEN);
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* 粗略估算文本的 token 数(保留向后兼容)。
|
|
290
|
+
* 使用 estimateTextTokens 的中英文分离 + 安全填充。
|
|
178
291
|
*/
|
|
179
292
|
export function estimateTokens(text) {
|
|
180
293
|
if (!text)
|
|
181
294
|
return 0;
|
|
182
|
-
|
|
295
|
+
// × ESTIMATION_SAFE_PADDING 确保估算始终偏大(安全侧)
|
|
296
|
+
// 参考 Claude Code 的 estimateMessageTokens 的 ×4/3 策略
|
|
297
|
+
return Math.ceil(estimateTextTokens(text) * ESTIMATION_SAFE_PADDING);
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* 块级内容 token 估算:识别 text/image_url 等不同块类型分别定价。
|
|
301
|
+
*/
|
|
302
|
+
function estimateContentBlock(block) {
|
|
303
|
+
if (typeof block === "object" && block !== null) {
|
|
304
|
+
const record = block;
|
|
305
|
+
if (record.type === "text" && typeof record.text === "string") {
|
|
306
|
+
return estimateTokens(record.text);
|
|
307
|
+
}
|
|
308
|
+
if (record.type === "image_url" || record.type === "document") {
|
|
309
|
+
return ESTIMATION_IMAGE_TOKENS;
|
|
310
|
+
}
|
|
311
|
+
// 其他类型(tool_result 嵌套等):JSON 估算
|
|
312
|
+
return Math.ceil(JSON.stringify(block).length / ESTIMATION_ASCII_CHARS_PER_TOKEN);
|
|
313
|
+
}
|
|
314
|
+
if (typeof block === "string") {
|
|
315
|
+
return estimateTokens(block);
|
|
316
|
+
}
|
|
317
|
+
return 0;
|
|
183
318
|
}
|
|
184
319
|
/**
|
|
185
320
|
* 估算单条消息的字节大小。
|
|
@@ -206,28 +341,25 @@ function estimateMessageBytes(message) {
|
|
|
206
341
|
}
|
|
207
342
|
/**
|
|
208
343
|
* 估算整个对话的 token 数。
|
|
344
|
+
* 使用块级识别 + 中英文分离 + 安全填充。
|
|
209
345
|
*/
|
|
210
346
|
export function estimateConversationTokens(messages) {
|
|
211
|
-
let
|
|
347
|
+
let total = 0;
|
|
212
348
|
for (const msg of messages) {
|
|
213
349
|
if (typeof msg.content === "string") {
|
|
214
|
-
|
|
350
|
+
total += estimateTokens(msg.content);
|
|
215
351
|
}
|
|
216
352
|
else if (Array.isArray(msg.content)) {
|
|
217
353
|
for (const part of msg.content) {
|
|
218
|
-
|
|
219
|
-
totalChars += JSON.stringify(part).length;
|
|
220
|
-
}
|
|
354
|
+
total += estimateContentBlock(part);
|
|
221
355
|
}
|
|
222
356
|
}
|
|
357
|
+
// tool_calls 结构开销
|
|
223
358
|
if (msg.tool_calls) {
|
|
224
|
-
|
|
225
|
-
}
|
|
226
|
-
if (msg.tool_call_id) {
|
|
227
|
-
totalChars += msg.tool_call_id.length;
|
|
359
|
+
total += ESTIMATION_TOOL_OVERHEAD + Math.ceil(JSON.stringify(msg.tool_calls).length / ESTIMATION_ASCII_CHARS_PER_TOKEN);
|
|
228
360
|
}
|
|
229
361
|
}
|
|
230
|
-
return
|
|
362
|
+
return total;
|
|
231
363
|
}
|
|
232
364
|
/**
|
|
233
365
|
* 计算对话的 KB 大小。
|
|
@@ -251,7 +383,7 @@ export function isOverflow(messages, contextLimit, _maxOutput) {
|
|
|
251
383
|
if (contextLimit <= 0)
|
|
252
384
|
return false;
|
|
253
385
|
const totalUsed = estimateConversationTokens(messages);
|
|
254
|
-
const ratioThreshold = Math.floor(contextLimit *
|
|
386
|
+
const ratioThreshold = Math.floor(contextLimit * getCompactionTriggerRatio(contextLimit));
|
|
255
387
|
return totalUsed >= ratioThreshold;
|
|
256
388
|
}
|
|
257
389
|
/**
|
|
@@ -260,7 +392,7 @@ export function isOverflow(messages, contextLimit, _maxOutput) {
|
|
|
260
392
|
* provider 每次请求都会返回实际 token 计数(input + output),
|
|
261
393
|
* 这个计数比基于文本的估算(estimateConversationTokens)要准确得多。
|
|
262
394
|
*
|
|
263
|
-
* 触发条件:累积 tokens >= contextLimit *
|
|
395
|
+
* 触发条件:累积 tokens >= contextLimit * getCompactionTriggerRatio(contextLimit)
|
|
264
396
|
* 使用显式传入的 contextLimit,不依赖模型名查找表。
|
|
265
397
|
*
|
|
266
398
|
* @param accumulatedInput provider 实际累积的 input tokens
|
|
@@ -271,7 +403,7 @@ export function isOverflowByActualUsage(accumulatedInput, accumulatedOutput, con
|
|
|
271
403
|
if (contextLimit <= 0)
|
|
272
404
|
return false;
|
|
273
405
|
const totalUsed = accumulatedInput + accumulatedOutput;
|
|
274
|
-
const ratioThreshold = Math.floor(contextLimit *
|
|
406
|
+
const ratioThreshold = Math.floor(contextLimit * getCompactionTriggerRatio(contextLimit));
|
|
275
407
|
return totalUsed >= ratioThreshold;
|
|
276
408
|
}
|
|
277
409
|
// ============ Prune 策略 ============
|
|
@@ -335,9 +467,12 @@ export function pruneToolOutputs(messages, contextLimit = DEFAULT_CONTEXT_LIMIT)
|
|
|
335
467
|
// 按比例调整保护线和最小收益阈值
|
|
336
468
|
const protectLine = Math.min(PRUNE_PROTECT, Math.floor(contextLimit * PRUNE_PROTECT_RATIO));
|
|
337
469
|
const minimumGain = Math.min(PRUNE_MINIMUM, Math.floor(contextLimit * PRUNE_MINIMUM_RATIO));
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
470
|
+
// 阶段 1:收集所有候选(按重要性分组)
|
|
471
|
+
// 在保护线内的工具输出(最近 N 轮),无论重要性如何都保留。
|
|
472
|
+
// 超过保护线的输出,按重要性排序,优先裁剪低重要性的。
|
|
473
|
+
let accumulatedTokens = 0;
|
|
474
|
+
const lowImportanceCandidates = [];
|
|
475
|
+
const highImportanceCandidates = [];
|
|
341
476
|
let turns = 0;
|
|
342
477
|
// 从最新往旧遍历
|
|
343
478
|
for (let i = messages.length - 1; i >= 0; i--) {
|
|
@@ -353,10 +488,41 @@ export function pruneToolOutputs(messages, contextLimit = DEFAULT_CONTEXT_LIMIT)
|
|
|
353
488
|
continue;
|
|
354
489
|
const contentStr = typeof msg.content === "string" ? msg.content : "";
|
|
355
490
|
const estimate = estimateTokens(contentStr);
|
|
356
|
-
|
|
357
|
-
if (
|
|
358
|
-
|
|
359
|
-
|
|
491
|
+
accumulatedTokens += estimate;
|
|
492
|
+
if (accumulatedTokens > protectLine) {
|
|
493
|
+
// 超过保护线,按重要性分组
|
|
494
|
+
const importance = toolName ? getToolImportance(toolName) : DEFAULT_TOOL_IMPORTANCE;
|
|
495
|
+
const candidate = { msg, tokens: estimate, name: toolName ?? "" };
|
|
496
|
+
if (importance <= 1) {
|
|
497
|
+
// 高重要性(Read/Grep/Edit 等):暂不优先裁剪
|
|
498
|
+
highImportanceCandidates.push(candidate);
|
|
499
|
+
}
|
|
500
|
+
else {
|
|
501
|
+
// 低重要性(Bash/WebSearch 等):优先裁剪
|
|
502
|
+
lowImportanceCandidates.push(candidate);
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
// 阶段 2:按重要性排序,低重要性优先裁剪
|
|
507
|
+
// 低重要性按 token 数降序(先裁大的),高重要性按 token 数升序(尽量保留)
|
|
508
|
+
lowImportanceCandidates.sort((a, b) => b.tokens - a.tokens);
|
|
509
|
+
highImportanceCandidates.sort((a, b) => a.tokens - b.tokens);
|
|
510
|
+
const toPrune = [];
|
|
511
|
+
let freedTokens = 0;
|
|
512
|
+
// 先裁低重要性
|
|
513
|
+
for (const c of lowImportanceCandidates) {
|
|
514
|
+
if (freedTokens >= minimumGain)
|
|
515
|
+
break;
|
|
516
|
+
freedTokens += c.tokens;
|
|
517
|
+
toPrune.push(c.msg);
|
|
518
|
+
}
|
|
519
|
+
// 如果低重要性不够,再裁高重要性(从最小的开始)
|
|
520
|
+
if (freedTokens < minimumGain) {
|
|
521
|
+
for (const c of highImportanceCandidates) {
|
|
522
|
+
freedTokens += c.tokens;
|
|
523
|
+
toPrune.push(c.msg);
|
|
524
|
+
if (freedTokens >= minimumGain)
|
|
525
|
+
break;
|
|
360
526
|
}
|
|
361
527
|
}
|
|
362
528
|
if (freedTokens < minimumGain) {
|
|
@@ -569,6 +735,69 @@ export async function summarizeConversation(messages, options) {
|
|
|
569
735
|
messages.push(...keptMessages);
|
|
570
736
|
return removableCount;
|
|
571
737
|
}
|
|
738
|
+
// ============ 配对不变量保护 ============
|
|
739
|
+
/**
|
|
740
|
+
* Snip:删除最旧的一组消息(从第一个非 system 消息到下一个 user 消息之前)。
|
|
741
|
+
*
|
|
742
|
+
* 作为压缩的最终手段——当 prune 和 summarize 都无法释放足够空间时使用。
|
|
743
|
+
* 能确保:
|
|
744
|
+
* 1. 不删除 system 消息
|
|
745
|
+
* 2. 删除的组不跨 user 边界(保证一个完整轮次)
|
|
746
|
+
* 3. 删除后至少保留 1 组非 system 消息
|
|
747
|
+
*
|
|
748
|
+
* @param messages 对话消息数组(会被原地修改,通过 splice 删除)
|
|
749
|
+
* @returns 删除的消息数
|
|
750
|
+
*/
|
|
751
|
+
export function snipOldestMessageGroup(messages) {
|
|
752
|
+
if (messages.length <= 1)
|
|
753
|
+
return 0;
|
|
754
|
+
// 找到第一个非 system 消息的索引
|
|
755
|
+
let startIdx = 0;
|
|
756
|
+
while (startIdx < messages.length && messages[startIdx].role === "system") {
|
|
757
|
+
startIdx++;
|
|
758
|
+
}
|
|
759
|
+
if (startIdx >= messages.length)
|
|
760
|
+
return 0;
|
|
761
|
+
// 找到下一个 user 消息的索引(作为删除组的结束边界)
|
|
762
|
+
let groupEnd = messages.length;
|
|
763
|
+
for (let i = startIdx + 1; i < messages.length; i++) {
|
|
764
|
+
if (messages[i].role === "user") {
|
|
765
|
+
groupEnd = i;
|
|
766
|
+
break;
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
// 不能删除全部非 system 消息(至少保留一组)
|
|
770
|
+
if (groupEnd >= messages.length)
|
|
771
|
+
return 0;
|
|
772
|
+
// 收集删除范围内 assistant 发起的 tool_call_id
|
|
773
|
+
const removedToolCallIds = new Set();
|
|
774
|
+
for (let i = startIdx; i < groupEnd; i++) {
|
|
775
|
+
const msg = messages[i];
|
|
776
|
+
if (msg.role === "assistant" && Array.isArray(msg.tool_calls)) {
|
|
777
|
+
for (const tc of msg.tool_calls) {
|
|
778
|
+
if (typeof tc === "object" && tc !== null && typeof tc.id === "string") {
|
|
779
|
+
removedToolCallIds.add(tc.id);
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
// 删除主组 [startIdx, groupEnd)
|
|
785
|
+
const removedCount = groupEnd - startIdx;
|
|
786
|
+
messages.splice(startIdx, removedCount);
|
|
787
|
+
// 清理孤儿 tool_result:其对应的 tool_call 已在上一步删除,但 tool_result 可能落在下一轮(groupEnd 之后)。
|
|
788
|
+
// 不能用连续 splice 扩展范围(会误删中间的 user 消息),故采用逆向遍历逐个删除孤儿 tool_result。
|
|
789
|
+
let orphanRemoved = 0;
|
|
790
|
+
if (removedToolCallIds.size > 0) {
|
|
791
|
+
for (let i = messages.length - 1; i >= startIdx; i--) {
|
|
792
|
+
const msg = messages[i];
|
|
793
|
+
if (msg.role === "tool" && msg.tool_call_id && removedToolCallIds.has(msg.tool_call_id)) {
|
|
794
|
+
messages.splice(i, 1);
|
|
795
|
+
orphanRemoved++;
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
return removedCount + orphanRemoved;
|
|
800
|
+
}
|
|
572
801
|
// ============ 完整压缩流程 ============
|
|
573
802
|
/**
|
|
574
803
|
* 执行完整压缩流程:Prune → 若仍溢出则 Summarize。
|
|
@@ -610,7 +839,16 @@ export async function performCompaction(messages, contextLimit, maxOutput = DEFA
|
|
|
610
839
|
});
|
|
611
840
|
}
|
|
612
841
|
// 阶段 2: 若仍溢出,执行 Summarize
|
|
613
|
-
|
|
842
|
+
//
|
|
843
|
+
// ★ 使用 effectiveUsed(文本估算与 actual 的较大值)而非仅文本估算:
|
|
844
|
+
// provider 实际 token 计数往往高于基于字符的估算,若仅依赖文本估算,
|
|
845
|
+
// 可能因估算值低于阈值而导致"假阴性"——实际已溢出但 isOverflow 返回 false,
|
|
846
|
+
// summarize 被直接跳过,最终策略为 "none"。
|
|
847
|
+
const tokensAfterPrune = estimateConversationTokens(messages);
|
|
848
|
+
const postPruneEffective = options?.actualUsedTokens
|
|
849
|
+
? Math.max(tokensAfterPrune, Math.max(options.actualUsedTokens, tokensBefore) - freedTokens)
|
|
850
|
+
: tokensAfterPrune;
|
|
851
|
+
if (postPruneEffective >= Math.floor(contextLimit * getCompactionTriggerRatio(contextLimit))) {
|
|
614
852
|
if (options?.onPhase) {
|
|
615
853
|
options.onPhase({ phase: "summarize_start", messageCount: messages.length });
|
|
616
854
|
}
|
|
@@ -629,6 +867,18 @@ export async function performCompaction(messages, contextLimit, maxOutput = DEFA
|
|
|
629
867
|
m.content.includes("summarized by LLM"));
|
|
630
868
|
usedLLM = Boolean(summaryMsg);
|
|
631
869
|
}
|
|
870
|
+
else {
|
|
871
|
+
// ★ 阶段 2b: Summarize 失败降级 → Snip 最旧消息组(最终手段)
|
|
872
|
+
// 当 summarize 返回 0(无法找到干净边界或清理后 kept 为空),
|
|
873
|
+
// 尝试直接删除最旧的一组非 system 消息。
|
|
874
|
+
const sniped = snipOldestMessageGroup(messages);
|
|
875
|
+
if (sniped > 0) {
|
|
876
|
+
strategy = strategy === "prune" ? "prune+summarize" : "summarize";
|
|
877
|
+
summarizedMessages = sniped;
|
|
878
|
+
const tokensAfter = estimateConversationTokens(messages);
|
|
879
|
+
freedTokens = Math.max(freedTokens, tokensBefore - tokensAfter);
|
|
880
|
+
}
|
|
881
|
+
}
|
|
632
882
|
if (options?.onPhase) {
|
|
633
883
|
options.onPhase({
|
|
634
884
|
phase: "summarize_end",
|
|
@@ -639,12 +889,15 @@ export async function performCompaction(messages, contextLimit, maxOutput = DEFA
|
|
|
639
889
|
}
|
|
640
890
|
const sizeAfterKB = conversationSizeKB(messages);
|
|
641
891
|
const messageCountAfter = messages.length;
|
|
892
|
+
const tokensAfter = estimateConversationTokens(messages);
|
|
642
893
|
if (strategy === "none") {
|
|
643
894
|
return {
|
|
644
895
|
strategy: "none",
|
|
645
896
|
freedTokens: 0,
|
|
646
897
|
sizeBeforeKB,
|
|
647
898
|
sizeAfterKB: sizeBeforeKB,
|
|
899
|
+
tokensBefore,
|
|
900
|
+
tokensAfter,
|
|
648
901
|
messageCountBefore,
|
|
649
902
|
messageCountAfter,
|
|
650
903
|
prunedToolMessages: 0,
|
|
@@ -656,6 +909,8 @@ export async function performCompaction(messages, contextLimit, maxOutput = DEFA
|
|
|
656
909
|
freedTokens,
|
|
657
910
|
sizeBeforeKB,
|
|
658
911
|
sizeAfterKB,
|
|
912
|
+
tokensBefore,
|
|
913
|
+
tokensAfter,
|
|
659
914
|
messageCountBefore,
|
|
660
915
|
messageCountAfter,
|
|
661
916
|
prunedToolMessages,
|
|
@@ -1,11 +1,34 @@
|
|
|
1
1
|
import { EventEmitter } from "node:events";
|
|
2
|
+
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
3
|
+
import type { Transport } from "@modelcontextprotocol/sdk/shared/transport.js";
|
|
4
|
+
import { type JsonObject } from "./built-in-file-tools.js";
|
|
2
5
|
import type { ACodeRuntimeConfig } from "./types.js";
|
|
6
|
+
export interface ACodeMcpConnection {
|
|
7
|
+
serverName: string;
|
|
8
|
+
client: Client;
|
|
9
|
+
transport: Transport;
|
|
10
|
+
tools: ACodeMcpTool[];
|
|
11
|
+
}
|
|
12
|
+
interface ACodeMcpTool {
|
|
13
|
+
kind: "mcp";
|
|
14
|
+
serverName: string;
|
|
15
|
+
toolName: string;
|
|
16
|
+
exposedName: string;
|
|
17
|
+
description?: string;
|
|
18
|
+
inputSchema: JsonObject;
|
|
19
|
+
}
|
|
3
20
|
export declare class ACodeRuntime extends EventEmitter {
|
|
4
21
|
private readonly config;
|
|
5
22
|
private readonly hookBus;
|
|
6
23
|
private initialConversation;
|
|
7
24
|
private state;
|
|
8
25
|
private abortController;
|
|
26
|
+
/**
|
|
27
|
+
* 正在处理中的 memory 子 agent 跟踪表。
|
|
28
|
+
* key = memory URI,value = subId(用于防止同一 memory 被重复委托)。
|
|
29
|
+
* 子 agent 完成后通过 SubAgentManager 事件回调移除对应 URI。
|
|
30
|
+
*/
|
|
31
|
+
private readonly pendingMemorySubAgents;
|
|
9
32
|
private submitQueue;
|
|
10
33
|
private activeTurn;
|
|
11
34
|
private abortRequested;
|
|
@@ -29,6 +52,8 @@ export declare class ACodeRuntime extends EventEmitter {
|
|
|
29
52
|
*/
|
|
30
53
|
private readonly questionWaiters;
|
|
31
54
|
constructor(config: ACodeRuntimeConfig);
|
|
55
|
+
/** 获取当前已暴露的工具名称列表(供 SubAgentManager 记录) */
|
|
56
|
+
getAvailableTools(): string[];
|
|
32
57
|
private emitAcodeEvent;
|
|
33
58
|
/**
|
|
34
59
|
* 发射压缩子事件(phase 事件)到面板时间线。
|
|
@@ -168,6 +193,90 @@ export declare class ACodeRuntime extends EventEmitter {
|
|
|
168
193
|
private readChatCompletionStream;
|
|
169
194
|
private handleToolCalls;
|
|
170
195
|
private callMcpToolWithTimeout;
|
|
196
|
+
/**
|
|
197
|
+
* 将子 agent 终态通知转为 poll_message 格式的合成 DirectMessage。
|
|
198
|
+
* 主流程:构建符合 MCP poll_message 返回格式的 JSON 字符串。
|
|
199
|
+
*/
|
|
200
|
+
private static formatSubAgentCompletionAsPollResult;
|
|
201
|
+
/**
|
|
202
|
+
* 将子 agent 终态通知合并到已有的 MCP poll_message 返回结果中。
|
|
203
|
+
* 主流程:解析 MCP 返回的 JSON -> 将通知转为 DirectMessage 插入到 directMessages 前面 -> 重新序列化。
|
|
204
|
+
*/
|
|
205
|
+
private static mergeSubAgentCompletionsIntoMcpResult;
|
|
206
|
+
/**
|
|
207
|
+
* Memory 自动委托 sub-agent 完成一轮后的外部重新检查。
|
|
208
|
+
*
|
|
209
|
+
* 查询服务端 memory 真实状态(通过 MCP 工具直接调用,非 LLM 自报),
|
|
210
|
+
* 判断 sub-agent 是否真正完成了处理:
|
|
211
|
+
* - memory_file_change:检查每条 memory 的 memory_status 是否已回到 normal
|
|
212
|
+
* - memory_expiration:检查每条 memory 是否已续期(expiresAt 在未来)或已清理(read 返回 null)
|
|
213
|
+
* - memory_cleanup:检查 get_memory_stats 中对应类型/域是否仍 exceeded
|
|
214
|
+
*
|
|
215
|
+
* 若仍有未完成项,返回 { done: false, continueMessage } 包含 "经检查,未完成对xxx的处理,请继续"
|
|
216
|
+
* 及具体未完成列表,由 SubAgentManager 注入同一 sub-agent 的下一轮 submit。
|
|
217
|
+
*
|
|
218
|
+
* recheck 自身出错(MCP 连接不可用、工具调用超时等)时返回 { done: true },不阻塞 sub-agent 结束。
|
|
219
|
+
*/
|
|
220
|
+
private recheckMemoryDelegate;
|
|
221
|
+
/**
|
|
222
|
+
* 通过 MCP read_memory 工具读取单条 memory 记录。
|
|
223
|
+
* 注入 _aws_sub_agent=true 避免状态上报污染父 agent 时间线。
|
|
224
|
+
* 返回 null 表示 memory 不存在或读取失败。
|
|
225
|
+
*/
|
|
226
|
+
private readMemoryViaMcp;
|
|
227
|
+
/** recheck memory_file_change:检查 memory_status 是否仍为 updating */
|
|
228
|
+
private recheckMemoryFileChange;
|
|
229
|
+
/** recheck memory_expiration:检查 expiresAt 是否仍过期 或 memory_status 是否仍为 recalling */
|
|
230
|
+
private recheckMemoryExpiration;
|
|
231
|
+
/** recheck memory_cleanup:检查 get_memory_stats 中对应类型/域是否仍 exceeded */
|
|
232
|
+
private recheckMemoryCleanup;
|
|
233
|
+
/**
|
|
234
|
+
* 构造 memory 自动委托子 agent 的 prompt。
|
|
235
|
+
* 主流程:根据 delegate 类型(过期整理/文件变更更新)生成自包含指令。
|
|
236
|
+
*/
|
|
237
|
+
private buildMemoryDelegatePrompt;
|
|
238
|
+
/**
|
|
239
|
+
* 处理 poll_message 结果中的 memory 自动委托标记 (_acodeAutoDelegate)。
|
|
240
|
+
* 主流程:解析 MCP 返回 -> 识别标记 -> spawn 子 agent -> 返回简化结果。
|
|
241
|
+
* 非 ACode 运行时(无 subAgentManager)直接透传原结果,不受影响。
|
|
242
|
+
* 返回 null 表示全部消息已被委托,调用方应重新 poll_message 继续等待真正的消息。
|
|
243
|
+
*/
|
|
244
|
+
private processMemoryAutoDelegates;
|
|
245
|
+
/**
|
|
246
|
+
* poll_message MCP 工具调用的子 agent 完成事件 race 包装器。
|
|
247
|
+
*
|
|
248
|
+
* 主流程:
|
|
249
|
+
* 1. 先检查 completionQueue 中是否有已完成的子 agent -> 有则直接返回合成结果(不调 MCP)
|
|
250
|
+
* 2. 启动 MCP poll_message 调用与 waitForAnyCompletion 的 race
|
|
251
|
+
* 3. 子 agent 先完成 -> 返回合成结果(MCP 调用被放弃但仍在运行,下次 poll_message 会复用 pendingPollMessage)
|
|
252
|
+
* 4. MCP 先返回 -> 合并新完成的子 agent 事件后返回
|
|
253
|
+
*
|
|
254
|
+
* 设计说明:
|
|
255
|
+
* - MCP server 的 poll_message 内部有 while(true) 永久阻塞,只在有消息时返回
|
|
256
|
+
* - 子 agent 完成事件由 SubAgentManager 在同进程内产生,通过 completionQueue 传递
|
|
257
|
+
* - 当子 agent 先完成时,MCP 调用被放弃(Promise 不再被 await),MCP server 侧的
|
|
258
|
+
* pendingPollMessage 仍在运行,下次 poll_message 调用会通过 pendingPollMessage 复用
|
|
259
|
+
*/
|
|
260
|
+
private callPollMessageWithSubAgentRace;
|
|
261
|
+
/**
|
|
262
|
+
* 检查 poll_message 结果是否包含实际消息(directMessages 或 groupMessages 非空)。
|
|
263
|
+
* 用于循环中过滤空结果,确保 poll_message 只在有消息时返回。
|
|
264
|
+
*/
|
|
265
|
+
private pollResultHasMessages;
|
|
266
|
+
/**
|
|
267
|
+
* 在 memory 委托消息被全部处理后,等待一段时间再重新 poll_message。
|
|
268
|
+
*
|
|
269
|
+
* 背景:MCP doPollMessage 对 updating memory 每次都返回通知(无去重),
|
|
270
|
+
* 而 processMemoryAutoDelegates 因 URI 已在 pendingMemorySubAgents 中而返回 null,
|
|
271
|
+
* 导致 while(true) 无延迟重 poll,每轮触发 handleToolCall 的 reportToolUse/reportThinking
|
|
272
|
+
* 状态上报,引发"思考→MCP→跳过"快速循环,最终连接丢失。
|
|
273
|
+
*
|
|
274
|
+
* 等待策略:
|
|
275
|
+
* 1. 固定延迟 DELEGATE_REPOLL_DELAY_MS(5s),给子 agent 时间完成 memory 更新
|
|
276
|
+
* 2. 可被 runtime stop 中断(通过 createRuntimeStopWaiter)
|
|
277
|
+
* 3. 不消费 completionQueue(下一轮 takeCompletedSubAgents 会取到)
|
|
278
|
+
*/
|
|
279
|
+
private waitForDelegateRepoll;
|
|
171
280
|
/**
|
|
172
281
|
* Build a one-shot waiter that rejects long-running MCP calls when the runtime stops.
|
|
173
282
|
* Main flow: register a stop callback -> race it with the SDK call -> remove it after either side settles.
|
|
@@ -180,6 +289,16 @@ export declare class ACodeRuntime extends EventEmitter {
|
|
|
180
289
|
private notifyRuntimeStop;
|
|
181
290
|
private appendSyntheticMultimodalUserMessage;
|
|
182
291
|
private appendToolFailureResult;
|
|
292
|
+
/**
|
|
293
|
+
* 为子 agent 过滤共享 MCP 连接:只保留 memory 工具。
|
|
294
|
+
*
|
|
295
|
+
* 原 MCP server 进程通过 AWS_SUB_AGENT=true 限制子 agent 只能调用 memory 工具,
|
|
296
|
+
* 共享连接后绕过了该机制。此方法在 ACode runtime 层重新施加限制:
|
|
297
|
+
* - 复用同一 client/transport(不创建新连接)
|
|
298
|
+
* - 仅暴露 MEMORY_TOOL_NAMES 中的工具
|
|
299
|
+
* - 防止子 agent 调用 poll_message(与父 agent 冲突)、send_group 等
|
|
300
|
+
*/
|
|
301
|
+
private filterSharedMcpConnectionsForSubAgent;
|
|
183
302
|
private connectMcpServers;
|
|
184
303
|
private createMcpTransport;
|
|
185
304
|
/**
|
|
@@ -196,4 +315,5 @@ export declare class ACodeRuntime extends EventEmitter {
|
|
|
196
315
|
private extractProfileFromToolResult;
|
|
197
316
|
private disconnectMcpServers;
|
|
198
317
|
}
|
|
318
|
+
export {};
|
|
199
319
|
//# sourceMappingURL=runtime.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AA+
|
|
1
|
+
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"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"}
|