@migor/agentia 0.7.1 → 0.8.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.
Files changed (98) hide show
  1. package/CHANGELOG.md +115 -1
  2. package/README.md +10 -6
  3. package/dist/AGENTS.md +27 -6
  4. package/dist/engine/loop-result.d.ts +72 -0
  5. package/dist/engine/loop-result.js +80 -0
  6. package/dist/engine/loop-result.js.map +1 -0
  7. package/dist/engine/loop.d.ts +3 -40
  8. package/dist/engine/loop.js +31 -125
  9. package/dist/engine/loop.js.map +1 -1
  10. package/dist/engine/resume-input.d.ts +26 -0
  11. package/dist/engine/resume-input.js +39 -0
  12. package/dist/engine/resume-input.js.map +1 -0
  13. package/dist/engine/retry.d.ts +8 -0
  14. package/dist/engine/retry.js +10 -0
  15. package/dist/engine/retry.js.map +1 -1
  16. package/dist/engine/run-config.d.ts +28 -0
  17. package/dist/engine/run-config.js +75 -0
  18. package/dist/engine/run-config.js.map +1 -0
  19. package/dist/engine/stop-reason.d.ts +27 -0
  20. package/dist/engine/stop-reason.js +76 -0
  21. package/dist/engine/stop-reason.js.map +1 -0
  22. package/dist/engine/text.d.ts +10 -0
  23. package/dist/engine/text.js +6 -0
  24. package/dist/engine/text.js.map +1 -0
  25. package/dist/engine/tool-context.d.ts +32 -0
  26. package/dist/engine/tool-context.js +18 -0
  27. package/dist/engine/tool-context.js.map +1 -0
  28. package/dist/engine/tool-events.d.ts +42 -0
  29. package/dist/engine/tool-events.js +64 -0
  30. package/dist/engine/tool-events.js.map +1 -0
  31. package/dist/engine/turn-request.d.ts +24 -0
  32. package/dist/engine/turn-request.js +12 -0
  33. package/dist/engine/turn-request.js.map +1 -0
  34. package/dist/engine/turn.d.ts +3 -25
  35. package/dist/engine/turn.js +43 -155
  36. package/dist/engine/turn.js.map +1 -1
  37. package/dist/index.d.ts +3 -2
  38. package/dist/index.js +3 -2
  39. package/dist/index.js.map +1 -1
  40. package/dist/integrations/anthropic.d.ts +5 -0
  41. package/dist/integrations/anthropic.js +29 -2
  42. package/dist/integrations/anthropic.js.map +1 -1
  43. package/dist/integrations/mcp-http.d.ts +43 -0
  44. package/dist/integrations/mcp-http.js +250 -0
  45. package/dist/integrations/mcp-http.js.map +1 -0
  46. package/dist/integrations/mcp-stdio.d.ts +46 -0
  47. package/dist/integrations/mcp-stdio.js +230 -0
  48. package/dist/integrations/mcp-stdio.js.map +1 -0
  49. package/dist/integrations/mcp.d.ts +37 -72
  50. package/dist/integrations/mcp.js +9 -468
  51. package/dist/integrations/mcp.js.map +1 -1
  52. package/dist/integrations/metrics-otlp.d.ts +42 -0
  53. package/dist/integrations/metrics-otlp.js +178 -0
  54. package/dist/integrations/metrics-otlp.js.map +1 -0
  55. package/dist/integrations/metrics-render.d.ts +2 -0
  56. package/dist/integrations/metrics-render.js +145 -0
  57. package/dist/integrations/metrics-render.js.map +1 -0
  58. package/dist/integrations/metrics-state.d.ts +191 -0
  59. package/dist/integrations/metrics-state.js +363 -0
  60. package/dist/integrations/metrics-state.js.map +1 -0
  61. package/dist/integrations/metrics.d.ts +3 -86
  62. package/dist/integrations/metrics.js +28 -648
  63. package/dist/integrations/metrics.js.map +1 -1
  64. package/dist/integrations/openai.js +4 -3
  65. package/dist/integrations/openai.js.map +1 -1
  66. package/dist/store/fsStore.d.ts +1 -1
  67. package/dist/store/fsStore.js +5 -2
  68. package/dist/store/fsStore.js.map +1 -1
  69. package/dist/toolkit/tool.js +1 -0
  70. package/dist/toolkit/tool.js.map +1 -1
  71. package/dist/transport/approval-policy.d.ts +30 -0
  72. package/dist/transport/approval-policy.js +37 -0
  73. package/dist/transport/approval-policy.js.map +1 -0
  74. package/dist/transport/async.d.ts +13 -5
  75. package/dist/transport/async.js +143 -150
  76. package/dist/transport/async.js.map +1 -1
  77. package/dist/transport/drain-gate.d.ts +28 -0
  78. package/dist/transport/drain-gate.js +62 -0
  79. package/dist/transport/drain-gate.js.map +1 -0
  80. package/dist/transport/http-route.d.ts +55 -0
  81. package/dist/transport/http-route.js +72 -0
  82. package/dist/transport/http-route.js.map +1 -0
  83. package/dist/transport/http-shapes.d.ts +57 -0
  84. package/dist/transport/http-shapes.js +56 -0
  85. package/dist/transport/http-shapes.js.map +1 -0
  86. package/dist/transport/http.d.ts +5 -21
  87. package/dist/transport/http.js +176 -232
  88. package/dist/transport/http.js.map +1 -1
  89. package/dist/transport/resume-policy.d.ts +40 -0
  90. package/dist/transport/resume-policy.js +25 -0
  91. package/dist/transport/resume-policy.js.map +1 -0
  92. package/dist/transport/slot-pool.d.ts +24 -0
  93. package/dist/transport/slot-pool.js +43 -0
  94. package/dist/transport/slot-pool.js.map +1 -0
  95. package/dist/transport/task-waiters.d.ts +25 -0
  96. package/dist/transport/task-waiters.js +63 -0
  97. package/dist/transport/task-waiters.js.map +1 -0
  98. package/package.json +5 -4
