@sema-agent/server 7.142.0 → 7.144.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 (301) hide show
  1. package/MIGRATION.md +608 -0
  2. package/USAGE.md +63 -36
  3. package/dist/adoption/plan.js +22 -0
  4. package/dist/approval-ask-audit-store.d.ts +7 -5
  5. package/dist/approval-ask-audit-store.js +12 -6
  6. package/dist/approval-ask-machine.d.ts +15 -7
  7. package/dist/approval-ask-machine.js +10 -4
  8. package/dist/approval-card.d.ts +155 -39
  9. package/dist/approval-card.js +111 -31
  10. package/dist/approval-queue-kind.d.ts +27 -0
  11. package/dist/approval-queue-kind.js +6 -0
  12. package/dist/approval-reconciler.d.ts +8 -8
  13. package/dist/approval-reconciler.js +3 -3
  14. package/dist/audit.js +4 -2
  15. package/dist/boot/budget-tracing.d.ts +1 -1
  16. package/dist/boot/execution-env.js +1 -1
  17. package/dist/boot/governance-seams.d.ts +26 -41
  18. package/dist/boot/governance-seams.js +61 -28
  19. package/dist/boot/late-binds.d.ts +7 -4
  20. package/dist/boot/late-binds.js +3 -1
  21. package/dist/boot/leader.js +2 -4
  22. package/dist/boot/memory-consolidation.d.ts +0 -8
  23. package/dist/boot/memory-consolidation.js +3 -3
  24. package/dist/boot/reapers.js +5 -4
  25. package/dist/boot/resolve-spec.d.ts +1 -1
  26. package/dist/boot/resolve-spec.js +8 -8
  27. package/dist/boot/runner-deps.d.ts +14 -6
  28. package/dist/boot/runner-deps.js +6 -17
  29. package/dist/boot/shutdown.d.ts +9 -0
  30. package/dist/boot/shutdown.js +18 -2
  31. package/dist/boot/stage-01-config.js +2 -0
  32. package/dist/boot/stage-02-web-admin-pull.js +3 -0
  33. package/dist/boot/stage-03-store-backend.d.ts +4 -1
  34. package/dist/boot/stage-03-store-backend.js +1 -2
  35. package/dist/boot/stage-04-stores.d.ts +5 -2
  36. package/dist/boot/stage-04-stores.js +3 -5
  37. package/dist/boot/stage-05-execution-env.d.ts +5 -2
  38. package/dist/boot/stage-06-runners.d.ts +5 -2
  39. package/dist/boot/stage-06-runners.js +1 -3
  40. package/dist/boot/stage-07-capability-layer.d.ts +5 -2
  41. package/dist/boot/stage-07-capability-layer.js +6 -2
  42. package/dist/boot/stage-08-reapers.d.ts +5 -2
  43. package/dist/boot/stage-09-leader.d.ts +5 -2
  44. package/dist/boot/stage-10-http-server.d.ts +5 -2
  45. package/dist/boot/stage-10-http-server.js +4 -1
  46. package/dist/boot/stores.d.ts +5 -2
  47. package/dist/boot/stores.js +7 -7
  48. package/dist/boot/web-admin.d.ts +5 -1
  49. package/dist/boot/web-admin.js +31 -19
  50. package/dist/capabilities/hands-lane.d.ts +9 -39
  51. package/dist/capabilities/hands-lane.js +8 -13
  52. package/dist/capabilities/mcp-probe.d.ts +3 -2
  53. package/dist/capabilities/scenarios.d.ts +23 -17
  54. package/dist/capabilities/scenarios.js +2 -2
  55. package/dist/capabilities/skills.d.ts +1 -17
  56. package/dist/capabilities/skills.js +0 -8
  57. package/dist/capability-facts.d.ts +8 -8
  58. package/dist/capability-facts.js +4 -4
  59. package/dist/card-void.d.ts +6 -9
  60. package/dist/config-catalog.js +1 -1
  61. package/dist/config-d-migration.d.ts +2 -0
  62. package/dist/config-dir-trust.js +58 -29
  63. package/dist/config-invariants.d.ts +7 -1
  64. package/dist/config-invariants.js +7 -0
  65. package/dist/config-provider.d.ts +10 -0
  66. package/dist/config-provider.js +15 -4
  67. package/dist/config-root-migration.d.ts +13 -0
  68. package/dist/config-root-migration.js +99 -0
  69. package/dist/config-types.d.ts +5 -5
  70. package/dist/config.d.ts +4 -3
  71. package/dist/config.js +1 -1
  72. package/dist/delegated-session-owner.d.ts +35 -151
  73. package/dist/delegated-session-owner.js +1 -83
  74. package/dist/device-ws-protocol.d.ts +1 -0
  75. package/dist/device-ws-protocol.js +2 -1
  76. package/dist/entry-mode-clamp-notice.d.ts +1 -1
  77. package/dist/env-model-table-gate.d.ts +53 -0
  78. package/dist/env-model-table-gate.js +53 -0
  79. package/dist/execution-placement.d.ts +7 -4
  80. package/dist/fleet/fleet-bus.d.ts +28 -52
  81. package/dist/fleet/fleet-bus.js +35 -100
  82. package/dist/fleet/fleet-reconciler.d.ts +4 -4
  83. package/dist/fleet/fleet-reconciler.js +1 -1
  84. package/dist/fleet/subagent-tail-bus.d.ts +14 -11
  85. package/dist/fleet/subagent-tail-bus.js +15 -28
  86. package/dist/hooks/classic-stations.d.ts +3 -1
  87. package/dist/hooks/classic-stations.js +2 -0
  88. package/dist/hooks/hook-runner.js +28 -7
  89. package/dist/host-decision.d.ts +54 -20
  90. package/dist/host-decision.js +42 -14
  91. package/dist/http/admission.d.ts +1 -1
  92. package/dist/http/admission.js +7 -3
  93. package/dist/http/approval-sweeps.js +11 -8
  94. package/dist/http/caller-trust.d.ts +1 -1
  95. package/dist/http/durable-run-leg.js +2 -2
  96. package/dist/http/engine-refusal.d.ts +16 -0
  97. package/dist/http/engine-refusal.js +17 -0
  98. package/dist/http/memory-compliance-failure-reply.d.ts +1 -3
  99. package/dist/http/memory-compliance-failure-reply.js +4 -6
  100. package/dist/http/owner-access.d.ts +11 -0
  101. package/dist/http/owner-access.js +13 -0
  102. package/dist/http/principal-gate.d.ts +1 -1
  103. package/dist/http/refusal-body.d.ts +7 -3
  104. package/dist/http/refusal-body.js +1 -0
  105. package/dist/http/resume-legs.d.ts +21 -7
  106. package/dist/http/resume-legs.js +82 -53
  107. package/dist/http/resume-restatement.d.ts +39 -0
  108. package/dist/http/resume-restatement.js +25 -0
  109. package/dist/http/route-ctx.d.ts +35 -10
  110. package/dist/http/route-ctx.js +1 -1
  111. package/dist/http/routes/approvals-assistant.d.ts +9 -1
  112. package/dist/http/routes/approvals-assistant.js +143 -31
  113. package/dist/http/routes/capabilities.js +11 -2
  114. package/dist/http/routes/memory-policy.d.ts +2 -2
  115. package/dist/http/routes/memory-policy.js +1 -1
  116. package/dist/http/routes/notify-wake.js +23 -25
  117. package/dist/http/routes/rules.js +48 -13
  118. package/dist/http/routes/runs.js +9 -8
  119. package/dist/http/routes/session-memory-sync.d.ts +34 -6
  120. package/dist/http/routes/session-memory-sync.js +27 -10
  121. package/dist/http/routes/session-sync.js +13 -20
  122. package/dist/http/routes/sessions.d.ts +2 -2
  123. package/dist/http/routes/sessions.js +22 -23
  124. package/dist/http/routes/tasks.js +27 -49
  125. package/dist/http/server.d.ts +13 -7
  126. package/dist/http/server.js +2 -2
  127. package/dist/http/stored-body-replay.js +15 -4
  128. package/dist/http/wire-types.d.ts +17 -7
  129. package/dist/index.d.ts +1 -0
  130. package/dist/index.js +1 -0
  131. package/dist/lane-home-probe.d.ts +15 -0
  132. package/dist/lane-home-probe.js +4 -0
  133. package/dist/leader/leader.js +5 -2
  134. package/dist/leader/wire.d.ts +7 -1
  135. package/dist/leader/wire.js +6 -5
  136. package/dist/leg-facts.d.ts +37 -0
  137. package/dist/leg-facts.js +15 -0
  138. package/dist/memory-bundle-engine.d.ts +1 -4
  139. package/dist/memory-bundle-engine.js +2 -2
  140. package/dist/memory-operator-faces.d.ts +30 -66
  141. package/dist/memory-operator-faces.js +17 -88
  142. package/dist/memory-scope-stores.d.ts +38 -40
  143. package/dist/memory-scope-stores.js +51 -36
  144. package/dist/memory-scope.d.ts +0 -9
  145. package/dist/memory-scope.js +0 -9
  146. package/dist/memory-sync-client.js +14 -3
  147. package/dist/memory-sync.d.ts +20 -4
  148. package/dist/memory-sync.js +23 -4
  149. package/dist/model-plane-face.d.ts +13 -7
  150. package/dist/model-plane-face.js +2 -1
  151. package/dist/observability/corrupt-read-seat.d.ts +5 -9
  152. package/dist/observability/corrupt-read-seat.js +1 -2
  153. package/dist/observability/fail-open.d.ts +30 -10
  154. package/dist/observability/fail-open.js +27 -10
  155. package/dist/observability/run-terminal.d.ts +1 -1
  156. package/dist/observability/run-terminal.js +6 -2
  157. package/dist/orchestration/workflow-completion-inbox.d.ts +5 -19
  158. package/dist/orchestration/workflow-completion-inbox.js +0 -12
  159. package/dist/orchestration/workflow-notify-journal.d.ts +3 -2
  160. package/dist/orchestration/workflow-park-decision.d.ts +8 -3
  161. package/dist/orchestration/workflow-park-decision.js +5 -3
  162. package/dist/org-delivery-gate.d.ts +11 -0
  163. package/dist/org-delivery-gate.js +19 -1
  164. package/dist/parked-decide.d.ts +13 -9
  165. package/dist/parked-decide.js +7 -7
  166. package/dist/parked-revive-surface.d.ts +6 -7
  167. package/dist/parked-revive-surface.js +1 -1
  168. package/dist/peer-inbound-face.d.ts +122 -0
  169. package/dist/peer-inbound-face.js +123 -0
  170. package/dist/permission-rule-list.d.ts +13 -9
  171. package/dist/permission-rule-list.js +7 -3
  172. package/dist/plugins/approval-ask-store-file.js +18 -6
  173. package/dist/plugins/approval-ask-store-memory.js +8 -6
  174. package/dist/plugins/approval-ask-store-sql.d.ts +28 -13
  175. package/dist/plugins/approval-ask-store-sql.js +30 -11
  176. package/dist/plugins/caching-session-store.d.ts +0 -3
  177. package/dist/plugins/caching-session-store.js +0 -3
  178. package/dist/plugins/checkpoint-store-sql.d.ts +45 -38
  179. package/dist/plugins/checkpoint-store-sql.js +108 -45
  180. package/dist/plugins/file-history-store-sql.d.ts +24 -18
  181. package/dist/plugins/file-history-store-sql.js +24 -19
  182. package/dist/plugins/file-run-store.d.ts +29 -0
  183. package/dist/plugins/file-run-store.js +97 -8
  184. package/dist/plugins/fork-routing-session-store.d.ts +8 -1
  185. package/dist/plugins/fork-routing-session-store.js +6 -0
  186. package/dist/plugins/imported-layer-root-retirement.d.ts +82 -0
  187. package/dist/plugins/imported-layer-root-retirement.js +96 -0
  188. package/dist/plugins/local-checkpoint-store.d.ts +6 -8
  189. package/dist/plugins/local-checkpoint-store.js +5 -4
  190. package/dist/plugins/local-session-store.d.ts +69 -30
  191. package/dist/plugins/local-session-store.js +133 -57
  192. package/dist/plugins/local-session-window.d.ts +4 -2
  193. package/dist/plugins/mailbox-recipient-lifecycle.d.ts +9 -31
  194. package/dist/plugins/mailbox-recipient-lifecycle.js +4 -0
  195. package/dist/plugins/mailbox-store-sql.d.ts +12 -8
  196. package/dist/plugins/mailbox-store-sql.js +76 -7
  197. package/dist/plugins/memory-sync-store-pg.d.ts +15 -0
  198. package/dist/plugins/memory-sync-store-pg.js +21 -0
  199. package/dist/plugins/memory-sync-store-tidb.d.ts +2 -0
  200. package/dist/plugins/memory-sync-store-tidb.js +13 -1
  201. package/dist/plugins/one-time-migrations.d.ts +44 -14
  202. package/dist/plugins/one-time-migrations.js +118 -15
  203. package/dist/plugins/org-delivery-quota-store.d.ts +1 -1
  204. package/dist/plugins/org-delivery-quota-store.js +2 -12
  205. package/dist/plugins/park-commit-watch.d.ts +1 -1
  206. package/dist/plugins/permission-rule-store-file.d.ts +10 -1
  207. package/dist/plugins/permission-rule-store-file.js +15 -2
  208. package/dist/plugins/permission-rule-store-sql.d.ts +31 -1
  209. package/dist/plugins/permission-rule-store-sql.js +35 -2
  210. package/dist/plugins/pg-session-storage.d.ts +1 -9
  211. package/dist/plugins/pg-session-storage.js +2 -19
  212. package/dist/plugins/remote-env-device.d.ts +8 -11
  213. package/dist/plugins/remote-env-device.js +6 -3
  214. package/dist/plugins/remote-env-host.d.ts +8 -4
  215. package/dist/plugins/remote-env-host.js +7 -9
  216. package/dist/plugins/remote-env-k8s.d.ts +37 -24
  217. package/dist/plugins/remote-env-k8s.js +50 -17
  218. package/dist/plugins/remote-shell.js +12 -2
  219. package/dist/plugins/retention-store-sql.d.ts +2 -2
  220. package/dist/plugins/sandbox-read-floor.d.ts +5 -7
  221. package/dist/plugins/sandbox-read-floor.js +2 -7
  222. package/dist/plugins/schema-consistency.d.ts +5 -1
  223. package/dist/plugins/session-fork.d.ts +1 -1
  224. package/dist/plugins/session-ownership.d.ts +9 -0
  225. package/dist/plugins/session-ownership.js +6 -0
  226. package/dist/plugins/session-store.d.ts +13 -16
  227. package/dist/plugins/session-store.js +9 -10
  228. package/dist/plugins/sql-errors.d.ts +10 -1
  229. package/dist/plugins/sql-errors.js +13 -0
  230. package/dist/plugins/sql-json-column.d.ts +24 -2
  231. package/dist/plugins/sql-json-column.js +38 -3
  232. package/dist/plugins/store-backend.d.ts +23 -28
  233. package/dist/plugins/store-backend.js +12 -3
  234. package/dist/plugins/store-contracts.d.ts +29 -5
  235. package/dist/plugins/store-contracts.js +4 -1
  236. package/dist/plugins/task-attachment-store.d.ts +2 -2
  237. package/dist/plugins/task-attachment-store.js +37 -52
  238. package/dist/plugins/tidb-session-store.d.ts +2 -14
  239. package/dist/plugins/tidb-session-store.js +2 -20
  240. package/dist/plugins/tool-result-store-sql.d.ts +9 -8
  241. package/dist/plugins/tool-result-store-sql.js +23 -2
  242. package/dist/plugins/wiring-section-codec.d.ts +32 -0
  243. package/dist/plugins/wiring-section-codec.js +55 -0
  244. package/dist/plugins/workspace-fill.d.ts +1 -1
  245. package/dist/rule-entry-list.d.ts +3 -2
  246. package/dist/rule-entry-list.js +5 -1
  247. package/dist/rules-consent.d.ts +28 -5
  248. package/dist/rules-consent.js +40 -28
  249. package/dist/run-local.js +11 -6
  250. package/dist/runs.d.ts +12 -8
  251. package/dist/runs.js +10 -7
  252. package/dist/runtime-governance.d.ts +1 -1
  253. package/dist/security.d.ts +0 -4
  254. package/dist/server-secret-env.d.ts +4 -0
  255. package/dist/session-error-wire.d.ts +34 -23
  256. package/dist/session-error-wire.js +8 -3
  257. package/dist/session-incarnation.d.ts +3 -3
  258. package/dist/session-notify-door.d.ts +106 -0
  259. package/dist/session-notify-door.js +97 -0
  260. package/dist/session-sync.d.ts +9 -14
  261. package/dist/session-sync.js +5 -5
  262. package/dist/session-workspace.d.ts +3 -13
  263. package/dist/session-workspace.js +0 -9
  264. package/dist/standing-answer-grant.d.ts +5 -0
  265. package/dist/standing-answer-grant.js +10 -0
  266. package/dist/stores-sql/session-policy-store-sql.d.ts +4 -2
  267. package/dist/stores-sql/session-policy-store-sql.js +3 -13
  268. package/dist/task-mcp.d.ts +1 -1
  269. package/dist/task-settings.d.ts +11 -8
  270. package/dist/task-settings.js +31 -11
  271. package/dist/tool-approval.d.ts +55 -35
  272. package/dist/tool-approval.js +112 -74
  273. package/dist/trace/core-keyset-guard.d.ts +12 -9
  274. package/dist/trace/engine-notice-wire.d.ts +1 -1
  275. package/dist/trace/engine-notice-wire.js +4 -2
  276. package/dist/trace/exit-seat.d.ts +7 -1
  277. package/dist/trace/exit-seat.js +1 -0
  278. package/dist/trace/ledger-sink.d.ts +2 -2
  279. package/dist/trace/ledger-sink.js +12 -4
  280. package/dist/trace/model-segment.d.ts +74 -25
  281. package/dist/trace/model-segment.js +141 -32
  282. package/dist/trace/project.d.ts +15 -6
  283. package/dist/trace/project.js +12 -4
  284. package/dist/trace/redact.d.ts +72 -9
  285. package/dist/trace/redact.js +1509 -471
  286. package/dist/trace/self-minted-wire.d.ts +598 -47
  287. package/dist/trace/self-minted-wire.js +190 -20
  288. package/dist/trace/wire-projection-faces.d.ts +1 -1
  289. package/dist/trace/wire-projection-faces.js +1 -1
  290. package/dist/verifier-pause-card.d.ts +33 -5
  291. package/dist/verifier-pause-card.js +15 -10
  292. package/dist/web-admin-client/apply-effective.d.ts +12 -16
  293. package/dist/web-admin-client/apply-effective.js +90 -10
  294. package/dist/workspace-space.d.ts +19 -3
  295. package/dist/workspace-space.js +8 -4
  296. package/docs/DEVICE-EXECUTOR-PROTOCOL.md +3 -1
  297. package/package.json +3 -2
  298. package/wire-changes/server@7.143.0.json +1167 -0
  299. package/wire-changes/server@7.144.0.json +291 -0
  300. package/dist/session-records-skipped-notice.d.ts +0 -21
  301. package/dist/session-records-skipped-notice.js +0 -27
