@sema-agent/server 7.142.0 → 7.143.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/MIGRATION.md +442 -0
- package/USAGE.md +41 -24
- package/dist/adoption/plan.js +22 -0
- package/dist/approval-ask-audit-store.d.ts +7 -5
- package/dist/approval-ask-audit-store.js +12 -6
- package/dist/approval-ask-machine.d.ts +15 -7
- package/dist/approval-ask-machine.js +10 -4
- package/dist/approval-card.d.ts +124 -25
- package/dist/approval-card.js +103 -23
- package/dist/approval-queue-kind.d.ts +27 -0
- package/dist/approval-queue-kind.js +6 -0
- package/dist/approval-reconciler.d.ts +8 -8
- package/dist/approval-reconciler.js +3 -3
- package/dist/audit.js +4 -2
- package/dist/boot/budget-tracing.d.ts +1 -1
- package/dist/boot/governance-seams.d.ts +26 -41
- package/dist/boot/governance-seams.js +61 -28
- package/dist/boot/late-binds.d.ts +7 -4
- package/dist/boot/late-binds.js +3 -1
- package/dist/boot/leader.js +2 -4
- package/dist/boot/memory-consolidation.d.ts +0 -8
- package/dist/boot/memory-consolidation.js +3 -3
- package/dist/boot/reapers.js +5 -4
- package/dist/boot/resolve-spec.d.ts +1 -1
- package/dist/boot/resolve-spec.js +8 -8
- package/dist/boot/runner-deps.d.ts +10 -7
- package/dist/boot/runner-deps.js +5 -17
- package/dist/boot/shutdown.d.ts +9 -0
- package/dist/boot/shutdown.js +16 -2
- package/dist/boot/stage-02-web-admin-pull.js +3 -0
- package/dist/boot/stage-03-store-backend.d.ts +4 -1
- package/dist/boot/stage-03-store-backend.js +1 -2
- package/dist/boot/stage-04-stores.d.ts +5 -2
- package/dist/boot/stage-04-stores.js +3 -5
- package/dist/boot/stage-05-execution-env.d.ts +5 -2
- package/dist/boot/stage-06-runners.d.ts +5 -2
- package/dist/boot/stage-06-runners.js +1 -3
- package/dist/boot/stage-07-capability-layer.d.ts +5 -2
- package/dist/boot/stage-07-capability-layer.js +5 -1
- package/dist/boot/stage-08-reapers.d.ts +5 -2
- package/dist/boot/stage-09-leader.d.ts +5 -2
- package/dist/boot/stage-10-http-server.d.ts +5 -2
- package/dist/boot/stage-10-http-server.js +9 -1
- package/dist/boot/stores.d.ts +5 -2
- package/dist/boot/stores.js +7 -7
- package/dist/boot/web-admin.d.ts +5 -1
- package/dist/boot/web-admin.js +31 -19
- package/dist/capabilities/hands-lane.d.ts +9 -39
- package/dist/capabilities/hands-lane.js +8 -13
- package/dist/capabilities/mcp-probe.d.ts +3 -2
- package/dist/capabilities/scenarios.d.ts +11 -1
- package/dist/capabilities/scenarios.js +1 -0
- package/dist/capabilities/skills.d.ts +1 -17
- package/dist/capabilities/skills.js +0 -8
- package/dist/capability-facts.d.ts +8 -8
- package/dist/capability-facts.js +4 -4
- package/dist/card-void.d.ts +6 -9
- package/dist/config-catalog.js +1 -1
- package/dist/config-dir-trust.js +58 -29
- package/dist/config-invariants.d.ts +7 -1
- package/dist/config-invariants.js +7 -0
- package/dist/config-provider.d.ts +10 -0
- package/dist/config-provider.js +15 -4
- package/dist/config-root-migration.d.ts +13 -0
- package/dist/config-root-migration.js +99 -0
- package/dist/config-types.d.ts +5 -5
- package/dist/config.d.ts +4 -3
- package/dist/config.js +1 -1
- package/dist/delegated-session-owner.d.ts +5 -3
- package/dist/delegated-session-owner.js +1 -1
- package/dist/device-ws-protocol.d.ts +1 -0
- package/dist/device-ws-protocol.js +2 -1
- package/dist/env-model-table-gate.d.ts +53 -0
- package/dist/env-model-table-gate.js +53 -0
- package/dist/fleet/fleet-bus.d.ts +28 -52
- package/dist/fleet/fleet-bus.js +35 -100
- package/dist/fleet/fleet-reconciler.d.ts +4 -4
- package/dist/fleet/fleet-reconciler.js +1 -1
- package/dist/fleet/subagent-tail-bus.d.ts +14 -11
- package/dist/fleet/subagent-tail-bus.js +15 -28
- package/dist/hooks/hook-runner.js +28 -7
- package/dist/host-decision.d.ts +54 -20
- package/dist/host-decision.js +42 -14
- package/dist/http/admission.d.ts +1 -1
- package/dist/http/admission.js +7 -3
- package/dist/http/approval-sweeps.js +11 -8
- package/dist/http/caller-trust.d.ts +1 -1
- package/dist/http/durable-run-leg.js +2 -2
- package/dist/http/engine-refusal.d.ts +16 -0
- package/dist/http/engine-refusal.js +17 -0
- package/dist/http/memory-compliance-failure-reply.d.ts +1 -3
- package/dist/http/memory-compliance-failure-reply.js +4 -6
- package/dist/http/owner-access.d.ts +11 -0
- package/dist/http/owner-access.js +13 -0
- package/dist/http/resume-legs.d.ts +21 -7
- package/dist/http/resume-legs.js +71 -49
- package/dist/http/resume-restatement.d.ts +39 -0
- package/dist/http/resume-restatement.js +25 -0
- package/dist/http/route-ctx.d.ts +35 -10
- package/dist/http/route-ctx.js +1 -1
- package/dist/http/routes/approvals-assistant.d.ts +9 -1
- package/dist/http/routes/approvals-assistant.js +142 -31
- package/dist/http/routes/capabilities.js +11 -2
- package/dist/http/routes/memory-policy.d.ts +2 -2
- package/dist/http/routes/memory-policy.js +1 -1
- package/dist/http/routes/notify-wake.js +23 -25
- package/dist/http/routes/rules.js +48 -13
- package/dist/http/routes/runs.js +9 -8
- package/dist/http/routes/session-memory-sync.d.ts +34 -6
- package/dist/http/routes/session-memory-sync.js +27 -10
- package/dist/http/routes/session-sync.js +13 -20
- package/dist/http/routes/sessions.d.ts +2 -2
- package/dist/http/routes/sessions.js +22 -23
- package/dist/http/routes/tasks.js +27 -49
- package/dist/http/server.d.ts +13 -7
- package/dist/http/server.js +2 -2
- package/dist/http/stored-body-replay.js +15 -4
- package/dist/http/wire-types.d.ts +17 -7
- package/dist/leader/leader.js +5 -2
- package/dist/leader/wire.d.ts +7 -1
- package/dist/leader/wire.js +6 -5
- package/dist/leg-facts.d.ts +37 -0
- package/dist/leg-facts.js +15 -0
- package/dist/memory-bundle-engine.d.ts +1 -4
- package/dist/memory-bundle-engine.js +2 -2
- package/dist/memory-operator-faces.d.ts +30 -66
- package/dist/memory-operator-faces.js +17 -88
- package/dist/memory-scope-stores.d.ts +38 -40
- package/dist/memory-scope-stores.js +51 -36
- package/dist/memory-scope.d.ts +0 -9
- package/dist/memory-scope.js +0 -9
- package/dist/memory-sync-client.js +14 -3
- package/dist/memory-sync.d.ts +20 -4
- package/dist/memory-sync.js +23 -4
- package/dist/model-plane-face.d.ts +13 -7
- package/dist/model-plane-face.js +2 -1
- package/dist/observability/fail-open.d.ts +20 -4
- package/dist/observability/fail-open.js +17 -4
- package/dist/observability/run-terminal.js +4 -0
- package/dist/orchestration/workflow-completion-inbox.d.ts +5 -19
- package/dist/orchestration/workflow-completion-inbox.js +0 -12
- package/dist/orchestration/workflow-notify-journal.d.ts +3 -2
- package/dist/orchestration/workflow-park-decision.d.ts +8 -3
- package/dist/orchestration/workflow-park-decision.js +5 -3
- package/dist/org-delivery-gate.d.ts +11 -0
- package/dist/org-delivery-gate.js +19 -1
- package/dist/parked-decide.d.ts +13 -9
- package/dist/parked-decide.js +7 -7
- package/dist/parked-revive-surface.js +1 -1
- package/dist/peer-inbound-face.d.ts +127 -0
- package/dist/peer-inbound-face.js +158 -0
- package/dist/permission-rule-list.d.ts +13 -9
- package/dist/permission-rule-list.js +7 -3
- package/dist/plugins/approval-ask-store-file.js +18 -6
- package/dist/plugins/approval-ask-store-memory.js +8 -6
- package/dist/plugins/approval-ask-store-sql.d.ts +28 -13
- package/dist/plugins/approval-ask-store-sql.js +30 -11
- package/dist/plugins/checkpoint-store-sql.d.ts +4 -4
- package/dist/plugins/checkpoint-store-sql.js +9 -7
- package/dist/plugins/file-history-store-sql.d.ts +24 -18
- package/dist/plugins/file-history-store-sql.js +24 -19
- package/dist/plugins/file-run-store.d.ts +29 -0
- package/dist/plugins/file-run-store.js +97 -8
- package/dist/plugins/imported-layer-root-retirement.d.ts +82 -0
- package/dist/plugins/imported-layer-root-retirement.js +96 -0
- package/dist/plugins/local-checkpoint-store.d.ts +1 -1
- package/dist/plugins/local-checkpoint-store.js +2 -2
- package/dist/plugins/local-session-store.d.ts +6 -2
- package/dist/plugins/local-session-store.js +8 -2
- package/dist/plugins/mailbox-recipient-lifecycle.d.ts +9 -31
- package/dist/plugins/mailbox-recipient-lifecycle.js +4 -0
- package/dist/plugins/mailbox-store-sql.d.ts +12 -8
- package/dist/plugins/mailbox-store-sql.js +76 -7
- package/dist/plugins/memory-sync-store-pg.d.ts +15 -0
- package/dist/plugins/memory-sync-store-pg.js +21 -0
- package/dist/plugins/memory-sync-store-tidb.d.ts +2 -0
- package/dist/plugins/memory-sync-store-tidb.js +13 -1
- package/dist/plugins/one-time-migrations.d.ts +32 -2
- package/dist/plugins/one-time-migrations.js +106 -3
- package/dist/plugins/org-delivery-quota-store.d.ts +1 -1
- package/dist/plugins/org-delivery-quota-store.js +2 -12
- package/dist/plugins/park-commit-watch.d.ts +1 -1
- package/dist/plugins/permission-rule-store-file.d.ts +10 -1
- package/dist/plugins/permission-rule-store-file.js +15 -2
- package/dist/plugins/permission-rule-store-sql.d.ts +31 -1
- package/dist/plugins/permission-rule-store-sql.js +35 -2
- package/dist/plugins/remote-env-device.d.ts +8 -11
- package/dist/plugins/remote-env-device.js +6 -3
- package/dist/plugins/remote-env-k8s.d.ts +37 -24
- package/dist/plugins/remote-env-k8s.js +50 -17
- package/dist/plugins/retention-store-sql.d.ts +2 -2
- package/dist/plugins/sandbox-read-floor.d.ts +5 -7
- package/dist/plugins/sandbox-read-floor.js +2 -7
- package/dist/plugins/sql-errors.d.ts +10 -1
- package/dist/plugins/sql-errors.js +13 -0
- package/dist/plugins/store-backend.d.ts +23 -28
- package/dist/plugins/store-backend.js +9 -1
- package/dist/plugins/store-contracts.d.ts +29 -5
- package/dist/plugins/store-contracts.js +4 -1
- package/dist/plugins/task-attachment-store.d.ts +2 -2
- package/dist/plugins/task-attachment-store.js +37 -52
- package/dist/plugins/tool-result-store-sql.d.ts +9 -8
- package/dist/plugins/tool-result-store-sql.js +23 -2
- package/dist/plugins/wiring-section-codec.d.ts +32 -0
- package/dist/plugins/wiring-section-codec.js +55 -0
- package/dist/plugins/workspace-fill.d.ts +1 -1
- package/dist/rule-entry-list.d.ts +3 -2
- package/dist/rule-entry-list.js +5 -1
- package/dist/rules-consent.d.ts +28 -5
- package/dist/rules-consent.js +40 -28
- package/dist/run-local.js +9 -5
- package/dist/runs.d.ts +12 -8
- package/dist/runs.js +6 -7
- package/dist/runtime-governance.d.ts +1 -1
- package/dist/server-secret-env.d.ts +4 -0
- package/dist/session-error-wire.d.ts +12 -0
- package/dist/session-error-wire.js +6 -0
- package/dist/session-incarnation.d.ts +1 -1
- package/dist/session-notify-door.d.ts +106 -0
- package/dist/session-notify-door.js +93 -0
- package/dist/session-sync.d.ts +9 -14
- package/dist/session-sync.js +5 -5
- package/dist/session-workspace.d.ts +3 -13
- package/dist/session-workspace.js +0 -9
- package/dist/standing-answer-grant.d.ts +5 -0
- package/dist/standing-answer-grant.js +10 -0
- package/dist/stores-sql/session-policy-store-sql.d.ts +4 -2
- package/dist/stores-sql/session-policy-store-sql.js +3 -13
- package/dist/task-mcp.d.ts +1 -1
- package/dist/task-settings.d.ts +11 -8
- package/dist/task-settings.js +31 -11
- package/dist/tool-approval.d.ts +52 -34
- package/dist/tool-approval.js +66 -57
- package/dist/trace/core-keyset-guard.d.ts +11 -8
- package/dist/trace/engine-notice-wire.d.ts +1 -1
- package/dist/trace/engine-notice-wire.js +3 -1
- package/dist/trace/exit-seat.d.ts +7 -1
- package/dist/trace/exit-seat.js +1 -0
- package/dist/trace/ledger-sink.d.ts +2 -2
- package/dist/trace/model-segment.d.ts +55 -25
- package/dist/trace/model-segment.js +101 -33
- package/dist/trace/project.d.ts +7 -4
- package/dist/trace/project.js +6 -0
- package/dist/trace/redact.d.ts +61 -9
- package/dist/trace/redact.js +1490 -468
- package/dist/trace/self-minted-wire.d.ts +510 -38
- package/dist/trace/self-minted-wire.js +165 -17
- package/dist/trace/wire-projection-faces.d.ts +1 -1
- package/dist/trace/wire-projection-faces.js +1 -1
- package/dist/verifier-pause-card.d.ts +33 -5
- package/dist/verifier-pause-card.js +15 -10
- package/dist/web-admin-client/apply-effective.d.ts +12 -16
- package/dist/web-admin-client/apply-effective.js +90 -10
- package/dist/workspace-space.d.ts +19 -3
- package/dist/workspace-space.js +8 -4
- package/docs/DEVICE-EXECUTOR-PROTOCOL.md +3 -1
- package/package.json +3 -2
- package/wire-changes/server@7.143.0.json +1167 -0
|
@@ -1,18 +1,5 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { TerminalCause, WorkflowRun } from "@sema-agent/core";
|
|
2
2
|
import type { RunRecord } from "../plugins/store-contracts.js";
|
|
3
|
-
/** [ref] 幽灵行案的单源判别:一条 `task_notification` 只有在 **agent 族 × 终态** 时才允许打
|
|
4
|
-
* `onChildTerminal`(fleet「subagent 树」只渲 agent 子代)。`background_bash`/`monitor`/`external`
|
|
5
|
-
* 不属 agent fleet 树——它们此前每条都打,fleet-bus 的「无 tick 无 claim」臂给 b\* 与 m\* handle 合成
|
|
6
|
-
* agent 形瞬态终帧,壳终态留存池把这帧渲 60s = footer 幽灵子行;monitor 的 `status:"event"` 还被
|
|
7
|
-
* 终态映射折成 `failed`。
|
|
8
|
-
*
|
|
9
|
-
* 🔴 [ref]([ref]):判别**本体已换 core 的 {@link isDelegatedAgentTerminal}**。此前这里是一份手写语义
|
|
10
|
-
* 孪生(自己枚举 `completed|failed|killed|cancelled`),头注自陈「与 core 语义同源——core 根导出后换装
|
|
11
|
-
* import 删本镜像」。core 现已从包根导出(`index.d.ts`),且它的终态集与 pending 店的驱逐偏好共用
|
|
12
|
-
* 同一份 `TERMINAL_STATUSES`(core 原话:「so "terminal" can never mean two things in this module」)——
|
|
13
|
-
* 孪生留在这里等于让 fleet 面板对「终态」的理解可以和引擎分家。本函数保留为**具名的 fleet 语义位**
|
|
14
|
-
* (调用点读的是「这条通知该不该打 fleet 的 onChildTerminal」,不是「core 怎么判终态」)。 */
|
|
15
|
-
export declare function isFleetAgentTerminalNotification(n: Pick<TaskNotificationPayload, "task_type" | "status">): boolean;
|
|
16
3
|
/** The fleet vocabulary the shell renders (MF-Fleet `FleetTask.status`). The service maps its run/workflow status
|
|
17
4
|
* onto this neutral set; `awaiting approval` = a needs-review/plan-approval park, `waiting` = a durable suspend.
|
|
18
5
|
*
|
|
@@ -144,8 +131,8 @@ export interface FleetTaskRow {
|
|
|
144
131
|
* - 缺席 = BCE 车道(`fleetBackgroundChildPublisher`)的 a\* 与 wa\* 真行,或顶层 run 行 —— 单源,常态。
|
|
145
132
|
* - `"run-leg"` = 由每腿的 `fleetRunPublisher` 从 `task_progress` tick 铸的**复合 id 行**
|
|
146
133
|
* (`${runId} ${childTaskId}`)。此形只在**没有 BCE 真行**的前台 delegation 上保留(同步腿委派的
|
|
147
|
-
* 子代不过 background-child registry ⇒ 不让位就没有行)
|
|
148
|
-
*
|
|
134
|
+
* 子代不过 background-child registry ⇒ 不让位就没有行);tick 点名的是 BCE 真行(后台子代的 tick 带它的行 id;workflow agent 的
|
|
135
|
+
* tick 带会话 id、经让位登记簿换成行 id),本车道**让位不铸**(双生行退役)。
|
|
149
136
|
* 消费端读法:带 `sourceLane:"run-leg"` 的行是过渡形,与 a\* 行**不会**同时描述同一个 agent;不需要再
|
|
150
137
|
* 自己发明「复合 id 首段==parentId 且撞 (parentId,name)」那类集合级判据(cli 侧的防御税)。
|
|
151
138
|
* ADDITIVE / tolerate-absent。 */
|
|
@@ -247,15 +234,14 @@ export type FleetFrame = {
|
|
|
247
234
|
* 车HW 逐条亲读本文件的七处 `removeTask` 铸点后改成真话,消费方面的成文版 =
|
|
248
235
|
* `docs/ASSISTANT-WIRE-CONTRACT.md` 附录 H)。缺席形其实是**两族**:
|
|
249
236
|
* (**按臂名找,不给行号** —— 本注与铸点同住一个文件,写死数字会被下一次改注自己顶歪。)
|
|
250
|
-
* · **结算级** —— 这一行**自己的**终态 `task` 帧刚发过,remove
|
|
251
|
-
* `fleetRunPublisher.
|
|
252
|
-
* `for` 体)、`fleetRunPublisher.onTerminal` 的顶层行(`publishTask(run.runId, fleetStatus)` →
|
|
237
|
+
* · **结算级** —— 这一行**自己的**终态 `task` 帧刚发过,remove 只是成对的后半。三处:
|
|
238
|
+
* `fleetRunPublisher.onTerminal` 的顶层行(`publishTask(run.runId, fleetStatus)` →
|
|
253
239
|
* `if (terminal) removeTask(run.runId)`)、`fleetBackgroundChildPublisher` 的子代终局
|
|
254
240
|
* (带残局键的行帧 → `removeTask(e.taskId)`)、以及对账腿 `fleet-reconciler.ts` 的 `retire` 与
|
|
255
241
|
* 候补窗 `upgradeWatched`(两者都先帧后撤)。
|
|
256
|
-
* · **投影级 —— 没有自己的终态帧,但也不是「这个任务结束了」**:①
|
|
257
|
-
* (`yieldToBackgroundChildLane`
|
|
258
|
-
*
|
|
242
|
+
* · **投影级 —— 没有自己的终态帧,但也不是「这个任务结束了」**:① **双生让位**
|
|
243
|
+
* (`yieldToBackgroundChildLane` 把本车道先前铸的 run-leg 行让给 BCE 权威行,由 run-leg 车道自己收)
|
|
244
|
+
* —— 同一个实体改由**另一行**渲染,终局会落在**那一行**上;
|
|
259
245
|
* ② **父 leg settle 时把子代行收走**(`onTerminal` 里的 `for (const cid of children) removeTask(cid)`),
|
|
260
246
|
* **含父 parked 的形**(理由逐字在该处:子代在父 park 期间并不在跑,resume 后新的 `task_progress`
|
|
261
247
|
* 会重新建行;而子代本来就从不发终态 tick)。
|
|
@@ -585,7 +571,7 @@ export declare class FleetEventBus {
|
|
|
585
571
|
*
|
|
586
572
|
* `opts`([ref],两键均 ADDITIVE):`removeReason:"orphaned"` = **陈述级退场**(没有结算语义,见
|
|
587
573
|
* {@link FleetFrame} 的 `task_remove` 臂;[ref] 起**不封被退那一代**,同代帧 = 复活);`cycleSeq` = 被退那一代的代际号。发布方的常规清场
|
|
588
|
-
* (`onTerminal
|
|
574
|
+
* (`onTerminal`、BCE 车道的子代终局)不传 opts ⇒ 帧逐字节与本改动之前相同。 */
|
|
589
575
|
removeTask(id: string, opts?: {
|
|
590
576
|
removeReason?: "orphaned";
|
|
591
577
|
cycleSeq?: number;
|
|
@@ -593,30 +579,28 @@ export declare class FleetEventBus {
|
|
|
593
579
|
private readonly bceClaims;
|
|
594
580
|
private static readonly BCE_CLAIM_MAX;
|
|
595
581
|
private static bceKey;
|
|
596
|
-
/** BCE
|
|
597
|
-
claimBackgroundChildLane(scope: string | undefined,
|
|
598
|
-
/** BCE
|
|
599
|
-
releaseBackgroundChildLane(scope: string | undefined,
|
|
600
|
-
/**
|
|
601
|
-
backgroundChildLaneRow(scope: string | undefined,
|
|
582
|
+
/** BCE 车道:腿的这个名字(会话 id 或腿 task id)点名的是本车道的这一行 —— run-leg 车道自此让位。幂等。 */
|
|
583
|
+
claimBackgroundChildLane(scope: string | undefined, legName: string, rowId: string): void;
|
|
584
|
+
/** BCE 车道:该行已终态离场 —— 撤它名下的**每一个**名字(重试换过会话的,几只都撤;后续同名的迟到 tick 回到旧行为)。幂等。 */
|
|
585
|
+
releaseBackgroundChildLane(scope: string | undefined, rowId: string): void;
|
|
586
|
+
/** 腿的这个名字点名的 BCE 行(有 ⇒ run-leg 让位、孙代挂它下面、审批归它)。 */
|
|
587
|
+
backgroundChildLaneRow(scope: string | undefined, legName: string): string | undefined;
|
|
602
588
|
/** [ref] 让位迁移料的读面:迁移「只补缺席位」需要看得见存活行现有什么(BCE 是权威车道,不覆盖)。 */
|
|
603
589
|
taskRow(id: string): Readonly<FleetTaskRow> | undefined;
|
|
604
590
|
/**
|
|
605
|
-
* [ref]
|
|
606
|
-
*
|
|
607
|
-
*
|
|
608
|
-
*
|
|
609
|
-
*
|
|
610
|
-
* (`
|
|
611
|
-
*
|
|
612
|
-
*
|
|
613
|
-
*
|
|
614
|
-
* 只取其一(此前取最早那个)会漏掉当前这一次的卡(codex r1 F3)。
|
|
615
|
-
* 换不出的键就缺席 / 空(不猜):父链接行 / 顶层 run 行两者皆无;BCE 行在本车道学到子代 uuid 之前 `sessionIds` 为空。
|
|
591
|
+
* [ref]:一条子代行在它两只**属主账**上的键。行 → 键的换算只写这一处(两种行 id 都是本文件铸的,会话 id 那张 join 表也住在这里):
|
|
592
|
+
* · `handle` —— core bg registry / `BackgroundAgentStore` 的行键:行 id 本身是引擎的句柄形(`DURABLE_AGENT_HANDLE_RE`)才有
|
|
593
|
+
* (`wa*` 与 run-leg 复合行不在 bg 账上);
|
|
594
|
+
* · `names` —— 这一行那条腿的名字,待决审批按它们认发起者(问上带它那条腿的名字:`agentId` = 腿 task id,委派子代的问另带
|
|
595
|
+
* 发起会话 `sourceSessionId`;任一个是这一行的名字 ⇒ 这一问是这一行的)。同一条读法点名 tick 的行,所以三形各取各的:句柄形的行 ⇒
|
|
596
|
+
* 行 id 本身(后台子代的会话 id 不是它的名字,本表不登);run-leg 复合行 `${runId} ${前台子代的腿 id}` ⇒ 尾段(前台子代的腿 id
|
|
597
|
+
* 就是它的会话 id);其余 BCE 行(`wa*`)⇒ 登记在它名下的**每一个**名字(会话 id,重试换了会话两次都在 —— 只取其一会漏掉当前这一次的卡,
|
|
598
|
+
* codex r1 F3;脚本声明的腿 task id,首拍起)。
|
|
599
|
+
* 换不出的键就缺席 / 空(不猜):顶层 run 行两者皆无。
|
|
616
600
|
*/
|
|
617
601
|
childOwnerKeys(row: Pick<FleetTaskRow, "id" | "scope">): {
|
|
618
602
|
handle?: string;
|
|
619
|
-
|
|
603
|
+
names: readonly string[];
|
|
620
604
|
};
|
|
621
605
|
/**
|
|
622
606
|
* Publish a workflow row + fan out. **The row is the whole row and REPLACES the previous one** (by `id`). A workflow row has exactly one producer,
|
|
@@ -691,14 +675,6 @@ export declare function fleetRunPublisher(bus: FleetEventBus | undefined, run: {
|
|
|
691
675
|
status?: string;
|
|
692
676
|
seq?: number;
|
|
693
677
|
}) => void;
|
|
694
|
-
/** Flip + remove one subagent CHILD row when its background completion notification arrives
|
|
695
|
-
* (task_progress never emits a terminal tick — without this a bg child sat "running" until parent settle).
|
|
696
|
-
* FLIP-THROUGH: publishes the terminal frame even when the row no longer exists — the parent leg's
|
|
697
|
-
* settle removes ALL child rows (it cannot tell a settled sync child from a still-running bg child), so a bg
|
|
698
|
-
* child that completes after parent settle otherwise had NO row to flip and the shell (auto-exit's fourth
|
|
699
|
-
* release condition watches the viewed cid's terminal) never saw a terminal transition. Returns whether the
|
|
700
|
-
* row EXISTED (hadRow — the observer logs it; false = the frame was synthesized flip-through). */
|
|
701
|
-
onChildTerminal: (taskId: string, status: string, altId?: string, toolUseId?: string) => boolean;
|
|
702
678
|
/** [ref]①/(a) 案:`residuals` = 顶层 run 的终局残局键(有源才传,见 FleetTaskRow 上的键注)。
|
|
703
679
|
* 只有**真终态**(completed/failed/killed)帧带残局——parked(suspended/needs_review)的行还活着,
|
|
704
680
|
* 没有「终局」可言,误传也不上帧。 */
|
|
@@ -739,9 +715,9 @@ export declare function fleetRunResiduals(result: {
|
|
|
739
715
|
* child frames), this observer lives as long as the process and covers the child's WHOLE lifecycle:
|
|
740
716
|
* spawn → row appears the moment the child registers (launch→turn-tail 零帧 fixed: no more waiting for a
|
|
741
717
|
* first tick that a slow child never emits inside the turn);
|
|
742
|
-
* tick → token rollup onto the row
|
|
743
|
-
*
|
|
744
|
-
*
|
|
718
|
+
* tick → token rollup onto the row. The child shows ONCE, keyed by its row id: a background agent's
|
|
719
|
+
* ticks carry that id (core 7.61.0), a workflow agent's carry its session id, registered here from
|
|
720
|
+
* the frame's `sessionId` — either way the per-leg lane yields; this lane writes only its own rows;
|
|
745
721
|
* terminal → terminal frame under the a* row id, row leaves the fleet, and the contract
|
|
746
722
|
* `bg_notification` frame rides the always-open stream (缺口②'s immediate idle delivery).
|
|
747
723
|
* Rows are tagged `scope` (tenant filter) from the registry scope and `sessionId` (the `?session=` filter)
|
package/dist/fleet/fleet-bus.js
CHANGED
|
@@ -1,13 +1,10 @@
|
|
|
1
1
|
import { EventEmitter } from "node:events";
|
|
2
|
-
import { DURABLE_AGENT_HANDLE_RE, deriveAgentDisplayStatus,
|
|
2
|
+
import { DURABLE_AGENT_HANDLE_RE, deriveAgentDisplayStatus, runParkedOf } from "@sema-agent/core";
|
|
3
3
|
import { persistedPlaneOf } from "../terminal.js";
|
|
4
4
|
import { takeWorkspaceSnapshotFailure } from "./workspace-snapshot-residual.js";
|
|
5
5
|
import { recordFailOpen } from "../observability/fail-open.js";
|
|
6
6
|
import { redactSecrets } from "../trace/redact.js";
|
|
7
7
|
import { buildRunObjectivePreview } from "../user-authored-text.js";
|
|
8
|
-
export function isFleetAgentTerminalNotification(n) {
|
|
9
|
-
return isDelegatedAgentTerminal(n);
|
|
10
|
-
}
|
|
11
8
|
export function buildFleetWorkflowRow(id, run) {
|
|
12
9
|
const agents = run.agents ?? [];
|
|
13
10
|
const done = agents.filter((a) => a.status === "completed").length;
|
|
@@ -156,9 +153,9 @@ export class FleetEventBus {
|
|
|
156
153
|
}
|
|
157
154
|
bceClaims = new Map();
|
|
158
155
|
static BCE_CLAIM_MAX = 4096;
|
|
159
|
-
static bceKey(scope,
|
|
160
|
-
claimBackgroundChildLane(scope,
|
|
161
|
-
const k = FleetEventBus.bceKey(scope,
|
|
156
|
+
static bceKey(scope, legName) { return `${scope ?? "default"}\u0000${legName}`; }
|
|
157
|
+
claimBackgroundChildLane(scope, legName, rowId) {
|
|
158
|
+
const k = FleetEventBus.bceKey(scope, legName);
|
|
162
159
|
this.bceClaims.delete(k);
|
|
163
160
|
this.bceClaims.set(k, rowId);
|
|
164
161
|
if (this.bceClaims.size > FleetEventBus.BCE_CLAIM_MAX) {
|
|
@@ -167,28 +164,30 @@ export class FleetEventBus {
|
|
|
167
164
|
this.bceClaims.delete(oldest.value);
|
|
168
165
|
}
|
|
169
166
|
}
|
|
170
|
-
releaseBackgroundChildLane(scope,
|
|
171
|
-
|
|
167
|
+
releaseBackgroundChildLane(scope, rowId) {
|
|
168
|
+
const prefix = FleetEventBus.bceKey(scope, "");
|
|
169
|
+
for (const [k, v] of this.bceClaims)
|
|
170
|
+
if (v === rowId && k.startsWith(prefix))
|
|
171
|
+
this.bceClaims.delete(k);
|
|
172
172
|
}
|
|
173
|
-
backgroundChildLaneRow(scope,
|
|
174
|
-
return this.bceClaims.get(FleetEventBus.bceKey(scope,
|
|
173
|
+
backgroundChildLaneRow(scope, legName) {
|
|
174
|
+
return this.bceClaims.get(FleetEventBus.bceKey(scope, legName));
|
|
175
175
|
}
|
|
176
176
|
taskRow(id) {
|
|
177
177
|
return this.tasks.get(id);
|
|
178
178
|
}
|
|
179
179
|
childOwnerKeys(row) {
|
|
180
|
+
if (DURABLE_AGENT_HANDLE_RE.test(row.id))
|
|
181
|
+
return { handle: row.id, names: [row.id] };
|
|
180
182
|
const sp = row.id.lastIndexOf(" ");
|
|
181
|
-
if (sp > 0)
|
|
182
|
-
|
|
183
|
-
const claimed = this.bceClaims.get(FleetEventBus.bceKey(row.scope, sessionId));
|
|
184
|
-
return { sessionIds: [sessionId], ...(claimed !== undefined && DURABLE_AGENT_HANDLE_RE.test(claimed) ? { handle: claimed } : {}) };
|
|
185
|
-
}
|
|
183
|
+
if (sp > 0)
|
|
184
|
+
return { names: [row.id.slice(sp + 1)] };
|
|
186
185
|
const prefix = FleetEventBus.bceKey(row.scope, "");
|
|
187
|
-
const
|
|
186
|
+
const names = [];
|
|
188
187
|
for (const [k, rowId] of this.bceClaims)
|
|
189
188
|
if (rowId === row.id && k.startsWith(prefix))
|
|
190
|
-
|
|
191
|
-
return {
|
|
189
|
+
names.push(k.slice(prefix.length));
|
|
190
|
+
return { names };
|
|
192
191
|
}
|
|
193
192
|
publishWorkflow(row) {
|
|
194
193
|
this.workflows.set(row.id, row);
|
|
@@ -231,15 +230,15 @@ export class FleetEventBus {
|
|
|
231
230
|
}
|
|
232
231
|
export function fleetRunPublisher(bus, run) {
|
|
233
232
|
if (!bus)
|
|
234
|
-
return { onStart: () => undefined, onEvent: () => undefined, onForwardEvent: () => undefined,
|
|
233
|
+
return { onStart: () => undefined, onEvent: () => undefined, onForwardEvent: () => undefined, onTerminal: () => undefined };
|
|
235
234
|
let tokens = 0;
|
|
236
235
|
const startedAt = Date.now();
|
|
237
236
|
const sessionField = run.sessionId ? { sessionId: run.sessionId } : {};
|
|
238
237
|
const children = new Set();
|
|
239
238
|
const childStartedAt = new Map();
|
|
240
|
-
const childByToolCall = new Map();
|
|
241
239
|
let settledLeg = false;
|
|
242
240
|
const childId = (taskId) => `${run.runId} ${taskId}`;
|
|
241
|
+
const backgroundRowOf = (taskId) => (DURABLE_AGENT_HANDLE_RE.test(taskId) ? taskId : bus.backgroundChildLaneRow(run.scope, taskId));
|
|
243
242
|
const tickStatus = (st) => (st === "completed" ? "completed" : st === "failed" ? "failed" : "running");
|
|
244
243
|
const workflowRunIdField = (ev) => (ev.workflowRunId ? { workflowRunId: ev.workflowRunId } : {});
|
|
245
244
|
const toolUsesOf = (usage) => {
|
|
@@ -247,15 +246,12 @@ export function fleetRunPublisher(bus, run) {
|
|
|
247
246
|
return typeof t === "number" ? t : undefined;
|
|
248
247
|
};
|
|
249
248
|
const yieldToBackgroundChildLane = (childTaskId, cid, tickName) => {
|
|
250
|
-
const bceRowId =
|
|
249
|
+
const bceRowId = backgroundRowOf(childTaskId);
|
|
251
250
|
if (bceRowId === undefined)
|
|
252
251
|
return false;
|
|
253
252
|
if (children.has(cid)) {
|
|
254
253
|
bus.removeTask(cid);
|
|
255
254
|
children.delete(cid);
|
|
256
|
-
for (const [k, v] of childByToolCall)
|
|
257
|
-
if (v === cid)
|
|
258
|
-
childByToolCall.delete(k);
|
|
259
255
|
}
|
|
260
256
|
const row = bus.taskRow(bceRowId);
|
|
261
257
|
if (row) {
|
|
@@ -303,8 +299,6 @@ export function fleetRunPublisher(bus, run) {
|
|
|
303
299
|
const childName = ev.name !== undefined ? redactSecrets(ev.name) : undefined;
|
|
304
300
|
if (!childStartedAt.has(cid))
|
|
305
301
|
childStartedAt.set(cid, Date.now());
|
|
306
|
-
if (ev.parentToolCallId)
|
|
307
|
-
childByToolCall.set(ev.parentToolCallId, cid);
|
|
308
302
|
bus.publishTask({ id: cid, sourceLane: "run-leg", ...(childName !== undefined ? { name: childName, agentType: childName } : {}), parentId: run.runId, scope: run.scope, ...sessionField, ...workflowRunIdField(ev), status: tickStatus(ev.status), tokens: sumTokens(ev.usage), ...(typeof ev.seq === "number" ? { cycleSeq: ev.seq } : {}), ...(() => { const t = toolUsesOf(ev.usage); return t !== undefined ? { toolUses: t } : {}; })(), elapsedMs: Date.now() - childStartedAt.get(cid) });
|
|
309
303
|
}
|
|
310
304
|
else if (ev.type === "tool_start" && ev.toolName) {
|
|
@@ -320,43 +314,12 @@ export function fleetRunPublisher(bus, run) {
|
|
|
320
314
|
if (yieldToBackgroundChildLane(ev.taskId, cid, ev.name))
|
|
321
315
|
return;
|
|
322
316
|
children.add(cid);
|
|
323
|
-
const parentId = ev.parentTaskId && ev.parentTaskId !== run.rootTaskId ? childId(ev.parentTaskId) : run.runId;
|
|
317
|
+
const parentId = ev.parentTaskId && ev.parentTaskId !== run.rootTaskId ? (backgroundRowOf(ev.parentTaskId) ?? childId(ev.parentTaskId)) : run.runId;
|
|
324
318
|
const fwdName = ev.name !== undefined ? redactSecrets(ev.name) : undefined;
|
|
325
319
|
if (!childStartedAt.has(cid))
|
|
326
320
|
childStartedAt.set(cid, Date.now());
|
|
327
|
-
if (ev.parentToolCallId)
|
|
328
|
-
childByToolCall.set(ev.parentToolCallId, cid);
|
|
329
321
|
bus.publishTask({ id: cid, sourceLane: "run-leg", ...(fwdName !== undefined ? { name: fwdName, agentType: fwdName } : {}), parentId, scope: run.scope, ...sessionField, ...workflowRunIdField(ev), status: tickStatus(ev.status), tokens: sumTokens(ev.usage), ...(typeof ev.seq === "number" ? { cycleSeq: ev.seq } : {}), ...(() => { const t = toolUsesOf(ev.usage); return t !== undefined ? { toolUses: t } : {}; })(), elapsedMs: Date.now() - childStartedAt.get(cid) });
|
|
330
322
|
},
|
|
331
|
-
onChildTerminal(taskId, status, altId, toolUseId) {
|
|
332
|
-
if (settledLeg)
|
|
333
|
-
return false;
|
|
334
|
-
const fleetStatus = status === "completed" ? "completed" : status === "killed" || status === "cancelled" ? "killed" : "failed";
|
|
335
|
-
const candidateCids = [childId(taskId)];
|
|
336
|
-
if (altId !== undefined && altId !== taskId)
|
|
337
|
-
candidateCids.push(childId(altId));
|
|
338
|
-
const viaToolCall = toolUseId !== undefined ? childByToolCall.get(toolUseId) : undefined;
|
|
339
|
-
if (viaToolCall !== undefined && !candidateCids.includes(viaToolCall))
|
|
340
|
-
candidateCids.push(viaToolCall);
|
|
341
|
-
const liveCids = candidateCids.filter((c) => children.has(c));
|
|
342
|
-
const hadRow = liveCids.length > 0;
|
|
343
|
-
if (!hadRow) {
|
|
344
|
-
const claimed = [taskId, altId].some((t) => t !== undefined && bus.backgroundChildLaneRow(run.scope, t) !== undefined);
|
|
345
|
-
if (claimed)
|
|
346
|
-
return true;
|
|
347
|
-
}
|
|
348
|
-
for (const cid of hadRow ? liveCids : [childId(taskId)]) {
|
|
349
|
-
const startedAtChild = childStartedAt.get(cid);
|
|
350
|
-
bus.publishTask({ id: cid, ...(children.has(cid) ? {} : { parentId: run.runId, scope: run.scope, ...sessionField }), status: fleetStatus, ...(startedAtChild !== undefined ? { elapsedMs: Date.now() - startedAtChild } : {}) });
|
|
351
|
-
bus.removeTask(cid);
|
|
352
|
-
children.delete(cid);
|
|
353
|
-
childStartedAt.delete(cid);
|
|
354
|
-
for (const [k, v] of childByToolCall)
|
|
355
|
-
if (v === cid)
|
|
356
|
-
childByToolCall.delete(k);
|
|
357
|
-
}
|
|
358
|
-
return hadRow;
|
|
359
|
-
},
|
|
360
323
|
onTerminal(status, residuals) {
|
|
361
324
|
settledLeg = true;
|
|
362
325
|
const fleetStatus = runStatusToFleet(status);
|
|
@@ -374,7 +337,6 @@ export function fleetRunPublisher(bus, run) {
|
|
|
374
337
|
bus.removeTask(cid);
|
|
375
338
|
children.clear();
|
|
376
339
|
childStartedAt.clear();
|
|
377
|
-
childByToolCall.clear();
|
|
378
340
|
if (terminal) {
|
|
379
341
|
bus.removeTask(run.runId);
|
|
380
342
|
}
|
|
@@ -433,11 +395,13 @@ export function fleetBackgroundChildPublisher(bus, log) {
|
|
|
433
395
|
}
|
|
434
396
|
}
|
|
435
397
|
};
|
|
436
|
-
const
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
if (
|
|
440
|
-
bus.claimBackgroundChildLane(m.tenantScope,
|
|
398
|
+
const joinWorkflowAgentNames = (e, m) => {
|
|
399
|
+
if (DURABLE_AGENT_HANDLE_RE.test(e.taskId))
|
|
400
|
+
return;
|
|
401
|
+
if (e.sessionId)
|
|
402
|
+
bus.claimBackgroundChildLane(m.tenantScope, e.sessionId, e.taskId);
|
|
403
|
+
if (e.kind === "tick" && e.progressTaskId && e.progressParentTaskId === m.parentTaskId)
|
|
404
|
+
bus.claimBackgroundChildLane(m.tenantScope, e.progressTaskId, e.taskId);
|
|
441
405
|
};
|
|
442
406
|
const resolveParentId = (parentInput, domain, childScope) => {
|
|
443
407
|
const rows = bus.snapshot().tasks;
|
|
@@ -445,12 +409,9 @@ export function fleetBackgroundChildPublisher(bus, log) {
|
|
|
445
409
|
if (rows.some((r) => r.id === parentInput && r.scope === childScope))
|
|
446
410
|
return { id: parentInput, resolved: true };
|
|
447
411
|
}
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
return { id: aStar, resolved: true };
|
|
452
|
-
}
|
|
453
|
-
}
|
|
412
|
+
const joined = bus.backgroundChildLaneRow(childScope, parentInput);
|
|
413
|
+
if (joined !== undefined && rows.some((r) => r.id === joined && r.scope === childScope))
|
|
414
|
+
return { id: joined, resolved: true };
|
|
454
415
|
let match;
|
|
455
416
|
for (const r of rows) {
|
|
456
417
|
if (r.sessionId === parentInput && r.parentId === undefined && r.scope === childScope && !meta.has(r.id))
|
|
@@ -506,7 +467,6 @@ export function fleetBackgroundChildPublisher(bus, log) {
|
|
|
506
467
|
...(e.startedAt !== undefined ? { spawnedAt: e.startedAt } : {}),
|
|
507
468
|
...(e.rootSessionId ? { rootSessionId: e.rootSessionId } : {}),
|
|
508
469
|
...(e.parentToolCallId ? { parentToolCallId: e.parentToolCallId } : {}),
|
|
509
|
-
...(e.sessionId ? { aliasUuid: e.sessionId } : {}),
|
|
510
470
|
...(e.workflowRunId ? { workflowRunId: e.workflowRunId } : {}),
|
|
511
471
|
...(e.workflowRunId && !(e.sessionScoped && e.owner)
|
|
512
472
|
? (e.rootSessionId ? { hostSessionId: e.rootSessionId } : {})
|
|
@@ -516,29 +476,13 @@ export function fleetBackgroundChildPublisher(bus, log) {
|
|
|
516
476
|
: {}),
|
|
517
477
|
};
|
|
518
478
|
remember(e.taskId, m);
|
|
519
|
-
|
|
479
|
+
joinWorkflowAgentNames(e, m);
|
|
520
480
|
const displayName = e.description ?? e.name;
|
|
521
481
|
bus.publishTask({ id: e.taskId, ...(displayName !== undefined ? { name: redactSecrets(displayName) } : {}), ...(e.agentType ? { agentType: redactSecrets(e.agentType) } : {}), ...(e.spawnName ? { agentName: e.spawnName } : {}), ...rowTags(m), status: "running", tokens: 0, ...(typeof e.seq === "number" ? { cycleSeq: e.seq } : {}), ...(e.transcriptId ? { transcriptId: e.transcriptId } : {}) });
|
|
522
482
|
dlog("bg_child_event", { kind: "spawn", taskId: e.taskId, sessionScoped: e.sessionScoped, scope: m.tenantScope, hostSessionId: m.hostSessionId ?? null, parentTaskId: m.parentTaskId ?? null });
|
|
523
483
|
};
|
|
524
484
|
const handleTick = (e, m) => {
|
|
525
|
-
|
|
526
|
-
if (!m.suppressedTwin && e.progressTaskId && (!e.progressParentTaskId || e.progressParentTaskId === (m.parentTaskId ?? m.parentSessionLink))) {
|
|
527
|
-
const tail = ` ${e.progressTaskId}`;
|
|
528
|
-
for (const row of bus.snapshot().tasks) {
|
|
529
|
-
if (row.id.endsWith(tail))
|
|
530
|
-
bus.removeTask(row.id);
|
|
531
|
-
}
|
|
532
|
-
m.suppressedTwin = true;
|
|
533
|
-
}
|
|
534
|
-
if (m.aliasUuid === undefined && e.progressTaskId && (!e.progressParentTaskId || e.progressParentTaskId === (m.parentTaskId ?? m.parentSessionLink))) {
|
|
535
|
-
m.aliasUuid = e.progressTaskId;
|
|
536
|
-
for (const [cid, cm] of meta) {
|
|
537
|
-
if ((cm.parentTaskId ?? cm.parentSessionLink) === m.aliasUuid && cm.resolvedParentId === undefined && !cm.done) {
|
|
538
|
-
bus.publishTask({ id: cid, ...rowTags(cm) });
|
|
539
|
-
}
|
|
540
|
-
}
|
|
541
|
-
}
|
|
485
|
+
joinWorkflowAgentNames(e, m);
|
|
542
486
|
const tokens = sumUsage(e.usage);
|
|
543
487
|
const name = e.name ? redactSecrets(e.name) : undefined;
|
|
544
488
|
const agentType = e.agentType ? redactSecrets(e.agentType) : undefined;
|
|
@@ -573,15 +517,7 @@ export function fleetBackgroundChildPublisher(bus, log) {
|
|
|
573
517
|
: {}),
|
|
574
518
|
});
|
|
575
519
|
bus.removeTask(e.taskId);
|
|
576
|
-
|
|
577
|
-
bus.releaseBackgroundChildLane(m.tenantScope, m.aliasUuid);
|
|
578
|
-
if (m.aliasUuid) {
|
|
579
|
-
const tail = ` ${m.aliasUuid}`;
|
|
580
|
-
for (const row of bus.snapshot().tasks) {
|
|
581
|
-
if (row.id.endsWith(tail))
|
|
582
|
-
bus.removeTask(row.id);
|
|
583
|
-
}
|
|
584
|
-
}
|
|
520
|
+
bus.releaseBackgroundChildLane(m.tenantScope, e.taskId);
|
|
585
521
|
if (m.workflowRunId !== undefined) {
|
|
586
522
|
m.done = true;
|
|
587
523
|
dlog("bg_child_event", { kind: "terminal-wa-no-notification", taskId: e.taskId, workflowRunId: m.workflowRunId });
|
|
@@ -623,7 +559,6 @@ export function fleetBackgroundChildPublisher(bus, log) {
|
|
|
623
559
|
});
|
|
624
560
|
dlog("bg_child_event", { kind: "terminal", taskId: e.taskId, status, scope: m.tenantScope ?? null, hostSessionId: m.hostSessionId ?? null, childSessionId: e.sessionId ?? null, bgNotificationPublished: true });
|
|
625
561
|
m.done = true;
|
|
626
|
-
m.suppressedTwin = true;
|
|
627
562
|
};
|
|
628
563
|
return (e) => {
|
|
629
564
|
if (e.kind === "spawn") {
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* ## 它修什么(§0 病灶机制链)
|
|
5
5
|
* fleet 总线是进程内纯内存聚合(`fleet-bus.ts` 头注自陈 NOT durable / NOT cross-replica),行的**唯一**
|
|
6
|
-
*
|
|
6
|
+
* 离场路径是发布方主动打终态臂(run-leg 的 `onTerminal`、BCE 车道的子代终局)。发布方没走到终态臂(run 事件环异常中断、引擎
|
|
7
7
|
* 被壳 reuse 而旧 run 对象已死、BCE 终态通知丢失),行就**永久僵在** `tasks` Map 里 —— 此后每个订阅方
|
|
8
8
|
* (含 snapshot 新连接)看到一条永远 "running" 的幽灵行。壳侧只能靠 overlay 防御(cli 1.0.74 过渡件)。
|
|
9
9
|
*
|
|
@@ -147,10 +147,10 @@ export interface FleetReconcilerDeps {
|
|
|
147
147
|
agents?: FleetReconcileAgentPort;
|
|
148
148
|
/**
|
|
149
149
|
* [ref]:子代活性的属主②:这只子代此刻有没有**待决**审批卡。只问是非(与 {@link isLiveOnThisReplica} 同姿势,
|
|
150
|
-
* 不搬 Map)
|
|
151
|
-
* 行 id →
|
|
150
|
+
* 不搬 Map)。入参是这一行那条腿的名字,**不总是**行 id(前台子代 = 会话 id;`wa*` = 会话 id 与脚本声明的腿 task id)——
|
|
151
|
+
* 行 id → 名字的换算只在 `FleetEventBus.childOwnerKeys`。生产 = `ToolApprovalCoordinator.hasLivePendingFromLeg`。
|
|
152
152
|
*/
|
|
153
|
-
hasPendingAsk?: (
|
|
153
|
+
hasPendingAsk?: (names: readonly string[]) => boolean;
|
|
154
154
|
/** 本副本 id(与 `RunRecord.instanceId` 同域)。只进日志/读数 —— 两条 `running` 臂的**处置相同**
|
|
155
155
|
* (都是陈述级退场),分不分得出 claim 属谁不改变行为,故它不是判据。 */
|
|
156
156
|
instanceId?: string;
|
|
@@ -146,7 +146,7 @@ export function createFleetReconciler(deps) {
|
|
|
146
146
|
}
|
|
147
147
|
}
|
|
148
148
|
const hasPendingAsk = deps.hasPendingAsk;
|
|
149
|
-
if (hasPendingAsk !== undefined && deps.bus.childOwnerKeys(row).
|
|
149
|
+
if (hasPendingAsk !== undefined && hasPendingAsk(deps.bus.childOwnerKeys(row).names)) {
|
|
150
150
|
keptAlive(row, "pending_ask");
|
|
151
151
|
return "settled";
|
|
152
152
|
}
|
|
@@ -6,10 +6,9 @@
|
|
|
6
6
|
export type SubagentTailFrame = Record<string, unknown> & {
|
|
7
7
|
type: string;
|
|
8
8
|
};
|
|
9
|
-
/** core forward 事件 → wire 投影(sync
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* 住在 {@link SubagentTailBus.onForwardFrame}(publish 侧是唯一知道句柄的地方)。 */
|
|
9
|
+
/** core forward 事件 → wire 投影(sync 主流同源;不认识的帧类型=null 不发——新 core 帧类型先经这里显式收编再出 wire)。
|
|
10
|
+
* ⚠️ **本函数是无状态逐帧投影**:模型文本(`text_delta` / `reasoning_delta` / `text_end` 与段界上的 `reasoning_end`)不在这里 ——
|
|
11
|
+
* 它们要按句柄攒段、经同一只脱敏器放行,住在 {@link SubagentTailBus.onForwardFrame} 的登记册里(publish 侧是唯一知道句柄的地方);本函数对它们答 null。 */
|
|
13
12
|
export declare function projectTailFrame(e: Record<string, unknown> & {
|
|
14
13
|
type?: string;
|
|
15
14
|
}): SubagentTailFrame | null;
|
|
@@ -53,16 +52,20 @@ export declare class SubagentTailBus {
|
|
|
53
52
|
*/
|
|
54
53
|
private readonly modeByHandle;
|
|
55
54
|
/**
|
|
56
|
-
* 句柄 → 该句柄这条 tail
|
|
55
|
+
* 句柄 → 该句柄这条 tail 流的**模型文本登记册**(`trace/model-segment.ts` 的 `createLiveModelText`:按流身份分账攒段、经同一只脱敏器放行)。
|
|
57
56
|
*
|
|
58
|
-
* 键必须是句柄,理由与 {@link modeByHandle}
|
|
59
|
-
*
|
|
57
|
+
* 键必须是句柄,理由与 {@link modeByHandle} 同源再加一条硬的:两个并发子代的逐块帧在**同一个** forward sink 上交错到达,
|
|
58
|
+
* 一只累积器会把两份文字拼成一段、再盖上其中一个的身份键(登记册内部再按流身份分账)。
|
|
60
59
|
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
60
|
+
* 🔴 **生命期 = 句柄活着的那段时间,不是有人在听的那段时间**:没人听时登记册照样攒原文、照样按段界收段(只是不扫描、不出帧 —— 免投影快门仍在),
|
|
61
|
+
* 订阅者半路进来,放行位从**此刻**起,而判定仍按**整段**的上下文:否则一个在 `password=` 之后才开始听的订阅者拿到的是一段没有锚的值,认不出、原样出门
|
|
62
|
+
* (同一段在 `done` / 账本上早已遮掉)。
|
|
63
|
+
* 🔴 **条目只活在开着的段上,没有容量逐出**:一条段的上下文只被**它自己的**段界 / 终态收走(登记册分账律的同一句,`trace/model-segment.ts`)——
|
|
64
|
+
* 按容量逐出一只开着的登记册 = 别的句柄替它收了段,它的下一块从一段没有锚的新文本算起、值原样出门(对抗复审 r1 high:4096 只只报进度的句柄就够)。
|
|
65
|
+
* 所以:段全收了(登记册空着,与新建的一只等价)就删条目;只报进度、从没开过段的句柄不留条目。条目数 = 此刻有开着的模型文本段的句柄数,
|
|
66
|
+
* 每条的量 = 那几段到此刻的原文 —— 在途的模型输出本身;句柄终态({@link forgetHandle})收段并删。
|
|
64
67
|
*/
|
|
65
|
-
private readonly
|
|
68
|
+
private readonly textByHandle;
|
|
66
69
|
/** 三条 run 腿的 forward 回调里逐帧调(在 `hasSubscribers` 快门**之前**——没人在听时也要学,
|
|
67
70
|
* 否则晚开的 tail 永远读不到供给形)。同值重复写是 no-op(热路径只付一次 Map.get)。 */
|
|
68
71
|
noteHandleContentMode(bgAgentId: string, mode: TailContentMode): void;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { taskProgressEventData, taskStartedEventData, toolStartEventData, toolEndEventData, textEndEventData } from "../trace/project.js";
|
|
1
|
+
import { taskProgressEventData, taskStartedEventData, toolStartEventData, toolEndEventData } from "../trace/project.js";
|
|
3
2
|
import { liveMediaBytesOf, liveToolEndForBacklog } from "../trace/tool-output-media.js";
|
|
4
|
-
import {
|
|
3
|
+
import { createLiveModelText } from "../trace/model-segment.js";
|
|
5
4
|
const TAIL_QUEUE_CAP = 512;
|
|
6
5
|
export function projectTailFrame(e) {
|
|
7
6
|
const t = e.type;
|
|
@@ -19,18 +18,6 @@ export function projectTailFrame(e) {
|
|
|
19
18
|
const te = e;
|
|
20
19
|
return { type: "tool_end", ...toolEndEventData(te) };
|
|
21
20
|
}
|
|
22
|
-
if (t === "text_delta") {
|
|
23
|
-
const td = e;
|
|
24
|
-
return { type: "text_delta", delta: td.delta, ...(td.eventId ? { eventId: td.eventId } : {}), ...(td.parentToolCallId ? { parentToolCallId: td.parentToolCallId } : {}) };
|
|
25
|
-
}
|
|
26
|
-
if (t === "text_end") {
|
|
27
|
-
const f = textEndEventData(e);
|
|
28
|
-
return f === null ? null : { type: "text_end", ...f };
|
|
29
|
-
}
|
|
30
|
-
if (t === "reasoning_delta") {
|
|
31
|
-
const rd = e;
|
|
32
|
-
return { type: "reasoning_delta", delta: redactSecrets(rd.delta), ...(rd.eventId ? { eventId: rd.eventId } : {}), ...(rd.parentToolCallId ? { parentToolCallId: rd.parentToolCallId } : {}) };
|
|
33
|
-
}
|
|
34
21
|
return null;
|
|
35
22
|
}
|
|
36
23
|
function putBounded(map, key, value) {
|
|
@@ -46,7 +33,7 @@ const HOST_MODE_CAP = 4096;
|
|
|
46
33
|
export class SubagentTailBus {
|
|
47
34
|
subs = new Map();
|
|
48
35
|
modeByHandle = new Map();
|
|
49
|
-
|
|
36
|
+
textByHandle = new Map();
|
|
50
37
|
noteHandleContentMode(bgAgentId, mode) {
|
|
51
38
|
if (this.modeByHandle.get(bgAgentId) === mode)
|
|
52
39
|
return;
|
|
@@ -54,23 +41,24 @@ export class SubagentTailBus {
|
|
|
54
41
|
}
|
|
55
42
|
onForwardFrame(bgAgentId, mode, e) {
|
|
56
43
|
this.noteHandleContentMode(bgAgentId, mode);
|
|
57
|
-
|
|
44
|
+
const deliver = this.hasSubscribers(bgAgentId);
|
|
45
|
+
const text = this.textByHandle.get(bgAgentId) ?? createLiveModelText();
|
|
46
|
+
for (const f of text.onEvent(e, deliver))
|
|
47
|
+
this.publish(bgAgentId, f);
|
|
48
|
+
if (text.isIdle())
|
|
49
|
+
this.textByHandle.delete(bgAgentId);
|
|
50
|
+
else
|
|
51
|
+
this.textByHandle.set(bgAgentId, text);
|
|
52
|
+
if (!deliver)
|
|
58
53
|
return;
|
|
59
|
-
let segs = this.segByHandle.get(bgAgentId);
|
|
60
|
-
if (segs === undefined) {
|
|
61
|
-
segs = createReasoningSegments();
|
|
62
|
-
this.segByHandle.set(bgAgentId, segs);
|
|
63
|
-
}
|
|
64
|
-
for (const end of segs.onEvent(e))
|
|
65
|
-
this.publish(bgAgentId, end);
|
|
66
54
|
const f = projectTailFrame(e);
|
|
67
55
|
if (f)
|
|
68
56
|
this.publish(bgAgentId, f);
|
|
69
57
|
}
|
|
70
58
|
forgetHandle(bgAgentId) {
|
|
71
|
-
for (const
|
|
72
|
-
this.publish(bgAgentId,
|
|
73
|
-
this.
|
|
59
|
+
for (const f of this.textByHandle.get(bgAgentId)?.cut(undefined, this.hasSubscribers(bgAgentId)) ?? [])
|
|
60
|
+
this.publish(bgAgentId, f);
|
|
61
|
+
this.textByHandle.delete(bgAgentId);
|
|
74
62
|
this.modeByHandle.delete(bgAgentId);
|
|
75
63
|
}
|
|
76
64
|
handleContentMode(bgAgentId) {
|
|
@@ -114,7 +102,6 @@ export class SubagentTailBus {
|
|
|
114
102
|
set.delete(sub);
|
|
115
103
|
if (set.size === 0 && this.subs.get(bgAgentId) === set) {
|
|
116
104
|
this.subs.delete(bgAgentId);
|
|
117
|
-
this.segByHandle.delete(bgAgentId);
|
|
118
105
|
}
|
|
119
106
|
};
|
|
120
107
|
const it = {
|