@@ -1,22 +1,29 @@
1
1
  import { createAnthropicClient } from '../integrations/anthropic.js';
2
- import { classifyError } from './errors.js';
3
- import { resolveRetry } from './retry.js';
2
+ import { abortedResult, failedResult, finishedResult, suspendedResult } from './loop-result.js';
3
+ import { tailToolUses, textOfParam } from './resume-input.js';
4
+ import { DEFAULT_MAX_ITERATIONS, DEFAULT_MAX_TOKENS, resolveDefaultModel, runConfigSnapshot, } from './run-config.js';
4
5
  import { TraceRecorder } from './tracer.js';
5
- import { abortedError, budgetError, buildLoopContext, checkTurnEntry, executeTurnTools, recordTurnUsage, resolveStopReason, streamTurn, textOf, } from './turn.js';
6
+ import { abortedError, budgetError, buildLoopContext, checkTurnEntry, executeTurnTools, recordTurnUsage, streamTurn, textOf, } from './turn.js';
7
+ import { resolveStopReason } from './stop-reason.js';
6
8
  import { isSuccessStopReason } from './types.js';
7
9
  /**
8
- * 缺省模型解析:显式传入 > AGENTIA_MODEL env > 'claude-opus-5'。
9
- * 不把端点私有模型写死在代码里 —— 走 Anthropic 兼容网关(如 DeepSeek 端点)时
10
- * export AGENTIA_MODEL=deepseek-… 即可全局覆盖,无需逐处传 model。
10
+ * Agentia —— 主循环(manual loop,流式)—— spec §5。
11
+ *
12
+ * 结构:核心是 `agentLoop` —— 不自开 run 根,所有 llm.turn 挂在给定的
13
+ * parentSpanId 下。同一套循环既能当主 agent(run 根为其父,由 runAgent 开),
14
+ * 也能当子 agent(capability span 为其父,见 toolkit/subagent.ts),llm.turn 与 usage
15
+ * 递归进同一条 trace(spec §9:子 agent = 一个 capability span,内部能力递归成它的子孙)。
16
+ *
17
+ * 工具执行经 ctx: ToolRunContext 把 {client, recorder, parentSpanId: 当前 turn}
18
+ * 交给 tool.run —— 普通工具忽略;子 agent 用它在正确位置开 capability span。
19
+ *
20
+ * 文件分工:本文件只留入口(runAgent / runAgentScoped)与 agentLoop 编排骨架 +
21
+ * run 根的装配;「一回合执行步骤」的实现机(回合上下文、请求/重试、记账、stop_reason
22
+ * 分流、工具执行)拆在同层 turn.ts,「缺省旋钮解析 + 生效配置快照」拆在同层
23
+ * run-config.ts,「出口的结果形状」拆在同层 loop-result.ts ——
24
+ * 「续跑入口的读取件」拆在同层 resume-input.ts ——
25
+ * 依赖方向单向 loop.ts → { turn.ts, run-config.ts, loop-result.ts, resume-input.ts }。
11
26
  */
12
- export function resolveDefaultModel(over) {
13
- if (over)
14
- return over;
15
- return process.env.AGENTIA_MODEL?.trim() || 'claude-opus-5';
16
- }
17
- /** 缺省单次 maxTokens / 循环上限:runAgent 与 runAgentScoped 共用,避免两处各写一遍漂移。 */
18
- const DEFAULT_MAX_TOKENS = 64_000;
19
- const DEFAULT_MAX_ITERATIONS = 40;
20
27
  /**
21
28
  * 上下文策略按 run 隔离:实现提供 `forRun` 时每条 run 拿一个全新实例 ——
22
29
  * 内置 createBudgetPolicy 的滞回计数(lastCompactAt)与增量 token 缓存都是
@@ -28,38 +35,6 @@ const DEFAULT_MAX_ITERATIONS = 40;
28
35
  function forkPolicyPerRun(policy) {
29
36
  return policy?.forRun ? policy.forRun() : policy;
30
37
  }
31
- /**
32
- * 取消息历史**末尾**那条 assistant 消息里待解决的 tool_use 块(恢复模式检测)。
33
- * 空数组 = 不是恢复场景(正常从 user 消息起跑)。
34
- */
35
- function tailToolUses(messages) {
36
- const tail = messages[messages.length - 1];
37
- if (tail?.role !== 'assistant' || !Array.isArray(tail.content))
38
- return [];
39
- // ToolUseBlockParam 结构上兼容 ToolUseBlock(多一个可选 cache_control)
40
- return tail.content.filter((b) => b.type === 'tool_use');
41
- }
42
- /** 取 MessageParam(请求侧)里的文本块拼成的文本(恢复模式收尾时用) */
43
- function textOfParam(message) {
44
- if (!Array.isArray(message.content))
45
- return typeof message.content === 'string' ? message.content : '';
46
- return message.content
47
- .filter((b) => b.type === 'text')
48
- .map((b) => b.text ?? '')
49
- .join('\n');
50
- }
51
- /** 挂起收尾的结果对象(两处出口共用:循环中途挂起 / 恢复模式进来发现决定仍不齐) */
52
- function suspendResult(ctx, pending) {
53
- return {
54
- stopReason: 'awaiting_approval',
55
- finalText: '',
56
- error: undefined,
57
- iterations: ctx.progress.iterations,
58
- typed: ctx.typed,
59
- suspendedMessages: [...ctx.messages],
60
- pendingApprovals: pending,
61
- };
62
- }
63
38
  /**
64
39
  * 循环体核心:带父 span 跑一轮 manual loop。请求失败按 error 收掉 turn 后抛出,由外层收尾。
65
40
  *
@@ -83,35 +58,25 @@ async function agentLoop(args) {
83
58
  if (resumeUses.length > 0) {
84
59
  // 已取消:不执行任何工具(副作用不该在取消后发生),按 aborted 收尾
85
60
  if (args.signal?.aborted) {
86
- return {
87
- stopReason: 'aborted',
88
- finalText: '',
89
- error: abortedError(),
90
- iterations: 0,
91
- typed: undefined,
92
- suspendedMessages: undefined,
93
- pendingApprovals: undefined,
94
- };
61
+ return abortedResult();
95
62
  }
96
63
  // 工具事件记到父 span:被恢复的回合属于挂起段的旧 trace,本段没有对应 llm.turn
97
64
  const outcome = await executeTurnTools(ctx, args.parentSpanId ?? '', resumeUses, null);
98
65
  if (outcome.kind === 'suspended') {
99
- return suspendResult(ctx, outcome.pending);
66
+ return suspendedResult(ctx, outcome.pending);
100
67
  }
101
68
  if (outcome.results.length > 0)
102
69
  ctx.messages.push({ role: 'user', content: outcome.results });
103
70
  if (ctx.submitted) {
104
71
  // 恢复的回合里 submit_result 校验通过:直接落定(finalText 取该 assistant 消息的文本块)
105
72
  const tail = ctx.messages[ctx.messages.length - 2]; // 刚 push 了 tool_results,前一条是那条 assistant
106
- return {
73
+ // iterations 0:本段没发过模型请求(恢复的工具执行不计往返)
74
+ return finishedResult({
107
75
  stopReason: 'end_turn',
108
76
  finalText: tail ? textOfParam(tail) : '',
109
- error: undefined,
110
77
  iterations: 0,
111
78
  typed: ctx.typed,
112
- suspendedMessages: undefined,
113
- pendingApprovals: undefined,
114
- };
79
+ });
115
80
  }
116
81
  }
117
82
  for (let iteration = 0; iteration < args.maxIterations; iteration++) {
@@ -154,7 +119,7 @@ async function agentLoop(args) {
154
119
  // error 保持 undefined —— 挂起不是失败。
155
120
  stopReason = 'awaiting_approval';
156
121
  finalText = textOf(message);
157
- return { ...suspendResult(ctx, outcome.pending), finalText };
122
+ return suspendedResult(ctx, outcome.pending, finalText);
158
123
  }
159
124
  if (outcome.results.length > 0)
160
125
  ctx.messages.push({ role: 'user', content: outcome.results });
@@ -184,15 +149,13 @@ async function agentLoop(args) {
184
149
  retryable: false,
185
150
  };
186
151
  }
187
- return {
152
+ return finishedResult({
188
153
  stopReason,
189
154
  finalText,
190
- error,
191
155
  iterations: ctx.progress.iterations,
192
156
  typed: ctx.typed,
193
- suspendedMessages: undefined,
194
- pendingApprovals: undefined,
195
- };
157
+ error,
158
+ });
196
159
  }
197
160
  /** 主入口:开 run 根 span,循环跑在其下。返回完整 trace(traceId 即 runId)。 */