@@ -19,12 +19,15 @@ export type SafeText = string & {
19
19
  * 的 `reason` / `status.error` / `listingIncomplete.error`;引擎铸点已抹过请求回显与同主体词表(记号 `[redacted]`),这一行读同一个脱敏器(引擎记号 = 已抹的值,
20
20
  * 引擎放过的形照抹);界 200 码元,原样出门(JSON 串值,消费方自己渲染)。
21
21
  * · `peer-declaration-sentence`:引擎判官对一份 MCP / A2A 对端声明说的句子(`toolAxes` / `toolFaces` / `sessionMetaKey` / 启动界的原因句,逐字带着声明方写的工具名、键名),
22
- * 进请求面 400 拒句、续跑重放的丢弃行与重读行、名册的跳过行 —— 读者是调用方与运维,句子已是一行;不设界(拒句要说全判官的话),原样出门。
22
+ * 进请求面 400 拒句、续跑重放的丢弃行与重读行、名册的跳过行,以及能力读面 `GET /v1/capabilities/mcp` 上引擎整集拒(两台撞同一工具命名空间前缀)的拒句 —— 读者是调用方与运维,句子已是一行;不设界(拒句要说全判官的话),原样出门。
23
23
  * · `inbox-diagnostics-text`:`workflow_complete` 补投帧上的诊断教学文本(`diagnostics`)—— 引擎在 workflow 完成通知上铸的「读哪里 / 怎么续跑」文本,入会话收件时洗一次,
24
24
  * 店里(`payload` 列)只放出门安全的字节,drain 逐字带出。洗法与 live `task_notification.diagnostics` 同一个 scope(`free-text`);
25
25
  * 这一行比 `trace-frame-text` 多一条界(4000 码元,与同族条目的文本位同额),原样出门:`payload` 列是 TEXT,无界的文本一旦超过列宽,入箱写整条失败、补投连摘要一起丢(完成已被记作送达),所以先有界。
26
26
  * · `boot-refusal-line`:起服拒启的一行拒句 —— 部署座装配的拒句(`mods-declaration.ts`:声明的席名、包名、读包者 / 引擎准入交回的话);它经进程级 fatal 出口原样多行进 stderr,
27
27
  * 所以必须在这里先压成一行(一句拒因里的换行会在运维的终端里伪造出第二条日志行);界 512 码元(含截断记号)。
28
+ * · `peer-inbound-card-text`:运维审批队列 `peer_inbound` 行(`GET /v1/approvals` 的 `pending[]` 与 `/v1/approvals/stream` 的 `pending` 帧)上被扣跨会话来信的
29
+ * 存储正文(`content`,core 的规范存储形 `[summary] message`)与发信方显示名(`fromName`)—— 别的会话写的自由文本,读者是收信方本人;不设界(core 存的那一份就是
30
+ * 收信方要审的全文,截了就审不全),原样出门(JSON 串值,消费方自己渲染)。
28
31
  */
29
32
  declare const EXIT_SEATS: {
30
33
  readonly "trace-frame-text": {
@@ -75,6 +78,9 @@ declare const EXIT_SEATS: {
75
78
  readonly maxChars: 512;
76
79
  readonly emit: "log-line";
77
80
  };
81
+ readonly "peer-inbound-card-text": {
82
+ readonly scope: "free-text";
83
+ };
78
84
  };
79
85
  export type ExitSeat = keyof typeof EXIT_SEATS;
80
86
  /** 设了界的座名。 */
@@ -16,6 +16,7 @@ const EXIT_SEATS = {
16
16
  "peer-declaration-sentence": { scope: "free-text" },
17
17
  "inbox-diagnostics-text": { scope: "free-text", maxChars: 4000 },
18
18
  "boot-refusal-line": { scope: "free-text", maxChars: 512, emit: "log-line" },
19
+ "peer-inbound-card-text": { scope: "free-text" },
19
20
  };
20
21
  export function seatMaxChars(seat) {
21
22
  return EXIT_SEATS[seat].maxChars;
@@ -152,8 +152,8 @@ export declare function createLedgerSink(opts: {
152
152
  * 各传自己看得见的那个词(位①=流事件 `ev.type`,位②=账本行 `type`);拿不到类型的打点方
153
153
  * (core 的 onActivity 第五席、resume 腿手动打点)省参,`kind` 诚实缺席(见 turn-activity.ts)。 */
154
154
  onActivity?: (kind?: string, statusData?: Record<string, unknown>) => void;
155
- /** 这条腿的 `wiring_manifest` **本仓自铸段**(`LegWiringSections`:[ref] `instructions` 读腿的 `InstructionSelectionLeg.segment`、run 级 `skills` 读 spec 字段
156
- * `runSkillsOf`)。**必填**:账本行与 live 帧是同一条腿的两个载体,段必须来自同一只腿;在投帧那一刻读(core 推帧之前已 await 过 loader)。 */
155
+ /** 这条腿的 `wiring_manifest` **本仓自铸段**(`LegWiringSections`:[ref] `instructions` 读腿的 `InstructionSelectionLeg.segment`、run 级 `skills` 读这条腿的部署事实
156
+ * `LegFacts.skills`,`leg-facts.ts`)。**必填**:账本行与 live 帧是同一条腿的两个载体,段必须来自同一只腿;在投帧那一刻读(core 推帧之前已 await 过 loader)。 */
157
157
  legSections: () => LegWiringSections;
158
158
  /** 这条腿的计量席(E8 累加器 + 归因键)。在场 ⇒ {@link LedgerSink.appendParked} 在停驻行之前先把未结清的用量差落成 `model_usage` 行(状态帧最后,见 `appendParkRow`);
159
159
  * 缺席 ⇒ 这条腿没接累加器,停驻行之前无账可结(夹具、不经 `appendParked` 停驻的腿)。 */
@@ -4,7 +4,7 @@ import { recordFailOpen } from "../observability/fail-open.js";
4
4
  import { modelTextEventData, toolStartEventData, toolEndEventData, taskProgressEventData, taskStartedEventData, taskNotificationEventData, compactedEventData, diagnosticsEventData, brainStatusEventData, steeringInjectedEventData, compactionOutcomeEventData, compactionStartedEventData, workspaceChangedEventData, wiringManifestEventData, toolRosterDeltaEventData, toolDisclosureEventData, humanInputEventData, turnEndEventData, contextUsageEventData, appendParkRow } from "./project.js";
5
5
  import { NotifiedKeys, taskNotificationStreamKeyOf } from "../orchestration/workflow-completion-inbox.js";
6
6
  import { isParkLedgerEventType } from "./ledger-events.js";
7
- import { isModelSegmentBoundary, reasoningDeltaBytes, reasoningSegmentEventId } from "./model-segment.js";
7
+ import { blockText, isModelSegmentBoundary, reasoningDeltaBytes, reasoningSegmentEventId } from "./model-segment.js";
8
8
  export function createSerialLedgerAppend(appendEvent, startSeq) {
9
9
  let seq = startSeq;
10
10
  let chain = Promise.resolve();
@@ -33,6 +33,7 @@ export function createLedgerSink(opts) {
33
33
  let seq = 0;
34
34
  let chain = Promise.resolve();
35
35
  let text = "";
36
+ let block = "";
36
37
  let reasoning = "";
37
38
  let textEventId;
38
39
  let reasoningEventId;
@@ -55,9 +56,11 @@ export function createLedgerSink(opts) {
55
56
  reasoning = "";
56
57
  reasoningEventId = undefined;
57
58
  }
58
- if (text) {
59
- await append("text", modelTextEventData({ text, eventId: textEventId }));
59
+ const segment = text + blockText(block);
60
+ if (segment) {
61
+ await append("text", modelTextEventData({ text: segment, eventId: textEventId }));
60
62
  text = "";
63
+ block = "";
61
64
  }
62
65
  };
63
66
  const onEvent = async (ev) => {
@@ -67,10 +70,15 @@ export function createLedgerSink(opts) {
67
70
  switch (ev.type) {
68
71
  case "text_delta": {
69
72
  const td = ev;
70
- text += td.delta;
73
+ block += td.delta;
71
74
  textEventId ??= td.eventId;
72
75
  break;
73
76
  }
77
+ case "text_end": {
78
+ text += blockText(block, ev);
79
+ block = "";
80
+ break;
81
+ }
74
82
  case "reasoning_delta": {
75
83
  const rd = ev;
76
84
  const bytes = reasoningDeltaBytes(rd);
@@ -1,4 +1,4 @@
1
- import { type SegmentEndFields } from "./project.js";
1
+ import { type LiveEventIdentity, type SegmentEndFields } from "./project.js";
2
2
  /**
3
3
  * 本帧是不是模型文本的段界。**四条消费腿共用这一只**:账本投影 switch(`trace/ledger-sink.ts`)、
4
4
  * 顶层 live 流与转发子代腿(`http/routes/tasks.ts`)、子代 tail 面(`fleet/subagent-tail-bus.ts`)。
@@ -13,43 +13,83 @@ export type ReasoningEndFrame = SegmentEndFields & {
13
13
  type: "reasoning_end";
14
14
  };
15
15
  /** 登记册**读到的全部字段**,逐个写出来(不是 `Record<string, unknown>`):`TaskEvent` 与转发腿的原始帧
16
- * 都结构性满足它,于是调用点一个宽断言都不必写;将来有人想读第七个键,得先在这里加一行。 */
17
- export interface ReasoningStreamEvent {
16
+ * 都结构性满足它,于是调用点一个宽断言都不必写;将来有人想读第八个键,得先在这里加一行。
17
+ * `type` 而不是 `interface`(与 `LiveEventIdentity` 同一条理由):`text_end` 的铸点收 `Record<string, unknown>`,别名才进得去。 */
18
+ export type ModelStreamEvent = {
18
19
  type?: string;
19
20
  delta?: unknown;
21
+ content?: unknown;
20
22
  eventId?: unknown;
21
23
  parentToolCallId?: unknown;
22
24
  sourceTaskId?: unknown;
23
25
  bgAgentId?: unknown;
24
- }
26
+ };
25
27
  /** 一条**流**的身份(不含 `eventId`:core 给每个内容事件铸各自的 eventId,拿它当流身份会把每块 delta
26
28
  * 切成一段)。三键都缺席 = 宿主自己的流。 */
27
- export interface ReasoningStreamIdent {
29
+ export interface ModelStreamIdent {
28
30
  parentToolCallId?: string;
29
31
  sourceTaskId?: string;
30
32
  bgAgentId?: string;
31
33
  }
34
+ /** live 面模型文本的帧(本登记册铸的全部四种):两族的逐块帧与各自的段末帧。 */
35
+ export type LiveModelTextFrame = (LiveEventIdentity & {
36
+ type: "text_delta" | "reasoning_delta";
37
+ delta: string;
38
+ }) | (SegmentEndFields & {
39
+ type: "text_end";
40
+ }) | ReasoningEndFrame;
32
41
  /**
33
- * 一条 live 腿上**按流身份分账**的 `reasoning` 段登记册。
42
+ * 🔴 **live 面模型文本的唯一铸点** —— 一条 live 腿上按**族 × 流身份**分账的段登记册(三条 live 腿共用:顶层流 / 转发子代腿 / 子代 tail 面)。
43
+ *
44
+ * ## 律(一条):凡出 wire 的模型文本经同一只脱敏器,不分帧
45
+ * 段末帧(`text_end.content` / `reasoning_end.content`)、`done.result`、账本 `text` / `reasoning` 行早就整段过 `redactModelText`;
46
+ * 逐块帧(`text_delta` / `reasoning_delta`)此前一个逐字、一个逐块脱敏 —— 跨块的凭据在两者上都留明文。现在逐块帧也只放**同一只脱敏器**判定过的字节:
47
+ * 每条流一只脱敏器的**流式口**(`trace/redact.ts` 的 `createRedactionStream`:喂入 / 取已判定前缀 / 收尾冲刷三口,同一只扫描器、同一张表):每块到达时喂入、
48
+ * 取出已判定的那一截放出(脱敏器自己的未决尾不出门,横跨切点的跨度整条不出);段末冲刷,余下的按整段读法放出,再发段末帧。
49
+ * ⇒ 一段的逐块帧依次拼接 = 该段段末帧的正文 —— 逐字节(凭据形换记号,不含凭据形的文本逐字节不变)。两族的段 = 账本 `text` / `reasoning` 行的单位(同一只段界谓词)。
50
+ *
51
+ * ## 文字块是段的切片(单位只有一个:段)
52
+ * 引擎的 `text_end` 关的是一个**文字块**,不是段:它是这一块的**交付点**,不收段 —— 段的状态(前文)跨块留着,账本 `text` 行按同一个段拼起来判。
53
+ * 一块的原文只有一个定义({@link blockText}:它的 delta 字节;一个 delta 字节都没有、只有 `text_end` 的块 = 它的正文),活流段流与两条账本腿同读 ——
54
+ * 只有 `text_end` 的块照样进本段的流,由段末帧交付(不另出逐块帧),也照样进账本 `text` 行。
55
+ * 交付点上:① 这一块还押在窗里的字节按整段读法、**文本到此为止**交出(流式口的 `takeAll`;一帧不带 `eventId` 的 `text_delta`,紧贴段末帧之前);
56
+ * ② `text_end.content` = 引擎这一块的正文,**接在本段已喂入的前文之后**判(`textEndEventData(ev, 前文)`:与账本行同一只 `redactModelText`;前文只作判定上下文);
57
+ * ③ 记下块界。⇒ 每块的逐块帧拼接 = 该块 `text_end.content`(引擎没修剪那一块时逐字节),各块依次拼接 = 账本 `text` 行(块界上到此为止的判定与整段判定不同时除外,见下)。
58
+ * 判定读不到交付点之后的字节,到此为止的判定可以与整段判定不同:一条凭据形恰横跨块界(交付那一截按到此为止判,读得出的半形出记号,后一块上横跨的那一条整枚换记号),
59
+ * 或交付时认作凭据、后文让它不再是(活流那一截是记号)—— 两种都是账本整段判,
60
+ * 段末核对对不上计一次 `server.live-text.hold-diverged` —— 这是交付点的定义,不是第二套规则(等后文 = 一段引子要扣到下一个结构帧,例如整份工具入参生成完)。
61
+ *
62
+ * ## 帧数与身份(消费端看得见的三件事)
63
+ * · 引擎的每一块 delta 仍恰好一帧、同一枚 `eventId`、原序(`delta` 可以是 `""`:那一块的字节还在窗里)—— 续流游标与 E18 的首块句柄不动;
64
+ * · 段末还在窗里的字节在段末帧**之前**一帧放出(同一族的逐块帧,带流身份三键、**不带** `eventId` ⇒ 不发 `id:` 行:它不是引擎的内容帧);
65
+ * · 延迟:一个字节在同一条流又到了脱敏器的未决尾上界(`PENDING_TAIL_UNITS` 个读法单元,由脱敏器的臂表算出)之后的下一次重扫时出门(重扫节律在流式口里);
66
+ * 盖住它的跨度还在判定(未收尾的栅栏 / 引号 / JSON 串值 …)⇒ 判定或段末。
34
67
  *
35
- * 🔴 **为什么是登记册而不是一只累积器**(codex 对抗复审 R1 两根 [high],亲跑复现后按类修):一条腿上
36
- * 并发子代的 `reasoning_delta` 是**交错**到达的。一只累积器只有两种活法,两条都错:
37
- * · 「换身份就收段」⇒ A 说一半、B 插一句、A 说另一半 ⇒ A 被切成两枚权威段,**跨块的凭据正好落在切口上**
38
- * ——本帧存在的唯一理由当场失效(实测:两枚 `reasoning_end` 拼起来仍是明文密钥);
39
- * · 「不换就不收」⇒ 两个子代的思考拼成一段,再盖上其中一个的身份键(串味 + 冤枉归属)。
40
- * 分账之后规则反而**更少**:一条流的段,只被**它自己**的段界或**它自己**的终态收走;别人说什么都与它无关。
68
+ * ## 段界(与账本腿同一只谓词)
69
+ * 两族都只在本流的段界词({@link isModelSegmentBoundary})与腿终局 / 子代终态({@link LiveModelText.cut})收段;引擎的 `text_end` 是块的交付点(上一节),不收段。
70
+ * 收段顺序:同一批里先散文、后推理。散文段收段时若最后一块之后还有字节(那一块没有 `text_end`:自定义 brain / 截断),余下的照样一帧放出,不铸 `text_end`(诚实缺席)。
41
71
  *
42
- * 状态的界:每条流的条目在它的首块 delta 上建、在收段时删;腿终局 {@link ReasoningSegments.cut} 不带
43
- * 匹配器 = 全收全删。子代终态那一次带匹配器的收段(转发腿的 `onTaskNotification`)是让**活着的子代数**
44
- * 而不是「这条 run 一共派过多少子代」成为上界的那一手。
72
+ * 🔴 **为什么分账**(codex 对抗复审 R1 两根 [high],亲跑复现后按类修):一条腿上并发子代的逐块帧是**交错**到达的。一只累积器只有两种活法,两条都错:
73
+ * · 「换身份就收段」⇒ A 说一半、B 插一句、A 说另一半 ⇒ A 被切成两段,**跨块的凭据正好落在切口上**;
74
+ * · 「不换就不收」⇒ 两个子代的文字拼成一段,再盖上其中一个的身份键(串味 + 冤枉归属)。
75
+ * 一条流的段,只被**它自己**的段界或**它自己**的终态收走;别人说什么都与它无关。
76
+ *
77
+ * ## 投递态(tail 面:有没有人在听)
78
+ * `onEvent(ev, deliver)`:`deliver = false` 时只攒原文、照常按段界收段,不扫描、不出帧(tail 面的免投影快门);一条流从不投递转为投递时,放行位跳到**此刻**的段尾
79
+ * —— 之前的字节没人收,之后的字节仍按**整段**的上下文判定(晚到的订阅者在 `password=` 之后才开始听,值照样认得出)。段末帧的正文恒是整段(`text_end` 恒是整块)。
80
+ * 没人在听时的块交付点只记块界(不扫描、不出帧)。
81
+ *
82
+ * 状态的界:每条流的条目在它的首块非空 delta 上建、在收段时删;腿终局 {@link LiveModelText.cut} 不带匹配器 = 全收全删。
83
+ * 子代终态那一次带匹配器的收段(转发腿的 `onTaskNotification`)让**活着的子代数**成为上界。
45
84
  */
46
- export interface ReasoningSegments {
47
- /** 喂一帧 → 本帧收走的段末帧(0 或 1 枚,且**只可能是本帧自己那条流**的段)。返回数组只为让调用点
48
- * 与 {@link cut} 同形(`for (const f of …) send(f)`),不是「一帧可能收多段」。 */
49
- onEvent(ev: ReasoningStreamEvent): ReasoningEndFrame[];
50
- /** 收段:`match` 缺省 = 本腿**全部**流(腿终局 / 句柄终态);给了就只收匹配的那几条(某个子代终态)。
85
+ export interface LiveModelText {
86
+ /** 喂一帧 → 本帧要写的帧(按序):逐块帧 / 本流收段放出的余下字节 + 段末帧。`deliver` 缺省 = 投递。 */
87
+ onEvent(ev: ModelStreamEvent, deliver?: boolean): LiveModelTextFrame[];
88
+ /** 收段:`match` 缺省 = 本腿**全部**流(腿终局 / 句柄终态);给了就只收匹配的那几条(某个子代终态)。`deliver` 同 {@link onEvent}(缺省 = 投递)。
51
89
  * 与账本腿 `LedgerSink.onDone → flush()` 同位同义 —— 段界表里没有终局词,终局走这扇门。 */
52
- cut(match?: (ident: ReasoningStreamIdent) => boolean): ReasoningEndFrame[];
90
+ cut(match?: (ident: ModelStreamIdent) => boolean, deliver?: boolean): LiveModelTextFrame[];
91
+ /** 没有开着的段(状态只有开着的段:空着的登记册与新建的一只等价,持有方可以删掉它、下一帧再建)。 */
92
+ isIdle(): boolean;
53
93
  }
54
94
  /**
55
95
  * 一段推理的**段末事件 id** —— 唯一铸点,live 段末帧与账本 `reasoning` 行共用这一只。
@@ -72,14 +112,23 @@ export interface ReasoningSegments {
72
112
  * 伪装成可锚)。
73
113
  */
74
114
  export declare function reasoningSegmentEventId(anchor: unknown): string | undefined;
115
+ /**
116
+ * 🔴 **一个文字块的原文 —— 唯一定义**(三处同读,各自不另判:活流段流 {@link createLiveModelText}、账本写口 `trace/ledger-sink.ts`、续跑腿 `http/resume-legs.ts`):
117
+ * 这一块的 `text_delta` 字节;一个 delta 字节都没有的块(只有 `text_end`)= 它的 `text_end` 正文(非串 ⇒ 空)。
118
+ * `deltas` = 这一块(上一个块界之后)已到的 delta 字节;`end` = 这一块的 `text_end`(块还没收口 ⇒ 不传:原文就是已到的 delta)。
119
+ * 段文本 = 段内各块原文依次拼接 —— 账本 `text` 行与活流段流读的都是它。
120
+ */
121
+ export declare function blockText(deltas: string, end?: {
122
+ content?: unknown;
123
+ }): string;
75
124
  /** 一块 `reasoning_delta` 对段的**贡献字节** —— 非空串才算。账本腿与三条 live 腿共用这一只:空/坏形
76
125
  * 增量一个字节都不贡献,既不开段也不参与闩锚 ⇒ 两面结构上不可能把锚闩在不同的帧上(`reasoning_end`
77
126
  * 与账本 `reasoning` 行的正文早就逐字节相等,身份面随 [ref] 收进同一条规则)。 */
78
127
  export declare function reasoningDeltaBytes(ev: {
79
128
  delta?: unknown;
80
129
  }): string | undefined;
81
- /** 「这条流属于这些子代 id 之一」—— 子代终态收段的匹配器(`task_id` 与 `sessionId` 是同一个子代的两个
82
- * id 域,取并集;`undefined` 成员自动忽略)。腿上共用这一只,免得各写一遍 id 域的并集。 */
83
- export declare function reasoningStreamOfTask(...ids: ReadonlyArray<string | undefined>): (ident: ReasoningStreamIdent) => boolean;
84
- export declare function createReasoningSegments(): ReasoningSegments;
130
+ /** 「这条流属于这只后台子代」—— 子代终态收段的匹配器。一只后台子代一个 id(引擎 7.61.0:它的帧的 `sourceTaskId`、
131
+ * 转发帧的 `bgAgentId`、完成通知的 `task_id` 都是它的注册表行 id),按那一个 id 认流。 */
132
+ export declare function modelStreamOfTask(taskId: string): (ident: ModelStreamIdent) => boolean;
133
+ export declare function createLiveModelText(): LiveModelText;
85
134
  //# sourceMappingURL=model-segment.d.ts.map
@@ -1,4 +1,9 @@
1
- import { reasoningEndEventData } from "./project.js";
1
+ import { recordFailOpen } from "../observability/fail-open.js";
2
+ import { errorKindOf } from "../observability/err-text.js";
3
+ import { OVERSIZED_REDACTION_PLACEHOLDER } from "../observability/run-terminal.js";
4
+ import { liveIdentityFields, reasoningEndEventData, textEndEventData } from "./project.js";
5
+ import { dropProjectedFace } from "./projection-drop.js";
6
+ import { createRedactionStream } from "./redact.js";
2
7
  const BOUNDARY = new Set([
3
8
  "tool_start", "tool_end", "status", "context_usage", "compacted", "diagnostics",
4
9
  "steering_injected", "compaction_outcome", "workspace_changed", "wiring_manifest",
@@ -11,12 +16,16 @@ const REASONING_SEGMENT_ID_MARK = "~reasoning_end";
11
16
  export function reasoningSegmentEventId(anchor) {
12
17
  return typeof anchor === "string" && anchor.length > 0 ? `${anchor}${REASONING_SEGMENT_ID_MARK}` : undefined;
13
18
  }
19
+ export function blockText(deltas, end) {
20
+ if (deltas !== "" || end === undefined)
21
+ return deltas;
22
+ return typeof end.content === "string" ? end.content : "";
23
+ }
14
24
  export function reasoningDeltaBytes(ev) {
15
25
  return typeof ev.delta === "string" && ev.delta !== "" ? ev.delta : undefined;
16
26
  }
17
- export function reasoningStreamOfTask(...ids) {
18
- const set = new Set(ids.filter((v) => typeof v === "string" && v !== ""));
19
- return (ident) => (ident.sourceTaskId !== undefined && set.has(ident.sourceTaskId)) || (ident.bgAgentId !== undefined && set.has(ident.bgAgentId));
27
+ export function modelStreamOfTask(taskId) {
28
+ return (ident) => ident.sourceTaskId === taskId || ident.bgAgentId === taskId;
20
29
  }
21
30
  function streamKeyOf(ident) {
22
31
  return `${ident.parentToolCallId ?? ""}\u0000${ident.sourceTaskId ?? ""}\u0000${ident.bgAgentId ?? ""}`;
@@ -25,44 +34,144 @@ function identOf(ev) {
25
34
  const s = (v) => (typeof v === "string" ? v : undefined);
26
35
  return { parentToolCallId: s(ev.parentToolCallId), sourceTaskId: s(ev.sourceTaskId), bgAgentId: s(ev.bgAgentId) };
27
36
  }
28
- export function createReasoningSegments() {
29
- const open = new Map();
30
- const cutKey = (key) => {
31
- const seg = open.get(key);
32
- if (seg === undefined)
37
+ function release(s) {
38
+ try {
39
+ return s.text.takeSettled();
40
+ }
41
+ catch (err) {
42
+ recordFailOpen("server.run-terminal.redact-threw", `live-hold len=${s.text.fed.length} err=${errorKindOf(err)}`);
43
+ return "";
44
+ }
45
+ }
46
+ function deliverBlock(s) {
47
+ try {
48
+ return s.text.takeAll();
49
+ }
50
+ catch (err) {
51
+ recordFailOpen("server.run-terminal.redact-threw", `live-hold len=${s.text.fed.length} err=${errorKindOf(err)}`);
52
+ s.text.skip();
53
+ return OVERSIZED_REDACTION_PLACEHOLDER;
54
+ }
55
+ }
56
+ function remainderOf(family, s) {
57
+ try {
58
+ const r = s.text.flush();
59
+ if (r.diverged)
60
+ recordFailOpen("server.live-text.hold-diverged", `family=${family} len=${s.text.fed.length}`);
61
+ return r.rest;
62
+ }
63
+ catch (err) {
64
+ recordFailOpen("server.run-terminal.redact-threw", `live-hold len=${s.text.fed.length} err=${errorKindOf(err)}`);
65
+ return OVERSIZED_REDACTION_PLACEHOLDER;
66
+ }
67
+ }
68
+ export function createLiveModelText() {
69
+ const open = { text: new Map(), reasoning: new Map() };
70
+ const deltaType = (family) => (family === "text" ? "text_delta" : "reasoning_delta");
71
+ const openSegment = (family, key, ident, deliver) => {
72
+ const s = { ident, text: createRedactionStream(), delivering: deliver, blockFrom: 0 };
73
+ open[family].set(key, s);
74
+ return s;
75
+ };
76
+ const close = (family, key, deliver) => {
77
+ const s = open[family].get(key);
78
+ if (s === undefined)
79
+ return [];
80
+ open[family].delete(key);
81
+ if (!deliver)
33
82
  return [];
34
- open.delete(key);
35
- const data = reasoningEndEventData({ ...seg.ident, eventId: seg.segmentEventId, content: seg.buf });
36
- return data === null ? [] : [{ type: "reasoning_end", ...data }];
83
+ if (!s.delivering)
84
+ s.text.skip();
85
+ const out = [];
86
+ const rest = remainderOf(family, s);
87
+ if (rest !== "")
88
+ out.push({ type: deltaType(family), delta: rest, ...liveIdentityFields(s.ident) });
89
+ if (family === "reasoning") {
90
+ const data = reasoningEndEventData({ ...s.ident, eventId: s.segmentEventId, content: s.text.fed });
91
+ if (data !== null)
92
+ out.push({ type: "reasoning_end", ...data });
93
+ }
94
+ return out;
95
+ };
96
+ const feed = (family, ev, deliver) => {
97
+ if (typeof ev.delta !== "string") {
98
+ if (family === "text")
99
+ dropProjectedFace("text_delta.delta is not a string");
100
+ else
101
+ dropProjectedFace("reasoning_delta.delta is not a string");
102
+ return [];
103
+ }
104
+ const ident = identOf(ev);
105
+ const key = streamKeyOf(ident);
106
+ let s = open[family].get(key);
107
+ if (s === undefined && ev.delta !== "")
108
+ s = openSegment(family, key, ident, deliver);
109
+ if (s !== undefined) {
110
+ if (deliver && !s.delivering) {
111
+ s.delivering = true;
112
+ s.text.skip();
113
+ }
114
+ else if (!deliver)
115
+ s.delivering = false;
116
+ s.text.feed(ev.delta);
117
+ if (family === "reasoning" && reasoningDeltaBytes(ev) !== undefined)
118
+ s.segmentEventId ??= reasoningSegmentEventId(ev.eventId);
119
+ }
120
+ if (!deliver)
121
+ return [];
122
+ return [{ type: deltaType(family), delta: s === undefined ? "" : release(s), ...liveIdentityFields(ev) }];
37
123
  };
38
124
  return {
39
- onEvent: (ev) => {
40
- if (ev.type === "reasoning_delta") {
41
- const bytes = reasoningDeltaBytes(ev);
42
- if (bytes === undefined)
43
- return [];
44
- const ident = identOf(ev);
45
- const key = streamKeyOf(ident);
46
- const seg = open.get(key);
47
- if (seg === undefined)
48
- open.set(key, { ident, segmentEventId: reasoningSegmentEventId(ev.eventId), buf: bytes });
49
- else {
50
- seg.buf += bytes;
51
- seg.segmentEventId ??= reasoningSegmentEventId(ev.eventId);
125
+ onEvent: (ev, deliver = true) => {
126
+ if (ev.type === "text_delta")
127
+ return feed("text", ev, deliver);
128
+ if (ev.type === "reasoning_delta")
129
+ return feed("reasoning", ev, deliver);
130
+ const key = streamKeyOf(identOf(ev));
131
+ if (ev.type === "text_end") {
132
+ let s = open.text.get(key);
133
+ const out = [];
134
+ const before = s === undefined ? "" : s.text.fed.slice(0, s.blockFrom);
135
+ const arrived = s === undefined ? "" : s.text.fed.slice(s.blockFrom);
136
+ const unfed = blockText(arrived, ev).slice(arrived.length);
137
+ const endOnly = unfed !== "" ? unfed : undefined;
138
+ if (s === undefined && endOnly !== undefined)
139
+ s = openSegment("text", key, identOf(ev), deliver);
140
+ if (s !== undefined) {
141
+ if (deliver && !s.delivering) {
142
+ s.delivering = true;
143
+ s.text.skip();
144
+ }
145
+ else if (!deliver)
146
+ s.delivering = false;
147
+ if (endOnly !== undefined)
148
+ s.text.feed(endOnly);
149
+ if (deliver) {
150
+ const rest = deliverBlock(s);
151
+ if (rest !== "" && endOnly === undefined)
152
+ out.push({ type: "text_delta", delta: rest, ...liveIdentityFields(s.ident) });
153
+ }
154
+ s.blockFrom = s.text.fed.length;
52
155
  }
53
- return [];
156
+ const end = deliver ? textEndEventData(ev, before) : null;
157
+ if (end !== null)
158
+ out.push({ type: "text_end", ...end });
159
+ return out;
54
160
  }
55
- return isModelSegmentBoundary(ev.type ?? "") ? cutKey(streamKeyOf(identOf(ev))) : [];
161
+ return isModelSegmentBoundary(ev.type ?? "") ? [...close("text", key, deliver), ...close("reasoning", key, deliver)] : [];
56
162
  },
57
- cut: (match) => {
163
+ cut: (match, deliver = true) => {
58
164
  const out = [];
59
- for (const [key, seg] of [...open]) {
60
- if (match !== undefined && !match(seg.ident))
61
- continue;
62
- out.push(...cutKey(key));
165
+ for (const family of ["text", "reasoning"]) {
166
+ for (const [key, s] of [...open[family]]) {
167
+ if (match !== undefined && !match(s.ident))
168
+ continue;
169
+ out.push(...close(family, key, deliver));
170
+ }
63
171
  }
64
172
  return out;
65
173
  },
174
+ isIdle: () => open.text.size === 0 && open.reasoning.size === 0,
66
175
  };
67
176
  }
68
177
  //# sourceMappingURL=model-segment.js.map
@@ -219,15 +219,17 @@ export declare function screenedGate(v: unknown): GateOutcome | undefined;
219
219
  * 不改原对象(调用方与账本共享引用):有变更时换一只信封,原记录一个字节不动。
220
220
  */
221
221
  export declare function screenedStoredEventData(type: string, data: unknown): unknown;
222
- /** `text_end` 段末帧的**唯一**铸点(三腿共用:top stream / 转发子代腿 / 子代 tail 面)。content = 段权威全文 ⇒ 与
222
+ /** `text_end` 段末帧的**唯一**铸点(三腿共用:top stream / 转发子代腿 / 子代 tail 面)。content = 引擎这一块的权威全文 ⇒ 与
223
223
  * durable 面(`result` / 账本 `text` 行)同一只 {@link redactModelText}(认出才改写、抛则占位、不设上限)。
224
+ * `before` = 本段在这一块之前已喂入的模型文本(引擎的文字块是段的切片,段 = 账本 `text` 行的单位):这一块**接在本段前文之后**判、只交这一块那一截
225
+ * (锚在前一块、值在这一块 ⇒ 照样认得出);由登记册在块的交付点给出,缺省 = 这一块就是段首。
224
226
  * 此前三处各自逐字透传 —— 同一份文本毫秒后在 `done.result.result` 上已脱,live 面却在凭据生成瞬间明文([ref])。
225
- * `text_delta` 仍逐字:跨 chunk 的凭据无法就地判;clay [ref] ②(2026-09-18)裁定**维持逐字成文**([ref] U-3 关票),
226
- * 权威段 `text_end.content` 已脱敏、消费端段末整段替换即得脱敏读法。
227
+ * 逐块的 `text_delta` 由 `trace/model-segment.ts` 的登记册铸(7.143.0 起经同一只脱敏器的放行窗,一段的逐块拼接 = 本帧 content);
228
+ * 本函数由登记册在段末调,三腿不再各自调。
227
229
  * 坏形(content 非串/空串)⇒ null(丢帧,不铸「权威空段」:core 契约明言空段不发本帧,消费端收到空段会清掉已攒 delta)。
228
230
  * 身份**四键**随行(live 现状带全四键,消费端可能已依赖);值经 {@link identityKey} —— 非空 string 才上 wire
229
231
  * ([ref] 起不再逐字透传:坏形身份键会在 live 写口上铸出假游标)。 */
230
- export declare function textEndEventData(ev: Record<string, unknown>): SegmentEndFields | null;
232
+ export declare function textEndEventData(ev: Record<string, unknown>, before?: string): SegmentEndFields | null;
231
233
  /**
232
234
  * live 面的**身份四键**(core `TaskEventIdentity` 全集)—— 一个属主,两处共用({@link segmentEndFields}
233
235
  * 与 sync 腿白名单 catch-all 的 `ident`;此前是两份手抄)。与 durable 面的 {@link identityFields} 的差别
@@ -637,6 +639,7 @@ export declare function compactionOutcomeEventData(ev: {
637
639
  trigger?: unknown;
638
640
  reason?: unknown;
639
641
  pass?: unknown;
642
+ requestedBy?: unknown;
640
643
  eventId?: unknown;
641
644
  parentToolCallId?: unknown;
642
645
  }): FrameData<{
@@ -887,8 +890,8 @@ export declare function toolRosterDeltaEventData(ev: {
887
890
  * (值可以是 `undefined`)—— 漏递的腿当场 tsc 红,而不是静默投出一个「缺席」(缺席在 wire 上是一句话:「这条腿对这件事没有陈述」)。
888
891
  * · `instructions`([ref],7.111.0)—— 这条腿的 project-memory loader 选中的指令文件链成员 `{ selected: string[] }`;值来自腿的
889
892
  * `InstructionSelectionLeg.segment()`。`undefined` ⇒ 段缺席;`{ selected: [] }` ⇒ 显式空(走了链、没选中)。
890
- * · `skills`(7.137.0)—— 这条 run 交给引擎的技能名册(`{ name, description, source }[]`,与场景卡技能清单同一张形);值来自 spec 字段 `runSkillsOf(spec)`
891
- * (唯一铸点 = resolveSpec 出口的 `buildRunSkills`)。**run 级** ⇒ 只投根腿 / 续跑腿的帧,委派子代的帧(`parentToolCallId` 在场)不投(子代的技能由它自己的定义决定);
893
+ * · `skills`(7.137.0)—— 这条 run 交给引擎的技能名册(`{ name, description, source }[]`,与场景卡技能清单同一张形);值来自这条腿的部署事实 `LegFacts.skills`
894
+ * (`leg-facts.ts`;名册由 `buildRunSkills` 合并、resolveSpec 出口登记,漏斗在复制之前读出)。**run 级** ⇒ 只投根腿 / 续跑腿的帧,委派子代的帧(`parentToolCallId` 在场)不投(子代的技能由它自己的定义决定);
892
895
  * `[]` = 零技能(含 `disableSkills`);`undefined` ⇒ 段缺席(这条腿的 spec 不是本仓装配的)。`description` 过上 wire 的自由文本出口 {@link sanitizeWireText}。
893
896
  */
894
897
  export interface LegWiringSections {
@@ -984,6 +987,9 @@ export declare function wiringManifestFaceEventData(ev: {
984
987
  * 路径或名字(引擎原样回声,不是解析后的落点 —— 多租户沙箱车道上它是这次 run 自己工作区里的相对 / 绝对路径串,帧上不出现任何别的租户
985
988
  * 或宿主盘的信息),与已展示的工具实参 / `workspace_changed.cwd` 同一信任级(UNTRUSTED 的路径串)⇒ 过 `redactSecrets`。长度界由引擎定
986
989
  * (`USER_ATTACHMENT_LABEL_MAX`),本仓不另截。非对象的成员丢、集外的成员键不投(同 `actor` 的白名单理由)。
990
+ * · `rewrittenBy[]`(core 7.62.0 [ref],只在腿的 prompt 屏 `prompt.submit` 改写过这条输入时在场)—— 改写它的扩展注册名,按改写序 ⇒ verbatim:
991
+ * 名字的形由引擎在注册入口判(`MOD_REGISTRATION_NAME`,能引号 / 括号 / 折句的名在入口拒),与会话行上同名位(`audit.ts` 的 `rewrittenBy: "verbatim"`)
992
+ * 同一读法。非数组不投、非串 / 空串成员丢、丢完为空不铸键(缺席 = 原样送达,不是空数组)。
987
993
  *
988
994
  * `actor` 逐键挑(禁 spread):core 已声明 `ActorAssertion` 是冻结三键形,但白名单的意义正是「core 加第
989
995
  * 四键时由人处置」——身份对象上多出来的键裸上线是本文件反复登记的病族。
@@ -1000,6 +1006,7 @@ export declare function humanInputEventData(ev: {
1000
1006
  principal?: unknown;
1001
1007
  entryId?: unknown;
1002
1008
  attachments?: unknown;
1009
+ rewrittenBy?: unknown;
1003
1010
  eventId?: unknown;
1004
1011
  parentToolCallId?: unknown;
1005
1012
  }): FrameData<{
@@ -1076,6 +1083,8 @@ export declare function compactedEventData(ev: {
1076
1083
  };
1077
1084
  /** [ref](core 7.53.0 [ref]):这次落地的压缩 pass 的 id —— 与它的 `compaction_started` 帧同一个值(引擎在每次落地上都设;型上可选)。逐字。 */
1078
1085
  pass?: string;
1086
+ /** core 7.61.0:扩展经 `$.session.compact` 提的手动请求落地的那一 pass —— 谁要的(同 {@link compactionOutcomeEventData} 那一位)。 */
1087
+ requestedBy?: unknown;
1079
1088
  }): FrameData<{
1080
1089
  attachedFiles?: Array<{
1081
1090
  path: SafeText;
@@ -210,10 +210,10 @@ function projectSettlement(st) {
210
210
  ...(typeof st.note === "string" ? { note: redactSecrets(st.note).slice(0, SETTLEMENT_NOTE_MAX) } : {}),
211
211
  };
212
212
  }
213
- export function textEndEventData(ev) {
213
+ export function textEndEventData(ev, before = "") {
214
214
  if (typeof ev.content !== "string" || ev.content.length === 0)
215
215
  return null;
216
- return segmentEndFields(ev.content, ev);
216
+ return segmentEndFields(ev.content, ev, before);
217
217
  }
218
218
  export function liveIdentityFields(ev) {
219
219
  return {
@@ -223,8 +223,8 @@ export function liveIdentityFields(ev) {
223
223
  ...(identityKey(ev.bgAgentId) !== undefined ? { bgAgentId: identityKey(ev.bgAgentId) } : {}),
224
224
  };
225
225
  }
226
- function segmentEndFields(content, ev) {
227
- return { content: redactModelText(content), ...liveIdentityFields(ev) };
226
+ function segmentEndFields(content, ev, before = "") {
227
+ return { content: redactModelText(content, before), ...liveIdentityFields(ev) };
228
228
  }
229
229
  export function reasoningEndEventData(ev) {
230
230
  if (typeof ev.content !== "string" || ev.content.trim().length === 0)
@@ -434,9 +434,14 @@ export function compactionOutcomeEventData(ev) {
434
434
  ...(s(ev.trigger) !== undefined ? { trigger: s(ev.trigger) } : {}),
435
435
  ...(ev.reason !== undefined ? { reason: seatText("trace-frame-text", String(ev.reason)) } : {}),
436
436
  ...(s(ev.pass) !== undefined ? { pass: s(ev.pass) } : {}),
437
+ ...requestedByField(ev.requestedBy, "compaction_outcome"),
437
438
  ...identityFields(ev),
438
439
  };
439
440
  }
441
+ function requestedByField(v, where) {
442
+ const requester = extensionRequesterOf(v, where);
443
+ return requester !== undefined ? { requestedBy: requester } : {};
444
+ }
440
445
  export function compactionStartedEventData(ev) {
441
446
  const s = (v) => (typeof v === "string" ? v : undefined);
442
447
  return {
@@ -806,6 +811,7 @@ export function humanInputEventData(ev) {
806
811
  ...(str(m.label) !== undefined ? { label: seatText("trace-frame-text", String(m.label)) } : {}),
807
812
  }))
808
813
  : undefined;
814
+ const rewrittenBy = Array.isArray(ev.rewrittenBy) ? ev.rewrittenBy.filter((n) => str(n) !== undefined) : [];
809
815
  const actor = {
810
816
  ...(str(a.id) !== undefined ? { id: seatText("trace-frame-text", String(a.id)) } : {}),
811
817
  ...(typeof a.hostAsserted === "boolean" ? { hostAsserted: a.hostAsserted } : {}),
@@ -821,6 +827,7 @@ export function humanInputEventData(ev) {
821
827
  ...(Object.keys(actor).length > 0 ? { actor } : {}),
822
828
  ...(str(ev.entryId) !== undefined ? { entryId: ev.entryId } : {}),
823
829
  ...(attachments !== undefined ? { attachments } : {}),
830
+ ...(rewrittenBy.length > 0 ? { rewrittenBy } : {}),
824
831
  ...identityFields(ev),
825
832
  };
826
833
  }
@@ -893,6 +900,7 @@ export function compactedEventData(ev) {
893
900
  ...(num(ev.durationMs) !== undefined ? { durationMs: num(ev.durationMs) } : {}),
894
901
  ...(phaseDurations !== undefined ? { phaseDurations } : {}),
895
902
  ...(typeof ev.pass === "string" ? { pass: ev.pass } : {}),
903
+ ...requestedByField(ev.requestedBy, "compacted"),
896
904
  };
897
905
  }
898
906
  export function contextUsageEventData(ev) {