@migor/agentia 0.9.4 → 0.10.0
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/CHANGELOG.md +1280 -4
- package/README.en.md +61 -3
- package/README.md +66 -4
- package/dist/AGENTS.md +330 -45
- package/dist/container/container.js +21 -0
- package/dist/container/container.js.map +1 -1
- package/dist/core/limits.d.ts +101 -14
- package/dist/core/limits.js +103 -13
- package/dist/core/limits.js.map +1 -1
- package/dist/core/line-framing.d.ts +36 -0
- package/dist/core/line-framing.js +39 -0
- package/dist/core/line-framing.js.map +1 -0
- package/dist/core/message.d.ts +11 -0
- package/dist/core/run.d.ts +68 -4
- package/dist/core/run.js +27 -1
- package/dist/core/run.js.map +1 -1
- package/dist/core/schema.js +59 -8
- package/dist/core/schema.js.map +1 -1
- package/dist/core/timeout.d.ts +43 -1
- package/dist/core/timeout.js +76 -3
- package/dist/core/timeout.js.map +1 -1
- package/dist/core/tool.d.ts +25 -1
- package/dist/core/trace.d.ts +40 -1
- package/dist/core/trace.js +26 -0
- package/dist/core/trace.js.map +1 -1
- package/dist/engine/budget.js +14 -0
- package/dist/engine/budget.js.map +1 -1
- package/dist/engine/defer.d.ts +49 -0
- package/dist/engine/defer.js +72 -0
- package/dist/engine/defer.js.map +1 -0
- package/dist/engine/errors.d.ts +23 -1
- package/dist/engine/errors.js +24 -0
- package/dist/engine/errors.js.map +1 -1
- package/dist/engine/forwarded.d.ts +14 -5
- package/dist/engine/forwarded.js +4 -1
- package/dist/engine/forwarded.js.map +1 -1
- package/dist/engine/loop-result.d.ts +65 -7
- package/dist/engine/loop-result.js +24 -5
- package/dist/engine/loop-result.js.map +1 -1
- package/dist/engine/loop.d.ts +2 -0
- package/dist/engine/loop.js +157 -17
- package/dist/engine/loop.js.map +1 -1
- package/dist/engine/mcp-server-http.d.ts +2 -0
- package/dist/engine/mcp-server-http.js +215 -0
- package/dist/engine/mcp-server-http.js.map +1 -0
- package/dist/engine/mcp-server-stdio.d.ts +15 -0
- package/dist/engine/mcp-server-stdio.js +106 -0
- package/dist/engine/mcp-server-stdio.js.map +1 -0
- package/dist/engine/mcp-server.d.ts +134 -0
- package/dist/engine/mcp-server.js +232 -0
- package/dist/engine/mcp-server.js.map +1 -0
- package/dist/engine/menu-drift.d.ts +34 -0
- package/dist/engine/menu-drift.js +81 -0
- package/dist/engine/menu-drift.js.map +1 -0
- package/dist/engine/policy.d.ts +2 -1
- package/dist/engine/policy.js +7 -1
- package/dist/engine/policy.js.map +1 -1
- package/dist/engine/replay.d.ts +2 -1
- package/dist/engine/replay.js +3 -2
- package/dist/engine/replay.js.map +1 -1
- package/dist/engine/resume-input.d.ts +10 -0
- package/dist/engine/resume-input.js +11 -0
- package/dist/engine/resume-input.js.map +1 -1
- package/dist/engine/run-config.d.ts +26 -2
- package/dist/engine/run-config.js +60 -0
- package/dist/engine/run-config.js.map +1 -1
- package/dist/engine/spec.d.ts +33 -4
- package/dist/engine/spec.js.map +1 -1
- package/dist/engine/tool-context.d.ts +10 -5
- package/dist/engine/tool-context.js +5 -1
- package/dist/engine/tool-context.js.map +1 -1
- package/dist/engine/tracer.d.ts +43 -5
- package/dist/engine/tracer.js +73 -10
- package/dist/engine/tracer.js.map +1 -1
- package/dist/engine/trimming.js +28 -2
- package/dist/engine/trimming.js.map +1 -1
- package/dist/engine/turn.d.ts +60 -3
- package/dist/engine/turn.js +180 -71
- package/dist/engine/turn.js.map +1 -1
- package/dist/engine/types.d.ts +89 -3
- package/dist/engine/types.js +38 -2
- package/dist/engine/types.js.map +1 -1
- package/dist/eval/export.d.ts +48 -0
- package/dist/eval/export.js +146 -0
- package/dist/eval/export.js.map +1 -0
- package/dist/eval/harvest.js +7 -2
- package/dist/eval/harvest.js.map +1 -1
- package/dist/index.d.ts +8 -5
- package/dist/index.js +6 -1
- package/dist/index.js.map +1 -1
- package/dist/integrations/adapter-options.d.ts +22 -0
- package/dist/integrations/adapter-options.js +51 -0
- package/dist/integrations/adapter-options.js.map +1 -1
- package/dist/integrations/anthropic.d.ts +4 -2
- package/dist/integrations/anthropic.js +27 -27
- package/dist/integrations/anthropic.js.map +1 -1
- package/dist/integrations/file-sink.d.ts +20 -0
- package/dist/integrations/file-sink.js +27 -0
- package/dist/integrations/file-sink.js.map +1 -0
- package/dist/integrations/mcp-http.d.ts +3 -3
- package/dist/integrations/mcp-http.js +1 -1
- package/dist/integrations/mcp-http.js.map +1 -1
- package/dist/integrations/mcp-protocol.d.ts +115 -0
- package/dist/integrations/mcp-protocol.js +69 -0
- package/dist/integrations/mcp-protocol.js.map +1 -0
- package/dist/integrations/mcp-stdio.d.ts +3 -3
- package/dist/integrations/mcp-stdio.js +17 -3
- package/dist/integrations/mcp-stdio.js.map +1 -1
- package/dist/integrations/mcp.d.ts +6 -95
- package/dist/integrations/mcp.js +24 -66
- package/dist/integrations/mcp.js.map +1 -1
- package/dist/integrations/metrics-otlp.js +52 -7
- package/dist/integrations/metrics-otlp.js.map +1 -1
- package/dist/integrations/metrics-render.d.ts +15 -0
- package/dist/integrations/metrics-render.js +79 -2
- package/dist/integrations/metrics-render.js.map +1 -1
- package/dist/integrations/metrics-state.d.ts +99 -1
- package/dist/integrations/metrics-state.js +128 -4
- package/dist/integrations/metrics-state.js.map +1 -1
- package/dist/integrations/metrics.d.ts +62 -6
- package/dist/integrations/metrics.js +49 -8
- package/dist/integrations/metrics.js.map +1 -1
- package/dist/integrations/openai.js +9 -31
- package/dist/integrations/openai.js.map +1 -1
- package/dist/integrations/otlp.d.ts +3 -3
- package/dist/integrations/report.d.ts +7 -0
- package/dist/integrations/report.js +20 -1
- package/dist/integrations/report.js.map +1 -1
- package/dist/runtime/memory.d.ts +61 -1
- package/dist/runtime/memory.js +47 -7
- package/dist/runtime/memory.js.map +1 -1
- package/dist/runtime/run.d.ts +12 -2
- package/dist/runtime/run.js +126 -17
- package/dist/runtime/run.js.map +1 -1
- package/dist/store/fsStore.js +10 -4
- package/dist/store/fsStore.js.map +1 -1
- package/dist/store/record.d.ts +41 -0
- package/dist/store/record.js +54 -0
- package/dist/store/record.js.map +1 -0
- package/dist/store/redisStore.d.ts +24 -1
- package/dist/store/redisStore.js +42 -7
- package/dist/store/redisStore.js.map +1 -1
- package/dist/store/sqliteStore.d.ts +23 -0
- package/dist/store/sqliteStore.js +103 -8
- package/dist/store/sqliteStore.js.map +1 -1
- package/dist/store/store.d.ts +65 -2
- package/dist/store/store.js +5 -2
- package/dist/store/store.js.map +1 -1
- package/dist/toolkit/capability-cycles.d.ts +50 -0
- package/dist/toolkit/capability-cycles.js +88 -0
- package/dist/toolkit/capability-cycles.js.map +1 -0
- package/dist/toolkit/capability-slice.d.ts +86 -0
- package/dist/toolkit/capability-slice.js +98 -0
- package/dist/toolkit/capability-slice.js.map +1 -0
- package/dist/toolkit/module.d.ts +7 -1
- package/dist/toolkit/module.js +65 -32
- package/dist/toolkit/module.js.map +1 -1
- package/dist/transport/approval-policy.d.ts +1 -1
- package/dist/transport/approval-policy.js +8 -4
- package/dist/transport/approval-policy.js.map +1 -1
- package/dist/transport/approval-supervisor.d.ts +73 -0
- package/dist/transport/approval-supervisor.js +252 -0
- package/dist/transport/approval-supervisor.js.map +1 -0
- package/dist/transport/async.d.ts +159 -56
- package/dist/transport/async.js +627 -269
- package/dist/transport/async.js.map +1 -1
- package/dist/transport/drain-gate.d.ts +6 -2
- package/dist/transport/drain-gate.js +14 -2
- package/dist/transport/drain-gate.js.map +1 -1
- package/dist/transport/http-endpoints.d.ts +151 -0
- package/dist/transport/http-endpoints.js +480 -0
- package/dist/transport/http-endpoints.js.map +1 -0
- package/dist/transport/http-io.d.ts +66 -0
- package/dist/transport/http-io.js +145 -0
- package/dist/transport/http-io.js.map +1 -0
- package/dist/transport/http-route.d.ts +10 -3
- package/dist/transport/http-route.js +18 -3
- package/dist/transport/http-route.js.map +1 -1
- package/dist/transport/http-shapes.d.ts +11 -0
- package/dist/transport/http-shapes.js +31 -1
- package/dist/transport/http-shapes.js.map +1 -1
- package/dist/transport/http.d.ts +22 -35
- package/dist/transport/http.js +98 -476
- package/dist/transport/http.js.map +1 -1
- package/dist/transport/owner-id.d.ts +29 -0
- package/dist/transport/owner-id.js +46 -0
- package/dist/transport/owner-id.js.map +1 -0
- package/dist/transport/owner-liveness.d.ts +8 -0
- package/dist/transport/owner-liveness.js +56 -0
- package/dist/transport/owner-liveness.js.map +1 -0
- package/dist/transport/resume-policy.d.ts +48 -10
- package/dist/transport/resume-policy.js +25 -10
- package/dist/transport/resume-policy.js.map +1 -1
- package/dist/transport/resume-scanner.d.ts +55 -0
- package/dist/transport/resume-scanner.js +219 -0
- package/dist/transport/resume-scanner.js.map +1 -0
- package/dist/transport/scheduler.js +9 -23
- package/dist/transport/scheduler.js.map +1 -1
- package/dist/transport/signal-supervisor.d.ts +80 -0
- package/dist/transport/signal-supervisor.js +129 -0
- package/dist/transport/signal-supervisor.js.map +1 -0
- package/dist/transport/slot-pool.d.ts +9 -1
- package/dist/transport/slot-pool.js +9 -1
- package/dist/transport/slot-pool.js.map +1 -1
- package/dist/transport/task-events.d.ts +34 -3
- package/dist/transport/task-events.js +93 -5
- package/dist/transport/task-events.js.map +1 -1
- package/dist/transport/wake-policy.d.ts +50 -0
- package/dist/transport/wake-policy.js +43 -0
- package/dist/transport/wake-policy.js.map +1 -0
- package/package.json +14 -4
package/dist/engine/policy.js
CHANGED
|
@@ -35,8 +35,14 @@ export function createBudgetPolicy(opts = {}) {
|
|
|
35
35
|
return current;
|
|
36
36
|
if (info.iteration - lastCompactAt < compactEvery)
|
|
37
37
|
return current;
|
|
38
|
+
// ⚠️ 滞回记的是「上次**成功**压缩的回合」(2026-09-28 修):原实现在 `compactMessages(...)`
|
|
39
|
+
// **之前**就写 `lastCompactAt` —— 摘要器走模型(429 / 超时都常见),压缩失败时额度却已被
|
|
40
|
+
// 烧掉,于是「这一回合没压成」还连带让后面 `compactEvery - 1` 个回合都不再尝试。
|
|
41
|
+
// 失败不记账 ⇒ 下一回合自然重试。代价要说清:**摘要器持续失败时每回合都会再调一次**
|
|
42
|
+
// (每次多一次失败的模型往返);要抑制请在 `summarize` 里自己退避,别靠滞回额度兜。
|
|
43
|
+
const compacted = await compactMessages(current, { keepRecent, summarize });
|
|
38
44
|
lastCompactAt = info.iteration;
|
|
39
|
-
return
|
|
45
|
+
return compacted;
|
|
40
46
|
},
|
|
41
47
|
};
|
|
42
48
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"policy.js","sourceRoot":"","sources":["../../src/engine/policy.ts"],"names":[],"mappings":"AACA,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,qBAAqB,EACrB,aAAa,GACd,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"policy.js","sourceRoot":"","sources":["../../src/engine/policy.ts"],"names":[],"mappings":"AACA,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,qBAAqB,EACrB,aAAa,GACd,MAAM,eAAe,CAAC;AAwCvB,MAAM,UAAU,kBAAkB,CAAC,IAAI,GAAwB,EAAE;IAC/D,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,IAAI,MAAM,CAAC;IACjD,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC;IACtD,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,aAAa,IAAI,CAAC,CAAC,CAAC;IAC3D,MAAM,QAAQ,GAAG,IAAI,CAAC,cAAc,IAAI,qBAAqB,CAAC;IAC9D,MAAM,iBAAiB,GAAG,IAAI,CAAC,iBAAiB,IAAI,IAAI,CAAC;IACzD,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;IACjC,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,YAAY,IAAI,CAAC,CAAC,CAAC;IACzD,IAAI,aAAa,GAAG,MAAM,CAAC,iBAAiB,CAAC;IAC7C,4CAA4C;IAC5C,MAAM,WAAW,GAAG,kBAAkB,CAAC,QAAQ,CAAC,CAAC;IAEjD,OAAO;QACL,YAAY;QACZ,yEAAyE;QACzE,0DAA0D;QAC1D,4DAA4D;QAC5D,iBAAiB;QACjB,MAAM,EAAE,GAAG,EAAE,CAAC,kBAAkB,CAAC,IAAI,CAAC;QACtC,KAAK,CAAC,UAAU,CAAC,QAAQ,EAAE,IAAI;YAC7B,IAAI,WAAW,CAAC,QAAQ,CAAC,IAAI,YAAY;gBAAE,OAAO,QAAQ,CAAC;YAE3D,oDAAoD;YACpD,IAAI,OAAO,GAAG,QAAQ,CAAC;YACvB,IAAI,iBAAiB,EAAE,CAAC;gBACtB,MAAM,OAAO,GAAG,aAAa,CAAC,OAAO,EAAE,EAAE,aAAa,EAAE,CAAC,CAAC;gBAC1D,IAAI,OAAO,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;oBACpC,OAAO,GAAG,OAAO,CAAC;oBAClB,IAAI,WAAW,CAAC,OAAO,CAAC,IAAI,YAAY;wBAAE,OAAO,OAAO,CAAC;gBAC3D,CAAC;YACH,CAAC;YAED,0BAA0B;YAC1B,IAAI,CAAC,SAAS;gBAAE,OAAO,OAAO,CAAC;YAC/B,IAAI,IAAI,CAAC,SAAS,GAAG,aAAa,GAAG,YAAY;gBAAE,OAAO,OAAO,CAAC;YAClE,oEAAoE;YACpE,6DAA6D;YAC7D,oDAAoD;YACpD,+CAA+C;YAC/C,kDAAkD;YAClD,MAAM,SAAS,GAAG,MAAM,eAAe,CAAC,OAAO,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC,CAAC;YAC5E,aAAa,GAAG,IAAI,CAAC,SAAS,CAAC;YAC/B,OAAO,SAAS,CAAC;QACnB,CAAC;KACF,CAAC;AACJ,CAAC"}
|
package/dist/engine/replay.d.ts
CHANGED
|
@@ -25,7 +25,8 @@ import type { Trace } from '../core/trace.js';
|
|
|
25
25
|
* 可直接作为 Messages API 的 messages 喂回模型(末条为 user 是硬要求:
|
|
26
26
|
* 以 assistant 收尾即 prefill,缺省模型上 400)。
|
|
27
27
|
*
|
|
28
|
-
* 注意:trace
|
|
28
|
+
* 注意:trace **缺省**不记录 assistant 文本(llm.turn 只记 usage/事件;opt-in 例外见
|
|
29
|
+
* `RunAgentOptions.traceContent: 'full'`,R8-P3a),还原的
|
|
29
30
|
* assistant 消息以标注文本占位,非逐字原文。trace 同样不记 run 的原始输入,
|
|
30
31
|
* 故重放的首尾说明性 user 均为合成(这一有损边界对 forkMessages 同样成立)。
|
|
31
32
|
*
|
package/dist/engine/replay.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { TOOL_INPUT_EVENT, TOOL_OUTPUT_EVENT } from '../core/trace.js';
|
|
1
2
|
import { stringifySafe, truncateWithMark } from '../core/json.js';
|
|
2
3
|
const DEFAULT_MAX_EVENT_CHARS = 2000;
|
|
3
4
|
export function traceToMessages(trace, opts = {}) {
|
|
@@ -54,8 +55,8 @@ function expandTurns(turns, byId, includeToolIO, maxChars) {
|
|
|
54
55
|
const content = [{ type: 'text', text: note }];
|
|
55
56
|
const pairs = [];
|
|
56
57
|
if (includeToolIO) {
|
|
57
|
-
const inputs = eventsOf(turn,
|
|
58
|
-
const outputs = eventsOf(turn,
|
|
58
|
+
const inputs = eventsOf(turn, TOOL_INPUT_EVENT);
|
|
59
|
+
const outputs = eventsOf(turn, TOOL_OUTPUT_EVENT);
|
|
59
60
|
const used = new Set();
|
|
60
61
|
for (const input of inputs) {
|
|
61
62
|
// 配对优先级:同 id 精确匹配 > 同名最早未配对 > 最早未配对。
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"replay.js","sourceRoot":"","sources":["../../src/engine/replay.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"replay.js","sourceRoot":"","sources":["../../src/engine/replay.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { MessageParam, ToolUseBlock } from '../core/message.js';
|
|
2
|
+
import type { TaskEvent } from '../core/run.js';
|
|
2
3
|
/**
|
|
3
4
|
* Agentia —— 续跑入口的**读取件**(engine/loop.ts 的拆分第三步)。
|
|
4
5
|
*
|
|
@@ -24,3 +25,12 @@ import type { MessageParam, ToolUseBlock } from '../core/message.js';
|
|
|
24
25
|
export declare function tailToolUses(messages: MessageParam[]): ToolUseBlock[];
|
|
25
26
|
/** 取 MessageParam(请求侧)里的文本块拼成的文本(恢复模式收尾时用) */
|
|
26
27
|
export declare function textOfParam(message: MessageParam): string;
|
|
28
|
+
/**
|
|
29
|
+
* run 事件 → **一条 user 文本消息**(2026-09-28 ⑥ 的 B1:外部永远不能构造 block ——
|
|
30
|
+
* 进来的只有文本,投毒面只到「内容注入」为止)。
|
|
31
|
+
*
|
|
32
|
+
* `eventId` **不进正文**:它是投递簿记(幂等去重依据),不是内容 —— 模型不需要知道
|
|
33
|
+
* 去重键,把它放进去只会给「同一件事换 id 再投一次」留语义噪音。留痕走 trace
|
|
34
|
+
* (`task.event` 事件,见 loop.ts 的注入点),不进消息。
|
|
35
|
+
*/
|
|
36
|
+
export declare function renderTaskEvent(ev: TaskEvent): MessageParam;
|
|
@@ -36,4 +36,15 @@ export function textOfParam(message) {
|
|
|
36
36
|
.map((b) => b.text ?? '')
|
|
37
37
|
.join('\n');
|
|
38
38
|
}
|
|
39
|
+
/**
|
|
40
|
+
* run 事件 → **一条 user 文本消息**(2026-09-28 ⑥ 的 B1:外部永远不能构造 block ——
|
|
41
|
+
* 进来的只有文本,投毒面只到「内容注入」为止)。
|
|
42
|
+
*
|
|
43
|
+
* `eventId` **不进正文**:它是投递簿记(幂等去重依据),不是内容 —— 模型不需要知道
|
|
44
|
+
* 去重键,把它放进去只会给「同一件事换 id 再投一次」留语义噪音。留痕走 trace
|
|
45
|
+
* (`task.event` 事件,见 loop.ts 的注入点),不进消息。
|
|
46
|
+
*/
|
|
47
|
+
export function renderTaskEvent(ev) {
|
|
48
|
+
return { role: 'user', content: `[事件 type=${ev.type}]\n${ev.payload}` };
|
|
49
|
+
}
|
|
39
50
|
//# sourceMappingURL=resume-input.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resume-input.js","sourceRoot":"","sources":["../../src/engine/resume-input.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"resume-input.js","sourceRoot":"","sources":["../../src/engine/resume-input.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;GAiBG;AAEH;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,QAAwB;IACnD,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC3C,IAAI,IAAI,EAAE,IAAI,KAAK,WAAW,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,EAAE,CAAC;IAC1E,4DAA4D;IAC5D,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAqB,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;AAC9E,CAAC;AAED,8CAA8C;AAC9C,MAAM,UAAU,WAAW,CAAC,OAAqB;IAC/C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC;QACjC,OAAO,OAAO,OAAO,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;IACpE,OAAO,OAAO,CAAC,OAAO;SACnB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC;SAChC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAE,CAAuB,CAAC,IAAI,IAAI,EAAE,CAAC;SAC/C,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,eAAe,CAAC,EAAa;IAC3C,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC,IAAI,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC;AAC1E,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { JsonSchema } from '../core/tool.js';
|
|
2
|
-
import type { RunAgentOptions } from './types.js';
|
|
1
|
+
import type { JsonSchema, ModelClient } from '../core/tool.js';
|
|
2
|
+
import type { ModelFallbackLink, RunAgentOptions } from './types.js';
|
|
3
3
|
import type { TraceLimits } from './tracer.js';
|
|
4
4
|
/**
|
|
5
5
|
* Agentia —— run 生效旋钮:**缺省解析 + 快照编码**(spec §5 / §9 G3)。
|
|
@@ -21,6 +21,30 @@ export declare function resolveDefaultModel(over?: string): string;
|
|
|
21
21
|
/** 缺省单次 maxTokens / 循环上限:runAgent 与 runAgentScoped 共用,避免两处各写一遍漂移。 */
|
|
22
22
|
export declare const DEFAULT_MAX_TOKENS = 64000;
|
|
23
23
|
export declare const DEFAULT_MAX_ITERATIONS = 40;
|
|
24
|
+
/** fallback 链的已解析形态(每环的 client 已就位) */
|
|
25
|
+
export interface ResolvedModelLink {
|
|
26
|
+
model: string;
|
|
27
|
+
client: ModelClient;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* 解析本 run 的模型链(R8-P2):主环 + `fallbacks` 逐环(环的 client 缺省复用主环的)。
|
|
31
|
+
*
|
|
32
|
+
* 校验在**这里**(run 入口,每次 run 都过 —— 含崩溃续跑读回的那份 options):
|
|
33
|
+
* - 环必须是对象、`model` 必须是非空字符串 —— 否则 TypeError(响亮失败,不静默跳过坏环);
|
|
34
|
+
* - 环的 `client`(若给)必须鸭子类型满足 `messages.stream` 是函数 —— 持久化 store
|
|
35
|
+
* 反序列化回来的空壳(`{}`)在这里变成可读报错,而不是发请求时才爆。
|
|
36
|
+
*/
|
|
37
|
+
export declare function resolveModelChain(args: {
|
|
38
|
+
model: string;
|
|
39
|
+
client: ModelClient;
|
|
40
|
+
fallbacks?: ModelFallbackLink[] | undefined;
|
|
41
|
+
}): ResolvedModelLink[];
|
|
42
|
+
/**
|
|
43
|
+
* 校验归因标签(R8-P4):键必须非空、值必须是字符串(**允许空串** —— 「租户未知」
|
|
44
|
+
* 是有意义的值)。坏值在 run 入口抛 TypeError(与 resolveModelChain 同一个
|
|
45
|
+
* 「配置错响亮失败」的落点),不静默丢键。
|
|
46
|
+
*/
|
|
47
|
+
export declare function validateLabels(labels: Record<string, string> | undefined): void;
|
|
24
48
|
/**
|
|
25
49
|
* 生效配置快照(G3):把本 run 实际生效的旋钮整理成 run 根的 `config.*` attributes。
|
|
26
50
|
* 只放标量(OTLP/日志/看板都能直接吃);缺省值也记,这样"没配"与"配了缺省值"可区分于
|
|
@@ -23,6 +23,54 @@ export function resolveDefaultModel(over) {
|
|
|
23
23
|
/** 缺省单次 maxTokens / 循环上限:runAgent 与 runAgentScoped 共用,避免两处各写一遍漂移。 */
|
|
24
24
|
export const DEFAULT_MAX_TOKENS = 64_000;
|
|
25
25
|
export const DEFAULT_MAX_ITERATIONS = 40;
|
|
26
|
+
/**
|
|
27
|
+
* 解析本 run 的模型链(R8-P2):主环 + `fallbacks` 逐环(环的 client 缺省复用主环的)。
|
|
28
|
+
*
|
|
29
|
+
* 校验在**这里**(run 入口,每次 run 都过 —— 含崩溃续跑读回的那份 options):
|
|
30
|
+
* - 环必须是对象、`model` 必须是非空字符串 —— 否则 TypeError(响亮失败,不静默跳过坏环);
|
|
31
|
+
* - 环的 `client`(若给)必须鸭子类型满足 `messages.stream` 是函数 —— 持久化 store
|
|
32
|
+
* 反序列化回来的空壳(`{}`)在这里变成可读报错,而不是发请求时才爆。
|
|
33
|
+
*/
|
|
34
|
+
export function resolveModelChain(args) {
|
|
35
|
+
const chain = [{ model: args.model, client: args.client }];
|
|
36
|
+
for (const [i, link] of (args.fallbacks ?? []).entries()) {
|
|
37
|
+
const where = `fallbacks[${i}]`;
|
|
38
|
+
if (typeof link !== 'object' || link === null) {
|
|
39
|
+
throw new TypeError(`${where} 必须是 { model, client? } 对象,收到 ${String(link)}`);
|
|
40
|
+
}
|
|
41
|
+
if (typeof link.model !== 'string' || link.model.trim() === '') {
|
|
42
|
+
throw new TypeError(`${where}.model 必须是非空字符串,收到 ${JSON.stringify(link.model)}`);
|
|
43
|
+
}
|
|
44
|
+
const client = link.client ?? args.client;
|
|
45
|
+
const stream = client?.messages?.stream;
|
|
46
|
+
if (typeof stream !== 'function') {
|
|
47
|
+
throw new TypeError(`${where}.client 不满足 ModelClient 契约(messages.stream 不是函数)—— ` +
|
|
48
|
+
'常见原因:异步任务的 options 经持久化 store JSON 往返后 client 变成空壳;' +
|
|
49
|
+
'跨重启仍成立的链请只写 model(client 由 runner/应用级配置兜住)');
|
|
50
|
+
}
|
|
51
|
+
chain.push({ model: link.model, client });
|
|
52
|
+
}
|
|
53
|
+
return chain;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* 校验归因标签(R8-P4):键必须非空、值必须是字符串(**允许空串** —— 「租户未知」
|
|
57
|
+
* 是有意义的值)。坏值在 run 入口抛 TypeError(与 resolveModelChain 同一个
|
|
58
|
+
* 「配置错响亮失败」的落点),不静默丢键。
|
|
59
|
+
*/
|
|
60
|
+
export function validateLabels(labels) {
|
|
61
|
+
if (labels === undefined)
|
|
62
|
+
return;
|
|
63
|
+
if (typeof labels !== 'object' || labels === null || Array.isArray(labels)) {
|
|
64
|
+
throw new TypeError(`labels 必须是 Record<string, string>,收到 ${JSON.stringify(labels)}`);
|
|
65
|
+
}
|
|
66
|
+
for (const [k, v] of Object.entries(labels)) {
|
|
67
|
+
if (k.trim() === '')
|
|
68
|
+
throw new TypeError('labels 的键不能为空字符串');
|
|
69
|
+
if (typeof v !== 'string') {
|
|
70
|
+
throw new TypeError(`labels.${k} 必须是字符串,收到 ${JSON.stringify(v)}`);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
26
74
|
/**
|
|
27
75
|
* 生效配置快照(G3):把本 run 实际生效的旋钮整理成 run 根的 `config.*` attributes。
|
|
28
76
|
* 只放标量(OTLP/日志/看板都能直接吃);缺省值也记,这样"没配"与"配了缺省值"可区分于
|
|
@@ -81,6 +129,18 @@ options) {
|
|
|
81
129
|
const overridden = options.priceOverrides ? Object.keys(options.priceOverrides) : [];
|
|
82
130
|
if (overridden.length > 0)
|
|
83
131
|
out['config.priceOverrides'] = overridden.sort().join(',');
|
|
132
|
+
// fallback 链(R8-P2):只记备用模型名(client 是对象,不可序列化;主模型在 config.model)
|
|
133
|
+
if (options.fallbacks && options.fallbacks.length > 0) {
|
|
134
|
+
out['config.fallbacks'] = options.fallbacks.map((l) => l.model).join(',');
|
|
135
|
+
}
|
|
136
|
+
// assistant 文本记录(R8-P3a):只在显式开启时记(缺省不记 = 没有这个键)
|
|
137
|
+
if (options.traceContent === 'full')
|
|
138
|
+
out['config.traceContent'] = 'full';
|
|
139
|
+
// 归因标签(R8-P4):只记**键名**(值可能含租户标识,配置快照不该复制它 ——
|
|
140
|
+
// 值本体在 labels.* 属性里,想看的人去看那里)
|
|
141
|
+
if (options.labels && Object.keys(options.labels).length > 0) {
|
|
142
|
+
out['config.labels'] = Object.keys(options.labels).sort().join(',');
|
|
143
|
+
}
|
|
84
144
|
if (options.resultSchema)
|
|
85
145
|
out['config.resultSchema'] = true;
|
|
86
146
|
return out;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-config.js","sourceRoot":"","sources":["../../src/engine/run-config.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAI1C;;;;;;;;;;GAUG;AAEH;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAa;IAC/C,IAAI,IAAI;QAAE,OAAO,IAAI,CAAC;IACtB,OAAO,OAAO,CAAC,GAAG,CAAC,aAAa,EAAE,IAAI,EAAE,IAAI,eAAe,CAAC;AAC9D,CAAC;AAED,qEAAqE;AACrE,MAAM,CAAC,MAAM,kBAAkB,GAAG,MAAM,CAAC;AACzC,MAAM,CAAC,MAAM,sBAAsB,GAAG,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"run-config.js","sourceRoot":"","sources":["../../src/engine/run-config.ts"],"names":[],"mappings":"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"}
|
package/dist/engine/spec.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type { MessageParam } from '../core/message.js';
|
|
2
2
|
import type { AgentTool, ApprovalDecision, ModelClient, ModelPricing } from '../core/tool.js';
|
|
3
3
|
import type { BlackboardSeed } from '../core/blackboard.js';
|
|
4
|
+
import type { TaskEvent } from '../core/run.js';
|
|
4
5
|
import type { TraceContext, TraceRecordEvent } from '../core/trace.js';
|
|
5
|
-
import type { ContextPolicy } from './types.js';
|
|
6
|
+
import type { ContextPolicy, ModelFallbackLink } from './types.js';
|
|
6
7
|
import type { RetryOptions } from './retry.js';
|
|
7
8
|
import type { TraceLimits } from './tracer.js';
|
|
8
9
|
/**
|
|
@@ -33,8 +34,10 @@ export interface RunInvocationOptions {
|
|
|
33
34
|
idempotencyKey?: string;
|
|
34
35
|
/**
|
|
35
36
|
* **记账的数量上限**(spec §9.4 的答案里「让少记了数据可数」那一半):整条 trace 的
|
|
36
|
-
*
|
|
37
|
-
*
|
|
37
|
+
* 事件总数上限,超限即停止记账并在 run 根留**两笔** `trace.truncated` ——
|
|
38
|
+
* 起点标记 `{ limit }`(断点在这里)+ 收尾摘要 `{ droppedEvents, limit }`(丢了多少)
|
|
39
|
+
* —— 缺口位置可预测(尾巴)、且有计数 ⇒ 可解释。两笔**同时**进交付的 trace 与增量流
|
|
40
|
+
* (见 `TraceLimits`:折叠契约在截断下无例外成立)。
|
|
38
41
|
*
|
|
39
42
|
* 与 `maxEventChars`(单个事件**正文长度**)正交:一个管「多长」、一个管「多少」,
|
|
40
43
|
* 各有各的家,两个都「不设 = 不限」。缺省**不设** —— 全量记账是本框架的承诺,
|
|
@@ -72,6 +75,24 @@ export interface RunInvocationOptions {
|
|
|
72
75
|
maxTotalTokens?: number;
|
|
73
76
|
/** 成本硬管控:累计成本(美元)上限;依赖模型在价格表内,见 createBudgetGuard */
|
|
74
77
|
maxCostUsd?: number;
|
|
78
|
+
/**
|
|
79
|
+
* 模型 fallback 链(R8-P2;语义见 `RunAgentOptions.fallbacks`)。
|
|
80
|
+
* ⚠️ 序列化边界:链环里的 `client` 是进程内对象,随 `TaskRecord` 落库会丢 ——
|
|
81
|
+
* 崩溃续跑读回的是空壳,run 入口会响亮抛 TypeError(鸭子类型校验)。要跨重启仍成立
|
|
82
|
+
* 的链只写 `model`(client 由 runner/应用级配置兜住),或干脆只在应用/run 级配置。
|
|
83
|
+
*/
|
|
84
|
+
fallbacks?: ModelFallbackLink[];
|
|
85
|
+
/**
|
|
86
|
+
* opt-in 记录 assistant 文本进 llm.turn span 的 `output.text`(R8-P3a;
|
|
87
|
+
* 语义与代价见 `RunAgentOptions.traceContent`)。可序列化(字符串枚举),异步任务
|
|
88
|
+
* 随 TaskRecord 落库、续跑不丢 —— 与 fallbacks 环里的 client 不同。
|
|
89
|
+
*/
|
|
90
|
+
traceContent?: 'full';
|
|
91
|
+
/**
|
|
92
|
+
* 租户/业务维度归因标签(R8-P4;语义与边界见 `RunAgentOptions.labels`)。
|
|
93
|
+
* 可序列化(字符串字典),异步任务随 TaskRecord 落库、续跑不丢。
|
|
94
|
+
*/
|
|
95
|
+
labels?: Record<string, string>;
|
|
75
96
|
/** 价格表覆盖/追加($/1M tokens);见 RunAgentOptions.priceOverrides */
|
|
76
97
|
priceOverrides?: Record<string, ModelPricing>;
|
|
77
98
|
/** 单个工具执行超时(毫秒);超时该条 tool_result 记 is_error,不杀 run */
|
|
@@ -88,7 +109,15 @@ export interface RunInvocationOptions {
|
|
|
88
109
|
*/
|
|
89
110
|
maxEventChars?: number | false;
|
|
90
111
|
/**
|
|
91
|
-
*
|
|
112
|
+
* 挂起期间投递的事件(2026-09-28 ⑥,run 事件投入口):随 `TaskRecord.pendingEvents`
|
|
113
|
+
* 落库(纯数据、可序列化,重启不丢),续跑段由引擎在**未决 tool_use 解决之后**
|
|
114
|
+
* 渲染成 user 文本消息注入消息流(为什么不是宿主直接追加到消息末尾:续跑判定
|
|
115
|
+
* 只认历史**末尾一条**,追加 user 消息会把续跑判成新对话 —— 见 engine/loop.ts)。
|
|
116
|
+
* 手工续跑「assistant 结尾带 tool_use」的消息历史时也可直接给 `app.run`。
|
|
117
|
+
*/
|
|
118
|
+
events?: TaskEvent[];
|
|
119
|
+
/**
|
|
120
|
+
* 人工审批决定(HITL):以 tool_use_id 为键。恢复 `suspended` 任务时由
|
|
92
121
|
* 异步宿主随记录传入(纯数据、可序列化,随 `TaskRecord` 落库);手工续跑
|
|
93
122
|
* 「assistant 结尾带 tool_use」的消息历史时也可直接给 `app.run`。
|
|
94
123
|
*/
|
package/dist/engine/spec.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spec.js","sourceRoot":"","sources":["../../src/engine/spec.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"spec.js","sourceRoot":"","sources":["../../src/engine/spec.ts"],"names":[],"mappings":"AAyJA;;;;;;;;GAQG;AACH,MAAM,OAAO,cAAe,SAAQ,KAAK;IACvC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;IAC/B,CAAC;CACF;AAED,wCAAwC;AACxC,MAAM,UAAU,iBAAiB,CAAC,KAAyB;IACzD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,mDAAmD;QACnD,IAAI,CAAC,KAAK;YAAE,MAAM,IAAI,cAAc,CAAC,kBAAkB,CAAC,CAAC;QACzD,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;IAC5C,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,MAAM,IAAI,cAAc,CAAC,kBAAkB,CAAC,CAAC;QACrE,OAAO,KAAuB,CAAC;IACjC,CAAC;IACD,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACvC,MAAM,CAAC,GAAG,KAAiE,CAAC;QAC5E,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC9B,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC;gBAAE,MAAM,IAAI,cAAc,CAAC,kBAAkB,CAAC,CAAC;YAC1E,OAAO,CAAC,CAAC,QAA0B,CAAC;QACtC,CAAC;QACD,IAAI,OAAO,CAAC,CAAC,MAAM,KAAK,QAAQ,IAAI,CAAC,CAAC,MAAM;YAAE,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;QAC3F,IAAI,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,CAAC,IAAI;YAAE,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACvF,CAAC;IACD,MAAM,IAAI,cAAc,CAAC,cAAc,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;AACjF,CAAC"}
|
|
@@ -2,15 +2,18 @@
|
|
|
2
2
|
* 单工具执行的**上下文装配**(纯):把引擎侧的取值摊成交给工具的 `ToolRunContext`。
|
|
3
3
|
*
|
|
4
4
|
* 从 turn.ts 的 executeOneTool 里外移(2026-09-20,turn 拆分第三步)。这段全部是搬运,但它
|
|
5
|
-
*
|
|
5
|
+
* **不是无害的样板**:十处条件展开里每一处都对应一个「漏了就静默降级」的守卫 ——
|
|
6
6
|
* 价格覆盖漏了 ⇒ 子 agent 用同一模型退化成「未定价」、`maxCostUsd` 静默失效;预算/超时上限
|
|
7
|
-
* 漏了 ⇒ 护栏在子循环里离线;`abandoned` 漏了 ⇒
|
|
7
|
+
* 漏了 ⇒ 护栏在子循环里离线;`abandoned` 漏了 ⇒ 超时后没人通知工具「别等了」;
|
|
8
|
+
* `deferUntil` 漏了 ⇒ 工具调用它当场 TypeError(工具契约里它有值,不是可选装饰)。
|
|
8
9
|
*
|
|
9
10
|
* 判定用哪一种是**语义**,不是风格,单测逐项钉住:
|
|
10
11
|
* - `signal` / `priceOverrides` / `onUnpricedModel` 用**真值**判定;
|
|
11
|
-
* - `maxEventChars` / `maxTotalTokens` / `maxCostUsd` / `toolTimeoutMs`
|
|
12
|
-
* 因为 `false`(不截断)与 `0
|
|
13
|
-
*
|
|
12
|
+
* - `maxEventChars` / `traceContent` / `maxTotalTokens` / `maxCostUsd` / `toolTimeoutMs`
|
|
13
|
+
* 用**非空**判定 —— 因为 `false`(不截断)与 `0`(不限/不超时)都是**有意义的值**,
|
|
14
|
+
* 真值判定会把它们吃掉;
|
|
15
|
+
* - `approval` 用 `!== undefined`:批/拒的决定要原样带给工具体(审计与分级授权用);
|
|
16
|
+
* - `deferUntil` 用真值判定:它是函数,没有「`false` = 有意义」这一档。
|
|
14
17
|
*
|
|
15
18
|
* 纯的边界:只做取值搬运,不读 ctx、不碰 recorder、不执行工具。
|
|
16
19
|
*/
|
|
@@ -25,8 +28,10 @@ export declare function buildToolRunContext(opts: {
|
|
|
25
28
|
priceOverrides?: ToolRunContext['priceOverrides'];
|
|
26
29
|
onUnpricedModel?: ToolRunContext['onUnpricedModel'];
|
|
27
30
|
maxEventChars?: ToolRunContext['maxEventChars'];
|
|
31
|
+
traceContent?: ToolRunContext['traceContent'];
|
|
28
32
|
maxTotalTokens?: ToolRunContext['maxTotalTokens'];
|
|
29
33
|
maxCostUsd?: ToolRunContext['maxCostUsd'];
|
|
30
34
|
toolTimeoutMs?: ToolRunContext['toolTimeoutMs'];
|
|
31
35
|
approval?: ToolRunContext['approval'];
|
|
36
|
+
deferUntil?: ToolRunContext['deferUntil'];
|
|
32
37
|
}): ToolRunContext;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export function buildToolRunContext(opts) {
|
|
2
|
-
const { client, recorder, parentSpanId, abandoned, signal, priceOverrides, onUnpricedModel, maxEventChars, maxTotalTokens, maxCostUsd, toolTimeoutMs, approval, } = opts;
|
|
2
|
+
const { client, recorder, parentSpanId, abandoned, signal, priceOverrides, onUnpricedModel, maxEventChars, traceContent, maxTotalTokens, maxCostUsd, toolTimeoutMs, approval, deferUntil, } = opts;
|
|
3
3
|
return {
|
|
4
4
|
client,
|
|
5
5
|
recorder,
|
|
@@ -9,10 +9,14 @@ export function buildToolRunContext(opts) {
|
|
|
9
9
|
...(priceOverrides ? { priceOverrides } : {}),
|
|
10
10
|
...(onUnpricedModel ? { onUnpricedModel } : {}),
|
|
11
11
|
...(maxEventChars != null ? { maxEventChars } : {}),
|
|
12
|
+
...(traceContent != null ? { traceContent } : {}),
|
|
12
13
|
...(maxTotalTokens != null ? { maxTotalTokens } : {}),
|
|
13
14
|
...(maxCostUsd != null ? { maxCostUsd } : {}),
|
|
14
15
|
...(toolTimeoutMs != null ? { toolTimeoutMs } : {}),
|
|
15
16
|
...(approval !== undefined ? { approval } : {}),
|
|
17
|
+
// 真值判定:它是个函数,没有 `false` / `0` 这类有意义的值(与上面那批「非空判定」的
|
|
18
|
+
// 旋钮不同类);装配点永远给一份,缺它只可能是「这条路径不走回合」(如 MCP 反向桥)
|
|
19
|
+
...(deferUntil ? { deferUntil } : {}),
|
|
16
20
|
};
|
|
17
21
|
}
|
|
18
22
|
//# sourceMappingURL=tool-context.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool-context.js","sourceRoot":"","sources":["../../src/engine/tool-context.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"tool-context.js","sourceRoot":"","sources":["../../src/engine/tool-context.ts"],"names":[],"mappings":"AAsBA,MAAM,UAAU,mBAAmB,CAAC,IAenC;IACC,MAAM,EACJ,MAAM,EACN,QAAQ,EACR,YAAY,EACZ,SAAS,EACT,MAAM,EACN,cAAc,EACd,eAAe,EACf,aAAa,EACb,YAAY,EACZ,cAAc,EACd,UAAU,EACV,aAAa,EACb,QAAQ,EACR,UAAU,GACX,GAAG,IAAI,CAAC;IACT,OAAO;QACL,MAAM;QACN,QAAQ;QACR,YAAY;QACZ,SAAS;QACT,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7B,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7C,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/C,GAAG,CAAC,aAAa,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACnD,GAAG,CAAC,YAAY,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACjD,GAAG,CAAC,cAAc,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACrD,GAAG,CAAC,UAAU,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7C,GAAG,CAAC,aAAa,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACnD,GAAG,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/C,mDAAmD;QACnD,8CAA8C;QAC9C,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACtC,CAAC;AACJ,CAAC"}
|
package/dist/engine/tracer.d.ts
CHANGED
|
@@ -2,18 +2,32 @@ import type { SpanError, SpanId, SpanKind, SpanLink, SpanStatus, Trace, TraceId,
|
|
|
2
2
|
/**
|
|
3
3
|
* 记账的**数量上限**(spec §9.4 的答案里「让少记了数据可数」那一半)。
|
|
4
4
|
*
|
|
5
|
-
* 只有 `maxEvents` 一个旋钮,而且它管的是**整条 trace
|
|
6
|
-
* (`tool.input` / `tool.output` / `score` / …
|
|
5
|
+
* 只有 `maxEvents` 一个旋钮,而且它管的是**整条 trace 的记录事件数**
|
|
6
|
+
* (`tool.input` / `tool.output` / `score` / … 都算,截断簿记那两笔不算)
|
|
7
|
+
* —— 因为成本就是整条 trace 的量。
|
|
7
8
|
* 与 `maxEventChars`(**单个事件正文长度**)是两个正交的旋钮,各有各的家:
|
|
8
9
|
* 一个管「多长」,一个管「多少」;两个都「不设 = 不限」。
|
|
9
10
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
11
|
+
* 超限后:**停止记账**(记录事件不再进 trace),并在 run 根上留**两笔**同名 `trace.truncated`
|
|
12
|
+
* 簿记 —— 按 body 区分(两笔都同时出现在交付的 trace 与增量流里,见下):
|
|
13
|
+
* - **起点标记** `{ limit }`:第一笔丢弃那一刻写下,标「从这里起有缺」(位置信号);
|
|
14
|
+
* - **收尾摘要** `{ droppedEvents, limit }`:`snapshot()` 交付时才写得出的最终计数。
|
|
15
|
+
* 缺口位置可预测(尾巴),且有计数 ⇒ 可解释。
|
|
16
|
+
*
|
|
17
|
+
* ⚠️ 两笔都**必须**进 `span.events`(而不是只派给增量订阅者):`core/trace.ts` 那条
|
|
18
|
+
* **折叠规则**(按 `seq` 折回逐字等于 `snapshot()`)是钉住的契约,只在一条缝上出现的事件
|
|
19
|
+
* 会让它在「设了上限且真截断」的 run 上变成假话。纯 `onTraceEvent` 的消费者因此也不再
|
|
20
|
+
* 面对一个静默的洞(2026-09-28 外部深评 P3-1;落点由 PR #164 复核 §4 定为「两缝同源」)。
|
|
21
|
+
*
|
|
12
22
|
* 刻意**不做**环形缓冲(丢最旧、留最近):那会让 trace 中间出现空洞,
|
|
13
23
|
* 而空洞比「尾巴截断」难解释得多(「这一回合怎么没有工具事件」)。
|
|
14
24
|
*/
|
|
15
25
|
export interface TraceLimits {
|
|
16
|
-
/**
|
|
26
|
+
/**
|
|
27
|
+
* **记录事件**的条数上限;`0` = 一条都不记(有意义的值,仍有计数);不设 = 不限。
|
|
28
|
+
* ⚠️ 这个计数**不含**上面那两笔 `trace.truncated` 簿记(它们是「关于记账」的簿记,不是被
|
|
29
|
+
* 记录的事实)⇒ 真截断时这条 trace 的事件数最多 `maxEvents + 2`。
|
|
30
|
+
*/
|
|
17
31
|
maxEvents?: number;
|
|
18
32
|
}
|
|
19
33
|
/**
|
|
@@ -35,6 +49,7 @@ export interface TraceRecorderOptions {
|
|
|
35
49
|
* 一次 run 一个 recorder;run 与 trace 1:1。
|
|
36
50
|
*/
|
|
37
51
|
export declare class TraceRecorder {
|
|
52
|
+
#private;
|
|
38
53
|
readonly traceId: TraceId;
|
|
39
54
|
private readonly spans;
|
|
40
55
|
private readonly index;
|
|
@@ -47,6 +62,12 @@ export declare class TraceRecorder {
|
|
|
47
62
|
private recordedEvents;
|
|
48
63
|
/** 因超限被丢弃的事件数(交付时写进 run 根的 `trace.truncated`) */
|
|
49
64
|
private droppedEvents;
|
|
65
|
+
/**
|
|
66
|
+
* 收尾摘要是否已派给增量出口。`snapshot()` 交付时派**一次**(见该方法的注释):
|
|
67
|
+
* 一次 run 只交付一次,但这个方法可以被调用多次(错误出口 / MCP / 引擎各一处),
|
|
68
|
+
* 重复派发会让增量流里出现两条摘要 ⇒ 折回的树与交付的树又对不上。
|
|
69
|
+
*/
|
|
70
|
+
private truncationSummarySent;
|
|
50
71
|
/** 记账事件订阅者(增量出口,见 `core/trace.ts` 的 `TraceRecordEvent`) */
|
|
51
72
|
private readonly listeners;
|
|
52
73
|
/**
|
|
@@ -98,6 +119,23 @@ export declare class TraceRecorder {
|
|
|
98
119
|
/** 子孙里所有 `llm.turn` 的 usage 之和(不含自身);无任何计量时返回 undefined */
|
|
99
120
|
private aggregateDescendantUsage;
|
|
100
121
|
event(id: SpanId, name: string, body: unknown): void;
|
|
122
|
+
/**
|
|
123
|
+
* 给 span 记一条属性(`key` 自由、`value` 三态)。
|
|
124
|
+
*
|
|
125
|
+
* ⚠️ **口径如实(2026-09-28 外部深评 E7)**:本方法**不过** `maxEvents` 那道数量闸
|
|
126
|
+
* (上面 `event()` 才过),属性值也**不做** `maxEventChars` 截断。所以「超限即停记」这句话
|
|
127
|
+
* 的射程是**事件**(`span.events`),不是属性(`span.attributes`)。
|
|
128
|
+
*
|
|
129
|
+
* 实际有界的部分(别把它读成「无界」):`turn.ts` 的 `traceContent:'full'` 正文**确实**按
|
|
130
|
+
* `maxEventChars` 截断;属性**条数**受调用点上限约束(turns ≤ `maxIterations`、
|
|
131
|
+
* 一次工具调用 ≤ 2 条、run 根的 `tools.names` / `labels.*` 由调用方在 run 入口给)。
|
|
132
|
+
* 真正「由调用方决定大小」的是 run 入口那几条(`labels.*` 的值、`tools.names` 的拼接结果)。
|
|
133
|
+
*
|
|
134
|
+
* ⚠️ **别顺手给它加截断**:属性是**交付的 trace** 与增量流共用的同一份载荷,
|
|
135
|
+
* 而 `core/trace.ts` 那条折叠契约(按 `seq` 折回**逐字等于** `snapshot()`)的两端就是它们 ——
|
|
136
|
+
* 只截一侧就当场毁掉那条契约(`tests/engine/trace-events.test.ts` 钉着它)。
|
|
137
|
+
* 要收就收「run 入口那几条的入参大小」,见 §10 ⑳ 的取舍。
|
|
138
|
+
*/
|
|
101
139
|
setAttribute(id: SpanId, key: string, value: string | number | boolean): void;
|
|
102
140
|
/**
|
|
103
141
|
* 给 span 记一条跨 trace 的链路引用(入站触发来源,见 `core/trace.ts` 的 `TraceContext`)。
|
package/dist/engine/tracer.js
CHANGED
|
@@ -40,6 +40,12 @@ export class TraceRecorder {
|
|
|
40
40
|
recordedEvents = 0;
|
|
41
41
|
/** 因超限被丢弃的事件数(交付时写进 run 根的 `trace.truncated`) */
|
|
42
42
|
droppedEvents = 0;
|
|
43
|
+
/**
|
|
44
|
+
* 收尾摘要是否已派给增量出口。`snapshot()` 交付时派**一次**(见该方法的注释):
|
|
45
|
+
* 一次 run 只交付一次,但这个方法可以被调用多次(错误出口 / MCP / 引擎各一处),
|
|
46
|
+
* 重复派发会让增量流里出现两条摘要 ⇒ 折回的树与交付的树又对不上。
|
|
47
|
+
*/
|
|
48
|
+
truncationSummarySent = false;
|
|
43
49
|
/** 记账事件订阅者(增量出口,见 `core/trace.ts` 的 `TraceRecordEvent`) */
|
|
44
50
|
listeners = [];
|
|
45
51
|
/**
|
|
@@ -206,9 +212,11 @@ export class TraceRecorder {
|
|
|
206
212
|
const span = this.index.get(id);
|
|
207
213
|
if (!span)
|
|
208
214
|
return; // 未知 span 静默忽略(见类注释的容错策略)—— 增量出口同样不派发
|
|
209
|
-
// 数量闸(traceLimits.maxEvents
|
|
210
|
-
//
|
|
215
|
+
// 数量闸(traceLimits.maxEvents):超限即**停止记账**(记录事件不再进 trace)——
|
|
216
|
+
// 但「缺口」本身要**在两条缝上都看得见**(2026-09-28 外部深评 P3-1;PR #164 复核 §4 改了落点)。
|
|
211
217
|
if (this.maxEvents !== undefined && this.recordedEvents >= this.maxEvents) {
|
|
218
|
+
if (this.droppedEvents === 0)
|
|
219
|
+
this.#markTruncationStart();
|
|
212
220
|
this.droppedEvents += 1;
|
|
213
221
|
return;
|
|
214
222
|
}
|
|
@@ -217,6 +225,52 @@ export class TraceRecorder {
|
|
|
217
225
|
span.events.push(event);
|
|
218
226
|
this.emit({ type: 'span.event', spanId: id, event: { ...event } });
|
|
219
227
|
}
|
|
228
|
+
/**
|
|
229
|
+
* 截断**开始**那一刻的簿记(只在第一笔丢弃时调一次):在 run 根上记一条
|
|
230
|
+
* `trace.truncated { limit }` —— 它**同时进 `span.events` 与增量流**(两处同一份载荷)。
|
|
231
|
+
*
|
|
232
|
+
* 为什么要进 `span.events`(而不是「只派给增量订阅者」):`core/trace.ts` 那条**折叠规则**
|
|
233
|
+
* 是钉住的契约 —— 「按 `seq` 折回必须逐字等于 `snapshot()`」。只要有一笔只出现在增量流里、
|
|
234
|
+
* 不出现在交付的 trace 里(或反过来),那条契约在**设了 `maxEvents` 且真截断**的 run 上就是假的。
|
|
235
|
+
* 这个 bug 的形态很隐蔽:默认不设上限 ⇒ 折叠用例永远碰不到 ⇒ 全绿。
|
|
236
|
+
*
|
|
237
|
+
* 两条纪律:
|
|
238
|
+
* - **不占** `recordedEvents` 配额(那是「被记录的事实」的上限;本事件是**关于**记账的簿记)
|
|
239
|
+
* ⇒ 截断时 trace 的事件数最多 `maxEvents + 2`(本条 + 收尾摘要);
|
|
240
|
+
* - 落在 **run 根**,不是「当时正在记的那条 span」:配额是**整条 trace 的**,「从哪里断」
|
|
241
|
+
* 因此是 trace 级的陈述,不是某条 span 的属性。
|
|
242
|
+
*
|
|
243
|
+
* 与收尾摘要的分工(两者同名 `trace.truncated`,按 body 区分,见 `TraceLimits` 的注释):
|
|
244
|
+
* 这条是**位置**信号(`{ limit }`,断点在这里),收尾摘要是**计数**(`{ droppedEvents, limit }`)。
|
|
245
|
+
*/
|
|
246
|
+
#markTruncationStart() {
|
|
247
|
+
const rootId = this.rootSpanId;
|
|
248
|
+
if (!rootId)
|
|
249
|
+
return; // 没有 run 根(不该发生):与收尾摘要的 `root?` 同款,不记也不派
|
|
250
|
+
const root = this.index.get(rootId);
|
|
251
|
+
if (!root)
|
|
252
|
+
return;
|
|
253
|
+
const marker = { time: Date.now(), name: 'trace.truncated', body: { limit: this.maxEvents } };
|
|
254
|
+
root.events.push(marker);
|
|
255
|
+
this.emit({ type: 'span.event', spanId: rootId, event: { ...marker } });
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* 给 span 记一条属性(`key` 自由、`value` 三态)。
|
|
259
|
+
*
|
|
260
|
+
* ⚠️ **口径如实(2026-09-28 外部深评 E7)**:本方法**不过** `maxEvents` 那道数量闸
|
|
261
|
+
* (上面 `event()` 才过),属性值也**不做** `maxEventChars` 截断。所以「超限即停记」这句话
|
|
262
|
+
* 的射程是**事件**(`span.events`),不是属性(`span.attributes`)。
|
|
263
|
+
*
|
|
264
|
+
* 实际有界的部分(别把它读成「无界」):`turn.ts` 的 `traceContent:'full'` 正文**确实**按
|
|
265
|
+
* `maxEventChars` 截断;属性**条数**受调用点上限约束(turns ≤ `maxIterations`、
|
|
266
|
+
* 一次工具调用 ≤ 2 条、run 根的 `tools.names` / `labels.*` 由调用方在 run 入口给)。
|
|
267
|
+
* 真正「由调用方决定大小」的是 run 入口那几条(`labels.*` 的值、`tools.names` 的拼接结果)。
|
|
268
|
+
*
|
|
269
|
+
* ⚠️ **别顺手给它加截断**:属性是**交付的 trace** 与增量流共用的同一份载荷,
|
|
270
|
+
* 而 `core/trace.ts` 那条折叠契约(按 `seq` 折回**逐字等于** `snapshot()`)的两端就是它们 ——
|
|
271
|
+
* 只截一侧就当场毁掉那条契约(`tests/engine/trace-events.test.ts` 钉着它)。
|
|
272
|
+
* 要收就收「run 入口那几条的入参大小」,见 §10 ⑳ 的取舍。
|
|
273
|
+
*/
|
|
220
274
|
setAttribute(id, key, value) {
|
|
221
275
|
const span = this.index.get(id);
|
|
222
276
|
if (!span)
|
|
@@ -284,16 +338,25 @@ export class TraceRecorder {
|
|
|
284
338
|
events: [...s.events],
|
|
285
339
|
...(s.links ? { links: [...s.links] } : {}),
|
|
286
340
|
}));
|
|
287
|
-
//
|
|
288
|
-
//
|
|
289
|
-
//
|
|
341
|
+
// 截断摘要:**交付时**才写得出的结论(与 totalUsage 同族),写在 run 根上。
|
|
342
|
+
// 它也**走增量出口**(2026-09-28 PR #164 复核 §4):否则「按 seq 折回的那棵树」会少这一笔
|
|
343
|
+
// —— 只要设了 `maxEvents` 且真截断,`core/trace.ts` 那条折叠规则就是**假的**(此前没有
|
|
344
|
+
// 用例覆盖到:默认不设上限,折叠用例永远碰不到截断)。同一对象两处用 ⇒ 时间戳逐字一致;
|
|
345
|
+
// 只派一次 ⇒ 重复交付不会让增量流里多出一条。
|
|
290
346
|
if (this.droppedEvents > 0) {
|
|
291
347
|
const root = spans.find((s) => s.spanId === this.rootSpanId);
|
|
292
|
-
root
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
348
|
+
if (root) {
|
|
349
|
+
const summary = {
|
|
350
|
+
time: Date.now(),
|
|
351
|
+
name: 'trace.truncated',
|
|
352
|
+
body: { droppedEvents: this.droppedEvents, limit: this.maxEvents },
|
|
353
|
+
};
|
|
354
|
+
root.events.push(summary);
|
|
355
|
+
if (!this.truncationSummarySent) {
|
|
356
|
+
this.truncationSummarySent = true;
|
|
357
|
+
this.emit({ type: 'span.event', spanId: this.rootSpanId, event: { ...summary } });
|
|
358
|
+
}
|
|
359
|
+
}
|
|
297
360
|
}
|
|
298
361
|
return {
|
|
299
362
|
traceId: this.traceId,
|