198
161
  export async function runAgent(options) {
@@ -260,15 +223,7 @@ export async function runAgent(options) {
260
223
  }
261
224
  catch (e) {
262
225
  // 硬写 0 会把「第 3 回合请求失败」报成「一次模型都没调」——按实际进度报
263
- result = {
264
- stopReason: 'error',
265
- finalText: '',
266
- error: classifyError(e),
267
- iterations: progress.iterations,
268
- typed: undefined,
269
- suspendedMessages: undefined,
270
- pendingApprovals: undefined,
271
- };
226
+ result = failedResult(e, progress.iterations);
272
227
  }
273
228
  // awaiting_approval 不是失败:挂起段本身执行无误(「等人」不该被看板算成「失败」),
274
229
  // trace 记 ok;它与成功的区分由 stop_reason attribute 承担。
@@ -319,53 +274,4 @@ export async function runAgentScoped(opts) {
319
274
  maxCostUsd: opts.maxCostUsd,
320
275
  });
321
276
  }
322
- /**
323
- * 生效配置快照(G3):把本 run 实际生效的旋钮整理成 run 根的 `config.*` attributes。
324
- * 只放标量(OTLP/日志/看板都能直接吃);缺省值也记,这样"没配"与"配了缺省值"可区分于
325
- * "该项不存在"。函数型选项只记"配没配",不记函数体。
326
- */
327
- function runConfigSnapshot(options) {
328
- const out = {
329
- 'config.model': resolveDefaultModel(options.model),
330
- 'config.maxTokens': options.maxTokens ?? DEFAULT_MAX_TOKENS,
331
- 'config.maxIterations': options.maxIterations ?? DEFAULT_MAX_ITERATIONS,
332
- };
333
- if (options.maxTotalTokens != null)
334
- out['config.maxTotalTokens'] = options.maxTotalTokens;
335
- if (options.maxCostUsd != null)
336
- out['config.maxCostUsd'] = options.maxCostUsd;
337
- if (options.toolTimeoutMs != null)
338
- out['config.toolTimeoutMs'] = options.toolTimeoutMs;
339
- // 非正 / 非有限值在 `mapWithConcurrency` 里一律等于「不限并发」,但原样记进 trace 会写成
340
- // `NaN`(过不了 JSON/OTLP 序列化,到看板上是 null)或 `-1`(读起来像「卡在负数个并发」)。
341
- // 记**生效的**整数(`floor` 且至少 1,见 `concurrency.ts`),不限则同 `maxEventChars` 记 'off'。
342
- if (options.maxToolConcurrency != null)
343
- out['config.maxToolConcurrency'] =
344
- Number.isFinite(options.maxToolConcurrency) && options.maxToolConcurrency > 0
345
- ? Math.max(1, Math.floor(options.maxToolConcurrency))
346
- : 'off';
347
- // 事件截断关掉时记 'off' 而不是 false:`maxEventChars: false` 在日志/看板里
348
- // 容易被读成「上限为 0」,'off' 一句话说清是**没有上限**
349
- if (options.maxEventChars != null)
350
- out['config.maxEventChars'] = options.maxEventChars === false ? 'off' : options.maxEventChars;
351
- // 重试:记生效的 maxAttempts(0 = 关闭)—— 比记 "custom/default" 更有信息量
352
- const retryCfg = resolveRetry(options.retry);
353
- out['config.retry.maxAttempts'] = retryCfg ? retryCfg.maxAttempts : 0;
354
- const policy = options.contextPolicy;
355
- if (policy) {
356
- out['config.contextPolicy'] = true;
357
- if (policy.budgetTokens != null)
358
- out['config.contextPolicy.budgetTokens'] = policy.budgetTokens;
359
- }
360
- else {
361
- out['config.contextPolicy'] = false;
362
- }
363
- // 价格覆盖:只记覆盖了哪几个模型(不记单价 —— 单价在价格表里,重复记会漂移)
364
- const overridden = options.priceOverrides ? Object.keys(options.priceOverrides) : [];
365
- if (overridden.length > 0)
366
- out['config.priceOverrides'] = overridden.sort().join(',');
367
- if (options.resultSchema)
368
- out['config.resultSchema'] = true;
369
- return out;
370
- }
371
277
  //# sourceMappingURL=loop.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"loop.js","sourceRoot":"","sources":["../../src/engine/loop.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"loop.js","sourceRoot":"","sources":["../../src/engine/loop.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import type { MessageParam, ToolUseBlock } from '../core/message.js';
