@north-light/crouter 0.3.312 → 0.3.313
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/dist/api/client.d.ts +27 -30
- package/dist/api/client.js +80 -67
- package/dist/api/dto/broker-ops.d.ts +10 -20
- package/dist/api/dto/canvas.d.ts +1 -10
- package/dist/api/dto/health.d.ts +113 -0
- package/dist/api/dto/human-requests.d.ts +14 -3
- package/dist/api/dto/human.d.ts +2 -48
- package/dist/api/dto/human.js +3 -2
- package/dist/api/dto/inbox.d.ts +14 -0
- package/dist/api/dto/mail.d.ts +43 -0
- package/dist/api/dto/nodes.d.ts +11 -8
- package/dist/api/dto/recovery.d.ts +96 -0
- package/dist/api/dto/reviews.d.ts +2 -2
- package/dist/api/routes.d.ts +9 -6
- package/dist/api/routes.js +11 -11
- package/dist/build-root.d.ts +4 -0
- package/dist/build-root.js +11 -1
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/integration/provider-rotation.test.ts +35 -47
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.d.ts +1 -1
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.js +12 -5
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.ts +12 -5
- package/dist/cli.js +10 -1
- package/dist/clients/__tests__/helpers/human-daemon.d.ts +11 -0
- package/dist/clients/__tests__/helpers/human-daemon.js +60 -0
- package/dist/clients/attach/chrome/canvas-panels.js +1 -1
- package/dist/clients/attach/chrome/inbox-strip.d.ts +3 -3
- package/dist/clients/attach/chrome/inbox-strip.js +17 -9
- package/dist/clients/attach/chrome/ticket-panel.d.ts +2 -2
- package/dist/clients/attach/chrome/ticket-panel.js +77 -46
- package/dist/clients/attach/overlays/graph.js +6 -9
- package/dist/clients/attach/render/chat-view.d.ts +5 -4
- package/dist/clients/attach/render/chat-view.js +22 -13
- package/dist/clients/attach/render/page-block.d.ts +11 -7
- package/dist/clients/attach/render/page-block.js +64 -55
- package/dist/clients/attach/viewer.js +746 -735
- package/dist/clients/inbox/__tests__/integration/inbox-controller.test.js +56 -56
- package/dist/clients/inbox/__tests__/integration/stale-row-activation.test.js +45 -32
- package/dist/clients/inbox/controller.d.ts +42 -14
- package/dist/clients/inbox/controller.js +240 -124
- package/dist/clients/inbox/dto-adapt.d.ts +28 -0
- package/dist/clients/inbox/dto-adapt.js +93 -0
- package/dist/clients/inbox/page-adapter.d.ts +5 -4
- package/dist/clients/inbox/page-adapter.js +12 -12
- package/dist/clients/inbox/resolve.d.ts +10 -5
- package/dist/clients/inbox/resolve.js +13 -12
- package/dist/clients/inbox/review/review-client.d.ts +0 -1
- package/dist/clients/inbox/review/review-client.js +0 -4
- package/dist/clients/inbox/review-adapter.d.ts +2 -1
- package/dist/clients/inbox/review-adapter.js +3 -5
- package/dist/clients/inbox/surface.d.ts +2 -2
- package/dist/clients/inbox/surface.js +19 -8
- package/dist/clients/inbox/tui.d.ts +3 -3
- package/dist/commands/__tests__/human.test.js +31 -15
- package/dist/commands/__tests__/integration/dashboard-snapshot.test.js +36 -11
- package/dist/commands/{sys/__tests__ → __tests__/integration}/migrate.test.js +142 -36
- package/dist/commands/__tests__/revive-now-gate.test.js +2 -0
- package/dist/commands/api-client.d.ts +5 -4
- package/dist/commands/api-client.js +13 -7
- package/dist/commands/canvas-history/shared.js +1 -1
- package/dist/commands/canvas-history.js +1 -1
- package/dist/commands/canvas-roster.js +1 -1
- package/dist/commands/canvas.js +1 -2
- package/dist/commands/human/feedback.js +20 -17
- package/dist/commands/human/prompts.js +45 -36
- package/dist/commands/human/queue.js +73 -123
- package/dist/commands/human/review.js +6 -16
- package/dist/commands/memory/__tests__/command-selector-and-mutation-guards.test.js +2 -0
- package/dist/commands/memory/__tests__/memory-list-and-lint-ignore.test.js +2 -0
- package/dist/commands/memory/__tests__/repository-root-lint.test.js +2 -0
- package/dist/commands/node-inspect-artifacts.js +1 -1
- package/dist/commands/node-lifecycle-revive.d.ts +2 -2
- package/dist/commands/node-lifecycle-revive.js +9 -19
- package/dist/commands/pkg/plugin-manage.js +0 -1
- package/dist/commands/profile/show.js +4 -12
- package/dist/commands/surface-tmux-spread.js +1 -5
- package/dist/commands/sys/__tests__/config-model-ladders.test.js +23 -30
- package/dist/commands/sys/__tests__/sync-project-guidance.test.js +37 -11
- package/dist/commands/sys/branch.d.ts +2 -0
- package/dist/commands/sys/branch.js +19 -0
- package/dist/commands/sys/config.js +106 -33
- package/dist/commands/sys/daemon.d.ts +2 -0
- package/dist/commands/sys/daemon.js +130 -7
- package/dist/commands/sys/doctor.js +5 -15
- package/dist/commands/sys/migrate.js +21 -92
- package/dist/commands/sys/setup-settings-runner.js +4 -2
- package/dist/commands/sys.js +2 -15
- package/dist/core/__tests__/boot-fault-attempt.test.js +23 -1
- package/dist/core/__tests__/boot.test.js +32 -25
- package/dist/core/__tests__/broker-launch-candidates.test.js +49 -0
- package/dist/core/__tests__/canvas-inbox-watcher-hold.test.js +149 -176
- package/dist/core/__tests__/canvas-inbox-watcher-naming.test.js +59 -10
- package/dist/core/__tests__/canvas-inbox-watcher.test.js +76 -20
- package/dist/core/__tests__/canvas.test.js +18 -47
- package/dist/core/__tests__/child-death-wake.test.js +29 -7
- package/dist/core/__tests__/cli-help-contract.test.js +2 -0
- package/dist/core/__tests__/close.test.js +29 -10
- package/dist/core/__tests__/collectible.test.js +2 -1
- package/dist/core/__tests__/config-change-delta.test.js +2 -0
- package/dist/core/__tests__/context-intro.test.js +13 -1
- package/dist/core/__tests__/cron-armed-context-failure.test.js +17 -12
- package/dist/core/__tests__/cron-held-settlement.test.js +21 -3
- package/dist/core/__tests__/cron-node-sink-parked-root.test.js +29 -10
- package/dist/core/__tests__/cron-self-cancel-delivery.test.js +14 -2
- package/dist/core/__tests__/cron-timeout-descendants.test.js +13 -1
- package/dist/core/__tests__/daemon-boot.test.js +51 -14
- package/dist/core/__tests__/fixtures/fake-engine.d.ts +1 -1
- package/dist/core/__tests__/fixtures/fake-engine.js +8 -3
- package/dist/core/__tests__/focuses.test.js +10 -5
- package/dist/core/__tests__/helpers/harness.js +50 -18
- package/dist/core/__tests__/history-inbox.test.js +12 -16
- package/dist/core/__tests__/human-action-delivery.test.js +48 -28
- package/dist/core/__tests__/human-actions.test.js +7 -3
- package/dist/core/__tests__/inline-memory-refs.test.js +7 -2
- package/dist/core/__tests__/integration/broker-fork-seam.test.js +37 -10
- package/dist/core/__tests__/integration/broker-sdk-wiring.test.js +42 -0
- package/dist/core/__tests__/integration/broker-snapshot-history.test.js +42 -29
- package/dist/core/__tests__/integration/broker-wedge-supervision.test.js +36 -35
- package/dist/core/__tests__/integration/command-plugins.test.js +15 -6
- package/dist/core/__tests__/integration/deferred-no-wake.test.js +113 -92
- package/dist/core/__tests__/integration/host-teardown-process-group.test.js +9 -5
- package/dist/core/__tests__/integration/lifecycle-hooks.test.js +16 -3
- package/dist/core/__tests__/integration/plugin-revalidate.test.js +4 -0
- package/dist/core/__tests__/integration/profile-pause.test.js +4 -4
- package/dist/core/__tests__/integration/refresh-stall-recycle.test.js +9 -12
- package/dist/core/__tests__/integration/revive.test.js +67 -21
- package/dist/core/__tests__/integration/spawn-root.test.js +51 -8
- package/dist/core/__tests__/integration/subscription-delivery.test.js +33 -21
- package/dist/core/__tests__/integration/worktree-land.test.js +5 -2
- package/dist/core/__tests__/integration/worktree-reap.test.js +15 -1
- package/dist/core/__tests__/kickoff.test.js +36 -39
- package/dist/core/__tests__/lifecycle-terminal-reasons.test.js +2 -1
- package/dist/core/__tests__/lifecycle.test.js +2 -1
- package/dist/core/__tests__/live-lifecycle-prompt.test.js +13 -1
- package/dist/core/__tests__/memory-resolver-precedence.test.js +2 -0
- package/dist/core/__tests__/migration.test.js +145 -31
- package/dist/core/__tests__/model-pin-durability.test.js +4 -1
- package/dist/core/__tests__/model-routes-config.test.js +13 -5
- package/dist/core/__tests__/node-outcome.test.js +93 -26
- package/dist/core/__tests__/on-read-crouter-home-fence.test.js +2 -1
- package/dist/core/__tests__/on-read-dedup-resume.test.js +2 -1
- package/dist/core/__tests__/on-read-nested-store.test.js +2 -1
- package/dist/core/__tests__/passive-subscription.test.js +50 -157
- package/dist/core/__tests__/plugin-kinds.test.js +6 -4
- package/dist/core/__tests__/plugin-link-symlinked-scope-root.test.js +6 -1
- package/dist/core/__tests__/plugin-page-components.test.js +6 -4
- package/dist/core/__tests__/preview-registry-sync.test.js +2 -0
- package/dist/core/__tests__/profile-project-memory-delivery.test.js +4 -1
- package/dist/core/__tests__/prune.test.js +11 -5
- package/dist/core/__tests__/push-final-guard.test.js +14 -7
- package/dist/core/__tests__/relaunch-root.test.js +30 -2
- package/dist/core/__tests__/remote-canvas-target.test.js +7 -1
- package/dist/core/__tests__/repository-root-identity.test.js +4 -0
- package/dist/core/__tests__/review-model-floor.test.js +6 -3
- package/dist/core/__tests__/revive-all.test.js +13 -3
- package/dist/core/__tests__/revive-capacity.test.js +26 -4
- package/dist/core/__tests__/revive-parked-fresh.test.js +31 -8
- package/dist/core/__tests__/seam/broker-attach-stream.test.js +1 -1
- package/dist/core/__tests__/seam/broker-cap-freeze.test.js +4 -3
- package/dist/core/__tests__/seam/broker-crash-teardown.test.js +11 -14
- package/dist/core/__tests__/seam/broker-provider-retry.test.js +85 -71
- package/dist/core/__tests__/seam/dormancy-release.test.js +33 -19
- package/dist/core/__tests__/seam/held-deferred-human-prompt.test.js +7 -5
- package/dist/core/__tests__/seam/inbox-reference-guidance.test.js +20 -6
- package/dist/core/__tests__/seam/node-outcome-delivery.test.js +27 -3
- package/dist/core/__tests__/spawn-worktree-id-conflict.test.js +2 -1
- package/dist/core/__tests__/stop-guard.test.js +2 -1
- package/dist/core/__tests__/subscription-pool-credential-guard.test.js +4 -3
- package/dist/core/__tests__/warm-claim-preference-snapshot.test.js +18 -4
- package/dist/core/__tests__/yield-ensures-daemon.test.js +2 -1
- package/dist/core/bootstrap.js +2 -0
- package/dist/core/broker-client/__tests__/transport-socket.test.js +51 -6
- package/dist/core/broker-client/transport-socket.d.ts +1 -0
- package/dist/core/broker-client/transport-socket.js +13 -5
- package/dist/core/canvas/__tests__/attention.test.js +29 -35
- package/dist/core/canvas/__tests__/history-transcript.test.js +6 -6
- package/dist/core/canvas/__tests__/render-remote.test.js +25 -9
- package/dist/core/canvas/attention.d.ts +2 -5
- package/dist/core/canvas/attention.js +15 -64
- package/dist/core/canvas/boot.d.ts +6 -7
- package/dist/core/canvas/boot.js +5 -9
- package/dist/core/canvas/canvas.d.ts +13 -109
- package/dist/core/canvas/canvas.js +140 -401
- package/dist/core/canvas/crons.d.ts +2 -0
- package/dist/core/canvas/crons.js +16 -15
- package/dist/core/canvas/daemon-owner.js +10 -0
- package/dist/core/canvas/db.d.ts +2 -2
- package/dist/core/canvas/db.js +2 -18
- package/dist/core/canvas/deliveries.d.ts +104 -0
- package/dist/core/canvas/deliveries.js +354 -0
- package/dist/core/canvas/executions.d.ts +29 -0
- package/dist/core/canvas/executions.js +68 -0
- package/dist/core/canvas/history.js +35 -35
- package/dist/core/canvas/index.d.ts +3 -1
- package/dist/core/canvas/index.js +3 -1
- package/dist/core/canvas/migrations.js +20 -12
- package/dist/core/canvas/nav-model.js +1 -3
- package/dist/core/canvas/nav-render.d.ts +4 -4
- package/dist/core/canvas/nav-render.js +11 -21
- package/dist/core/canvas/node-sql-migration.d.ts +3 -0
- package/dist/core/canvas/node-sql-migration.js +261 -0
- package/dist/core/canvas/paths.d.ts +2 -16
- package/dist/core/canvas/paths.js +2 -31
- package/dist/core/canvas/recovery.d.ts +76 -0
- package/dist/core/canvas/recovery.js +588 -0
- package/dist/core/canvas/remote-canvas-source.js +4 -0
- package/dist/core/canvas/render-source.d.ts +16 -27
- package/dist/core/canvas/render-source.js +16 -45
- package/dist/core/canvas/sessions.d.ts +33 -0
- package/dist/core/canvas/sessions.js +78 -0
- package/dist/core/canvas/types.d.ts +33 -33
- package/dist/core/canvas/types.js +2 -5
- package/dist/core/canvas/waits.d.ts +18 -0
- package/dist/core/canvas/waits.js +70 -0
- package/dist/core/canvas/worktrees.d.ts +40 -0
- package/dist/core/canvas/worktrees.js +93 -0
- package/dist/core/config.d.ts +17 -12
- package/dist/core/config.js +106 -155
- package/dist/core/feed/__tests__/inbox-migrate.test.js +27 -31
- package/dist/core/feed/feed.d.ts +0 -6
- package/dist/core/feed/feed.js +68 -56
- package/dist/core/feed/inbox.d.ts +7 -81
- package/dist/core/feed/inbox.js +46 -378
- package/dist/core/feed/messages.d.ts +58 -0
- package/dist/core/feed/messages.js +217 -0
- package/dist/core/fs-utils.d.ts +4 -0
- package/dist/core/fs-utils.js +21 -1
- package/dist/core/human/answer.d.ts +1 -1
- package/dist/core/human/answer.js +1 -1
- package/dist/core/human/claim.d.ts +1 -1
- package/dist/core/human/claim.js +2 -4
- package/dist/core/human/component-docs.js +1 -1
- package/dist/core/human/feedback-companion.js +3 -2
- package/dist/core/human/feedback.d.ts +5 -8
- package/dist/core/human/feedback.js +57 -85
- package/dist/core/human/page-authoring.d.ts +30 -0
- package/dist/core/human/page-authoring.js +19 -0
- package/dist/core/human/requests.d.ts +136 -0
- package/dist/core/human/requests.js +515 -0
- package/dist/core/human/root.d.ts +0 -7
- package/dist/core/human/root.js +0 -17
- package/dist/core/human/scan.d.ts +2 -7
- package/dist/core/human/scan.js +48 -132
- package/dist/core/human/summary.d.ts +1 -1
- package/dist/core/human/summary.js +1 -1
- package/dist/core/human/tickets.d.ts +23 -83
- package/dist/core/human/tickets.js +92 -243
- package/dist/core/human/types.d.ts +5 -1
- package/dist/core/installed-plugins.js +8 -3
- package/dist/core/keybindings/__tests__/resolve.test.js +19 -17
- package/dist/core/locked-file.d.ts +6 -3
- package/dist/core/locked-file.js +36 -9
- package/dist/core/memory/extensions.js +2 -0
- package/dist/core/preview-registry.js +0 -1
- package/dist/core/profiles/__tests__/env-store.test.js +2 -0
- package/dist/core/profiles/default-binding.d.ts +0 -4
- package/dist/core/profiles/default-binding.js +12 -58
- package/dist/core/profiles/env-store.js +8 -3
- package/dist/core/profiles/manifest.d.ts +2 -37
- package/dist/core/profiles/manifest.js +35 -161
- package/dist/core/profiles/select.js +3 -0
- package/dist/core/review/__tests__/capture-origin.test.js +13 -2
- package/dist/core/review/__tests__/comments.test.js +28 -10
- package/dist/core/review/__tests__/remap.test.js +28 -10
- package/dist/core/review/__tests__/stage-identity.test.js +17 -7
- package/dist/core/review/birth.d.ts +1 -1
- package/dist/core/review/birth.js +34 -5
- package/dist/core/review/comments.js +1 -1
- package/dist/core/review/document.js +1 -1
- package/dist/core/review/project.d.ts +5 -1
- package/dist/core/review/project.js +14 -36
- package/dist/core/review/realize.d.ts +3 -6
- package/dist/core/review/realize.js +51 -168
- package/dist/core/review/remap.js +1 -1
- package/dist/core/review/stage.d.ts +3 -2
- package/dist/core/review/stage.js +2 -3
- package/dist/core/review/store.d.ts +3 -21
- package/dist/core/review/store.js +140 -186
- package/dist/core/review/types.d.ts +0 -1
- package/dist/core/runtime/__tests__/install-id-cache-scoping.test.js +9 -5
- package/dist/core/runtime/__tests__/spawn-env.test.js +8 -9
- package/dist/core/runtime/broker/auth-reload.js +9 -10
- package/dist/core/runtime/broker/daemon-ops.d.ts +25 -8
- package/dist/core/runtime/broker/daemon-ops.js +42 -9
- package/dist/core/runtime/broker/extension-abort.d.ts +3 -0
- package/dist/core/runtime/broker/extension-abort.js +11 -0
- package/dist/core/runtime/broker/fault-retry.d.ts +15 -6
- package/dist/core/runtime/broker/fault-retry.js +142 -95
- package/dist/core/runtime/broker/inbox.d.ts +4 -32
- package/dist/core/runtime/broker/inbox.js +4 -92
- package/dist/core/runtime/broker/rebind.d.ts +1 -0
- package/dist/core/runtime/broker/rebind.js +21 -12
- package/dist/core/runtime/broker-persona-guidance.d.ts +1 -1
- package/dist/core/runtime/broker-persona-guidance.js +2 -13
- package/dist/core/runtime/broker.js +28 -22
- package/dist/core/runtime/close.d.ts +3 -9
- package/dist/core/runtime/close.js +16 -27
- package/dist/core/runtime/fault.d.ts +3 -93
- package/dist/core/runtime/fault.js +9 -419
- package/dist/core/runtime/kickoff.d.ts +3 -6
- package/dist/core/runtime/kickoff.js +12 -18
- package/dist/core/runtime/launch.js +1 -1
- package/dist/core/runtime/lifecycle.js +40 -7
- package/dist/core/runtime/placement.js +2 -2
- package/dist/core/runtime/recycle.js +8 -2
- package/dist/core/runtime/reset.js +22 -6
- package/dist/core/runtime/revive.js +226 -218
- package/dist/core/runtime/spawn.js +14 -3
- package/dist/core/scoped-state/db.d.ts +7 -0
- package/dist/core/scoped-state/db.js +92 -0
- package/dist/core/scoped-state/migrate.d.ts +11 -0
- package/dist/core/scoped-state/migrate.js +198 -0
- package/dist/core/scoped-state/paths.d.ts +9 -0
- package/dist/core/scoped-state/paths.js +27 -0
- package/dist/core/scoped-state/profiles.d.ts +12 -0
- package/dist/core/scoped-state/profiles.js +62 -0
- package/dist/core/scoped-state/providers.d.ts +16 -0
- package/dist/core/scoped-state/providers.js +8 -0
- package/dist/core/scoped-state/schema.d.ts +3 -0
- package/dist/core/scoped-state/schema.js +26 -0
- package/dist/core/scoped-state/settings.d.ts +28 -0
- package/dist/core/scoped-state/settings.js +82 -0
- package/dist/core/subscription-state.d.ts +29 -48
- package/dist/core/subscription-state.js +176 -712
- package/dist/core/worktree-close.js +4 -4
- package/dist/core/worktree-mutation-async.js +2 -2
- package/dist/core/worktree-sweep.js +11 -16
- package/dist/core/worktree.js +6 -12
- package/dist/daemon/__tests__/autostart-storm.test.js +1 -39
- package/dist/daemon/__tests__/helpers/source-daemon.d.ts +2 -2
- package/dist/daemon/__tests__/helpers/source-daemon.js +7 -6
- package/dist/daemon/__tests__/integration/migration-startup.test.js +59 -26
- package/dist/daemon/__tests__/node-deadline-lane.test.js +2 -1
- package/dist/daemon/__tests__/node-outcome-birth-invariants.test.js +39 -15
- package/dist/daemon/__tests__/node-outcome-delivery.test.js +39 -10
- package/dist/daemon/__tests__/reconciler-signature.test.js +2 -2
- package/dist/daemon/__tests__/subtree-filter-freshness.test.js +2 -2
- package/dist/daemon/api/__tests__/broker-settle-park.test.js +17 -12
- package/dist/daemon/api/__tests__/canvas-snapshot-fields.test.js +27 -5
- package/dist/daemon/api/__tests__/model-config.test.js +8 -8
- package/dist/daemon/api/__tests__/node-create-description.test.js +22 -5
- package/dist/daemon/api/__tests__/node-model-validation.test.js +21 -1
- package/dist/daemon/api/__tests__/nodes-activity-query.test.js +10 -12
- package/dist/daemon/api/__tests__/profile-launch-gates.test.js +4 -1
- package/dist/daemon/api/__tests__/profile-metadata-route.test.js +4 -1
- package/dist/daemon/api/__tests__/reopen-delivery.test.js +26 -8
- package/dist/daemon/api/__tests__/seam/api-server.test.js +24 -32
- package/dist/daemon/api/__tests__/seam/b10-attach-modelauth.test.js +4 -1
- package/dist/daemon/api/__tests__/seam/leaf-api-parity.test.js +5 -4
- package/dist/daemon/api/__tests__/seam/profile-delete.test.js +27 -41
- package/dist/daemon/api/__tests__/submit-result.test.js +3 -2
- package/dist/daemon/api/bridge.js +1 -1
- package/dist/daemon/api/handlers/bash-jobs.js +6 -7
- package/dist/daemon/api/handlers/broker-ops.js +47 -84
- package/dist/daemon/api/handlers/broker-recovery.d.ts +4 -0
- package/dist/daemon/api/handlers/broker-recovery.js +251 -0
- package/dist/daemon/api/handlers/canvas.js +2 -44
- package/dist/daemon/api/handlers/daemon.js +41 -0
- package/dist/daemon/api/handlers/feedback-comments.js +2 -2
- package/dist/daemon/api/handlers/health.js +10 -5
- package/dist/daemon/api/handlers/human-requests.js +168 -188
- package/dist/daemon/api/handlers/human.js +3 -151
- package/dist/daemon/api/handlers/inbox-page.d.ts +4 -0
- package/dist/daemon/api/handlers/inbox-page.js +89 -0
- package/dist/daemon/api/handlers/inbox.js +21 -120
- package/dist/daemon/api/handlers/messages.d.ts +1 -0
- package/dist/daemon/api/handlers/messages.js +73 -15
- package/dist/daemon/api/handlers/node-outcomes.js +58 -13
- package/dist/daemon/api/handlers/nodes.js +7 -13
- package/dist/daemon/api/handlers/reviews.js +4 -29
- package/dist/daemon/api/map.d.ts +25 -3
- package/dist/daemon/api/map.js +84 -14
- package/dist/daemon/api/server.js +68 -9
- package/dist/daemon/control.d.ts +18 -0
- package/dist/daemon/cron/disposition.d.ts +2 -0
- package/dist/daemon/cron/disposition.js +8 -5
- package/dist/daemon/cron/settle.js +37 -13
- package/dist/daemon/cron/sinks.d.ts +18 -1
- package/dist/daemon/cron/sinks.js +47 -93
- package/dist/daemon/crtrd-cli.js +4 -19
- package/dist/daemon/crtrd.d.ts +2 -0
- package/dist/daemon/crtrd.js +206 -81
- package/dist/daemon/fleet.js +5 -6
- package/dist/daemon/human/finish.d.ts +12 -24
- package/dist/daemon/human/finish.js +88 -285
- package/dist/daemon/human/settle.d.ts +40 -0
- package/dist/daemon/human/settle.js +89 -0
- package/dist/daemon/human/sweep.d.ts +20 -5
- package/dist/daemon/human/sweep.js +56 -60
- package/dist/daemon/manage.d.ts +21 -16
- package/dist/daemon/manage.js +85 -51
- package/dist/daemon/messaging/node-message.d.ts +1 -1
- package/dist/daemon/messaging/node-message.js +9 -12
- package/dist/daemon/park-activity.js +3 -3
- package/dist/daemon/reconcilers/bash-deadline.js +6 -7
- package/dist/daemon/reconcilers/broker-supervision.d.ts +1 -1
- package/dist/daemon/reconcilers/broker-supervision.js +41 -19
- package/dist/daemon/reconcilers/controller-death.js +6 -18
- package/dist/daemon/reconcilers/delivery-lane.d.ts +9 -0
- package/dist/daemon/reconcilers/delivery-lane.js +130 -0
- package/dist/daemon/reconcilers/live-obligation.js +3 -3
- package/dist/daemon/reconcilers/node-deadline.js +1 -1
- package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.d.ts +1 -1
- package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.js +10 -12
- package/dist/daemon/reconcilers/node-lifecycle/tick.js +5 -5
- package/dist/daemon/reconcilers/node-lifecycle/wants-execution.js +1 -1
- package/dist/daemon/reconcilers/pending-review-submit.js +3 -3
- package/dist/daemon/reconcilers/storage-maintenance.d.ts +2 -8
- package/dist/daemon/reconcilers/storage-maintenance.js +13 -43
- package/dist/daemon/review/companion.js +5 -11
- package/dist/daemon/review/deliver.d.ts +1 -5
- package/dist/daemon/review/deliver.js +3 -52
- package/dist/daemon/review/finish.d.ts +2 -27
- package/dist/daemon/review/finish.js +79 -263
- package/dist/daemon/review/sweep.d.ts +3 -10
- package/dist/daemon/review/sweep.js +13 -131
- package/dist/daemon/startup-policy.d.ts +0 -5
- package/dist/daemon/startup-policy.js +0 -5
- package/dist/index.d.ts +2 -1
- package/dist/index.js +1 -1
- package/dist/migrations/__tests__/activation-concurrency.test.js +3 -2
- package/dist/migrations/__tests__/activation.test.js +9 -6
- package/dist/migrations/activation.d.ts +3 -2
- package/dist/migrations/activation.js +2 -4
- package/dist/migrations/corpus.d.ts +2 -5
- package/dist/migrations/corpus.js +9 -20
- package/dist/migrations/runner.d.ts +3 -1
- package/dist/migrations/runner.js +6 -2
- package/dist/pi-extensions/__tests__/canvas-context-intro.test.js +21 -89
- package/dist/pi-extensions/__tests__/canvas-goal-capture-envelope.test.js +4 -2
- package/dist/pi-extensions/__tests__/canvas-stophook-agentend.test.js +51 -33
- package/dist/pi-extensions/__tests__/canvas-stophook-context-nudge.test.js +16 -2
- package/dist/pi-extensions/__tests__/pre-command-gate.test.js +13 -1
- package/dist/pi-extensions/canvas-inbox-watcher.js +98 -244
- package/dist/pi-extensions/canvas-passive-context.d.ts +4 -8
- package/dist/pi-extensions/canvas-passive-context.js +85 -37
- package/dist/pi-extensions/canvas-stophook.js +47 -31
- package/dist/shared/env.d.ts +1 -0
- package/dist/shared/env.js +3 -0
- package/package.json +1 -1
- package/runtime.lock.json +5 -5
- package/dist/clients/attach/__tests__/page-block.test.js +0 -54
- package/dist/clients/inbox/review-visibility.d.ts +0 -5
- package/dist/clients/inbox/review-visibility.js +0 -19
- package/dist/commands/canvas-rebuild-index.d.ts +0 -2
- package/dist/commands/canvas-rebuild-index.js +0 -46
- package/dist/core/__tests__/human-cancel-guard.test.js +0 -110
- package/dist/core/__tests__/human-deliver.test.d.ts +0 -1
- package/dist/core/__tests__/human-deliver.test.js +0 -256
- package/dist/core/__tests__/human-node-not-supervised.test.d.ts +0 -1
- package/dist/core/__tests__/human-node-not-supervised.test.js +0 -89
- package/dist/core/__tests__/integration/human-deliver-e2e.test.d.ts +0 -1
- package/dist/core/__tests__/integration/human-deliver-e2e.test.js +0 -131
- package/dist/core/__tests__/phase4-review-store.test.d.ts +0 -1
- package/dist/core/__tests__/phase4-review-store.test.js +0 -144
- package/dist/core/__tests__/watchdog-abort-arms-retry.test.d.ts +0 -1
- package/dist/core/__tests__/watchdog-abort-arms-retry.test.js +0 -110
- package/dist/core/canvas/human-deliveries.d.ts +0 -39
- package/dist/core/canvas/human-deliveries.js +0 -75
- package/dist/core/canvas/node-outcome-deliveries.d.ts +0 -64
- package/dist/core/canvas/node-outcome-deliveries.js +0 -159
- package/dist/core/feed/passive.d.ts +0 -3
- package/dist/core/feed/passive.js +0 -53
- package/dist/core/human/__tests__/inbox-cancel-worker.d.ts +0 -1
- package/dist/core/human/__tests__/inbox-cancel-worker.js +0 -7
- package/dist/core/human/__tests__/inbox-claim-worker.d.ts +0 -1
- package/dist/core/human/__tests__/inbox-claim-worker.js +0 -17
- package/dist/core/human/__tests__/inbox-stale-claim-worker.d.ts +0 -1
- package/dist/core/human/__tests__/inbox-stale-claim-worker.js +0 -8
- package/dist/core/human/__tests__/integration/inbox-core.test.d.ts +0 -1
- package/dist/core/human/__tests__/integration/inbox-core.test.js +0 -145
- package/dist/core/human/__tests__/page-tickets.test.d.ts +0 -1
- package/dist/core/human/__tests__/page-tickets.test.js +0 -161
- package/dist/core/review/ticket-filter.d.ts +0 -17
- package/dist/core/review/ticket-filter.js +0 -21
- package/dist/core/runtime/broker/passive.d.ts +0 -17
- package/dist/core/runtime/broker/passive.js +0 -44
- package/dist/core/runtime/busy.d.ts +0 -46
- package/dist/core/runtime/busy.js +0 -150
- package/dist/daemon/__tests__/startup-block-marker.test.d.ts +0 -1
- package/dist/daemon/__tests__/startup-block-marker.test.js +0 -86
- package/dist/daemon/api/__tests__/review-terminal-conflict.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/review-terminal-conflict.test.js +0 -98
- package/dist/daemon/human/deliver-action.d.ts +0 -3
- package/dist/daemon/human/deliver-action.js +0 -9
- package/dist/daemon/node-outcome/deliver-outcome.d.ts +0 -3
- package/dist/daemon/node-outcome/deliver-outcome.js +0 -9
- package/dist/daemon/reconcilers/human-delivery-lane.d.ts +0 -10
- package/dist/daemon/reconcilers/human-delivery-lane.js +0 -41
- package/dist/daemon/reconcilers/node-outcome-delivery-lane.d.ts +0 -10
- package/dist/daemon/reconcilers/node-outcome-delivery-lane.js +0 -41
- package/dist/daemon/startup-block-marker.d.ts +0 -25
- package/dist/daemon/startup-block-marker.js +0 -99
- /package/dist/{clients/attach/__tests__/page-block.test.d.ts → api/dto/mail.js} +0 -0
- /package/dist/{commands/sys/__tests__/migrate.test.d.ts → api/dto/recovery.js} +0 -0
- /package/dist/{core/__tests__/human-cancel-guard.test.d.ts → commands/__tests__/integration/migrate.test.d.ts} +0 -0
|
@@ -3,37 +3,70 @@
|
|
|
3
3
|
// autostart another daemon.
|
|
4
4
|
import { CrtrClient } from '../../../api/client.js';
|
|
5
5
|
import { ApiError } from '../../../api/errors.js';
|
|
6
|
+
import { envExecutionId } from '../../../shared/env.js';
|
|
6
7
|
function daemonClient() {
|
|
7
8
|
return CrtrClient.forLocalSocket({ autostart: false });
|
|
8
9
|
}
|
|
10
|
+
export function brokerExecutionId() {
|
|
11
|
+
const id = envExecutionId();
|
|
12
|
+
if (id === undefined || id === '')
|
|
13
|
+
throw new Error('broker launch is missing CRTR_EXECUTION_ID');
|
|
14
|
+
return id;
|
|
15
|
+
}
|
|
9
16
|
export function bindBrokerSession(nodeId, request) {
|
|
10
|
-
return daemonClient().bindBrokerSession(nodeId, request);
|
|
17
|
+
return daemonClient().bindBrokerSession(nodeId, { ...request, executionId: brokerExecutionId() });
|
|
11
18
|
}
|
|
12
19
|
export function settleBroker(nodeId, request) {
|
|
13
|
-
return daemonClient().settleBroker(nodeId, request);
|
|
20
|
+
return daemonClient().settleBroker(nodeId, { ...request, expected_execution_id: brokerExecutionId() });
|
|
14
21
|
}
|
|
15
22
|
export function completeBrokerPark(nodeId, request) {
|
|
16
|
-
return daemonClient().completeBrokerPark(nodeId, request);
|
|
23
|
+
return daemonClient().completeBrokerPark(nodeId, { ...request, expected_execution_id: brokerExecutionId() });
|
|
17
24
|
}
|
|
18
25
|
export function recordBrokerParkActivity(nodeId) {
|
|
19
|
-
return daemonClient().recordBrokerParkActivity(nodeId);
|
|
26
|
+
return daemonClient().recordBrokerParkActivity(nodeId, { expected_execution_id: brokerExecutionId() });
|
|
27
|
+
}
|
|
28
|
+
export function claimBrokerMail(nodeId, channel) {
|
|
29
|
+
return daemonClient().claimNodeMail(nodeId, { execution_id: brokerExecutionId(), channel });
|
|
30
|
+
}
|
|
31
|
+
export function acknowledgeBrokerMail(nodeId, deliveries) {
|
|
32
|
+
return daemonClient().acknowledgeNodeMail(nodeId, { execution_id: brokerExecutionId(), deliveries });
|
|
33
|
+
}
|
|
34
|
+
export function recordBrokerTurn(nodeId, request) {
|
|
35
|
+
return daemonClient().recordBrokerTurn(nodeId, { ...request, expected_execution_id: brokerExecutionId() });
|
|
36
|
+
}
|
|
37
|
+
export function mutateBrokerProviderRetry(nodeId, request) {
|
|
38
|
+
return daemonClient().mutateBrokerProviderRetry(nodeId, { ...request, expected_execution_id: brokerExecutionId() });
|
|
39
|
+
}
|
|
40
|
+
export function mutateBrokerFault(nodeId, request) {
|
|
41
|
+
return daemonClient().mutateBrokerFault(nodeId, { ...request, expected_execution_id: brokerExecutionId() });
|
|
42
|
+
}
|
|
43
|
+
export function brokerRecovery(nodeId) {
|
|
44
|
+
return daemonClient().getBrokerRecovery(nodeId, brokerExecutionId());
|
|
45
|
+
}
|
|
46
|
+
/** Node-scoped fault writes are for non-broker clients such as attach transport.
|
|
47
|
+
* Broker-owned recovery mutations use the execution-fenced wrappers above. */
|
|
48
|
+
export function recordNodeFault(nodeId, input) {
|
|
49
|
+
return daemonClient().recordNodeFault(nodeId, input);
|
|
20
50
|
}
|
|
21
|
-
export function
|
|
22
|
-
return daemonClient().
|
|
51
|
+
export function clearNodeFault(nodeId, opts = {}) {
|
|
52
|
+
return daemonClient().clearNodeFault(nodeId, {
|
|
53
|
+
...(opts.link === undefined ? {} : { link: opts.link }),
|
|
54
|
+
...(opts.preserveEpisode === undefined ? {} : { preserve_episode: opts.preserveEpisode }),
|
|
55
|
+
}).then((result) => result.cleared);
|
|
23
56
|
}
|
|
24
57
|
/** Fixed canvas projection for broker extension rendering. It deliberately
|
|
25
58
|
* exposes no generic node/database facade. */
|
|
26
59
|
export function commitBrokerModel(nodeId, request) {
|
|
27
|
-
return daemonClient().commitBrokerModel(nodeId, request);
|
|
60
|
+
return daemonClient().commitBrokerModel(nodeId, { ...request, expected_execution_id: brokerExecutionId() });
|
|
28
61
|
}
|
|
29
62
|
export function brokerExtensionState(nodeId) {
|
|
30
63
|
return daemonClient().brokerExtensionState(nodeId);
|
|
31
64
|
}
|
|
32
65
|
export function commitBrokerGeneratedName(nodeId, request) {
|
|
33
|
-
return daemonClient().commitBrokerGeneratedName(nodeId, request);
|
|
66
|
+
return daemonClient().commitBrokerGeneratedName(nodeId, { ...request, expected_execution_id: brokerExecutionId() });
|
|
34
67
|
}
|
|
35
68
|
export function commitBrokerPersonaAck(nodeId, request) {
|
|
36
|
-
return daemonClient().commitBrokerPersonaAck(nodeId, request);
|
|
69
|
+
return daemonClient().commitBrokerPersonaAck(nodeId, { ...request, expected_execution_id: brokerExecutionId() });
|
|
37
70
|
}
|
|
38
71
|
/** Reports still use the canonical daemon report handler; this broker adapter
|
|
39
72
|
* only preserves terminal structured output's idempotent finalization result. */
|
|
@@ -2,6 +2,9 @@ interface AbortableSession {
|
|
|
2
2
|
clearQueue(): unknown;
|
|
3
3
|
abort(): Promise<unknown>;
|
|
4
4
|
}
|
|
5
|
+
export declare function refuseTurn(abort: () => void): void;
|
|
6
|
+
export declare function wasTurnRefused(): boolean;
|
|
7
|
+
export declare function clearRefusedTurn(): void;
|
|
5
8
|
/** Mark one synchronous ExtensionContext.abort() call as a refresh boundary. */
|
|
6
9
|
export declare function runRefreshAbort(abort: () => void): void;
|
|
7
10
|
/** Bound into Pi's extension context by the broker for every session generation. */
|
|
@@ -5,6 +5,17 @@
|
|
|
5
5
|
// Other aborts (notably a critical inbox entry) leave queues intact because the
|
|
6
6
|
// current conversation still owns those already-handed-off messages.
|
|
7
7
|
let refreshAbortScope = false;
|
|
8
|
+
let refusedTurn = false;
|
|
9
|
+
export function refuseTurn(abort) {
|
|
10
|
+
refusedTurn = true;
|
|
11
|
+
abort();
|
|
12
|
+
}
|
|
13
|
+
export function wasTurnRefused() {
|
|
14
|
+
return refusedTurn;
|
|
15
|
+
}
|
|
16
|
+
export function clearRefusedTurn() {
|
|
17
|
+
refusedTurn = false;
|
|
18
|
+
}
|
|
8
19
|
/** Mark one synchronous ExtensionContext.abort() call as a refresh boundary. */
|
|
9
20
|
export function runRefreshAbort(abort) {
|
|
10
21
|
refreshAbortScope = true;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { AgentSessionServices, ModelRegistry } from '@earendil-works/pi-coding-agent';
|
|
2
|
-
import {
|
|
2
|
+
import type { Fault } from '../../fault-classifier.js';
|
|
3
|
+
import type { RecoveryFaultDTO } from '../../../api/dto/recovery.js';
|
|
3
4
|
import type { BrokerSdkConfig } from '../launch.js';
|
|
4
5
|
import type { BrokerToClient } from '../broker-protocol.js';
|
|
5
6
|
import type { BrokerSession } from './read-ops.js';
|
|
@@ -26,12 +27,21 @@ export declare class FaultRetry {
|
|
|
26
27
|
private providerFallbackInFlight;
|
|
27
28
|
private notFoundFallbackInFlight;
|
|
28
29
|
private stagedCapacityFailure;
|
|
30
|
+
private personaGateFailed;
|
|
29
31
|
constructor(deps: FaultRetryDeps);
|
|
30
32
|
clearTimer(): void;
|
|
31
33
|
reset(): void;
|
|
34
|
+
/** A failed daemon-backed persona gate is local evidence, not a provider fault. */
|
|
35
|
+
notePersonaGateFailure(): void;
|
|
36
|
+
private state;
|
|
37
|
+
private recordFault;
|
|
38
|
+
private clearFault;
|
|
39
|
+
private sessionId;
|
|
40
|
+
private clearEpisode;
|
|
32
41
|
onEvent(event: BrokerToClient): void;
|
|
33
|
-
isActiveAutoFault(fault:
|
|
34
|
-
|
|
42
|
+
isActiveAutoFault(fault: RecoveryFaultDTO | null): fault is RecoveryFaultDTO;
|
|
43
|
+
isActiveAutoFault(fault: Fault | null): fault is Fault;
|
|
44
|
+
publishSettledProviderFault(generation: SubscriptionGeneration): Promise<void>;
|
|
35
45
|
/** Startup re-drive reads the durable episode surviving from the process this
|
|
36
46
|
* replaces. Revive deliberately clears the ordinary fault marker before this
|
|
37
47
|
* boundary, so the episode is the recovery authority. A `pending` episode
|
|
@@ -44,7 +54,7 @@ export declare class FaultRetry {
|
|
|
44
54
|
* it out below), so it is treated the same as "no progress" rather than
|
|
45
55
|
* blocking the ladder. Returns 'retry-armed' when the timer now owns the
|
|
46
56
|
* first turn, 'none' when the caller's default kickoff should proceed. */
|
|
47
|
-
recoverOnStartup(): 'retry-armed' | 'none'
|
|
57
|
+
recoverOnStartup(): Promise<'retry-armed' | 'none'>;
|
|
48
58
|
/** True iff the branch segment strictly after `anchorEntryId` (root→leaf,
|
|
49
59
|
* anchor exclusive) contains an assistant message with non-empty content or
|
|
50
60
|
* a tool result — the two shapes a runtime card and a `content: []`
|
|
@@ -52,14 +62,13 @@ export declare class FaultRetry {
|
|
|
52
62
|
* branch cannot be distinguished from "no progress" here; callers treat it
|
|
53
63
|
* as no progress rather than as a positive finding. */
|
|
54
64
|
private hasProgressPastAnchor;
|
|
55
|
-
schedule(): void
|
|
65
|
+
schedule(): Promise<void>;
|
|
56
66
|
private maybeSwitchProviderForRetry;
|
|
57
67
|
private maybeFallbackOnUnusableModel;
|
|
58
68
|
private nextEligibleFallbackRoute;
|
|
59
69
|
private targetCannotFitContext;
|
|
60
70
|
private stageCapacityFailure;
|
|
61
71
|
private recordPendingProviderFault;
|
|
62
|
-
private sessionFile;
|
|
63
72
|
private pendingEpisodeMatches;
|
|
64
73
|
private faultRetryDelayMs;
|
|
65
74
|
private clearAndArmFaultRetry;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { realpathSync } from 'node:fs';
|
|
2
1
|
import { envModelIntent, envNodeCwd, envProfileId } from '../../../shared/env.js';
|
|
3
2
|
import { isContextOverflow } from '@earendil-works/pi-ai';
|
|
4
3
|
import { classify } from '../../fault-classifier.js';
|
|
5
|
-
import {
|
|
4
|
+
import { isModelNotFoundError, isProviderUnconfiguredError } from '../fault.js';
|
|
5
|
+
import { brokerRecovery, mutateBrokerFault, mutateBrokerProviderRetry } from './daemon-ops.js';
|
|
6
6
|
import { extractCoolingDeadline } from '../managed-provider-cooling.js';
|
|
7
7
|
import { extractProviderFailureDetails } from '../../provider-failure.js';
|
|
8
8
|
import { expandModelCandidates, modelRequestFromConfig, probeRouteAvailability } from '../../model-routes.js';
|
|
@@ -15,6 +15,32 @@ import { endedByAbort } from '../session-cycles.js';
|
|
|
15
15
|
import { resolveProviderCandidates } from '../../subscription-state.js';
|
|
16
16
|
import { announceMessageOrigin } from '../stamp/channel.js';
|
|
17
17
|
const MAX_TIMEOUT_MS = 2_147_483_647;
|
|
18
|
+
function policyFault(fault) {
|
|
19
|
+
return {
|
|
20
|
+
link: fault.link,
|
|
21
|
+
op: fault.op,
|
|
22
|
+
kind: fault.kind,
|
|
23
|
+
retry: fault.retry,
|
|
24
|
+
message: fault.message,
|
|
25
|
+
since: fault.since,
|
|
26
|
+
operation_id: fault.operation_id,
|
|
27
|
+
...(fault.anchor_entry_id === undefined ? {} : { anchorEntryId: fault.anchor_entry_id }),
|
|
28
|
+
...(fault.provider_error === undefined ? {} : { providerError: fault.provider_error }),
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
function faultInput(fault) {
|
|
32
|
+
return {
|
|
33
|
+
link: fault.link,
|
|
34
|
+
op: fault.op,
|
|
35
|
+
kind: fault.kind,
|
|
36
|
+
retry: fault.retry,
|
|
37
|
+
message: fault.message,
|
|
38
|
+
...(fault.operation_id === undefined ? {} : { operation_id: fault.operation_id }),
|
|
39
|
+
...(fault.since === undefined ? {} : { since: fault.since }),
|
|
40
|
+
...(fault.anchorEntryId === undefined ? {} : { anchor_entry_id: fault.anchorEntryId }),
|
|
41
|
+
...(fault.providerError === undefined ? {} : { provider_error: fault.providerError }),
|
|
42
|
+
};
|
|
43
|
+
}
|
|
18
44
|
/** Owns provider fallback and daemon-driven fault retry state for one broker session. */
|
|
19
45
|
export class FaultRetry {
|
|
20
46
|
deps;
|
|
@@ -28,6 +54,7 @@ export class FaultRetry {
|
|
|
28
54
|
// agent_end staging field: message_end precedes agent_end, which resets that
|
|
29
55
|
// field for the ordinary provider result.
|
|
30
56
|
stagedCapacityFailure = null;
|
|
57
|
+
personaGateFailed = false;
|
|
31
58
|
constructor(deps) {
|
|
32
59
|
this.deps = deps;
|
|
33
60
|
}
|
|
@@ -42,6 +69,29 @@ export class FaultRetry {
|
|
|
42
69
|
this.providerFallbackInFlight = null;
|
|
43
70
|
this.notFoundFallbackInFlight = null;
|
|
44
71
|
this.stagedCapacityFailure = null;
|
|
72
|
+
this.personaGateFailed = false;
|
|
73
|
+
}
|
|
74
|
+
/** A failed daemon-backed persona gate is local evidence, not a provider fault. */
|
|
75
|
+
notePersonaGateFailure() {
|
|
76
|
+
this.personaGateFailed = true;
|
|
77
|
+
}
|
|
78
|
+
state() {
|
|
79
|
+
return brokerRecovery(this.deps.nodeId);
|
|
80
|
+
}
|
|
81
|
+
async recordFault(input) {
|
|
82
|
+
return (await mutateBrokerFault(this.deps.nodeId, { op: 'record', input })).fault;
|
|
83
|
+
}
|
|
84
|
+
async clearFault(link, preserveEpisode = false) {
|
|
85
|
+
await mutateBrokerFault(this.deps.nodeId, { op: 'clear', ...(link === undefined ? {} : { link }), ...(preserveEpisode ? { preserve_episode: true } : {}) });
|
|
86
|
+
}
|
|
87
|
+
sessionId(session) {
|
|
88
|
+
const id = session.sessionManager.getSessionId?.();
|
|
89
|
+
return typeof id === 'string' && id !== '' ? id : null;
|
|
90
|
+
}
|
|
91
|
+
async clearEpisode(session) {
|
|
92
|
+
const sessionId = this.sessionId(session);
|
|
93
|
+
if (sessionId !== null)
|
|
94
|
+
await mutateBrokerProviderRetry(this.deps.nodeId, { op: 'clear', session_id: sessionId });
|
|
45
95
|
}
|
|
46
96
|
onEvent(event) {
|
|
47
97
|
this.maybeSwitchProviderForRetry(event);
|
|
@@ -56,13 +106,15 @@ export class FaultRetry {
|
|
|
56
106
|
return false;
|
|
57
107
|
return fault.kind === 'connection' || fault.kind === 'rate-limit' || fault.kind === 'overloaded';
|
|
58
108
|
}
|
|
59
|
-
publishSettledProviderFault(generation) {
|
|
109
|
+
async publishSettledProviderFault(generation) {
|
|
60
110
|
const agentEnd = generation.stagedProviderAgentEnd;
|
|
61
111
|
const watchdogAbort = generation.stagedWatchdogAbort;
|
|
62
112
|
const refreshAbort = generation.stagedRefreshAbort;
|
|
63
113
|
const overflowFailure = generation.stagedOverflowFailure;
|
|
64
114
|
const capacityFailure = this.stagedCapacityFailure?.generation === generation ? this.stagedCapacityFailure : null;
|
|
115
|
+
const personaGateFailed = this.personaGateFailed;
|
|
65
116
|
this.stagedCapacityFailure = null;
|
|
117
|
+
this.personaGateFailed = false;
|
|
66
118
|
generation.stagedProviderAgentEnd = null;
|
|
67
119
|
generation.stagedWatchdogAbort = false;
|
|
68
120
|
generation.stagedRefreshAbort = false;
|
|
@@ -71,54 +123,52 @@ export class FaultRetry {
|
|
|
71
123
|
// turn_end clears the ordinary marker before this settlement. A failed
|
|
72
124
|
// admitted retry therefore carries from its durable episode, while an
|
|
73
125
|
// initial provider failure still reads from the ordinary marker.
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
// turning it into a fatal pi→provider `other` fault.
|
|
79
|
-
if (prior?.link === 'broker↔crtrd' && prior.kind === 'connection') {
|
|
80
|
-
clearProviderRetryEpisode(this.deps.nodeId);
|
|
81
|
-
return;
|
|
82
|
-
}
|
|
83
|
-
const durableEpisode = readProviderRetryEpisode(this.deps.nodeId);
|
|
126
|
+
const initialState = await this.state();
|
|
127
|
+
const prior = initialState.fault;
|
|
128
|
+
const durableEpisode = initialState.episode;
|
|
129
|
+
const sessionId = this.sessionId(settledSession);
|
|
84
130
|
const episodeFault = this.isActiveAutoFault(prior) && prior.link === 'pi→provider'
|
|
85
131
|
? prior
|
|
86
132
|
: durableEpisode?.state === 'admitted' &&
|
|
87
|
-
durableEpisode.
|
|
133
|
+
durableEpisode.session_id === sessionId &&
|
|
88
134
|
this.isActiveAutoFault(durableEpisode.fault)
|
|
89
135
|
? durableEpisode.fault
|
|
90
136
|
: null;
|
|
91
137
|
const episode = episodeFault === null
|
|
92
138
|
? null
|
|
93
|
-
: { since: episodeFault.since, anchorEntryId: episodeFault.
|
|
139
|
+
: { since: episodeFault.since, anchorEntryId: episodeFault.anchor_entry_id, attempt: episodeFault.retry.attempt };
|
|
94
140
|
const messages = Array.isArray(agentEnd?.messages) ? agentEnd.messages : [];
|
|
95
141
|
const last = [...messages].reverse().find((message) => typeof message === 'object' && message !== null && message.role === 'assistant');
|
|
142
|
+
if (personaGateFailed) {
|
|
143
|
+
await this.clearEpisode(settledSession);
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
96
146
|
if (capacityFailure !== null || overflowFailure !== null) {
|
|
97
|
-
clearFault(
|
|
98
|
-
|
|
99
|
-
recordFault(
|
|
147
|
+
await this.clearFault('pi→provider');
|
|
148
|
+
await this.clearEpisode(settledSession);
|
|
149
|
+
await this.recordFault({
|
|
100
150
|
link: 'pi→provider', op: 'context overflow recovery', kind: 'context-overflow', retry: { disposition: 'fatal' },
|
|
101
|
-
message: capacityFailure?.errorMessage ?? overflowFailure.errorMessage,
|
|
151
|
+
message: capacityFailure?.errorMessage ?? overflowFailure.errorMessage, anchor_entry_id: settledSession.sessionManager.getLeafId?.() ?? undefined,
|
|
102
152
|
});
|
|
103
153
|
return;
|
|
104
154
|
}
|
|
105
155
|
if (watchdogAbort && last?.stopReason === 'aborted') {
|
|
106
|
-
this.recordPendingProviderFault(settledSession, {
|
|
156
|
+
await this.recordPendingProviderFault(settledSession, {
|
|
107
157
|
link: 'pi→provider', op: 'generation turn', kind: 'connection',
|
|
108
158
|
retry: { disposition: 'auto', by: 'daemon', ...(episode?.attempt !== undefined ? { attempt: episode.attempt } : {}) },
|
|
109
159
|
message: typeof last.errorMessage === 'string' ? last.errorMessage : 'engine error (no errorMessage recorded)',
|
|
110
160
|
...(episode !== null ? { since: episode.since } : {}),
|
|
111
|
-
|
|
161
|
+
anchor_entry_id: episode?.anchorEntryId ?? settledSession.sessionManager.getLeafId?.() ?? undefined,
|
|
112
162
|
});
|
|
113
163
|
return;
|
|
114
164
|
}
|
|
115
165
|
if (last?.stopReason !== 'error') {
|
|
116
166
|
if (last !== undefined)
|
|
117
|
-
|
|
167
|
+
await this.clearEpisode(settledSession);
|
|
118
168
|
return;
|
|
119
169
|
}
|
|
120
170
|
if (refreshAbort) {
|
|
121
|
-
|
|
171
|
+
await this.clearEpisode(settledSession);
|
|
122
172
|
return;
|
|
123
173
|
}
|
|
124
174
|
const raw = typeof last.errorMessage === 'string' ? last.errorMessage : 'engine error (no errorMessage recorded)';
|
|
@@ -126,7 +176,7 @@ export class FaultRetry {
|
|
|
126
176
|
// and settles as an error rather than `aborted`. Something asked that turn
|
|
127
177
|
// to stop, so there is no provider fault to record.
|
|
128
178
|
if (endedByAbort({ stopReason: 'error', errorMessage: raw })) {
|
|
129
|
-
|
|
179
|
+
await this.clearEpisode(settledSession);
|
|
130
180
|
return;
|
|
131
181
|
}
|
|
132
182
|
const uncompactedOverflow = isContextOverflow(last, settledSession.model?.contextWindow);
|
|
@@ -139,8 +189,8 @@ export class FaultRetry {
|
|
|
139
189
|
? undefined
|
|
140
190
|
: { provider, model, ...failure };
|
|
141
191
|
if (uncompactedOverflow) {
|
|
142
|
-
clearFault(
|
|
143
|
-
|
|
192
|
+
await this.clearFault('pi→provider');
|
|
193
|
+
await this.clearEpisode(settledSession);
|
|
144
194
|
}
|
|
145
195
|
const faultInput = {
|
|
146
196
|
link: 'pi→provider', op: 'generation turn', kind: uncompactedOverflow ? 'context-overflow' : classified.kind,
|
|
@@ -155,16 +205,16 @@ export class FaultRetry {
|
|
|
155
205
|
: { disposition: classified.disposition },
|
|
156
206
|
message: raw,
|
|
157
207
|
...(!uncompactedOverflow && classified.disposition === 'auto' && episode !== null ? { since: episode.since } : {}),
|
|
158
|
-
|
|
208
|
+
anchor_entry_id: !uncompactedOverflow && classified.disposition === 'auto' && episode?.anchorEntryId !== undefined
|
|
159
209
|
? episode.anchorEntryId
|
|
160
210
|
: settledSession.sessionManager.getLeafId?.() ?? undefined,
|
|
161
|
-
...(providerError === undefined ? {} : { providerError }),
|
|
211
|
+
...(providerError === undefined ? {} : { provider_error: providerError }),
|
|
162
212
|
};
|
|
163
213
|
if (faultInput.retry.disposition === 'auto')
|
|
164
|
-
this.recordPendingProviderFault(settledSession, faultInput);
|
|
214
|
+
await this.recordPendingProviderFault(settledSession, faultInput);
|
|
165
215
|
else {
|
|
166
|
-
|
|
167
|
-
recordFault(
|
|
216
|
+
await this.clearEpisode(settledSession);
|
|
217
|
+
await this.recordFault(faultInput);
|
|
168
218
|
}
|
|
169
219
|
}
|
|
170
220
|
/** Startup re-drive reads the durable episode surviving from the process this
|
|
@@ -179,42 +229,42 @@ export class FaultRetry {
|
|
|
179
229
|
* it out below), so it is treated the same as "no progress" rather than
|
|
180
230
|
* blocking the ladder. Returns 'retry-armed' when the timer now owns the
|
|
181
231
|
* first turn, 'none' when the caller's default kickoff should proceed. */
|
|
182
|
-
recoverOnStartup() {
|
|
232
|
+
async recoverOnStartup() {
|
|
183
233
|
const generation = this.deps.installedGeneration();
|
|
184
234
|
if (generation === undefined)
|
|
185
235
|
return 'none';
|
|
186
|
-
const episode =
|
|
187
|
-
const
|
|
236
|
+
const episode = (await this.state()).episode;
|
|
237
|
+
const sessionId = this.sessionId(generation.session);
|
|
188
238
|
// A new-cycle launch deliberately roots a new transcript branch even though
|
|
189
239
|
// it reuses the same .jsonl. Its old anchor is no longer a valid recovery
|
|
190
240
|
// coordinate, so mark the episode invalid rather than inferring that from
|
|
191
241
|
// the shared path or letting startup re-drive into the fresh cycle.
|
|
192
242
|
if (this.deps.cfg.newCycle === true) {
|
|
193
|
-
if (episode !== null &&
|
|
194
|
-
|
|
243
|
+
if (episode !== null && sessionId !== null && episode.session_id === sessionId) {
|
|
244
|
+
await mutateBrokerProviderRetry(this.deps.nodeId, { op: 'invalidate', session_id: sessionId });
|
|
195
245
|
}
|
|
196
246
|
return 'none';
|
|
197
247
|
}
|
|
198
|
-
if (episode === null ||
|
|
248
|
+
if (episode === null || sessionId === null || episode.session_id !== sessionId)
|
|
199
249
|
return 'none';
|
|
200
250
|
if (episode.state === 'admitted') {
|
|
201
|
-
if (episode.
|
|
202
|
-
if (!
|
|
251
|
+
if (episode.fault.anchor_entry_id !== undefined && !this.hasProgressPastAnchor(generation.session, episode.fault.anchor_entry_id)) {
|
|
252
|
+
if (!(await mutateBrokerProviderRetry(this.deps.nodeId, { op: 'reopen', session_id: sessionId })).applied)
|
|
203
253
|
return 'none';
|
|
204
254
|
}
|
|
205
255
|
else {
|
|
206
256
|
// Progress detected past the anchor (or no anchor to prove against) — the
|
|
207
257
|
// dead attempt did real work. Never roll that back; clear the episode and
|
|
208
258
|
// let the caller's default kickoff continue where it actually got to.
|
|
209
|
-
|
|
259
|
+
await this.clearEpisode(generation.session);
|
|
210
260
|
return 'none';
|
|
211
261
|
}
|
|
212
262
|
}
|
|
213
263
|
else if (episode.state !== 'pending') {
|
|
214
264
|
return 'none';
|
|
215
265
|
}
|
|
216
|
-
recordFault(
|
|
217
|
-
this.schedule();
|
|
266
|
+
await this.recordFault(faultInput(policyFault(episode.fault)));
|
|
267
|
+
await this.schedule();
|
|
218
268
|
return 'retry-armed';
|
|
219
269
|
}
|
|
220
270
|
/** True iff the branch segment strictly after `anchorEntryId` (root→leaf,
|
|
@@ -236,17 +286,17 @@ export class FaultRetry {
|
|
|
236
286
|
return message.role === 'assistant' && Array.isArray(message.content) && message.content.length > 0;
|
|
237
287
|
});
|
|
238
288
|
}
|
|
239
|
-
schedule() {
|
|
289
|
+
async schedule() {
|
|
240
290
|
const generation = this.deps.installedGeneration();
|
|
241
291
|
const session = this.deps.currentSession();
|
|
242
292
|
if (generation === undefined || session.isStreaming || this.timer !== null)
|
|
243
293
|
return;
|
|
244
|
-
const
|
|
245
|
-
|
|
246
|
-
//
|
|
247
|
-
// exists, require its pending episode so
|
|
248
|
-
// inert
|
|
249
|
-
if (!this.isActiveAutoFault(fault) || (this.
|
|
294
|
+
const state = await this.state();
|
|
295
|
+
const fault = state.fault;
|
|
296
|
+
// A live session without a durable session binding still owns its ordinary
|
|
297
|
+
// in-process timer; once one exists, require its pending episode so
|
|
298
|
+
// admitted/invalidated retries stay inert before replacement startup.
|
|
299
|
+
if (!this.isActiveAutoFault(fault) || (this.sessionId(session) !== null && !this.pendingEpisodeMatches(session, fault, state))) {
|
|
250
300
|
this.clearTimer();
|
|
251
301
|
return;
|
|
252
302
|
}
|
|
@@ -355,7 +405,7 @@ export class FaultRetry {
|
|
|
355
405
|
if (this.deps.installedGeneration() !== generation || this.deps.currentSession() !== candidateSession)
|
|
356
406
|
return;
|
|
357
407
|
if (unconfigured)
|
|
358
|
-
clearFault(
|
|
408
|
+
await this.clearFault('pi→provider');
|
|
359
409
|
const fallbackCard = formatCard('recovery', {}, formatModelFallbackRecovery(currentSpec, resolved, unconfigured ? 'credential' : 'not-found'));
|
|
360
410
|
announceMessageOrigin(fallbackCard, { type: 'runtime', kind: 'recovery' });
|
|
361
411
|
await this.deps.turnAdmission.admit((release) => operationIdContext.fresh(() => candidateSession.prompt(fallbackCard, { preflightResult: release })));
|
|
@@ -399,42 +449,31 @@ export class FaultRetry {
|
|
|
399
449
|
: 'All available fallback models have context windows smaller than the current conversation.',
|
|
400
450
|
};
|
|
401
451
|
}
|
|
402
|
-
recordPendingProviderFault(session, input) {
|
|
403
|
-
const
|
|
404
|
-
// A
|
|
405
|
-
//
|
|
406
|
-
if (
|
|
407
|
-
recordFault(
|
|
452
|
+
async recordPendingProviderFault(session, input) {
|
|
453
|
+
const sessionId = this.sessionId(session);
|
|
454
|
+
// A session without a daemon binding cannot crash-recover, but its live
|
|
455
|
+
// broker still records its ordinary auto-retry fault.
|
|
456
|
+
if (sessionId === null) {
|
|
457
|
+
await this.recordFault(input);
|
|
408
458
|
return;
|
|
409
459
|
}
|
|
410
|
-
|
|
460
|
+
await mutateBrokerProviderRetry(this.deps.nodeId, { op: 'record-pending', session_id: sessionId, input });
|
|
411
461
|
}
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
return realpathSync(session.sessionFile);
|
|
417
|
-
}
|
|
418
|
-
catch {
|
|
419
|
-
return session.sessionFile;
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
pendingEpisodeMatches(session, fault) {
|
|
423
|
-
const sessionFile = this.sessionFile(session);
|
|
424
|
-
const episode = readProviderRetryEpisode(this.deps.nodeId);
|
|
425
|
-
return sessionFile !== null &&
|
|
462
|
+
pendingEpisodeMatches(session, fault, state) {
|
|
463
|
+
const sessionId = this.sessionId(session);
|
|
464
|
+
const episode = state.episode;
|
|
465
|
+
return sessionId !== null &&
|
|
426
466
|
episode !== null &&
|
|
427
467
|
episode.state === 'pending' &&
|
|
428
|
-
episode.
|
|
429
|
-
episode.fault.
|
|
430
|
-
episode.anchorEntryId === (fault.anchorEntryId ?? null);
|
|
468
|
+
episode.session_id === sessionId &&
|
|
469
|
+
episode.fault.fault_id === fault.fault_id;
|
|
431
470
|
}
|
|
432
471
|
faultRetryDelayMs(fault, now) {
|
|
433
472
|
if (fault.retry.nextAt !== undefined) {
|
|
434
473
|
const ms = Date.parse(fault.retry.nextAt) - now;
|
|
435
474
|
return Number.isFinite(ms) ? Math.max(0, ms) : null;
|
|
436
475
|
}
|
|
437
|
-
return nextFaultRetry(fault, now)?.delayMs ?? null;
|
|
476
|
+
return nextFaultRetry(policyFault(fault), now)?.delayMs ?? null;
|
|
438
477
|
}
|
|
439
478
|
clearAndArmFaultRetry(delayMs, generation) {
|
|
440
479
|
if (this.deps.installedGeneration() !== generation)
|
|
@@ -464,7 +503,7 @@ export class FaultRetry {
|
|
|
464
503
|
const candidateSession = generation.session;
|
|
465
504
|
if (candidateSession.isStreaming)
|
|
466
505
|
return;
|
|
467
|
-
const initial =
|
|
506
|
+
const initial = (await this.state()).fault;
|
|
468
507
|
if (!this.isActiveAutoFault(initial))
|
|
469
508
|
return;
|
|
470
509
|
let fault = initial;
|
|
@@ -472,7 +511,7 @@ export class FaultRetry {
|
|
|
472
511
|
const online = await this.deps.retryProbe();
|
|
473
512
|
if (this.deps.installedGeneration() !== generation || this.deps.currentSession() !== candidateSession || candidateSession.isStreaming)
|
|
474
513
|
return;
|
|
475
|
-
const fresh =
|
|
514
|
+
const fresh = (await this.state()).fault;
|
|
476
515
|
if (!this.isActiveAutoFault(fresh) || fresh.since !== initial.since)
|
|
477
516
|
return;
|
|
478
517
|
if (!online) {
|
|
@@ -484,20 +523,20 @@ export class FaultRetry {
|
|
|
484
523
|
const attempt = fault.retry.attempt ?? 0;
|
|
485
524
|
const policy = policyFor(fault.kind);
|
|
486
525
|
if (attempt >= policy.max) {
|
|
487
|
-
recordFault(
|
|
488
|
-
|
|
526
|
+
await this.recordFault(faultInput(markFatalOnExhaust(policyFault(fault))));
|
|
527
|
+
await this.clearEpisode(candidateSession);
|
|
489
528
|
return;
|
|
490
529
|
}
|
|
491
|
-
const plan = nextFaultRetry(fault, Date.now());
|
|
530
|
+
const plan = nextFaultRetry(policyFault(fault), Date.now());
|
|
492
531
|
if (plan === null) {
|
|
493
|
-
recordFault(
|
|
494
|
-
|
|
532
|
+
await this.recordFault(faultInput(markFatalOnExhaust(policyFault(fault))));
|
|
533
|
+
await this.clearEpisode(candidateSession);
|
|
495
534
|
return;
|
|
496
535
|
}
|
|
497
|
-
if (fault.
|
|
536
|
+
if (fault.anchor_entry_id !== undefined) {
|
|
498
537
|
try {
|
|
499
|
-
if ((candidateSession.sessionManager.getLeafId?.() ?? null) !== fault.
|
|
500
|
-
await candidateSession.navigateTree(fault.
|
|
538
|
+
if ((candidateSession.sessionManager.getLeafId?.() ?? null) !== fault.anchor_entry_id) {
|
|
539
|
+
await candidateSession.navigateTree(fault.anchor_entry_id);
|
|
501
540
|
if (this.deps.installedGeneration() !== generation || this.deps.currentSession() !== candidateSession)
|
|
502
541
|
return;
|
|
503
542
|
}
|
|
@@ -508,27 +547,35 @@ export class FaultRetry {
|
|
|
508
547
|
}
|
|
509
548
|
if (this.deps.installedGeneration() !== generation || this.deps.currentSession() !== candidateSession)
|
|
510
549
|
return;
|
|
511
|
-
await this.deps.turnAdmission.admit((release) => {
|
|
512
|
-
const current =
|
|
550
|
+
await this.deps.turnAdmission.admit(async (release) => {
|
|
551
|
+
const current = (await this.state()).fault;
|
|
513
552
|
if (this.deps.installedGeneration() !== generation ||
|
|
514
553
|
this.deps.currentSession() !== candidateSession ||
|
|
515
554
|
candidateSession.isStreaming ||
|
|
516
555
|
!this.isActiveAutoFault(current) ||
|
|
517
556
|
current.since !== fault.since) {
|
|
518
557
|
release();
|
|
519
|
-
return
|
|
558
|
+
return;
|
|
520
559
|
}
|
|
521
560
|
// This is the admission point: all generation/session/streaming/fault
|
|
522
561
|
// revalidation above has passed, and only now may the durable episode
|
|
523
|
-
// become admitted.
|
|
524
|
-
//
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
if (sessionFile !== null && !admitProviderRetryEpisode(this.deps.nodeId, sessionFile, plan.fault)) {
|
|
562
|
+
// become admitted. A rejected or failed mutation releases without
|
|
563
|
+
// calling prompt, so stale brokers never run a recovery turn.
|
|
564
|
+
const sessionId = this.sessionId(candidateSession);
|
|
565
|
+
if (sessionId === null) {
|
|
528
566
|
release();
|
|
529
|
-
return
|
|
567
|
+
return;
|
|
568
|
+
}
|
|
569
|
+
const admitted = await mutateBrokerProviderRetry(this.deps.nodeId, {
|
|
570
|
+
op: 'admit',
|
|
571
|
+
session_id: sessionId,
|
|
572
|
+
fault_id: current.fault_id,
|
|
573
|
+
retry: plan.fault.retry,
|
|
574
|
+
});
|
|
575
|
+
if (!admitted.applied) {
|
|
576
|
+
release();
|
|
577
|
+
return;
|
|
530
578
|
}
|
|
531
|
-
recordFault(this.deps.nodeId, plan.fault);
|
|
532
579
|
// The attempt facts are what makes a rolled-back retry legible: every
|
|
533
580
|
// superseded attempt falls off the active branch, so this one card is the
|
|
534
581
|
// whole visible record of the sequence, and without them a reader cannot
|