@migor/agentia 0.9.4 → 0.9.5
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 +688 -4
- package/README.md +1 -1
- package/dist/AGENTS.md +313 -33
- package/dist/container/container.js +15 -0
- package/dist/container/container.js.map +1 -1
- package/dist/core/limits.d.ts +93 -13
- 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/defer.d.ts +49 -0
- package/dist/engine/defer.js +72 -0
- package/dist/engine/defer.js.map +1 -0
- 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 +112 -15
- 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 +3 -1
- package/dist/store/redisStore.js +21 -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/async.d.ts +197 -18
- package/dist/transport/async.js +871 -85
- 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/scheduler.js +9 -23
- package/dist/transport/scheduler.js.map +1 -1
- 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 +86 -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 +6 -4
|
@@ -86,6 +86,21 @@ export class Container {
|
|
|
86
86
|
finally {
|
|
87
87
|
this.resolving.pop();
|
|
88
88
|
}
|
|
89
|
+
// thenable 检测(外部深评 K4):容器是**同步**解析的 —— `async` 工厂返回的 Promise
|
|
90
|
+
// 会原样被当成「值」缓存,下游注入到的是 Promise 本身:首次属性访问全 `undefined`、
|
|
91
|
+
// 零报错、`tsc` 也看不出来(类型断言成 T 了)。这类「静默给错东西」必须在构造/解析期响亮失败。
|
|
92
|
+
//
|
|
93
|
+
// ⚠️ 检测器**就地写**、不从别处 import:`container` 是纯叶子(`layering.test.ts` 里
|
|
94
|
+
// `container: []`,不许引内部任何模块),为两行逻辑破叶子边界不值得。
|
|
95
|
+
// 逃逸口:确实要注入 Promise **本体**,包一层即可(`useValue: { promise }`)。
|
|
96
|
+
if (value !== null && (typeof value === 'object' || typeof value === 'function')) {
|
|
97
|
+
const then = value.then;
|
|
98
|
+
if (typeof then === 'function') {
|
|
99
|
+
throw new TypeError(`provider "${token}" 解析出的是 Promise:容器同步解析,它会被原样缓存成「值」,` +
|
|
100
|
+
'下游拿到 Promise 而非 await 过的结果(首次属性访问全 undefined、且零报错)。' +
|
|
101
|
+
'异步初始化请在装配前 await 好再用 useValue 注入;确实要注入 Promise 本体,包一层:useValue: { promise }');
|
|
102
|
+
}
|
|
103
|
+
}
|
|
89
104
|
this.cache.set(token, value);
|
|
90
105
|
return value;
|
|
91
106
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"container.js","sourceRoot":"","sources":["../../src/container/container.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"container.js","sourceRoot":"","sources":["../../src/container/container.ts"],"names":[],"mappings":"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"}
|
package/dist/core/limits.d.ts
CHANGED
|
@@ -86,7 +86,7 @@ export declare const LIMIT_SEMANTICS: readonly [{
|
|
|
86
86
|
readonly zero: 'unlimited';
|
|
87
87
|
readonly zeroClause: '0 = 不限';
|
|
88
88
|
readonly badValue: 'throws';
|
|
89
|
-
readonly note: 'NaN/Infinity 会被 setTimeout 钳到 1ms ⇒ 每个任务立即「超时」失败,且 NaN 会绕过 `< 0` 静默通过;所以要「不限」必须显式传 0
|
|
89
|
+
readonly note: 'NaN/Infinity 会被 setTimeout 钳到 1ms ⇒ 每个任务立即「超时」失败,且 NaN 会绕过 `< 0` 静默通过;所以要「不限」必须显式传 0。⚠️ 2026-09-28 补上界:**超过 2^31-1ms(约 24.86 天)同样会被钳到 1ms**,构造期一并拒掉 —— 此前只查「非负有限」,于是「配 30 天超时 = 每个任务立即超时」这种配置合法、行为相反的坑能静默上线(上限单源在 core/timeout.ts)。';
|
|
90
90
|
}, {
|
|
91
91
|
readonly knob: 'AsyncRunner.approvalTimeoutMs';
|
|
92
92
|
readonly where: 'transport/async.ts';
|
|
@@ -95,6 +95,14 @@ export declare const LIMIT_SEMANTICS: readonly [{
|
|
|
95
95
|
readonly zeroClause: '0 = 不限';
|
|
96
96
|
readonly badValue: 'throws';
|
|
97
97
|
readonly note: '同 runTimeoutMs:非有限数会让「已挂起多久」的比较静默失效或立即超时。';
|
|
98
|
+
}, {
|
|
99
|
+
readonly knob: 'AsyncRunner.maxQueued';
|
|
100
|
+
readonly where: 'transport/async.ts';
|
|
101
|
+
readonly unit: 'count';
|
|
102
|
+
readonly zero: 'unlimited';
|
|
103
|
+
readonly zeroClause: '0 = 不限(不设排队上限)';
|
|
104
|
+
readonly badValue: 'throws';
|
|
105
|
+
readonly note: '2026-09-28 外部深评 T5 补登的**新旋钮**,也刻意是「数量 + 0 = 不限」的**第二个**样本(第一个是 `mapWithConcurrency.limit`)。⚠️ 它必须登记的理由不是形式:`maxQueued: 0` 的直觉读法是「一条都不许排」(= `disabled`),而**那样读的后果正是本旋钮要防的反面** —— 并发一满,每个提交都 503。所以 0 = 不限是**刻意选的**(缺省行为与加本旋钮之前逐字一致),探针必须把这两种读法分开:`concurrency: 1` + `maxQueued: 0` 下灌 3 条,断言**都受理**且都跑完(若读成 disabled,第 2 条就抛)。';
|
|
98
106
|
}, {
|
|
99
107
|
readonly knob: 'AsyncRunner.drain.timeoutMs';
|
|
100
108
|
readonly where: 'transport/drain-gate.ts';
|
|
@@ -102,7 +110,7 @@ export declare const LIMIT_SEMANTICS: readonly [{
|
|
|
102
110
|
readonly zero: 'unlimited';
|
|
103
111
|
readonly zeroClause: '非正 = 一直等';
|
|
104
112
|
readonly badValue: 'none';
|
|
105
|
-
readonly note: '**历史事故现场**:`http.ts` 的优雅停机把剩余预算算成 `timeoutMs - elapsed` 再交给它,deadline 已过时算出 1 或 0 ⇒ 旧读法(`0` = 已到点)让它跨过 deadline 后**永不返回**。现在 `http.ts` 自己先判「已到点就认账」,不把 0
|
|
113
|
+
readonly note: '**历史事故现场**:`http.ts` 的优雅停机把剩余预算算成 `timeoutMs - elapsed` 再交给它,deadline 已过时算出 1 或 0 ⇒ 旧读法(`0` = 已到点)让它跨过 deadline 后**永不返回**。现在 `http.ts` 自己先判「已到点就认账」,不把 0 交给下游去猜。⚠️ 2026-09-28:`NaN` 与超过 2^31-1ms 的预算在闸口拒掉(超上限会被钳到 1ms ⇒「等 30 天排空」变成「1ms 后返回 false」,而 `false` 的语义是「宿主必须退出」,静默拿到它代价很高)。';
|
|
106
114
|
}, {
|
|
107
115
|
readonly knob: 'mapWithConcurrency.limit';
|
|
108
116
|
readonly where: 'engine/concurrency.ts';
|
|
@@ -149,8 +157,8 @@ export declare const LIMIT_SEMANTICS: readonly [{
|
|
|
149
157
|
readonly unit: 'ms';
|
|
150
158
|
readonly zero: 'disabled';
|
|
151
159
|
readonly zeroClause: '非正 = 不设超时(原样透传)';
|
|
152
|
-
readonly badValue: '
|
|
153
|
-
readonly note: '`toolTimeoutMs` 的底座。⚠️ 漏透传这个值不是「少一层保险」而是**反的**:`withTimeout(p, 0)` 直接返回原 promise = 永不超时,同时 MCP 桥找不到引擎预算又起自己的 60s 兜底 ⇒ 双计时器、双账本(`toolkit/subagent.ts` / `skill.ts`
|
|
160
|
+
readonly badValue: 'throws';
|
|
161
|
+
readonly note: '`toolTimeoutMs` 的底座。⚠️ 漏透传这个值不是「少一层保险」而是**反的**:`withTimeout(p, 0)` 直接返回原 promise = 永不超时,同时 MCP 桥找不到引擎预算又起自己的 60s 兜底 ⇒ 双计时器、双账本(`toolkit/subagent.ts` / `skill.ts` 的透传注释指的就是这条)。⚠️ 2026-09-28 起 `NaN` 与超过 2^31-1ms 的值在入口拒掉(`assertTimerDelay`):`NaN` 会**静默**落进上面那句「非正 = 不设超时」(判据是 `!(x > 0)`,NaN 满足),与「我设了个预算」的预期正好相反;超上限则被钳到 1ms ⇒ 每个工具调用立即超时。`0` / 负数仍是合法的「不设超时」。';
|
|
154
162
|
}, {
|
|
155
163
|
readonly knob: 'TaskEventStreams.retainTerminal';
|
|
156
164
|
readonly where: 'transport/task-events.ts';
|
|
@@ -159,14 +167,22 @@ export declare const LIMIT_SEMANTICS: readonly [{
|
|
|
159
167
|
readonly zeroClause: '0 = 不留终态流(终态即忘)';
|
|
160
168
|
readonly badValue: 'throws';
|
|
161
169
|
readonly note: '判定是 `excess <= 0 提前返回` ⇒ NaN 恒假、**全部**无订阅者的终态流被清空(保留机制静默失效,方向与 maxEvents 的「闸失效」相反、同族)。⚠️ 只跳过「还有订阅者」的终态流 —— 那是还没被读完的流,丢了下游会莫名断在半路。';
|
|
170
|
+
}, {
|
|
171
|
+
readonly knob: 'TaskEventStreams.nonTerminalBuffers';
|
|
172
|
+
readonly where: 'transport/task-events.ts';
|
|
173
|
+
readonly unit: 'count';
|
|
174
|
+
readonly zero: 'disabled';
|
|
175
|
+
readonly zeroClause: '0 = 不为没人读的非终态流保留回放缓冲(有订阅者的照旧留着)';
|
|
176
|
+
readonly badValue: 'throws';
|
|
177
|
+
readonly note: '判定是 `buffered <= quota 提前返回` ⇒ NaN 恒假 ⇒ **每条**非终态流的回放缓冲都被立刻回收(回放历史静默全没,与 retainTerminal 那条「保留机制失效」同族、方向相反)。⚠️ 回收的是**缓冲**不是**表项**:`has()` 仍为真、序号接着走,缺口由 `firstAvailable` 明示(读者先收一帧 `stream.truncated`)—— 连表项一起删会让恢复段的序号从 1 重来,拿 `Last-Event-ID` 续订的读者从此静默收不到东西。⚠️ 只跳过「还有订阅者」的流(正在被读的不抽走)⇒ 被实时读的流不受配额约束。';
|
|
162
178
|
}, {
|
|
163
179
|
readonly knob: 'interruptibleSleep.ms';
|
|
164
180
|
readonly where: 'core/timeout.ts';
|
|
165
181
|
readonly unit: 'ms';
|
|
166
182
|
readonly zero: 'immediate';
|
|
167
183
|
readonly zeroClause: '非正 = 不睡';
|
|
168
|
-
readonly badValue: '
|
|
169
|
-
readonly note: '⚠️ 这一判**先于** aborted 检查 —— 别把它「修」成「已中止就该 reject」。2026-09-19 外部复核把它当一致性缺口改反过一次,被 `tests/core/timeout.test.ts` + `tests/core/sse-text-stats.test.ts`
|
|
184
|
+
readonly badValue: 'throws';
|
|
185
|
+
readonly note: '⚠️ 这一判**先于** aborted 检查 —— 别把它「修」成「已中止就该 reject」。2026-09-19 外部复核把它当一致性缺口改反过一次,被 `tests/core/timeout.test.ts` + `tests/core/sse-text-stats.test.ts` 拦住。⚠️ 2026-09-28 起 `NaN` 与超 2^31-1ms 在入口拒掉(`assertTimerDelay`,判在「非正」**之前** —— `NaN <= 0` 是 false,不先挡就会穿透直落 `setTimeout(NaN)`,被钳成 1ms ⇒「退避」变成「立刻重试」)。上游给的荒谬 `Retry-After` 不走这条:它在 `backoffMs` 里被**夹**到上限(外部数据不该把一次 429 升级成硬失败)。';
|
|
170
186
|
}, {
|
|
171
187
|
readonly knob: 'metricsSink.intervalMs';
|
|
172
188
|
readonly where: 'integrations/metrics.ts';
|
|
@@ -175,12 +191,52 @@ export declare const LIMIT_SEMANTICS: readonly [{
|
|
|
175
191
|
readonly zeroClause: '0 = 立即导出';
|
|
176
192
|
readonly badValue: 'none';
|
|
177
193
|
readonly note: '⚠️ **同名反义**:`Scheduler.every` 的 `intervalMs: 0` 是**配置错误**(抛错),这里却是「关掉定时器、每次累加后立即导出」。两个同名旋钮两种读法 —— 改任何一个之前先看这张表。';
|
|
194
|
+
}, {
|
|
195
|
+
readonly knob: 'BudgetGuardOptions.maxTotalTokens';
|
|
196
|
+
readonly where: 'engine/budget.ts(createBudgetGuard;由 RunAgentOptions.maxTotalTokens 传进来)';
|
|
197
|
+
readonly unit: 'count';
|
|
198
|
+
readonly zero: 'immediate';
|
|
199
|
+
readonly zeroClause: '0 = 第一次记账就超预算(等价于「任何用量都不许」)';
|
|
200
|
+
readonly badValue: 'none';
|
|
201
|
+
readonly note: '闸门判据是 `totalTokens > maxTotalTokens`(**严格大于**):0 时任何非零用量立刻撞线;负数同理(`> -1` 恒真)。这里刻意**不抛错** —— 预算是运行期累计量,配成 0 是「这次 run 一条都别花」的合法意图(与 `maxIterations: 0` 同档),不是坏配置。⚠️ 与 `maxCostUsd` 是两个独立闸,**tokens 先判、撞了就返回**(不再看 cost)。⚠️ 2026-09-28 补登:这两个旋钮自 v0.5.0 起就存在,却一直没进这张表(「改 0 的读法不改表就构建红」这条纪律对它们曾是空的)。';
|
|
202
|
+
}, {
|
|
203
|
+
readonly knob: 'BudgetGuardOptions.maxCostUsd';
|
|
204
|
+
readonly where: 'engine/budget.ts(createBudgetGuard;由 RunAgentOptions.maxCostUsd 传进来)';
|
|
205
|
+
readonly unit: 'n/a';
|
|
206
|
+
readonly zero: 'immediate';
|
|
207
|
+
readonly zeroClause: '0 = 第一笔成本就超预算(等价于「一分钱都不许花」)';
|
|
208
|
+
readonly badValue: 'none';
|
|
209
|
+
readonly note: '判据 `costUsd > maxCostUsd`,而 `costUsd` 取 `usage.costEstimate ?? 0` ⇒ **模型不在价格表内时它恒为 0**,这个闸对未定价模型**永不触发**(静默失效;要无条件兜底请用 `maxTotalTokens`)。这一句在 `BudgetGuardOptions` 的注释里已如实写着,这里登记是为了让「0 的读法」也有单一真源。';
|
|
210
|
+
}, {
|
|
211
|
+
readonly knob: 'metricsSink.maxCapabilities';
|
|
212
|
+
readonly where: 'integrations/metrics.ts(metricsSink)';
|
|
213
|
+
readonly unit: 'count';
|
|
214
|
+
readonly zero: 'invalid';
|
|
215
|
+
readonly zeroClause: '0 = 一个能力都认不下(配置错误)';
|
|
216
|
+
readonly badValue: 'throws';
|
|
217
|
+
readonly note: '与 `maxModels` / `maxScores` / `maxLabelValues` / `maxLabelCombos` 同族:都是**基数封顶**,0 会让所有条目折进同一个桶 ⇒ 看板看起来「只剩一个能力」,而没有任何报错。2026-09-28 补登(这三个此前不在表里 —— 与 `BudgetGuardOptions` 那两个同一种漏登记)。';
|
|
218
|
+
}, {
|
|
219
|
+
readonly knob: 'metricsSink.maxModels';
|
|
220
|
+
readonly where: 'integrations/metrics.ts(metricsSink)';
|
|
221
|
+
readonly unit: 'count';
|
|
222
|
+
readonly zero: 'invalid';
|
|
223
|
+
readonly zeroClause: '0 = 一个模型都认不下(配置错误)';
|
|
224
|
+
readonly badValue: 'throws';
|
|
225
|
+
readonly note: '同 `maxCapabilities`(该组同款判据、同款文案)。';
|
|
226
|
+
}, {
|
|
227
|
+
readonly knob: 'metricsSink.maxScores';
|
|
228
|
+
readonly where: 'integrations/metrics.ts(metricsSink)';
|
|
229
|
+
readonly unit: 'count';
|
|
230
|
+
readonly zero: 'invalid';
|
|
231
|
+
readonly zeroClause: '0 = 一个分数都认不下(配置错误)';
|
|
232
|
+
readonly badValue: 'throws';
|
|
233
|
+
readonly note: '同 `maxCapabilities`。';
|
|
178
234
|
}, {
|
|
179
235
|
readonly knob: 'AsyncRunner.concurrency';
|
|
180
236
|
readonly where: 'transport/async.ts';
|
|
181
237
|
readonly unit: 'count';
|
|
182
238
|
readonly zero: 'invalid';
|
|
183
|
-
readonly zeroClause: '
|
|
239
|
+
readonly zeroClause: '0 = 没有 worker';
|
|
184
240
|
readonly badValue: 'throws';
|
|
185
241
|
readonly note: '0 个 worker 的池子会让每个任务永远排在队列里(既不跑也不失败)。';
|
|
186
242
|
}, {
|
|
@@ -188,7 +244,7 @@ export declare const LIMIT_SEMANTICS: readonly [{
|
|
|
188
244
|
readonly where: 'transport/scheduler.ts';
|
|
189
245
|
readonly unit: 'count';
|
|
190
246
|
readonly zero: 'invalid';
|
|
191
|
-
readonly zeroClause: '
|
|
247
|
+
readonly zeroClause: 'Infinity = 关闸门;0 = 没有在飞名额,周期任务永不派发';
|
|
192
248
|
readonly badValue: 'throws';
|
|
193
249
|
readonly note: '与 `AsyncRunner.concurrency` **同族**(「在飞名额」数量旋钮):闸门判据是 `inFlight.size >= maxInFlight`,0 时恒真 ⇒ 每次 tick 都跳过,周期任务**既不跑也不失败**(探针实测 60ms 内派发 0 次、无任何报错/日志;负数同理)。⚠️ 旧实现 `opts.maxInFlight ?? 1` 把 0 静默留下,而写成 `||` 又会把它静默抬成 1 —— **两个方向都在替使用者改配置**(与 `streamBufferEvents` 记的旧 `Math.max(1, …)` 是同一个反模式)。';
|
|
194
250
|
}, {
|
|
@@ -196,15 +252,23 @@ export declare const LIMIT_SEMANTICS: readonly [{
|
|
|
196
252
|
readonly where: 'transport/http.ts(createHttpHandler)';
|
|
197
253
|
readonly unit: 'bytes';
|
|
198
254
|
readonly zero: 'invalid';
|
|
199
|
-
readonly zeroClause: '
|
|
255
|
+
readonly zeroClause: '0 = 每个带 body 的请求都 413';
|
|
200
256
|
readonly badValue: 'throws';
|
|
201
257
|
readonly note: "与**同一个选项接口里**的 `maxConcurrentRuns` 同款 —— 那条写着「0 / 负数则全部 503 —— 都是配置错误,宁可在构造期响亮失败」,这条是同一形状:`readBody` 的判据是 `size > maxBytes`,0 时**任何字节**都超限 ⇒ `POST /run` / `POST /tasks` / 审批全部 413(实测 3 条 POST 全 413),服务器看着在跑却收不了任何输入。⚠️ 还挡一类事故:`Number('') === 0` —— 从**空的环境变量**读出来的配置会静默变成「拒绝一切」。要「不限」用 `Infinity`(`size > Infinity` 恒假),**别用 0**。";
|
|
258
|
+
}, {
|
|
259
|
+
readonly knob: 'HttpHandlerOptions.maxConcurrentRuns';
|
|
260
|
+
readonly where: 'transport/http.ts(createHttpHandler)';
|
|
261
|
+
readonly unit: 'count';
|
|
262
|
+
readonly zero: 'invalid';
|
|
263
|
+
readonly zeroClause: 'Infinity = 无上限(0 = 全部 503)';
|
|
264
|
+
readonly badValue: 'throws';
|
|
265
|
+
readonly note: '闸门判据是 `inFlightRuns >= maxConcurrentRuns`:0 / 负数时恒真 ⇒ 每个 `POST /run` 都 503(服务器看着在跑却一个 run 都不收);NaN 让它恒假 ⇒ 闸门静默失效。它是**存量旋钮**(校验早就有),2026-09-27 复核时发现始终没登记进这张表(文案也没走 `zeroClauseOf`),补登。';
|
|
202
266
|
}, {
|
|
203
267
|
readonly knob: 'SseWriterOptions.maxBufferedBytes';
|
|
204
268
|
readonly where: 'transport/sse.ts(sseWriter)+ transport/http.ts(createHttpHandler 的 sseMaxBufferedBytes 透传)';
|
|
205
269
|
readonly unit: 'bytes';
|
|
206
270
|
readonly zero: 'invalid';
|
|
207
|
-
readonly zeroClause: '
|
|
271
|
+
readonly zeroClause: '0 = 流活不过一帧';
|
|
208
272
|
readonly badValue: 'throws';
|
|
209
273
|
readonly note: '判据是**写入前**的 `pending > limitBytes` ⇒ 0 时第 1 帧照写(pending 还是 0),**第 2 帧必收口**(实测:`closed=true` / `ended=true` / `onBackpressure` 回调 1 次)—— 流活不过一帧,没有任何正当用法:这个旋钮的定位是「只拦连上但不读的病态消费者」,而 0 会让**每个**消费者都被判成病态。要「关掉」用 `Infinity`。';
|
|
210
274
|
}, {
|
|
@@ -222,7 +286,7 @@ export declare const LIMIT_SEMANTICS: readonly [{
|
|
|
222
286
|
readonly zero: 'invalid';
|
|
223
287
|
readonly zeroClause: '必须为正有限数(0 会空转)';
|
|
224
288
|
readonly badValue: 'throws';
|
|
225
|
-
readonly note: '`setInterval(0)` 退化成「尽快重复」的空转循环(Node 钳到 1ms,仍是每毫秒一轮忙轮询);超过 2^31-1ms
|
|
289
|
+
readonly note: '`setInterval(0)` 退化成「尽快重复」的空转循环(Node 钳到 1ms,仍是每毫秒一轮忙轮询);超过 2^31-1ms 的延迟**不会被遵守**(Node 只在 stderr 留一行 `TimeoutOverflowWarning`,随后钳到 1ms),同款失败。上限单源 2026-09-28 上提到 core/timeout.ts,与其余五处直喂 `setTimeout` 的站点共用。';
|
|
226
290
|
}, {
|
|
227
291
|
readonly knob: 'createAnthropicClient.timeout';
|
|
228
292
|
readonly where: 'integrations/anthropic.ts';
|
|
@@ -230,15 +294,31 @@ export declare const LIMIT_SEMANTICS: readonly [{
|
|
|
230
294
|
readonly zero: 'invalid';
|
|
231
295
|
readonly zeroClause: '不设 = 不限;0 = 非法';
|
|
232
296
|
readonly badValue: 'throws';
|
|
233
|
-
readonly note: '「不限」的表达方式是**不传**,不是传 0 —— 与 `runTimeoutMs` 的读法**相反**(那个要求显式传 0
|
|
297
|
+
readonly note: '「不限」的表达方式是**不传**,不是传 0 —— 与 `runTimeoutMs` 的读法**相反**(那个要求显式传 0)。⚠️ 2026-09-28 补上界:超过 2^31-1ms 的值同样被钳到 1ms ⇒「30 天超时」变成「每个请求立即超时」,构造期一并拒掉。';
|
|
234
298
|
}, {
|
|
235
299
|
readonly knob: 'metricsSink.windowSize';
|
|
236
300
|
readonly where: 'integrations/metrics.ts';
|
|
237
301
|
readonly unit: 'count';
|
|
238
302
|
readonly zero: 'invalid';
|
|
239
|
-
readonly zeroClause: '
|
|
303
|
+
readonly zeroClause: '0 = 窗口里什么都没有';
|
|
240
304
|
readonly badValue: 'throws';
|
|
241
305
|
readonly note: '同款的还有 `maxCapabilities` / `maxModels` / `maxScores` —— 都是「必须为正数」。';
|
|
306
|
+
}, {
|
|
307
|
+
readonly knob: 'metricsSink.maxLabelValues';
|
|
308
|
+
readonly where: 'integrations/metrics.ts';
|
|
309
|
+
readonly unit: 'count';
|
|
310
|
+
readonly zero: 'invalid';
|
|
311
|
+
readonly zeroClause: '0 = 一个标签值都认不下';
|
|
312
|
+
readonly badValue: 'throws';
|
|
313
|
+
readonly note: '归因标签(R8-P4)的基数上限,与 `maxCapabilities` / `maxModels` / `maxScores` 同族。0 时**每个**值都折叠进 `__other__` —— 「opt-in 了标签维度却一个值都区分不开」没有正当读法,是配置错误;且这道上限刻意不可关(opt-in 挡不住「明知几千租户偏要上」,内存不变量要求每个新基数维度都有 cap)。';
|
|
314
|
+
}, {
|
|
315
|
+
readonly knob: 'metricsSink.maxLabelCombos';
|
|
316
|
+
readonly where: 'integrations/metrics.ts';
|
|
317
|
+
readonly unit: 'count';
|
|
318
|
+
readonly zero: 'invalid';
|
|
319
|
+
readonly zeroClause: '0 = 一个标签组合都认不下,全折进一个桶';
|
|
320
|
+
readonly badValue: 'throws';
|
|
321
|
+
readonly note: '**组合数**上限(2026-09-27 ⑧ 补的第四条基数上限)。`maxLabelValues` 只封每个键的**值域**,而进内存的是组合,数量是叉乘 `(maxLabelValues+1)^labelKeys.length` —— 缺省 100 × 3 键就是一百万条,且每键的 dropped 计数看不见它。与另外三道同款:超限折进一个全 `__other__` 的桶(量不丢),折叠数见 `droppedLabelCombos` / `dropped_keys{kind="label:combos"}`。';
|
|
242
322
|
}];
|
|
243
323
|
/** 表里全部旋钮的标识(用例按它建穷尽表:少一项 `typecheck:tests` 就红) */
|
|
244
324
|
export type LimitKnob = (typeof LIMIT_SEMANTICS)[number]['knob'];
|
package/dist/core/limits.js
CHANGED
|
@@ -48,7 +48,7 @@ export const LIMIT_SEMANTICS = [
|
|
|
48
48
|
zero: 'unlimited',
|
|
49
49
|
zeroClause: '0 = 不限',
|
|
50
50
|
badValue: 'throws',
|
|
51
|
-
note: 'NaN/Infinity 会被 setTimeout 钳到 1ms ⇒ 每个任务立即「超时」失败,且 NaN 会绕过 `< 0` 静默通过;所以要「不限」必须显式传 0
|
|
51
|
+
note: 'NaN/Infinity 会被 setTimeout 钳到 1ms ⇒ 每个任务立即「超时」失败,且 NaN 会绕过 `< 0` 静默通过;所以要「不限」必须显式传 0。⚠️ 2026-09-28 补上界:**超过 2^31-1ms(约 24.86 天)同样会被钳到 1ms**,构造期一并拒掉 —— 此前只查「非负有限」,于是「配 30 天超时 = 每个任务立即超时」这种配置合法、行为相反的坑能静默上线(上限单源在 core/timeout.ts)。',
|
|
52
52
|
},
|
|
53
53
|
{
|
|
54
54
|
knob: 'AsyncRunner.approvalTimeoutMs',
|
|
@@ -59,6 +59,15 @@ export const LIMIT_SEMANTICS = [
|
|
|
59
59
|
badValue: 'throws',
|
|
60
60
|
note: '同 runTimeoutMs:非有限数会让「已挂起多久」的比较静默失效或立即超时。',
|
|
61
61
|
},
|
|
62
|
+
{
|
|
63
|
+
knob: 'AsyncRunner.maxQueued',
|
|
64
|
+
where: 'transport/async.ts',
|
|
65
|
+
unit: 'count',
|
|
66
|
+
zero: 'unlimited',
|
|
67
|
+
zeroClause: '0 = 不限(不设排队上限)',
|
|
68
|
+
badValue: 'throws',
|
|
69
|
+
note: '2026-09-28 外部深评 T5 补登的**新旋钮**,也刻意是「数量 + 0 = 不限」的**第二个**样本(第一个是 `mapWithConcurrency.limit`)。⚠️ 它必须登记的理由不是形式:`maxQueued: 0` 的直觉读法是「一条都不许排」(= `disabled`),而**那样读的后果正是本旋钮要防的反面** —— 并发一满,每个提交都 503。所以 0 = 不限是**刻意选的**(缺省行为与加本旋钮之前逐字一致),探针必须把这两种读法分开:`concurrency: 1` + `maxQueued: 0` 下灌 3 条,断言**都受理**且都跑完(若读成 disabled,第 2 条就抛)。',
|
|
70
|
+
},
|
|
62
71
|
{
|
|
63
72
|
knob: 'AsyncRunner.drain.timeoutMs',
|
|
64
73
|
where: 'transport/drain-gate.ts',
|
|
@@ -66,7 +75,7 @@ export const LIMIT_SEMANTICS = [
|
|
|
66
75
|
zero: 'unlimited',
|
|
67
76
|
zeroClause: '非正 = 一直等',
|
|
68
77
|
badValue: 'none',
|
|
69
|
-
note: '**历史事故现场**:`http.ts` 的优雅停机把剩余预算算成 `timeoutMs - elapsed` 再交给它,deadline 已过时算出 1 或 0 ⇒ 旧读法(`0` = 已到点)让它跨过 deadline 后**永不返回**。现在 `http.ts` 自己先判「已到点就认账」,不把 0
|
|
78
|
+
note: '**历史事故现场**:`http.ts` 的优雅停机把剩余预算算成 `timeoutMs - elapsed` 再交给它,deadline 已过时算出 1 或 0 ⇒ 旧读法(`0` = 已到点)让它跨过 deadline 后**永不返回**。现在 `http.ts` 自己先判「已到点就认账」,不把 0 交给下游去猜。⚠️ 2026-09-28:`NaN` 与超过 2^31-1ms 的预算在闸口拒掉(超上限会被钳到 1ms ⇒「等 30 天排空」变成「1ms 后返回 false」,而 `false` 的语义是「宿主必须退出」,静默拿到它代价很高)。',
|
|
70
79
|
},
|
|
71
80
|
{
|
|
72
81
|
knob: 'mapWithConcurrency.limit',
|
|
@@ -120,8 +129,8 @@ export const LIMIT_SEMANTICS = [
|
|
|
120
129
|
unit: 'ms',
|
|
121
130
|
zero: 'disabled',
|
|
122
131
|
zeroClause: '非正 = 不设超时(原样透传)',
|
|
123
|
-
badValue: '
|
|
124
|
-
note: '`toolTimeoutMs` 的底座。⚠️ 漏透传这个值不是「少一层保险」而是**反的**:`withTimeout(p, 0)` 直接返回原 promise = 永不超时,同时 MCP 桥找不到引擎预算又起自己的 60s 兜底 ⇒ 双计时器、双账本(`toolkit/subagent.ts` / `skill.ts`
|
|
132
|
+
badValue: 'throws',
|
|
133
|
+
note: '`toolTimeoutMs` 的底座。⚠️ 漏透传这个值不是「少一层保险」而是**反的**:`withTimeout(p, 0)` 直接返回原 promise = 永不超时,同时 MCP 桥找不到引擎预算又起自己的 60s 兜底 ⇒ 双计时器、双账本(`toolkit/subagent.ts` / `skill.ts` 的透传注释指的就是这条)。⚠️ 2026-09-28 起 `NaN` 与超过 2^31-1ms 的值在入口拒掉(`assertTimerDelay`):`NaN` 会**静默**落进上面那句「非正 = 不设超时」(判据是 `!(x > 0)`,NaN 满足),与「我设了个预算」的预期正好相反;超上限则被钳到 1ms ⇒ 每个工具调用立即超时。`0` / 负数仍是合法的「不设超时」。',
|
|
125
134
|
},
|
|
126
135
|
{
|
|
127
136
|
knob: 'TaskEventStreams.retainTerminal',
|
|
@@ -132,6 +141,15 @@ export const LIMIT_SEMANTICS = [
|
|
|
132
141
|
badValue: 'throws',
|
|
133
142
|
note: '判定是 `excess <= 0 提前返回` ⇒ NaN 恒假、**全部**无订阅者的终态流被清空(保留机制静默失效,方向与 maxEvents 的「闸失效」相反、同族)。⚠️ 只跳过「还有订阅者」的终态流 —— 那是还没被读完的流,丢了下游会莫名断在半路。',
|
|
134
143
|
},
|
|
144
|
+
{
|
|
145
|
+
knob: 'TaskEventStreams.nonTerminalBuffers',
|
|
146
|
+
where: 'transport/task-events.ts',
|
|
147
|
+
unit: 'count',
|
|
148
|
+
zero: 'disabled',
|
|
149
|
+
zeroClause: '0 = 不为没人读的非终态流保留回放缓冲(有订阅者的照旧留着)',
|
|
150
|
+
badValue: 'throws',
|
|
151
|
+
note: '判定是 `buffered <= quota 提前返回` ⇒ NaN 恒假 ⇒ **每条**非终态流的回放缓冲都被立刻回收(回放历史静默全没,与 retainTerminal 那条「保留机制失效」同族、方向相反)。⚠️ 回收的是**缓冲**不是**表项**:`has()` 仍为真、序号接着走,缺口由 `firstAvailable` 明示(读者先收一帧 `stream.truncated`)—— 连表项一起删会让恢复段的序号从 1 重来,拿 `Last-Event-ID` 续订的读者从此静默收不到东西。⚠️ 只跳过「还有订阅者」的流(正在被读的不抽走)⇒ 被实时读的流不受配额约束。',
|
|
152
|
+
},
|
|
135
153
|
// ── 0 = 立即执行(等待预算为 0 ⇒ 这次等待不存在)─────────────────────────
|
|
136
154
|
{
|
|
137
155
|
knob: 'interruptibleSleep.ms',
|
|
@@ -139,8 +157,8 @@ export const LIMIT_SEMANTICS = [
|
|
|
139
157
|
unit: 'ms',
|
|
140
158
|
zero: 'immediate',
|
|
141
159
|
zeroClause: '非正 = 不睡',
|
|
142
|
-
badValue: '
|
|
143
|
-
note: '⚠️ 这一判**先于** aborted 检查 —— 别把它「修」成「已中止就该 reject」。2026-09-19 外部复核把它当一致性缺口改反过一次,被 `tests/core/timeout.test.ts` + `tests/core/sse-text-stats.test.ts`
|
|
160
|
+
badValue: 'throws',
|
|
161
|
+
note: '⚠️ 这一判**先于** aborted 检查 —— 别把它「修」成「已中止就该 reject」。2026-09-19 外部复核把它当一致性缺口改反过一次,被 `tests/core/timeout.test.ts` + `tests/core/sse-text-stats.test.ts` 拦住。⚠️ 2026-09-28 起 `NaN` 与超 2^31-1ms 在入口拒掉(`assertTimerDelay`,判在「非正」**之前** —— `NaN <= 0` 是 false,不先挡就会穿透直落 `setTimeout(NaN)`,被钳成 1ms ⇒「退避」变成「立刻重试」)。上游给的荒谬 `Retry-After` 不走这条:它在 `backoffMs` 里被**夹**到上限(外部数据不该把一次 429 升级成硬失败)。',
|
|
144
162
|
},
|
|
145
163
|
{
|
|
146
164
|
knob: 'metricsSink.intervalMs',
|
|
@@ -151,13 +169,58 @@ export const LIMIT_SEMANTICS = [
|
|
|
151
169
|
badValue: 'none',
|
|
152
170
|
note: '⚠️ **同名反义**:`Scheduler.every` 的 `intervalMs: 0` 是**配置错误**(抛错),这里却是「关掉定时器、每次累加后立即导出」。两个同名旋钮两种读法 —— 改任何一个之前先看这张表。',
|
|
153
171
|
},
|
|
172
|
+
{
|
|
173
|
+
knob: 'BudgetGuardOptions.maxTotalTokens',
|
|
174
|
+
where: 'engine/budget.ts(createBudgetGuard;由 RunAgentOptions.maxTotalTokens 传进来)',
|
|
175
|
+
unit: 'count',
|
|
176
|
+
zero: 'immediate',
|
|
177
|
+
zeroClause: '0 = 第一次记账就超预算(等价于「任何用量都不许」)',
|
|
178
|
+
badValue: 'none',
|
|
179
|
+
note: '闸门判据是 `totalTokens > maxTotalTokens`(**严格大于**):0 时任何非零用量立刻撞线;负数同理(`> -1` 恒真)。这里刻意**不抛错** —— 预算是运行期累计量,配成 0 是「这次 run 一条都别花」的合法意图(与 `maxIterations: 0` 同档),不是坏配置。⚠️ 与 `maxCostUsd` 是两个独立闸,**tokens 先判、撞了就返回**(不再看 cost)。⚠️ 2026-09-28 补登:这两个旋钮自 v0.5.0 起就存在,却一直没进这张表(「改 0 的读法不改表就构建红」这条纪律对它们曾是空的)。',
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
knob: 'BudgetGuardOptions.maxCostUsd',
|
|
183
|
+
where: 'engine/budget.ts(createBudgetGuard;由 RunAgentOptions.maxCostUsd 传进来)',
|
|
184
|
+
unit: 'n/a',
|
|
185
|
+
zero: 'immediate',
|
|
186
|
+
zeroClause: '0 = 第一笔成本就超预算(等价于「一分钱都不许花」)',
|
|
187
|
+
badValue: 'none',
|
|
188
|
+
note: '判据 `costUsd > maxCostUsd`,而 `costUsd` 取 `usage.costEstimate ?? 0` ⇒ **模型不在价格表内时它恒为 0**,这个闸对未定价模型**永不触发**(静默失效;要无条件兜底请用 `maxTotalTokens`)。这一句在 `BudgetGuardOptions` 的注释里已如实写着,这里登记是为了让「0 的读法」也有单一真源。',
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
knob: 'metricsSink.maxCapabilities',
|
|
192
|
+
where: 'integrations/metrics.ts(metricsSink)',
|
|
193
|
+
unit: 'count',
|
|
194
|
+
zero: 'invalid',
|
|
195
|
+
zeroClause: '0 = 一个能力都认不下(配置错误)',
|
|
196
|
+
badValue: 'throws',
|
|
197
|
+
note: '与 `maxModels` / `maxScores` / `maxLabelValues` / `maxLabelCombos` 同族:都是**基数封顶**,0 会让所有条目折进同一个桶 ⇒ 看板看起来「只剩一个能力」,而没有任何报错。2026-09-28 补登(这三个此前不在表里 —— 与 `BudgetGuardOptions` 那两个同一种漏登记)。',
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
knob: 'metricsSink.maxModels',
|
|
201
|
+
where: 'integrations/metrics.ts(metricsSink)',
|
|
202
|
+
unit: 'count',
|
|
203
|
+
zero: 'invalid',
|
|
204
|
+
zeroClause: '0 = 一个模型都认不下(配置错误)',
|
|
205
|
+
badValue: 'throws',
|
|
206
|
+
note: '同 `maxCapabilities`(该组同款判据、同款文案)。',
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
knob: 'metricsSink.maxScores',
|
|
210
|
+
where: 'integrations/metrics.ts(metricsSink)',
|
|
211
|
+
unit: 'count',
|
|
212
|
+
zero: 'invalid',
|
|
213
|
+
zeroClause: '0 = 一个分数都认不下(配置错误)',
|
|
214
|
+
badValue: 'throws',
|
|
215
|
+
note: '同 `maxCapabilities`。',
|
|
216
|
+
},
|
|
154
217
|
// ── 0 = 非法配置(响亮失败)─────────────────────────────────────────────
|
|
155
218
|
{
|
|
156
219
|
knob: 'AsyncRunner.concurrency',
|
|
157
220
|
where: 'transport/async.ts',
|
|
158
221
|
unit: 'count',
|
|
159
222
|
zero: 'invalid',
|
|
160
|
-
zeroClause: '
|
|
223
|
+
zeroClause: '0 = 没有 worker',
|
|
161
224
|
badValue: 'throws',
|
|
162
225
|
note: '0 个 worker 的池子会让每个任务永远排在队列里(既不跑也不失败)。',
|
|
163
226
|
},
|
|
@@ -166,7 +229,7 @@ export const LIMIT_SEMANTICS = [
|
|
|
166
229
|
where: 'transport/scheduler.ts',
|
|
167
230
|
unit: 'count',
|
|
168
231
|
zero: 'invalid',
|
|
169
|
-
zeroClause: '
|
|
232
|
+
zeroClause: 'Infinity = 关闸门;0 = 没有在飞名额,周期任务永不派发',
|
|
170
233
|
badValue: 'throws',
|
|
171
234
|
note: '与 `AsyncRunner.concurrency` **同族**(「在飞名额」数量旋钮):闸门判据是 `inFlight.size >= maxInFlight`,0 时恒真 ⇒ 每次 tick 都跳过,周期任务**既不跑也不失败**(探针实测 60ms 内派发 0 次、无任何报错/日志;负数同理)。⚠️ 旧实现 `opts.maxInFlight ?? 1` 把 0 静默留下,而写成 `||` 又会把它静默抬成 1 —— **两个方向都在替使用者改配置**(与 `streamBufferEvents` 记的旧 `Math.max(1, …)` 是同一个反模式)。',
|
|
172
235
|
},
|
|
@@ -175,16 +238,25 @@ export const LIMIT_SEMANTICS = [
|
|
|
175
238
|
where: 'transport/http.ts(createHttpHandler)',
|
|
176
239
|
unit: 'bytes',
|
|
177
240
|
zero: 'invalid',
|
|
178
|
-
zeroClause: '
|
|
241
|
+
zeroClause: '0 = 每个带 body 的请求都 413',
|
|
179
242
|
badValue: 'throws',
|
|
180
243
|
note: "与**同一个选项接口里**的 `maxConcurrentRuns` 同款 —— 那条写着「0 / 负数则全部 503 —— 都是配置错误,宁可在构造期响亮失败」,这条是同一形状:`readBody` 的判据是 `size > maxBytes`,0 时**任何字节**都超限 ⇒ `POST /run` / `POST /tasks` / 审批全部 413(实测 3 条 POST 全 413),服务器看着在跑却收不了任何输入。⚠️ 还挡一类事故:`Number('') === 0` —— 从**空的环境变量**读出来的配置会静默变成「拒绝一切」。要「不限」用 `Infinity`(`size > Infinity` 恒假),**别用 0**。",
|
|
181
244
|
},
|
|
245
|
+
{
|
|
246
|
+
knob: 'HttpHandlerOptions.maxConcurrentRuns',
|
|
247
|
+
where: 'transport/http.ts(createHttpHandler)',
|
|
248
|
+
unit: 'count',
|
|
249
|
+
zero: 'invalid',
|
|
250
|
+
zeroClause: 'Infinity = 无上限(0 = 全部 503)',
|
|
251
|
+
badValue: 'throws',
|
|
252
|
+
note: '闸门判据是 `inFlightRuns >= maxConcurrentRuns`:0 / 负数时恒真 ⇒ 每个 `POST /run` 都 503(服务器看着在跑却一个 run 都不收);NaN 让它恒假 ⇒ 闸门静默失效。它是**存量旋钮**(校验早就有),2026-09-27 复核时发现始终没登记进这张表(文案也没走 `zeroClauseOf`),补登。',
|
|
253
|
+
},
|
|
182
254
|
{
|
|
183
255
|
knob: 'SseWriterOptions.maxBufferedBytes',
|
|
184
256
|
where: 'transport/sse.ts(sseWriter)+ transport/http.ts(createHttpHandler 的 sseMaxBufferedBytes 透传)',
|
|
185
257
|
unit: 'bytes',
|
|
186
258
|
zero: 'invalid',
|
|
187
|
-
zeroClause: '
|
|
259
|
+
zeroClause: '0 = 流活不过一帧',
|
|
188
260
|
badValue: 'throws',
|
|
189
261
|
note: '判据是**写入前**的 `pending > limitBytes` ⇒ 0 时第 1 帧照写(pending 还是 0),**第 2 帧必收口**(实测:`closed=true` / `ended=true` / `onBackpressure` 回调 1 次)—— 流活不过一帧,没有任何正当用法:这个旋钮的定位是「只拦连上但不读的病态消费者」,而 0 会让**每个**消费者都被判成病态。要「关掉」用 `Infinity`。',
|
|
190
262
|
},
|
|
@@ -204,7 +276,7 @@ export const LIMIT_SEMANTICS = [
|
|
|
204
276
|
zero: 'invalid',
|
|
205
277
|
zeroClause: '必须为正有限数(0 会空转)',
|
|
206
278
|
badValue: 'throws',
|
|
207
|
-
note: '`setInterval(0)` 退化成「尽快重复」的空转循环(Node 钳到 1ms,仍是每毫秒一轮忙轮询);超过 2^31-1ms
|
|
279
|
+
note: '`setInterval(0)` 退化成「尽快重复」的空转循环(Node 钳到 1ms,仍是每毫秒一轮忙轮询);超过 2^31-1ms 的延迟**不会被遵守**(Node 只在 stderr 留一行 `TimeoutOverflowWarning`,随后钳到 1ms),同款失败。上限单源 2026-09-28 上提到 core/timeout.ts,与其余五处直喂 `setTimeout` 的站点共用。',
|
|
208
280
|
},
|
|
209
281
|
{
|
|
210
282
|
knob: 'createAnthropicClient.timeout',
|
|
@@ -213,17 +285,35 @@ export const LIMIT_SEMANTICS = [
|
|
|
213
285
|
zero: 'invalid',
|
|
214
286
|
zeroClause: '不设 = 不限;0 = 非法',
|
|
215
287
|
badValue: 'throws',
|
|
216
|
-
note: '「不限」的表达方式是**不传**,不是传 0 —— 与 `runTimeoutMs` 的读法**相反**(那个要求显式传 0
|
|
288
|
+
note: '「不限」的表达方式是**不传**,不是传 0 —— 与 `runTimeoutMs` 的读法**相反**(那个要求显式传 0)。⚠️ 2026-09-28 补上界:超过 2^31-1ms 的值同样被钳到 1ms ⇒「30 天超时」变成「每个请求立即超时」,构造期一并拒掉。',
|
|
217
289
|
},
|
|
218
290
|
{
|
|
219
291
|
knob: 'metricsSink.windowSize',
|
|
220
292
|
where: 'integrations/metrics.ts',
|
|
221
293
|
unit: 'count',
|
|
222
294
|
zero: 'invalid',
|
|
223
|
-
zeroClause: '
|
|
295
|
+
zeroClause: '0 = 窗口里什么都没有',
|
|
224
296
|
badValue: 'throws',
|
|
225
297
|
note: '同款的还有 `maxCapabilities` / `maxModels` / `maxScores` —— 都是「必须为正数」。',
|
|
226
298
|
},
|
|
299
|
+
{
|
|
300
|
+
knob: 'metricsSink.maxLabelValues',
|
|
301
|
+
where: 'integrations/metrics.ts',
|
|
302
|
+
unit: 'count',
|
|
303
|
+
zero: 'invalid',
|
|
304
|
+
zeroClause: '0 = 一个标签值都认不下',
|
|
305
|
+
badValue: 'throws',
|
|
306
|
+
note: '归因标签(R8-P4)的基数上限,与 `maxCapabilities` / `maxModels` / `maxScores` 同族。0 时**每个**值都折叠进 `__other__` —— 「opt-in 了标签维度却一个值都区分不开」没有正当读法,是配置错误;且这道上限刻意不可关(opt-in 挡不住「明知几千租户偏要上」,内存不变量要求每个新基数维度都有 cap)。',
|
|
307
|
+
},
|
|
308
|
+
{
|
|
309
|
+
knob: 'metricsSink.maxLabelCombos',
|
|
310
|
+
where: 'integrations/metrics.ts',
|
|
311
|
+
unit: 'count',
|
|
312
|
+
zero: 'invalid',
|
|
313
|
+
zeroClause: '0 = 一个标签组合都认不下,全折进一个桶',
|
|
314
|
+
badValue: 'throws',
|
|
315
|
+
note: '**组合数**上限(2026-09-27 ⑧ 补的第四条基数上限)。`maxLabelValues` 只封每个键的**值域**,而进内存的是组合,数量是叉乘 `(maxLabelValues+1)^labelKeys.length` —— 缺省 100 × 3 键就是一百万条,且每键的 dropped 计数看不见它。与另外三道同款:超限折进一个全 `__other__` 的桶(量不丢),折叠数见 `droppedLabelCombos` / `dropped_keys{kind="label:combos"}`。',
|
|
316
|
+
},
|
|
227
317
|
];
|
|
228
318
|
/** 按旋钮取那行(拼错旋钮名 = 编译期报错,不是运行期 undefined) */
|
|
229
319
|
export function limitSemanticOf(knob) {
|
package/dist/core/limits.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"limits.js","sourceRoot":"","sources":["../../src/core/limits.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AA6CH;;GAEG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,gEAAgE;IAChE;QACE,IAAI,EAAE,0BAA0B;QAChC,KAAK,EAAE,oBAAoB;QAC3B,IAAI,EAAE,IAAI;QACV,IAAI,EAAE,WAAW;QACjB,UAAU,EAAE,QAAQ;QACpB,QAAQ,EAAE,QAAQ;QAClB,IAAI,EAAE,
|
|
1
|
+
{"version":3,"file":"limits.js","sourceRoot":"","sources":["../../src/core/limits.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agentia —— 换行分隔 JSON-RPC 的**分帧缓冲上限**(两条 MCP 桥**共用一份**)。
|
|
3
|
+
*
|
|
4
|
+
* 为什么要有这个文件:两个方向的桥各自攒一个字符串缓冲按 `\n` 切帧 ——
|
|
5
|
+
* ① 正向连接器 `integrations/mcp-stdio.ts` 读**子进程 stdout**;
|
|
6
|
+
* ② 反向桥 `engine/mcp-server-stdio.ts` 读**宿主 stdin**。
|
|
7
|
+
* 两份都是 `buf += chunk` 然后找换行,**没有任何长度上限**(2026-09-28 外部深评 S6):
|
|
8
|
+
* 对端只要一直吐不带换行的字节(坏 server / 坏宿主 / 一条 5GB 的「一行」),缓冲区就无界
|
|
9
|
+
* 增长 ⇒ 先 OOM 再谈协议。这不是「罕见输入」:stdout 里混日志的 MCP server 本来就常见
|
|
10
|
+
* (连接器那条的注释已认下这点),而**一个不换行的日志行**就是这形态。
|
|
11
|
+
*
|
|
12
|
+
* 为什么两份共用一份常量而不是各写一个:这正是本仓反复吃过的「同一契约两份实现」的坑
|
|
13
|
+
* (见 `docs/guards.md`)—— 两侧上限漂了不会有任何症状,直到某天一侧先 OOM。
|
|
14
|
+
* 放 `core` 是因为 `integrations` 与 `engine` 都只许依赖 `core`(分层守卫),
|
|
15
|
+
* 谁也不能把常量挂在对方身上。
|
|
16
|
+
*
|
|
17
|
+
* ⚠️ 单位是 **UTF-16 码元**(`string.length`),不是字节。为什么不按字节:两侧的缓冲都是
|
|
18
|
+
* `setEncoding('utf8')` 之后的**字符串**,逐块算 `Buffer.byteLength` 要么每次重算整段
|
|
19
|
+
* (O(n²)),要么另维护一个字节计数器(同一段缓冲两套长度,迟早漂)。码元长度是现成的、
|
|
20
|
+
* 单调递增的,做**上限**足够 —— 而且它是**保守**的:每个码元在内存里最少占 2 字节,
|
|
21
|
+
* 所以真实内存占用 ≤ 2× 这个值,不会低估到危险。
|
|
22
|
+
*
|
|
23
|
+
* 取值口径:**远大于任何合法报文,远小于能让进程 OOM**。MCP 的单条报文里可能装着工具结果
|
|
24
|
+
* (整份文件、整段日志),给小了会把正常调用打成协议错 —— 那比 OOM 更难查(症状是「偶发
|
|
25
|
+
* 失败」)。800 万码元是「一次性工具结果」的宽裕上界,同时上千个并发连接各自缓冲一份也仍
|
|
26
|
+
* 在几 GB 量级之外。
|
|
27
|
+
*
|
|
28
|
+
* ⚠️ 这是**硬上限,不是旋钮**:它没有「0 = 不限」的读法,所以不进 `core/limits.ts` 的旋钮表
|
|
29
|
+
* (那张表管的是「使用者能设的旋钮,0 是什么意思」)。要改它只能改代码 + 两侧用例。
|
|
30
|
+
*/
|
|
31
|
+
export declare const MAX_FRAME_CHARS: number;
|
|
32
|
+
/**
|
|
33
|
+
* 上限的人类可读说法(两条桥的报错文案共用 —— 免得一处写「8 MiB」一处写「8388608」)。
|
|
34
|
+
* 数值与 `MAX_FRAME_CHARS` 同源,改上限不会让文案漂。
|
|
35
|
+
*/
|
|
36
|
+
export declare function frameLimitText(): string;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agentia —— 换行分隔 JSON-RPC 的**分帧缓冲上限**(两条 MCP 桥**共用一份**)。
|
|
3
|
+
*
|
|
4
|
+
* 为什么要有这个文件:两个方向的桥各自攒一个字符串缓冲按 `\n` 切帧 ——
|
|
5
|
+
* ① 正向连接器 `integrations/mcp-stdio.ts` 读**子进程 stdout**;
|
|
6
|
+
* ② 反向桥 `engine/mcp-server-stdio.ts` 读**宿主 stdin**。
|
|
7
|
+
* 两份都是 `buf += chunk` 然后找换行,**没有任何长度上限**(2026-09-28 外部深评 S6):
|
|
8
|
+
* 对端只要一直吐不带换行的字节(坏 server / 坏宿主 / 一条 5GB 的「一行」),缓冲区就无界
|
|
9
|
+
* 增长 ⇒ 先 OOM 再谈协议。这不是「罕见输入」:stdout 里混日志的 MCP server 本来就常见
|
|
10
|
+
* (连接器那条的注释已认下这点),而**一个不换行的日志行**就是这形态。
|
|
11
|
+
*
|
|
12
|
+
* 为什么两份共用一份常量而不是各写一个:这正是本仓反复吃过的「同一契约两份实现」的坑
|
|
13
|
+
* (见 `docs/guards.md`)—— 两侧上限漂了不会有任何症状,直到某天一侧先 OOM。
|
|
14
|
+
* 放 `core` 是因为 `integrations` 与 `engine` 都只许依赖 `core`(分层守卫),
|
|
15
|
+
* 谁也不能把常量挂在对方身上。
|
|
16
|
+
*
|
|
17
|
+
* ⚠️ 单位是 **UTF-16 码元**(`string.length`),不是字节。为什么不按字节:两侧的缓冲都是
|
|
18
|
+
* `setEncoding('utf8')` 之后的**字符串**,逐块算 `Buffer.byteLength` 要么每次重算整段
|
|
19
|
+
* (O(n²)),要么另维护一个字节计数器(同一段缓冲两套长度,迟早漂)。码元长度是现成的、
|
|
20
|
+
* 单调递增的,做**上限**足够 —— 而且它是**保守**的:每个码元在内存里最少占 2 字节,
|
|
21
|
+
* 所以真实内存占用 ≤ 2× 这个值,不会低估到危险。
|
|
22
|
+
*
|
|
23
|
+
* 取值口径:**远大于任何合法报文,远小于能让进程 OOM**。MCP 的单条报文里可能装着工具结果
|
|
24
|
+
* (整份文件、整段日志),给小了会把正常调用打成协议错 —— 那比 OOM 更难查(症状是「偶发
|
|
25
|
+
* 失败」)。800 万码元是「一次性工具结果」的宽裕上界,同时上千个并发连接各自缓冲一份也仍
|
|
26
|
+
* 在几 GB 量级之外。
|
|
27
|
+
*
|
|
28
|
+
* ⚠️ 这是**硬上限,不是旋钮**:它没有「0 = 不限」的读法,所以不进 `core/limits.ts` 的旋钮表
|
|
29
|
+
* (那张表管的是「使用者能设的旋钮,0 是什么意思」)。要改它只能改代码 + 两侧用例。
|
|
30
|
+
*/
|
|
31
|
+
export const MAX_FRAME_CHARS = 8 * 1024 * 1024;
|
|
32
|
+
/**
|
|
33
|
+
* 上限的人类可读说法(两条桥的报错文案共用 —— 免得一处写「8 MiB」一处写「8388608」)。
|
|
34
|
+
* 数值与 `MAX_FRAME_CHARS` 同源,改上限不会让文案漂。
|
|
35
|
+
*/
|
|
36
|
+
export function frameLimitText() {
|
|
37
|
+
return `${MAX_FRAME_CHARS} 码元(约 ${MAX_FRAME_CHARS / (1024 * 1024)} MiB)`;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=line-framing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"line-framing.js","sourceRoot":"","sources":["../../src/core/line-framing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;AAE/C;;;GAGG;AACH,MAAM,UAAU,cAAc;IAC5B,OAAO,GAAG,eAAe,SAAS,eAAe,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC;AAC3E,CAAC"}
|
package/dist/core/message.d.ts
CHANGED
|
@@ -134,6 +134,17 @@ export interface MessageUsage {
|
|
|
134
134
|
output_tokens: number;
|
|
135
135
|
cache_creation_input_tokens?: number | null;
|
|
136
136
|
cache_read_input_tokens?: number | null;
|
|
137
|
+
/**
|
|
138
|
+
* 上游**根本没回报 usage**(整条流 / 整个响应都没带计量)时为 `true` ——
|
|
139
|
+
* 此时上面那些 `0` 是**替身值**,不是读数(2026-09-28 外部深评 S2)。
|
|
140
|
+
* 缺省 `undefined` = 上游真的回报了。
|
|
141
|
+
*
|
|
142
|
+
* 为什么必须显式标出来:`0` 与「不知道」在数值上无法区分,而成本估算拿到的就是
|
|
143
|
+
* 这个 `0` —— 于是 `maxCostUsd` 这条护栏**静默失效**(花销看起来恒为 0),
|
|
144
|
+
* 连「算不出成本」的信号都没有。引擎侧据此在 llm.turn span 上记 `usage.missing`
|
|
145
|
+
* 事件(见 `engine/turn.ts` 的 `recordTurnUsage`),报告与指标各有一处出声。
|
|
146
|
+
*/
|
|
147
|
+
unreported?: true;
|
|
137
148
|
}
|
|
138
149
|
/** 一次模型往返的最终响应(`ModelClient.messages.stream().finalMessage()` 的产物) */
|
|
139
150
|
export interface Message {
|