2
+ /**
3
+ * Agentia —— 续跑入口的**读取件**(engine/loop.ts 的拆分第三步)。
4
+ *
5
+ * 两个函数只服务同一条路径:**HITL 挂起后的续跑**(也是通用续跑入口)。
6
+ *
7
+ * ① `tailToolUses`:识别这次进循环是「续跑」还是「新起一段」—— 判据是**历史末尾**
8
+ * 那条 assistant 里还有没有未解决的 tool_use。判错的后果不对称:漏判 = 把续跑
9
+ * 当新对话(重新请求模型、花费翻倍、同一批工具再跑一遍);误判 = 一个工具都没
10
+ * 声明就发请求。所以它只认末尾一条,且把「不是 assistant / content 不是块数组」
11
+ * 一律当**不是续跑**(宁可不续,不可乱续)。
12
+ * ② `textOfParam`:续跑落定时从历史里取那段文本(`submit_result` 校验通过后,
13
+ * finalText 要取**该 assistant 消息**的文本块,而不是刚 push 进去的 tool_results)。
14
+ *
15
+ * 文件分工:文本口径的单源仍是 `engine/text.ts`(多块用 `\n` 连接);这里不直接用
16
+ * `textOf()` 是因为**请求侧消息的形状不同** —— `content` 可能是裸字符串,且块的
17
+ * `text` 是可选的(`?? ''`),与响应侧 Message 的必填 `text` 不是同一个类型。
18
+ * 编排(什么时候调用、调用完做什么)留在 engine/loop.ts。
19
+ */
20
+ /**
21
+ * 取消息历史**末尾**那条 assistant 消息里待解决的 tool_use 块(恢复模式检测)。
22
+ * 空数组 = 不是恢复场景(正常从 user 消息起跑)。
23
+ */
24
+ export declare function tailToolUses(messages: MessageParam[]): ToolUseBlock[];
25
+ /** 取 MessageParam(请求侧)里的文本块拼成的文本(恢复模式收尾时用) */
26
+ export declare function textOfParam(message: MessageParam): string;
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Agentia —— 续跑入口的**读取件**(engine/loop.ts 的拆分第三步)。
3
+ *
4
+ * 两个函数只服务同一条路径:**HITL 挂起后的续跑**(也是通用续跑入口)。
5
+ *
6
+ * ① `tailToolUses`:识别这次进循环是「续跑」还是「新起一段」—— 判据是**历史末尾**
7
+ * 那条 assistant 里还有没有未解决的 tool_use。判错的后果不对称:漏判 = 把续跑
8
+ * 当新对话(重新请求模型、花费翻倍、同一批工具再跑一遍);误判 = 一个工具都没
9
+ * 声明就发请求。所以它只认末尾一条,且把「不是 assistant / content 不是块数组」
10
+ * 一律当**不是续跑**(宁可不续,不可乱续)。
11
+ * ② `textOfParam`:续跑落定时从历史里取那段文本(`submit_result` 校验通过后,
12
+ * finalText 要取**该 assistant 消息**的文本块,而不是刚 push 进去的 tool_results)。
13
+ *
14
+ * 文件分工:文本口径的单源仍是 `engine/text.ts`(多块用 `\n` 连接);这里不直接用
15
+ * `textOf()` 是因为**请求侧消息的形状不同** —— `content` 可能是裸字符串,且块的
16
+ * `text` 是可选的(`?? ''`),与响应侧 Message 的必填 `text` 不是同一个类型。
17
+ * 编排(什么时候调用、调用完做什么)留在 engine/loop.ts。
18
+ */
19
+ /**
20
+ * 取消息历史**末尾**那条 assistant 消息里待解决的 tool_use 块(恢复模式检测)。
21
+ * 空数组 = 不是恢复场景(正常从 user 消息起跑)。
22
+ */
23
+ export function tailToolUses(messages) {
24
+ const tail = messages[messages.length - 1];
25
+ if (tail?.role !== 'assistant' || !Array.isArray(tail.content))
26
+ return [];
27
+ // ToolUseBlockParam 结构上兼容 ToolUseBlock(多一个可选 cache_control)
28
+ return tail.content.filter((b) => b.type === 'tool_use');
29
+ }
30
+ /** 取 MessageParam(请求侧)里的文本块拼成的文本(恢复模式收尾时用) */
31
+ export function textOfParam(message) {
32
+ if (!Array.isArray(message.content))
33
+ return typeof message.content === 'string' ? message.content : '';
34
+ return message.content
35
+ .filter((b) => b.type === 'text')
36
+ .map((b) => b.text ?? '')
37
+ .join('\n');
38
+ }
39
+ //# sourceMappingURL=resume-input.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resume-input.js","sourceRoot":"","sources":["../../src/engine/resume-input.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;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"}
@@ -61,3 +61,11 @@ export declare function backoffDelay(attempt: number, r: ResolvedRetry): number;
61
61
  * 逼出来的,所以合一的落点只能是 core。这里只钉住本层的取消文案。
62
62
  */
63
63
  export declare function sleep(ms: number, signal?: AbortSignal): Promise<void>;
64
+ /**
65
+ * 本次失败能否重试:**四项合取** —— 配置在场 + 次数未尽 + 判定可重试 + 本次尝试**未产出任何文本**。
66
+ *
67
+ * 从 turn.ts 的 streamTurn 行内抽出(2026-09-20,turn 拆分第二步)。最后一项是护栏,不是优化:
68
+ * **已经吐出去的字收不回来**,重试会重复输出 —— 所以吐过就一律不重试,哪怕错误本身可重试、
69
+ * 次数也还有余量。这四条此前只能透过整条 run 的行为间接观察。
70
+ */
71
+ export declare function retryAllowed(cfg: ResolvedRetry | null, attempt: number, error: unknown, emitted: boolean): boolean;
@@ -67,4 +67,14 @@ export function backoffDelay(attempt, r) {
67
67
  export function sleep(ms, signal) {
68
68
  return interruptibleSleep(ms, signal, 'run 已被取消');
69
69
  }
70
+ /**
71
+ * 本次失败能否重试:**四项合取** —— 配置在场 + 次数未尽 + 判定可重试 + 本次尝试**未产出任何文本**。
72
+ *
73
+ * 从 turn.ts 的 streamTurn 行内抽出(2026-09-20,turn 拆分第二步)。最后一项是护栏,不是优化:
74
+ * **已经吐出去的字收不回来**,重试会重复输出 —— 所以吐过就一律不重试,哪怕错误本身可重试、
75
+ * 次数也还有余量。这四条此前只能透过整条 run 的行为间接观察。
76
+ */
77
+ export function retryAllowed(cfg, attempt, error, emitted) {
78
+ return cfg !== null && attempt < cfg.maxAttempts && cfg.isRetryable(error) && !emitted;
79
+ }
70
80
  //# sourceMappingURL=retry.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"retry.js","sourceRoot":"","sources":["../../src/engine/retry.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAgC5C,+CAA+C;AAC/C,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,WAAW,EAAE,CAAC;IACd,WAAW,EAAE,GAAG;IAChB,UAAU,EAAE,IAAI;IAChB,MAAM,EAAE,GAAG;CACH,CAAC;AAIX;;;;;;;GAOG;AACH,SAAS,WAAW,CAAC,CAA2B;IAC9C,MAAM,GAAG,GAAiB,EAAE,CAAC;IAC7B,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;QAC7C,IAAI,CAAC,KAAK,SAAS;YAAG,GAA+B,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAC/D,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,8DAA8D;AAC9D,MAAM,UAAU,YAAY,CAAC,CAAmC;IAC9D,IAAI,CAAC,KAAK,KAAK;QAAE,OAAO,IAAI,CAAC;IAC7B,6CAA6C;IAC7C,mEAAmE;IACnE,wDAAwD;IACxD,iEAAiE;IACjE,yDAAyD;IACzD,MAAM,MAAM,GAAG,EAAE,GAAG,aAAa,EAAE,GAAG,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC;IACvD,IAAI,CAAC,CAAC,MAAM,CAAC,WAAW,IAAI,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC,CAAC,uBAAuB;IACpE,OAAO;QACL,GAAG,MAAM;QACT,WAAW,EAAE,CAAC,EAAE,WAAW,IAAI,CAAC,CAAC,CAAU,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAC3E,OAAO,EAAE,CAAC,EAAE,OAAO,IAAI,CAAC,GAAS,EAAE,GAAE,CAAC,CAAC;KACxC,CAAC;AACJ,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,YAAY,CAAC,OAAe,EAAE,CAAgB;IAC5D,MAAM,GAAG,GAAG,CAAC,CAAC,WAAW,GAAG,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,CAAC,CAAC;IAC1D,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC;IAC3C,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9E,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC;AAClD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,KAAK,CAAC,EAAU,EAAE,MAAoB;IACpD,OAAO,kBAAkB,CAAC,EAAE,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;AACpD,CAAC"}
1
+ {"version":3,"file":"retry.js","sourceRoot":"","sources":["../../src/engine/retry.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAgC5C,+CAA+C;AAC/C,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,WAAW,EAAE,CAAC;IACd,WAAW,EAAE,GAAG;IAChB,UAAU,EAAE,IAAI;IAChB,MAAM,EAAE,GAAG;CACH,CAAC;AAIX;;;;;;;GAOG;AACH,SAAS,WAAW,CAAC,CAA2B;IAC9C,MAAM,GAAG,GAAiB,EAAE,CAAC;IAC7B,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;QAC7C,IAAI,CAAC,KAAK,SAAS;YAAG,GAA+B,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAC/D,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,8DAA8D;AAC9D,MAAM,UAAU,YAAY,CAAC,CAAmC;IAC9D,IAAI,CAAC,KAAK,KAAK;QAAE,OAAO,IAAI,CAAC;IAC7B,6CAA6C;IAC7C,mEAAmE;IACnE,wDAAwD;IACxD,iEAAiE;IACjE,yDAAyD;IACzD,MAAM,MAAM,GAAG,EAAE,GAAG,aAAa,EAAE,GAAG,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC;IACvD,IAAI,CAAC,CAAC,MAAM,CAAC,WAAW,IAAI,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC,CAAC,uBAAuB;IACpE,OAAO;QACL,GAAG,MAAM;QACT,WAAW,EAAE,CAAC,EAAE,WAAW,IAAI,CAAC,CAAC,CAAU,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAC3E,OAAO,EAAE,CAAC,EAAE,OAAO,IAAI,CAAC,GAAS,EAAE,GAAE,CAAC,CAAC;KACxC,CAAC;AACJ,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,YAAY,CAAC,OAAe,EAAE,CAAgB;IAC5D,MAAM,GAAG,GAAG,CAAC,CAAC,WAAW,GAAG,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,CAAC,CAAC;IAC1D,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC;IAC3C,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9E,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC;AAClD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,KAAK,CAAC,EAAU,EAAE,MAAoB;IACpD,OAAO,kBAAkB,CAAC,EAAE,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;AACpD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAC1B,GAAyB,EACzB,OAAe,EACf,KAAc,EACd,OAAgB;IAEhB,OAAO,GAAG,KAAK,IAAI,IAAI,OAAO,GAAG,GAAG,CAAC,WAAW,IAAI,GAAG,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC;AACzF,CAAC"}
@@ -0,0 +1,28 @@
1
+ import type { JsonSchema } from '../core/tool.js';
2
+ import type { RunAgentOptions } from './types.js';
3
+ /**
4
+ * Agentia —— run 生效旋钮:**缺省解析 + 快照编码**(spec §5 / §9 G3)。
5
+ *
6
+ * 本文件回答两件事,而且是同一件事的两面:
7
+ * ① 跑一条 run 时各项旋钮**实际取到什么值**(显式传入 / env / 缺省);
8
+ * ② 这些值**怎么记进 run 根**(`config.*` attributes)。
9
+ * 认下缺省值的人必须是把它写进 trace 的人 —— 否则「记录的」与「生效的」会漂移。
10
+ *
11
+ * 文件分工:本文件只做**纯映射**(读 options 与 env,不碰 recorder / 网络 / 时钟,
12
+ * 不构造 span,不写属性);开 run 根、把快照写进去、循环编排都在 engine/loop.ts。
13
+ */
14
+ /**
15
+ * 缺省模型解析:显式传入 > AGENTIA_MODEL env > 'claude-opus-5'。
16
+ * 不把端点私有模型写死在代码里 —— 走 Anthropic 兼容网关(如 DeepSeek 端点)时
17
+ * export AGENTIA_MODEL=deepseek-… 即可全局覆盖,无需逐处传 model。
18
+ */
19
+ export declare function resolveDefaultModel(over?: string): string;
20
+ /** 缺省单次 maxTokens / 循环上限:runAgent 与 runAgentScoped 共用,避免两处各写一遍漂移。 */
21
+ export declare const DEFAULT_MAX_TOKENS = 64000;
22
+ export declare const DEFAULT_MAX_ITERATIONS = 40;
23
+ /**
24
+ * 生效配置快照(G3):把本 run 实际生效的旋钮整理成 run 根的 `config.*` attributes。
25
+ * 只放标量(OTLP/日志/看板都能直接吃);缺省值也记,这样"没配"与"配了缺省值"可区分于
26
+ * "该项不存在"。函数型选项只记"配没配",不记函数体。
27
+ */
28
+ export declare function runConfigSnapshot(options: RunAgentOptions<JsonSchema>): Record<string, string | number | boolean>;
@@ -0,0 +1,75 @@
1
+ import { resolveRetry } from './retry.js';
2
+ /**
3
+ * Agentia —— run 生效旋钮:**缺省解析 + 快照编码**(spec §5 / §9 G3)。
4
+ *
5
+ * 本文件回答两件事,而且是同一件事的两面:
6
+ * ① 跑一条 run 时各项旋钮**实际取到什么值**(显式传入 / env / 缺省);
7
+ * ② 这些值**怎么记进 run 根**(`config.*` attributes)。
8
+ * 认下缺省值的人必须是把它写进 trace 的人 —— 否则「记录的」与「生效的」会漂移。
9
+ *
10
+ * 文件分工:本文件只做**纯映射**(读 options 与 env,不碰 recorder / 网络 / 时钟,
11
+ * 不构造 span,不写属性);开 run 根、把快照写进去、循环编排都在 engine/loop.ts。
12
+ */
13
+ /**
14
+ * 缺省模型解析:显式传入 > AGENTIA_MODEL env > 'claude-opus-5'。
15
+ * 不把端点私有模型写死在代码里 —— 走 Anthropic 兼容网关(如 DeepSeek 端点)时
16
+ * export AGENTIA_MODEL=deepseek-… 即可全局覆盖,无需逐处传 model。
17
+ */
18
+ export function resolveDefaultModel(over) {
19
+ if (over)
20
+ return over;
21
+ return process.env.AGENTIA_MODEL?.trim() || 'claude-opus-5';
22
+ }
23
+ /** 缺省单次 maxTokens / 循环上限:runAgent 与 runAgentScoped 共用,避免两处各写一遍漂移。 */
24
+ export const DEFAULT_MAX_TOKENS = 64_000;
25
+ export const DEFAULT_MAX_ITERATIONS = 40;
26
+ /**
27
+ * 生效配置快照(G3):把本 run 实际生效的旋钮整理成 run 根的 `config.*` attributes。
28
+ * 只放标量(OTLP/日志/看板都能直接吃);缺省值也记,这样"没配"与"配了缺省值"可区分于
29
+ * "该项不存在"。函数型选项只记"配没配",不记函数体。
30
+ */
31
+ export function runConfigSnapshot(options) {
32
+ const out = {
33
+ 'config.model': resolveDefaultModel(options.model),
34
+ 'config.maxTokens': options.maxTokens ?? DEFAULT_MAX_TOKENS,
35
+ 'config.maxIterations': options.maxIterations ?? DEFAULT_MAX_ITERATIONS,
36
+ };
37
+ if (options.maxTotalTokens != null)
38
+ out['config.maxTotalTokens'] = options.maxTotalTokens;
39
+ if (options.maxCostUsd != null)
40
+ out['config.maxCostUsd'] = options.maxCostUsd;
41
+ if (options.toolTimeoutMs != null)
42
+ out['config.toolTimeoutMs'] = options.toolTimeoutMs;
43
+ // 非正 / 非有限值在 `mapWithConcurrency` 里一律等于「不限并发」,但原样记进 trace 会写成
44
+ // `NaN`(过不了 JSON/OTLP 序列化,到看板上是 null)或 `-1`(读起来像「卡在负数个并发」)。
45
+ // 记**生效的**整数(`floor` 且至少 1,见 `concurrency.ts`),不限则同 `maxEventChars` 记 'off'。
46
+ if (options.maxToolConcurrency != null)
47
+ out['config.maxToolConcurrency'] =
48
+ Number.isFinite(options.maxToolConcurrency) && options.maxToolConcurrency > 0
49
+ ? Math.max(1, Math.floor(options.maxToolConcurrency))
50
+ : 'off';
51
+ // 事件截断关掉时记 'off' 而不是 false:`maxEventChars: false` 在日志/看板里
52
+ // 容易被读成「上限为 0」,'off' 一句话说清是**没有上限**
53
+ if (options.maxEventChars != null)
54
+ out['config.maxEventChars'] = options.maxEventChars === false ? 'off' : options.maxEventChars;
55
+ // 重试:记生效的 maxAttempts(0 = 关闭)—— 比记 "custom/default" 更有信息量
56
+ const retryCfg = resolveRetry(options.retry);
57
+ out['config.retry.maxAttempts'] = retryCfg ? retryCfg.maxAttempts : 0;
58
+ const policy = options.contextPolicy;
59
+ if (policy) {
60
+ out['config.contextPolicy'] = true;
61
+ if (policy.budgetTokens != null)
62
+ out['config.contextPolicy.budgetTokens'] = policy.budgetTokens;
63
+ }
64
+ else {
65
+ out['config.contextPolicy'] = false;
66
+ }
67
+ // 价格覆盖:只记覆盖了哪几个模型(不记单价 —— 单价在价格表里,重复记会漂移)
68
+ const overridden = options.priceOverrides ? Object.keys(options.priceOverrides) : [];
69
+ if (overridden.length > 0)
70
+ out['config.priceOverrides'] = overridden.sort().join(',');
71
+ if (options.resultSchema)
72
+ out['config.resultSchema'] = true;
73
+ return out;
74
+ }
75
+ //# sourceMappingURL=run-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-config.js","sourceRoot":"","sources":["../../src/engine/run-config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * 回合收尾的**纯判定**:把模型返回的 `stop_reason` 映射成循环该做什么。
3
+ *
4
+ * 从 turn.ts 外移(2026-09-20)。理由与 transport 那批一致:这张映射表混在 700 行的回合执行机里
5
+ * 时,只能透过 `loop.test.ts` 的端到端用例间接观察 —— 而它恰恰是「非正常收尾必须带结构化 error」
6
+ * 这条不变量的唯一落点(`tool_use_no_blocks` 曾经漏挂 error:run 以 failed 收尾却看不出原因)。
7
+ *
8
+ * 纯的边界:只读 `message.stop_reason` 与 `message.content`,不碰引擎、不记账、不落库。
9
+ */
10
+ import type { Message, ToolUseBlock } from '../core/message.js';
11
+ import type { SpanError } from '../core/trace.js';
12
+ import type { AgentStopReason } from './types.js';
13
+ export type StopResolution = {
14
+ kind: 'finish';
15
+ stopReason: AgentStopReason;
16
+ finalText: string;
17
+ error?: SpanError;
18
+ } | {
19
+ kind: 'tools';
20
+ toolUses: ToolUseBlock[];
21
+ };
22
+ /**
23
+ * —— 终止/边界分支(每个都给出终止结论,退出循环不再兜底改判)——
24
+ * 五种已知 stop_reason 各有归宿;剩余形态按「有没有可执行块」区分:
25
+ * 畸形 tool_use(块为空)与框架不认识的 stop_reason。
26
+ */
27
+ export declare function resolveStopReason(message: Message, maxTokens: number): StopResolution;
@@ -0,0 +1,76 @@
1
+ import { textOf } from './text.js';
2
+ /**
3
+ * —— 终止/边界分支(每个都给出终止结论,退出循环不再兜底改判)——
4
+ * 五种已知 stop_reason 各有归宿;剩余形态按「有没有可执行块」区分:
5
+ * 畸形 tool_use(块为空)与框架不认识的 stop_reason。
6
+ */
7
+ export function resolveStopReason(message, maxTokens) {
8
+ if (message.stop_reason === 'end_turn') {
9
+ return { kind: 'finish', stopReason: 'end_turn', finalText: textOf(message) };
10
+ }
11
+ if (message.stop_reason === 'refusal') {
12
+ return {
13
+ kind: 'finish',
14
+ stopReason: 'refusal',
15
+ finalText: textOf(message),
16
+ error: { type: 'refusal', message: 'model refused the request', retryable: false },
17
+ };
18
+ }
19
+ if (message.stop_reason === 'max_tokens') {
20
+ // 与 budget_exceeded / refusal 同口径:非正常收尾都带结构化 error(进 run 根 span),
21
+ // 否则 trace 里这类 run「失败却没有原因」
22
+ return {
23
+ kind: 'finish',
24
+ stopReason: 'max_tokens',
25
+ finalText: textOf(message),
26
+ error: {
27
+ type: 'max_tokens',
28
+ message: `模型输出触顶被截断(max_tokens=${maxTokens})`,
29
+ retryable: false,
30
+ },
31
+ };
32
+ }
33
+ if (message.stop_reason === 'pause_turn') {
34
+ // 无 server tools 时正常不会到;避免无限循环直接停
35
+ return {
36
+ kind: 'finish',
37
+ stopReason: 'pause_turn',
38
+ finalText: textOf(message),
39
+ error: {
40
+ type: 'pause_turn',
41
+ message: '模型返回 pause_turn(无 server tools 的场景不应出现),防死循环直接收尾',
42
+ retryable: false,
43
+ },
44
+ };
45
+ }
46
+ if (message.stop_reason === 'stop_sequence') {
47
+ // 命中 stop 序列 = 正常收尾(与 end_turn 同类),不是失败
48
+ return { kind: 'finish', stopReason: 'stop_sequence', finalText: textOf(message) };
49
+ }
50
+ const toolUses = message.content.filter((b) => b.type === 'tool_use');
51
+ if (toolUses.length === 0) {
52
+ // 到这里的剩余 stop_reason 不会产生可执行块,防死循环直接停:
53
+ // 'tool_use' 但块为空(畸形响应)与「本框架不认识的 stop_reason」区分开。
54
+ //
55
+ // **两种都属非正常收尾,都必须挂结构化 error** —— engine/loop.ts 的不变量是
56
+ // 「非正常收尾都带结构化 error」(与 budget_exceeded / refusal / max_iterations 同口径)。
57
+ // 此前只有 unknown_stop_reason 带 error,tool_use_no_blocks 不带:run 以
58
+ // status:'failed' 收尾、result.error 却是 undefined,HTTP body 与任务记录里
59
+ // 看不出「为什么失败」,只能看到一句 stopReason 字符串。
60
+ const stopReason = message.stop_reason === 'tool_use' ? 'tool_use_no_blocks' : 'unknown_stop_reason';
61
+ return {
62
+ kind: 'finish',
63
+ stopReason,
64
+ finalText: textOf(message),
65
+ error: {
66
+ type: 'agent_error',
67
+ message: stopReason === 'tool_use_no_blocks'
68
+ ? '模型以 stop_reason=tool_use 收尾,但响应里没有任何 tool_use 块(畸形响应)'
69
+ : `模型返回了未识别的 stop_reason: ${String(message.stop_reason)}`,
70
+ retryable: false,
71
+ },
72
+ };
73
+ }
74
+ return { kind: 'tools', toolUses };
75
+ }
76
+ //# sourceMappingURL=stop-reason.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stop-reason.js","sourceRoot":"","sources":["../../src/engine/stop-reason.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAMnC;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAAgB,EAAE,SAAiB;IACnE,IAAI,OAAO,CAAC,WAAW,KAAK,UAAU,EAAE,CAAC;QACvC,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;IAChF,CAAC;IACD,IAAI,OAAO,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;QACtC,OAAO;YACL,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE,SAAS;YACrB,SAAS,EAAE,MAAM,CAAC,OAAO,CAAC;YAC1B,KAAK,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,2BAA2B,EAAE,SAAS,EAAE,KAAK,EAAE;SACnF,CAAC;IACJ,CAAC;IACD,IAAI,OAAO,CAAC,WAAW,KAAK,YAAY,EAAE,CAAC;QACzC,kEAAkE;QAClE,4BAA4B;QAC5B,OAAO;YACL,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE,YAAY;YACxB,SAAS,EAAE,MAAM,CAAC,OAAO,CAAC;YAC1B,KAAK,EAAE;gBACL,IAAI,EAAE,YAAY;gBAClB,OAAO,EAAE,wBAAwB,SAAS,GAAG;gBAC7C,SAAS,EAAE,KAAK;aACjB;SACF,CAAC;IACJ,CAAC;IACD,IAAI,OAAO,CAAC,WAAW,KAAK,YAAY,EAAE,CAAC;QACzC,kCAAkC;QAClC,OAAO;YACL,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE,YAAY;YACxB,SAAS,EAAE,MAAM,CAAC,OAAO,CAAC;YAC1B,KAAK,EAAE;gBACL,IAAI,EAAE,YAAY;gBAClB,OAAO,EAAE,kDAAkD;gBAC3D,SAAS,EAAE,KAAK;aACjB;SACF,CAAC;IACJ,CAAC;IACD,IAAI,OAAO,CAAC,WAAW,KAAK,eAAe,EAAE,CAAC;QAC5C,wCAAwC;QACxC,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;IACrF,CAAC;IAED,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAqB,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;IACzF,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,uCAAuC;QACvC,kDAAkD;QAClD,EAAE;QACF,sDAAsD;QACtD,wEAAwE;QACxE,+DAA+D;QAC/D,gEAAgE;QAChE,oCAAoC;QACpC,MAAM,UAAU,GACd,OAAO,CAAC,WAAW,KAAK,UAAU,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,qBAAqB,CAAC;QACpF,OAAO;YACL,IAAI,EAAE,QAAQ;YACd,UAAU;YACV,SAAS,EAAE,MAAM,CAAC,OAAO,CAAC;YAC1B,KAAK,EAAE;gBACL,IAAI,EAAE,aAAa;gBACnB,OAAO,EACL,UAAU,KAAK,oBAAoB;oBACjC,CAAC,CAAC,uDAAuD;oBACzD,CAAC,CAAC,0BAA0B,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE;gBAC7D,SAAS,EAAE,KAAK;aACjB;SACF,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC;AACrC,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * 引擎侧的文本读取口径(**单源**):多文本块用 `\n` 连接。
3
+ *
4
+ * 从 turn.ts 外移(2026-09-20,turn 拆分第一步):`stop-reason.ts` 也要用这个口径,而它若
5
+ * 继续从 turn.ts 取、turn.ts 又要 import stop-reason.ts ⇒ **成环**(分层守卫禁环)。这一层很薄,
6
+ * 但「引擎用 `\n`、适配器用 `''`」这个选择必须只有一处 —— 见 core/text.ts 头注。
7
+ */
8
+ import type { Message } from '../core/message.js';
9
+ /** 取消息里的全部文本块(引擎口径:多块按 `\n` 连接,保住模型的分段输出) */
10
+ export declare function textOf(message: Message): string;
@@ -0,0 +1,6 @@
1
+ import { textOf as coreTextOf } from '../core/text.js';
2
+ /** 取消息里的全部文本块(引擎口径:多块按 `\n` 连接,保住模型的分段输出) */
3
+ export function textOf(message) {
4
+ return coreTextOf(message, '\n');
5
+ }
6
+ //# sourceMappingURL=text.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text.js","sourceRoot":"","sources":["../../src/engine/text.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAEvD,6CAA6C;AAC7C,MAAM,UAAU,MAAM,CAAC,OAAgB;IACrC,OAAO,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;AACnC,CAAC"}