@north-light/cli 0.3.561 → 0.3.563
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 -4
- package/dist/api/client.js +3 -3
- package/dist/api/contract.d.ts +1 -1
- package/dist/api/contract.js +1 -1
- package/dist/api/dto/bash-jobs.d.ts +5 -1
- package/dist/api/dto/broker-ops.d.ts +25 -1
- package/dist/api/dto/charges.d.ts +9 -2
- package/dist/api/dto/delivery.d.ts +26 -2
- package/dist/api/dto/execution-start.d.ts +57 -0
- package/dist/api/dto/execution-start.js +0 -0
- package/dist/api/dto/modelauth.d.ts +5 -0
- package/dist/api/dto/node-records.d.ts +16 -0
- package/dist/api/dto/objects.d.ts +1 -1
- package/dist/api/dto/reports.d.ts +0 -3
- package/dist/api/dto/run-events.d.ts +7 -1
- package/dist/api/dto/settings.d.ts +55 -0
- package/dist/api/dto/settings.js +0 -0
- package/dist/api/index.d.ts +2 -0
- package/dist/api/index.js +1 -1
- package/dist/api/routes.d.ts +11 -0
- package/dist/api/routes.js +1 -1
- package/dist/build-root.d.ts +1 -0
- package/dist/build-root.js +1 -1
- package/dist/builtin-memory/crouter-sdk/release-notes.md +4 -0
- package/dist/cli.js +7 -7
- package/dist/clients/attach/chrome/bash-jobs.d.ts +11 -1
- package/dist/clients/attach/chrome/bash-jobs.js +1 -1
- package/dist/clients/attach/chrome/canvas-panels.d.ts +1 -1
- package/dist/clients/attach/chrome/roster.js +6 -4
- package/dist/clients/attach/overlays/auth.js +2 -2
- package/dist/clients/attach/render/chat-view.js +1 -1
- package/dist/clients/attach/viewer.js +550 -567
- package/dist/commands/canvas-config.js +2 -2
- package/dist/commands/canvas-use.js +1 -1
- package/dist/commands/human.js +2 -2
- package/dist/commands/node/bash.js +3 -3
- package/dist/commands/node/create.js +2 -2
- package/dist/commands/person-settings.d.ts +1 -0
- package/dist/commands/person-settings.js +1 -0
- package/dist/commands/pkg/market-manage.d.ts +2 -2
- package/dist/commands/pkg/market-manage.js +1 -1
- package/dist/commands/pkg/plugin-manage.js +13 -13
- package/dist/commands/pkg/shared.js +1 -1
- package/dist/commands/profile/default.js +1 -1
- package/dist/commands/push.js +2 -3
- package/dist/commands/sys/config.js +1 -1
- package/dist/commands/sys/connect.js +1 -1
- package/dist/commands/sys/context/sysprompt.js +2 -2
- package/dist/commands/sys/doctor.js +1 -1
- package/dist/commands/sys/join.js +1 -1
- package/dist/commands/sys/panels/broker-limits-panel.js +1 -1
- package/dist/commands/sys/panels/keybindings-panel.js +1 -1
- package/dist/commands/sys/panels/models-panel.d.ts +8 -2
- package/dist/commands/sys/panels/models-panel.js +1 -1
- package/dist/commands/sys/panels/prefs-panel.d.ts +1 -0
- package/dist/commands/sys/panels/prefs-panel.js +1 -1
- package/dist/commands/sys/panels/profiles-panel.js +1 -1
- package/dist/commands/sys/panels/provider-panel.d.ts +4 -0
- package/dist/commands/sys/panels/provider-panel.js +1 -1
- package/dist/commands/sys/provider-login.js +5 -5
- package/dist/commands/sys/setup-core.js +3 -3
- package/dist/commands/sys/setup-settings-runner.js +1 -1
- package/dist/commands/sys/spend.js +3 -3
- package/dist/commands/sys/update.js +1 -1
- package/dist/core/auth-file.d.ts +11 -19
- package/dist/core/auth-file.js +1 -2
- package/dist/core/auto-update.d.ts +1 -1
- package/dist/core/auto-update.js +4 -4
- package/dist/core/bash-jobs.d.ts +29 -71
- package/dist/core/bash-jobs.js +9 -10
- package/dist/core/blobs/directory.d.ts +3 -0
- package/dist/core/blobs/directory.js +1 -0
- package/dist/core/blobs/fault.d.ts +3 -0
- package/dist/core/blobs/fault.js +1 -0
- package/dist/core/blobs/index.d.ts +21 -0
- package/dist/core/blobs/index.js +1 -0
- package/dist/core/blobs/r2.d.ts +9 -0
- package/dist/core/blobs/r2.js +4 -0
- package/dist/core/bootstrap.d.ts +1 -1
- package/dist/core/bootstrap.js +2 -2
- package/dist/core/canvas/canvas.d.ts +9 -7
- package/dist/core/canvas/canvas.js +8 -8
- package/dist/core/canvas/crons.d.ts +3 -2
- package/dist/core/canvas/crons.js +3 -3
- package/dist/core/canvas/daemon-owner.d.ts +5 -0
- package/dist/core/canvas/daemon-owner.js +1 -1
- package/dist/core/canvas/db.d.ts +10 -9
- package/dist/core/canvas/db.js +4 -4
- package/dist/core/canvas/executions.d.ts +100 -4
- package/dist/core/canvas/executions.js +1 -1
- package/dist/core/canvas/export-sqlite.js +1 -1
- package/dist/core/canvas/focuses.d.ts +4 -0
- package/dist/core/canvas/focuses.js +1 -1
- package/dist/core/canvas/history.js +9 -9
- package/dist/core/canvas/managed-worktree-sweep-candidates.d.ts +2 -1
- package/dist/core/canvas/managed-worktree-sweep-candidates.js +3 -2
- package/dist/core/canvas/node-tokens.d.ts +1 -4
- package/dist/core/canvas/node-tokens.js +3 -3
- package/dist/core/canvas/paths.d.ts +0 -1
- package/dist/core/canvas/paths.js +1 -1
- package/dist/core/canvas/person-state.d.ts +26 -0
- package/dist/core/canvas/person-state.js +1 -0
- package/dist/core/canvas/person.d.ts +3 -10
- package/dist/core/canvas/person.js +7 -7
- package/dist/core/canvas/reconciler-leases.d.ts +12 -0
- package/dist/core/canvas/reconciler-leases.js +8 -0
- package/dist/core/canvas/recovery.d.ts +4 -0
- package/dist/core/canvas/recovery.js +1 -1
- package/dist/core/canvas/schema-pg/003-fleet-removals.sql +1 -1
- package/dist/core/canvas/schema-pg/005-fleet-blobs.sql +13 -0
- package/dist/core/canvas/schema-pg/006-job-rows.sql +20 -0
- package/dist/core/canvas/schema-pg/007-ledger-check.sql +117 -0
- package/dist/core/canvas/schema-version.d.ts +1 -1
- package/dist/core/canvas/schema-version.js +1 -1
- package/dist/core/canvas/sessions.d.ts +8 -11
- package/dist/core/canvas/sessions.js +1 -4
- package/dist/core/canvas/tree.d.ts +4 -2
- package/dist/core/canvas/tree.js +6 -6
- package/dist/core/canvas/types.d.ts +7 -0
- package/dist/core/command-hooks/transport/exec-lifecycle.js +1 -1
- package/dist/core/command-plugins/bundle.d.ts +1 -1
- package/dist/core/command-plugins/bundle.js +1 -1
- package/dist/core/command-plugins/compose.d.ts +1 -1
- package/dist/core/command-plugins/discovery.d.ts +0 -1
- package/dist/core/command-plugins/discovery.js +1 -1
- package/dist/core/command-plugins/help-addenda.js +1 -1
- package/dist/core/command-plugins/presence.d.ts +2 -0
- package/dist/core/command-plugins/presence.js +1 -1
- package/dist/core/config.d.ts +16 -15
- package/dist/core/config.js +1 -1
- package/dist/core/conversation-store/client-worker.js +1 -1
- package/dist/core/conversation-store/client.js +2 -2
- package/dist/core/conversation-store/index.d.ts +9 -11
- package/dist/core/conversation-store/index.js +1 -1
- package/dist/core/conversation-store/patch.js +1 -1
- package/dist/core/conversation-store/row-store.d.ts +14 -0
- package/dist/core/conversation-store/row-store.js +13 -0
- package/dist/core/directory/join.d.ts +5 -3
- package/dist/core/directory/join.js +1 -1
- package/dist/core/env-name.d.ts +1 -0
- package/dist/core/env-name.js +1 -1
- package/dist/core/environment-recipe.d.ts +15 -0
- package/dist/core/environment-recipe.js +1 -0
- package/dist/core/environments.js +1 -1
- package/dist/core/events/emit.js +2 -2
- package/dist/core/events/run-event-chunks.d.ts +25 -0
- package/dist/core/events/run-event-chunks.js +5 -0
- package/dist/core/feed/messages.js +5 -5
- package/dist/core/grants/mirror.d.ts +15 -0
- package/dist/core/grants/mirror.js +15 -3
- package/dist/core/grants/on-sync.d.ts +9 -5
- package/dist/core/grants/on-sync.js +1 -1
- package/dist/core/grants/remove.d.ts +1 -6
- package/dist/core/grants/remove.js +1 -1
- package/dist/core/grants/sync.js +1 -1
- package/dist/core/grants/watch.d.ts +15 -9
- package/dist/core/grants/watch.js +1 -1
- package/dist/core/graph/custom.js +8 -8
- package/dist/core/graph/jobs.d.ts +83 -5
- package/dist/core/graph/jobs.js +11 -2
- package/dist/core/graph/kinds/job.js +2 -2
- package/dist/core/graph/names.js +7 -7
- package/dist/core/graph/objects.d.ts +5 -1
- package/dist/core/graph/objects.js +11 -11
- package/dist/core/graph/reader.d.ts +3 -0
- package/dist/core/graph/reader.js +3 -3
- package/dist/core/graph/repo-sync/identity.d.ts +3 -1
- package/dist/core/graph/repo-sync/identity.js +1 -1
- package/dist/core/graph/repo-sync/repos.d.ts +1 -1
- package/dist/core/graph/repo-sync/repos.js +2 -2
- package/dist/core/graph/repo-sync/sync.js +2 -2
- package/dist/core/installed-plugins.js +1 -1
- package/dist/core/keybindings/persistence.d.ts +1 -1
- package/dist/core/keybindings/persistence.js +1 -1
- package/dist/core/layout-migrate/loose-keys.d.ts +1 -1
- package/dist/core/layout-migrate/loose-keys.js +1 -1
- package/dist/core/ledger/account.d.ts +12 -0
- package/dist/core/ledger/account.js +2 -0
- package/dist/core/ledger/charges.d.ts +2 -2
- package/dist/core/ledger/charges.js +1 -1
- package/dist/core/ledger/check.d.ts +5 -1
- package/dist/core/ledger/check.js +1 -7
- package/dist/core/ledger/chunks.d.ts +8 -0
- package/dist/core/ledger/chunks.js +2 -0
- package/dist/core/ledger/index.d.ts +2 -1
- package/dist/core/ledger/index.js +1 -1
- package/dist/core/ledger/infra-allowance.d.ts +9 -0
- package/dist/core/ledger/infra-allowance.js +1 -0
- package/dist/core/ledger/limits.js +3 -3
- package/dist/core/ledger/payer.d.ts +1 -1
- package/dist/core/ledger/payer.js +1 -1
- package/dist/core/ledger/read.d.ts +14 -4
- package/dist/core/ledger/read.js +2 -3
- package/dist/core/ledger/totals.d.ts +5 -16
- package/dist/core/ledger/totals.js +4 -4
- package/dist/core/ledger/types.d.ts +12 -3
- package/dist/core/llm/run.js +2 -2
- package/dist/core/managed-providers.d.ts +72 -0
- package/dist/core/managed-providers.js +1 -0
- package/dist/core/model-auth/api-credential-store.d.ts +10 -0
- package/dist/core/model-auth/api-credential-store.js +1 -0
- package/dist/core/model-auth/daemon-login.d.ts +1 -1
- package/dist/core/model-auth/daemon-login.js +1 -1
- package/dist/core/model-auth/flows.d.ts +5 -4
- package/dist/core/model-auth/flows.js +1 -1
- package/dist/core/model-auth/handoff-jti.d.ts +3 -4
- package/dist/core/model-auth/handoff-jti.js +1 -1
- package/dist/core/model-auth/readiness.js +1 -1
- package/dist/core/model-config.d.ts +1 -1
- package/dist/core/model-config.js +1 -1
- package/dist/core/model-routes-pool.d.ts +14 -0
- package/dist/core/model-routes-pool.js +1 -0
- package/dist/core/model-routes.d.ts +11 -16
- package/dist/core/model-routes.js +1 -1
- package/dist/core/peer/ingest.d.ts +2 -0
- package/dist/core/peer/ingest.js +1 -1
- package/dist/core/peer/stubs.d.ts +8 -0
- package/dist/core/peer/stubs.js +1 -1
- package/dist/core/permissions/evaluator.d.ts +7 -2
- package/dist/core/permissions/evaluator.js +2 -2
- package/dist/core/plugin-env.js +1 -1
- package/dist/core/pool-credential-store.d.ts +2 -5
- package/dist/core/pool-credential-store.js +1 -1
- package/dist/core/profiles/app-env-store.d.ts +5 -5
- package/dist/core/profiles/app-env-store.js +1 -2
- package/dist/core/profiles/default-binding.d.ts +5 -5
- package/dist/core/profiles/default-binding.js +1 -1
- package/dist/core/profiles/env-store.d.ts +10 -21
- package/dist/core/profiles/env-store.js +1 -2
- package/dist/core/profiles/manifest.d.ts +14 -18
- package/dist/core/profiles/manifest.js +1 -1
- package/dist/core/profiles/relocate.js +1 -1
- package/dist/core/profiles/select.js +21 -21
- package/dist/core/provider-credential.d.ts +1 -1
- package/dist/core/provider-credential.js +1 -1
- package/dist/core/provider-management.d.ts +3 -4
- package/dist/core/provider-management.js +1 -1
- package/dist/core/providers/bundles.js +2 -2
- package/dist/core/providers/call.d.ts +3 -34
- package/dist/core/providers/description.d.ts +34 -0
- package/dist/core/providers/description.js +0 -0
- package/dist/core/providers/token-cache.d.ts +14 -14
- package/dist/core/providers/token-cache.js +1 -1
- package/dist/core/review/companion.js +1 -1
- package/dist/core/runs/activity.d.ts +1 -1
- package/dist/core/runs/activity.js +1 -1
- package/dist/core/runs/events.d.ts +7 -5
- package/dist/core/runs/events.js +2 -6
- package/dist/core/runs/operations.d.ts +1 -1
- package/dist/core/runs/operations.js +6 -6
- package/dist/core/runtime/bearings.js +1 -1
- package/dist/core/runtime/broker/attachments-fetch.d.ts +5 -0
- package/dist/core/runtime/broker/attachments-fetch.js +1 -0
- package/dist/core/runtime/broker/bash-job-launch.d.ts +4 -2
- package/dist/core/runtime/broker/bash-job-launch.js +1 -1
- package/dist/core/runtime/broker/boot-state.d.ts +9 -0
- package/dist/core/runtime/broker/boot-state.js +1 -0
- package/dist/core/runtime/broker/cli-relay.d.ts +2 -1
- package/dist/core/runtime/broker/cli-relay.js +1 -1
- package/dist/core/runtime/broker/client-registry.d.ts +3 -3
- package/dist/core/runtime/broker/daemon-ops.d.ts +10 -1
- package/dist/core/runtime/broker/daemon-ops.js +1 -1
- package/dist/core/runtime/broker/fault-retry.d.ts +2 -0
- package/dist/core/runtime/broker/fault-retry.js +1 -1
- package/dist/core/runtime/broker/frame-engine-control.js +1 -1
- package/dist/core/runtime/broker/held-deferred-inbox.d.ts +3 -0
- package/dist/core/runtime/broker/held-deferred-inbox.js +1 -1
- package/dist/core/runtime/broker/job-reporter.d.ts +18 -0
- package/dist/core/runtime/broker/job-reporter.js +2 -0
- package/dist/core/runtime/broker/model-adapter.d.ts +3 -0
- package/dist/core/runtime/broker/model-adapter.js +3 -2
- package/dist/core/runtime/broker/signal-stream.js +1 -1
- package/dist/core/runtime/broker/spilled-body.d.ts +5 -0
- package/dist/core/runtime/broker/spilled-body.js +1 -0
- package/dist/core/runtime/broker/summaries-post.d.ts +5 -0
- package/dist/core/runtime/broker/summaries-post.js +1 -0
- package/dist/core/runtime/broker/tool-groups.d.ts +3 -0
- package/dist/core/runtime/broker/tool-groups.js +1 -1
- package/dist/core/runtime/broker/turn-replies.d.ts +1 -0
- package/dist/core/runtime/broker/turn-replies.js +1 -1
- package/dist/core/runtime/broker-persona-guidance.js +2 -2
- package/dist/core/runtime/broker.js +1 -1
- package/dist/core/runtime/deliver-live.js +1 -1
- package/dist/core/runtime/first-boot-rows.d.ts +8 -0
- package/dist/core/runtime/first-boot-rows.js +2 -0
- package/dist/core/runtime/fleet.d.ts +13 -12
- package/dist/core/runtime/front-door-login.js +1 -1
- package/dist/core/runtime/front-door.js +6 -6
- package/dist/core/runtime/headless-pi.js +1 -1
- package/dist/core/runtime/host.d.ts +14 -3
- package/dist/core/runtime/host.js +3 -3
- package/dist/core/runtime/invocation.d.ts +6 -0
- package/dist/core/runtime/kickoff.d.ts +2 -14
- package/dist/core/runtime/kickoff.js +17 -19
- package/dist/core/runtime/launch-config-worker.js +1 -1
- package/dist/core/runtime/launch.js +2 -2
- package/dist/core/runtime/model-registry.js +1 -1
- package/dist/core/runtime/node-read.d.ts +4 -6
- package/dist/core/runtime/node-read.js +3 -3
- package/dist/core/runtime/nodes.js +1 -1
- package/dist/core/runtime/outcome-document.d.ts +0 -1
- package/dist/core/runtime/outcome-document.js +1 -1
- package/dist/core/runtime/output-result.d.ts +15 -0
- package/dist/core/runtime/output-result.js +5 -0
- package/dist/core/runtime/placement.d.ts +17 -1
- package/dist/core/runtime/placement.js +1 -1
- package/dist/core/runtime/provider-credential-gate.d.ts +6 -2
- package/dist/core/runtime/provider-credential-gate.js +2 -2
- package/dist/core/runtime/recovery-hold.d.ts +21 -2
- package/dist/core/runtime/recovery-hold.js +2 -1
- package/dist/core/runtime/recycle.js +1 -1
- package/dist/core/runtime/reset.js +1 -1
- package/dist/core/runtime/revive.d.ts +2 -2
- package/dist/core/runtime/revive.js +2 -2
- package/dist/core/runtime/runner/blaxel/client.d.ts +81 -0
- package/dist/core/runtime/runner/blaxel/client.js +1 -0
- package/dist/core/runtime/runner/blaxel/image-build.d.ts +74 -0
- package/dist/core/runtime/runner/blaxel/image-build.js +5 -0
- package/dist/core/runtime/runner/blaxel/runner.d.ts +41 -0
- package/dist/core/runtime/runner/blaxel/runner.js +3 -0
- package/dist/core/runtime/runner/index.d.ts +8 -0
- package/dist/core/runtime/runner/index.js +1 -0
- package/dist/core/runtime/runner/process.d.ts +11 -0
- package/dist/core/runtime/runner/process.js +1 -0
- package/dist/core/runtime/runner/types.d.ts +95 -0
- package/dist/core/runtime/runner/types.js +0 -0
- package/dist/core/runtime/situational-context.d.ts +3 -6
- package/dist/core/runtime/situational-context.js +2 -2
- package/dist/core/runtime/situational-live.js +1 -1
- package/dist/core/runtime/spawn-env-rows.d.ts +5 -0
- package/dist/core/runtime/spawn-env-rows.js +1 -0
- package/dist/core/runtime/spawn-env.d.ts +4 -18
- package/dist/core/runtime/spawn-env.js +1 -1
- package/dist/core/runtime/spawn.js +2 -2
- package/dist/core/runtime/stop-guard.d.ts +1 -1
- package/dist/core/runtime/stop-guard.js +2 -8
- package/dist/core/runtime/structured-output.d.ts +0 -67
- package/dist/core/runtime/structured-output.js +3 -8
- package/dist/core/runtime/tmux-driver.d.ts +8 -0
- package/dist/core/runtime/tmux-driver.js +6 -6
- package/dist/core/runtime/view-socket.d.ts +20 -0
- package/dist/core/runtime/view-socket.js +3 -1
- package/dist/core/runtime/warm-pool.d.ts +13 -1
- package/dist/core/runtime/warm-pool.js +1 -1
- package/dist/core/scoped-state/legacy-profiles.d.ts +11 -0
- package/dist/core/scoped-state/legacy-profiles.js +1 -0
- package/dist/core/scoped-state/materialized-plugins.d.ts +18 -0
- package/dist/core/scoped-state/materialized-plugins.js +1 -0
- package/dist/core/scoped-state/migrate.d.ts +8 -1
- package/dist/core/scoped-state/migrate.js +3 -3
- package/dist/core/scoped-state/person-rows.d.ts +10 -0
- package/dist/core/scoped-state/person-rows.js +6 -0
- package/dist/core/scoped-state/person-store.d.ts +72 -0
- package/dist/core/scoped-state/person-store.js +1 -0
- package/dist/core/secrets/blaxel-launch.d.ts +24 -0
- package/dist/core/secrets/blaxel-launch.js +4 -0
- package/dist/core/secrets/blaxel-register.d.ts +2 -0
- package/dist/core/secrets/blaxel-register.js +1 -0
- package/dist/core/secrets/env-rows.d.ts +17 -0
- package/dist/core/secrets/env-rows.js +4 -0
- package/dist/core/secrets/environment-owner.d.ts +8 -0
- package/dist/core/secrets/environment-owner.js +1 -0
- package/dist/core/secrets/environment-secrets.d.ts +14 -0
- package/dist/core/secrets/environment-secrets.js +1 -0
- package/dist/core/secrets/index.d.ts +2 -0
- package/dist/core/secrets/index.js +1 -0
- package/dist/core/secrets/key.d.ts +3 -0
- package/dist/core/secrets/key.js +2 -0
- package/dist/core/secrets/seal.d.ts +18 -0
- package/dist/core/secrets/seal.js +1 -0
- package/dist/core/spaces/mounts.d.ts +1 -1
- package/dist/core/spaces/mounts.js +1 -1
- package/dist/core/spaces/process.d.ts +1 -1
- package/dist/core/spaces/stop.d.ts +7 -5
- package/dist/core/spaces/stop.js +2 -2
- package/dist/core/spaces/users.d.ts +2 -1
- package/dist/core/spaces/users.js +1 -1
- package/dist/core/storage/attachments.d.ts +11 -8
- package/dist/core/storage/attachments.js +1 -1
- package/dist/core/storage/tables.d.ts +4 -0
- package/dist/core/storage/tables.js +3 -3
- package/dist/core/subscription-state.d.ts +34 -72
- package/dist/core/subscription-state.js +1 -4
- package/dist/core/substrate/delivery/plan.js +1 -1
- package/dist/core/user-settings.js +1 -1
- package/dist/daemon/api/app-listener.js +10 -10
- package/dist/daemon/api/auth/person-bearer.d.ts +14 -0
- package/dist/daemon/api/auth/person-bearer.js +1 -0
- package/dist/daemon/api/bridge.js +4 -4
- package/dist/daemon/api/document-listener.js +3 -3
- package/dist/daemon/api/environment-of.d.ts +18 -0
- package/dist/daemon/api/environment-of.js +5 -0
- package/dist/daemon/api/handlers/analytics.js +1 -1
- package/dist/daemon/api/handlers/app-profiles.d.ts +2 -2
- package/dist/daemon/api/handlers/app-profiles.js +1 -1
- package/dist/daemon/api/handlers/bash-jobs.js +1 -1
- package/dist/daemon/api/handlers/bash.js +1 -1
- package/dist/daemon/api/handlers/broker-ops.d.ts +3 -0
- package/dist/daemon/api/handlers/broker-ops.js +1 -1
- package/dist/daemon/api/handlers/broker-recovery.js +1 -1
- package/dist/daemon/api/handlers/broker-signals.d.ts +0 -3
- package/dist/daemon/api/handlers/broker-signals.js +2 -2
- package/dist/daemon/api/handlers/canvas.js +4 -4
- package/dist/daemon/api/handlers/charges.d.ts +1 -1
- package/dist/daemon/api/handlers/charges.js +1 -1
- package/dist/daemon/api/handlers/conversations.d.ts +2 -0
- package/dist/daemon/api/handlers/conversations.js +3 -0
- package/dist/daemon/api/handlers/crons.js +1 -1
- package/dist/daemon/api/handlers/daemon.js +1 -1
- package/dist/daemon/api/handlers/delivery.d.ts +1 -1
- package/dist/daemon/api/handlers/delivery.js +1 -1
- package/dist/daemon/api/handlers/docs.js +1 -1
- package/dist/daemon/api/handlers/exec.js +1 -1
- package/dist/daemon/api/handlers/execution-start.d.ts +2 -0
- package/dist/daemon/api/handlers/execution-start.js +2 -0
- package/dist/daemon/api/handlers/files.js +1 -1
- package/dist/daemon/api/handlers/git-credential.d.ts +11 -0
- package/dist/daemon/api/handlers/git-credential.js +1 -0
- package/dist/daemon/api/handlers/hook-exec.d.ts +1 -1
- package/dist/daemon/api/handlers/hook-exec.js +1 -1
- package/dist/daemon/api/handlers/human-requests.js +1 -1
- package/dist/daemon/api/handlers/inbox.js +1 -1
- package/dist/daemon/api/handlers/messages.js +1 -1
- package/dist/daemon/api/handlers/model-config.js +1 -1
- package/dist/daemon/api/handlers/modelauth.d.ts +1 -1
- package/dist/daemon/api/handlers/modelauth.js +1 -1
- package/dist/daemon/api/handlers/node-events.d.ts +6 -0
- package/dist/daemon/api/handlers/node-events.js +3 -3
- package/dist/daemon/api/handlers/node-outcomes.js +1 -1
- package/dist/daemon/api/handlers/node-records.js +3 -2
- package/dist/daemon/api/handlers/nodes.js +1 -1
- package/dist/daemon/api/handlers/objects.js +3 -3
- package/dist/daemon/api/handlers/profiles.js +1 -1
- package/dist/daemon/api/handlers/providers.js +1 -1
- package/dist/daemon/api/handlers/reports.js +9 -13
- package/dist/daemon/api/handlers/reviews.js +1 -1
- package/dist/daemon/api/handlers/runs.js +1 -1
- package/dist/daemon/api/handlers/settings.d.ts +2 -0
- package/dist/daemon/api/handlers/settings.js +1 -0
- package/dist/daemon/api/handlers/structured-requests.js +1 -1
- package/dist/daemon/api/handlers/vendor-status.d.ts +1 -1
- package/dist/daemon/api/handlers/vendor-status.js +1 -1
- package/dist/daemon/api/handlers/worktree.js +1 -1
- package/dist/daemon/api/map.d.ts +2 -2
- package/dist/daemon/api/map.js +2 -2
- package/dist/daemon/api/operations.js +1 -1
- package/dist/daemon/api/reader.d.ts +8 -1
- package/dist/daemon/api/reader.js +1 -1
- package/dist/daemon/api/router.d.ts +4 -2
- package/dist/daemon/api/router.js +1 -1
- package/dist/daemon/api/server.d.ts +15 -3
- package/dist/daemon/api/server.js +1 -1
- package/dist/daemon/api/vendor-signin.d.ts +2 -1
- package/dist/daemon/api/vendor-signin.js +19 -19
- package/dist/daemon/api/viewer-presence.d.ts +20 -6
- package/dist/daemon/api/viewer-presence.js +2 -1
- package/dist/daemon/boot-settings.d.ts +3 -0
- package/dist/daemon/boot-settings.js +1 -0
- package/dist/daemon/broker-signals/bus.d.ts +48 -11
- package/dist/daemon/broker-signals/bus.js +1 -1
- package/dist/daemon/cron/armed-context.js +1 -1
- package/dist/daemon/cron/lease-recovery.js +1 -1
- package/dist/daemon/cron/live-runs.d.ts +6 -0
- package/dist/daemon/cron/live-runs.js +1 -1
- package/dist/daemon/cron/run-socket.js +1 -1
- package/dist/daemon/cron-run.js +2 -2
- package/dist/daemon/crtrd-cli.js +1 -1
- package/dist/daemon/crtrd.d.ts +10 -0
- package/dist/daemon/crtrd.js +18 -17
- package/dist/daemon/delivery/run-delivery.d.ts +1 -1
- package/dist/daemon/delivery/run-delivery.js +1 -1
- package/dist/daemon/due-sources.d.ts +1 -1
- package/dist/daemon/due-sources.js +1 -1
- package/dist/daemon/due.js +7 -6
- package/dist/daemon/fleet.d.ts +6 -6
- package/dist/daemon/fleet.js +9 -9
- package/dist/daemon/park-activity.d.ts +2 -1
- package/dist/daemon/park-activity.js +1 -1
- package/dist/daemon/park-pending.d.ts +20 -13
- package/dist/daemon/park-pending.js +3 -1
- package/dist/daemon/profile-delete.js +1 -1
- package/dist/daemon/reconcilers/bash-deadline.d.ts +15 -10
- package/dist/daemon/reconcilers/bash-deadline.js +1 -3
- package/dist/daemon/reconcilers/broker-supervision.d.ts +13 -3
- package/dist/daemon/reconcilers/broker-supervision.js +4 -4
- package/dist/daemon/reconcilers/cron-lane.d.ts +0 -1
- package/dist/daemon/reconcilers/cron-lane.js +1 -1
- package/dist/daemon/reconcilers/fault-retry-backstop.d.ts +2 -9
- package/dist/daemon/reconcilers/fault-retry-backstop.js +1 -1
- package/dist/daemon/reconcilers/grant-effects.d.ts +8 -0
- package/dist/daemon/reconcilers/grant-effects.js +1 -0
- package/dist/daemon/reconcilers/grove-instance-sweep.d.ts +1 -3
- package/dist/daemon/reconcilers/grove-instance-sweep.js +1 -1
- package/dist/daemon/reconcilers/ledger-r2.d.ts +27 -0
- package/dist/daemon/reconcilers/ledger-r2.js +7 -0
- package/dist/daemon/reconcilers/ledger-sandbox.d.ts +55 -0
- package/dist/daemon/reconcilers/ledger-sandbox.js +9 -0
- package/dist/daemon/reconcilers/ledger-storage.d.ts +22 -0
- package/dist/daemon/reconcilers/ledger-storage.js +5 -0
- package/dist/daemon/reconcilers/live-obligation.d.ts +3 -2
- package/dist/daemon/reconcilers/live-obligation.js +1 -1
- package/dist/daemon/reconcilers/managed-worktree-sweep.d.ts +0 -5
- package/dist/daemon/reconcilers/managed-worktree-sweep.js +1 -1
- package/dist/daemon/reconcilers/node-deadline.d.ts +2 -1
- package/dist/daemon/reconcilers/node-deadline.js +1 -1
- package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.d.ts +1 -2
- package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.js +1 -1
- package/dist/daemon/reconcilers/node-lifecycle/remote-wake.d.ts +31 -0
- package/dist/daemon/reconcilers/node-lifecycle/remote-wake.js +1 -0
- package/dist/daemon/reconcilers/node-lifecycle/requested-stops.d.ts +5 -0
- package/dist/daemon/reconcilers/node-lifecycle/requested-stops.js +2 -0
- package/dist/daemon/reconcilers/node-lifecycle/tick.js +1 -1
- package/dist/daemon/reconcilers/pending-review-submit.js +1 -1
- package/dist/daemon/reconcilers/recipe-image.d.ts +49 -0
- package/dist/daemon/reconcilers/recipe-image.js +7 -0
- package/dist/daemon/reconcilers/row-claim.d.ts +19 -0
- package/dist/daemon/reconcilers/row-claim.js +2 -0
- package/dist/daemon/reconcilers/storage-due-work.d.ts +18 -3
- package/dist/daemon/reconcilers/storage-due-work.js +2 -1
- package/dist/daemon/reconcilers/storage-maintenance.d.ts +5 -13
- package/dist/daemon/reconcilers/storage-maintenance.js +1 -1
- package/dist/daemon/reconcilers/structured-request-lane.js +1 -1
- package/dist/daemon/reconcilers/throttled-lane.d.ts +11 -0
- package/dist/daemon/reconcilers/throttled-lane.js +1 -0
- package/dist/daemon/review/finish.js +1 -1
- package/dist/daemon/run-notices.d.ts +3 -0
- package/dist/daemon/run-notices.js +1 -1
- package/dist/daemon/runs/append-section.d.ts +4 -1
- package/dist/daemon/runs/append-section.js +2 -2
- package/dist/daemon/runs/observer.d.ts +3 -2
- package/dist/daemon/runs/observer.js +3 -2
- package/dist/daemon/runs/view-transport.d.ts +19 -0
- package/dist/daemon/runs/view-transport.js +1 -0
- package/dist/daemon/structured-requests/boot.d.ts +2 -1
- package/dist/daemon/structured-requests/boot.js +1 -1
- package/dist/daemon/structured-requests/effects.d.ts +4 -3
- package/dist/daemon/structured-requests/effects.js +1 -1
- package/dist/daemon/structured-requests/notifier.d.ts +2 -0
- package/dist/daemon/structured-requests/notifier.js +1 -1
- package/dist/daemon/structured-requests/sidecar.d.ts +4 -3
- package/dist/daemon/structured-requests/sidecar.js +1 -1
- package/dist/launcher/validate.js +1 -1
- package/dist/migrations/004-canvas-documents/index.js +2 -2
- package/dist/pi-extensions/broker-local.d.ts +3 -3
- package/dist/pi-extensions/broker-local.js +1 -2
- package/dist/pi-extensions/canvas-bash-valve.js +6 -6
- package/dist/pi-extensions/canvas-context-intro.js +2 -2
- package/dist/pi-extensions/canvas-elapsed.js +2 -2
- package/dist/pi-extensions/canvas-goal-capture.js +1 -1
- package/dist/pi-extensions/canvas-inbox-watcher.js +2 -2
- package/dist/pi-extensions/canvas-review-boundary.d.ts +11 -1
- package/dist/pi-extensions/canvas-review-boundary.js +3 -3
- package/dist/pi-extensions/canvas-stophook.js +1 -1
- package/dist/pi-extensions/canvas-structured-output.d.ts +5 -3
- package/dist/pi-extensions/canvas-structured-output.js +6 -11
- package/dist/pi-extensions/canvas-tool-guide.d.ts +9 -2
- package/dist/pi-extensions/canvas-tool-guide.js +6 -6
- package/dist/shared/inbox-entry-body.js +7 -7
- package/dist/types.d.ts +12 -0
- package/docs/sdk/release-notes.md +4 -0
- package/package.json +7 -4
- package/packages/crouter-identity/package.json +1 -1
- package/runtime.lock.json +13 -13
- package/scripts/git-credential-crtr +33 -0
- package/scripts/sandbox-bootstrap.sh +54 -0
- package/scripts/sandbox-start.mjs +320 -0
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.d.ts +0 -78
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.js +0 -1179
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.ts +0 -1406
- package/dist/core/conversation-store/file-store.d.ts +0 -37
- package/dist/core/conversation-store/file-store.js +0 -9
- package/dist/core/conversation-store/listener.d.ts +0 -4
- package/dist/core/conversation-store/listener.js +0 -8
- package/dist/core/scoped-state/profiles.d.ts +0 -27
- package/dist/core/scoped-state/profiles.js +0 -1
- package/dist/core/scoped-state/providers.d.ts +0 -24
- package/dist/core/scoped-state/providers.js +0 -1
- package/dist/core/scoped-state/settings.d.ts +0 -28
- package/dist/core/scoped-state/settings.js +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
var p=Object.defineProperty;var
|
|
1
|
+
var p=Object.defineProperty;var s=(t,o)=>p(t,"name",{value:o,configurable:!0});import{spawn as l}from"node:child_process";import{writeFileSync as a}from"node:fs";import{BASH_JOB_SUPERVISOR_SCRIPT as h}from"../../bash-job-supervisor.js";import{readBashNiceness as j}from"../../bash-jobs.js";import{capturePidIdentities as S}from"../../canvas/pid.js";import{freshChildNodeExecPath as g}from"../branded-host.js";import{resolveAdmittedHostCommand as y}from"../spawn-env.js";import{brokerApiUrl as I,startBrokerBashJob as P}from"./daemon-ops.js";function w(){return process.platform==="linux"&&I()===void 0}s(w,"bashJobsUseLauncher");async function C(t,o,f,n,d){const b=await g();if(w()){const{pid:e}=await P(t,{job_id:o.jobId,cwd:n,env:d});return{pgid:e,identity:`launcher:${e}`}}const m=y("bash",d,n),i=l(m,["-c",h,"--",o.cmdSh,o.jobLog,o.jobExit,o.jobRun,o.jobDone,m,String(j(f)),b,o.jobActivity],{cwd:n,detached:!0,stdio:"ignore",env:d}),r=await new Promise((e,u)=>{i.once("error",u),i.pid!==void 0&&e(i.pid)});i.unref();const c=S([r])?.get(r);if(c===void 0){try{process.kill(-r,"SIGKILL")}catch{}throw new Error(`bash job ${o.jobId} started without a process identity`)}return a(o.jobPgid,String(r)),a(o.jobPgidIdentity,c),{pgid:r,identity:c}}s(C,"launchBashJobSupervisor");export{w as bashJobsUseLauncher,C as launchBashJobSupervisor};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { BrokerExtensionStateDTO } from '../../../api/dto/broker-ops.js';
|
|
2
|
+
type ExtensionStateReader = (nodeId: string) => Promise<BrokerExtensionStateDTO>;
|
|
3
|
+
/** The extension state before session bind: one daemon read, shared. */
|
|
4
|
+
export declare function bootExtensionState(nodeId: string, read?: ExtensionStateReader): Promise<BrokerExtensionStateDTO>;
|
|
5
|
+
/** The extension state after session bind: one fresh daemon read, shared. */
|
|
6
|
+
export declare function boundExtensionState(nodeId: string, read?: ExtensionStateReader): Promise<BrokerExtensionStateDTO>;
|
|
7
|
+
/** End the share; the next caller reads the daemon. */
|
|
8
|
+
export declare function retireBootExtensionState(): void;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var d=Object.defineProperty;var n=(t,e)=>d(t,"name",{value:e,configurable:!0});import{brokerExtensionState as a}from"./daemon-ops.js";const h=Symbol.for("@crouton-kit/crtr:boot-extension-state");function u(){const t=globalThis;return t[h]??={}}n(u,"slot");function c(t,e,f){const o=u(),r=o.shared;if(r!==void 0&&r.nodeId===t&&(r.afterBind||!e))return r.state;const s=f(t),i={nodeId:t,afterBind:e,state:s};return o.shared=i,s.catch(()=>{o.shared===i&&(o.shared=void 0)}),s}n(c,"share");function b(t,e=a){return c(t,!1,e)}n(b,"bootExtensionState");function E(t,e=a){return c(t,!0,e)}n(E,"boundExtensionState");function S(){u().shared=void 0}n(S,"retireBootExtensionState");export{b as bootExtensionState,E as boundExtensionState,S as retireBootExtensionState};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
/** The broker alone holds the bearer. CLI processes see only this socket path.
|
|
1
|
+
/** The broker alone holds the bearer. CLI processes see only this socket path. Each request goes on to
|
|
2
|
+
* `CRTR_API_URL` when the launcher set one (a broker in a sandbox), else to the local API socket. */
|
|
2
3
|
export declare function serveCliRelay(nodeId: string, token: string): Promise<{
|
|
3
4
|
path: string;
|
|
4
5
|
close(): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var S=Object.defineProperty;var f=(i,d)=>S(i,"name",{value:d,configurable:!0});import{createServer as _,request as h}from"node:http";import{request as k}from"node:https";import{chmodSync as A,existsSync as R,rmSync as B,unlinkSync as y}from"node:fs";import{join as l}from"node:path";import{apiSocketPath as C,BROKER_RELEASED_MARKER as b,BROKER_RELAY_GENERATION as v,nodeRunDir as E}from"../../canvas/paths.js";import{writeFileBeneath as O}from"../../spaces/open-beneath.js";import{currentCausedBy as q}from"./turn-cause.js";import{brokerApiUrl as x}from"./daemon-ops.js";async function j(i,d){const o=l(E(i),"cli.sock"),m=x(),w=f((r,e,t,c)=>{if(m===void 0)return h({socketPath:C(),path:r,method:e,headers:t},c);const s=new URL(r??"/",m);return delete t.host,(s.protocol==="https:"?k:h)(s,{method:e,headers:t},c)},"forward"),n=_((r,e)=>{const t={...r.headers,authorization:`Bearer ${d}`},c=q();c!==void 0&&t["crtr-caused-by"]===void 0&&(t["crtr-caused-by"]=c),delete t.connection;const s=w(r.url,r.method,t,a=>{e.writeHead(a.statusCode??502,a.headers),a.pipe(e)});s.on("error",a=>{e.headersSent||e.writeHead(503,{"content-type":"application/json"}),e.end(JSON.stringify({error:{code:"daemon_unavailable",message:a.message}}))}),r.pipe(s),e.on("close",()=>s.destroy())});R(o)&&y(o),await new Promise((r,e)=>{n.once("error",e),n.listen(o,()=>{n.off("error",e),r()})}),A(o,384);const p=E(i),u=process.env.CRTR_EXECUTION_ID;if(!u)throw new Error("broker relay has no execution id");return O(p,l(p,v),u,{atomic:!0}),B(l(p,b),{force:!0}),{path:o,close(){n.closeAllConnections(),n.close(),R(o)&&y(o)}}}f(j,"serveCliRelay");export{j as serveCliRelay};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Duplex } from 'node:stream';
|
|
2
2
|
import { FrameDecoder, type BrokerSnapshot, type BrokerToClient, type ClientRole } from '../broker-protocol.js';
|
|
3
3
|
export interface BrokerClient {
|
|
4
4
|
id: string;
|
|
5
5
|
role: ClientRole;
|
|
6
|
-
socket:
|
|
6
|
+
socket: Duplex;
|
|
7
7
|
decoder: FrameDecoder;
|
|
8
8
|
helloed: boolean;
|
|
9
9
|
/** Fixed by the first hello; absent `attends` remains backward-compatible true. */
|
|
@@ -21,7 +21,7 @@ export declare class BrokerClientRegistry {
|
|
|
21
21
|
private readonly displayWidgets;
|
|
22
22
|
private displayTitle;
|
|
23
23
|
constructor(nodeId: string);
|
|
24
|
-
create(socket:
|
|
24
|
+
create(socket: Duplex): BrokerClient;
|
|
25
25
|
writableClients(): BrokerClient[];
|
|
26
26
|
persistAttachState(): void;
|
|
27
27
|
dropClient(client: BrokerClient, reason: string): void;
|
|
@@ -1,11 +1,16 @@
|
|
|
1
|
+
import { CrtrClient } from '../../../api/client.js';
|
|
1
2
|
import { type BrokerSignalCachedNode } from '../../../daemon/broker-signals/bus.js';
|
|
2
3
|
import type { BrokerExtensionStateDTO, BrokerGeneratedNameRequest, BrokerGeneratedNameResultDTO, BrokerModelCommitRequest, BrokerModelCommitResultDTO, BrokerParkActivityResultDTO, BrokerParkCompleteRequest, BrokerPersonaAckRequest, BrokerPersonaAckResultDTO, BrokerSessionBoundRequest, BrokerSessionBoundResultDTO, BrokerSettleDirective, BrokerSettleRequest, BrokerTelemetryRequest } from '../../../api/dto/broker-ops.js';
|
|
3
4
|
import type { AcknowledgeMailResultDTO, ClaimMailResultDTO, MailReceiptDTO } from '../../../api/dto/mail.js';
|
|
4
5
|
import type { BrokerFaultInputDTO, BrokerFaultRequest, BrokerFaultResultDTO, BrokerProviderRetryRequest, BrokerProviderRetryResultDTO, BrokerTurnRequest, BrokerTurnResultDTO, RecoveryStateDTO } from '../../../api/dto/recovery.js';
|
|
5
6
|
import type { RelaunchRootResultDTO } from '../../../api/dto/lifecycle.js';
|
|
6
7
|
import type { PushReportRequest } from '../../../api/dto/reports.js';
|
|
7
|
-
import type { BackgroundedJobDTO, BackgroundedJobRequest, DeliveryRequest, DeliveryResponse } from '../../../api/dto/delivery.js';
|
|
8
|
+
import type { BackgroundedJobDTO, BackgroundedJobRequest, JobReportRequest, DeliveryRequest, DeliveryResponse } from '../../../api/dto/delivery.js';
|
|
8
9
|
import type { NodeLogAppendResultDTO, NodeMessageBodyDTO, NodePushedFinalResultDTO, NodeTelemetryRecordRequest } from '../../../api/dto/node-records.js';
|
|
10
|
+
/** Where this broker reaches `/v1`: `CRTR_API_URL` when the launcher set one (an http(s) URL in a
|
|
11
|
+
* sandbox), else the local API socket. */
|
|
12
|
+
export declare function brokerApiUrl(): string | undefined;
|
|
13
|
+
export declare function daemonClient(): CrtrClient;
|
|
9
14
|
export declare function appendBrokerLog(nodeId: string, record: string): Promise<NodeLogAppendResultDTO>;
|
|
10
15
|
export declare function putBrokerTelemetry(nodeId: string, telemetry: Omit<NodeTelemetryRecordRequest, 'expected_execution_id'>): Promise<void>;
|
|
11
16
|
export declare function putBrokerRecap(nodeId: string, briefing: string): Promise<void>;
|
|
@@ -22,15 +27,19 @@ export declare function startBrokerBashJob(nodeId: string, request: {
|
|
|
22
27
|
}>;
|
|
23
28
|
/** Record a command the valve just backgrounded as this node's job object. */
|
|
24
29
|
export declare function recordBackgroundedJob(nodeId: string, jobId: string, request: BackgroundedJobRequest): Promise<BackgroundedJobDTO>;
|
|
30
|
+
/** Report on a job this broker runs: process identity, activity, output, exit. */
|
|
31
|
+
export declare function reportBrokerJob(nodeId: string, jobId: string, request: Omit<JobReportRequest, 'expected_execution_id'>): Promise<void>;
|
|
25
32
|
export declare function stopBrokerBashJob(nodeId: string, jobId: string): Promise<void>;
|
|
26
33
|
export declare function brokerExecutionId(): string;
|
|
27
34
|
export declare function bindBrokerSession(nodeId: string, request: Omit<BrokerSessionBoundRequest, 'executionId'>): Promise<BrokerSessionBoundResultDTO>;
|
|
28
35
|
type BrokerInput<T> = T extends unknown ? Omit<T, 'expected_execution_id'> : never;
|
|
29
36
|
export declare function settleBroker(nodeId: string, request: BrokerInput<BrokerSettleRequest>): Promise<BrokerSettleDirective>;
|
|
37
|
+
export declare function postBrokerIdle(nodeId: string): Promise<void>;
|
|
30
38
|
export declare function completeBrokerPark(nodeId: string, request: BrokerInput<BrokerParkCompleteRequest>): Promise<BrokerSettleDirective>;
|
|
31
39
|
export declare function recordBrokerParkActivity(nodeId: string): Promise<BrokerParkActivityResultDTO>;
|
|
32
40
|
export declare function recordBrokerTelemetry(nodeId: string, request: Omit<BrokerTelemetryRequest, 'expected_execution_id'>): Promise<void>;
|
|
33
41
|
export declare function claimBrokerMail(nodeId: string, channel: 'wake' | 'passive' | 'deferred_run', reportBodies: Map<string, Promise<string>>): Promise<ClaimMailResultDTO>;
|
|
42
|
+
/** Mail is settled only after the entries the turn wrote are durable: a failed flush rejects and nothing is acknowledged. */
|
|
34
43
|
export declare function acknowledgeBrokerMail(nodeId: string, deliveries: MailReceiptDTO[]): Promise<AcknowledgeMailResultDTO>;
|
|
35
44
|
export declare function recordBrokerTurn(nodeId: string, request: Omit<BrokerTurnRequest, 'expected_execution_id'>): Promise<BrokerTurnResultDTO>;
|
|
36
45
|
export declare function mutateBrokerProviderRetry(nodeId: string, request: Omit<BrokerProviderRetryRequest, 'expected_execution_id'>): Promise<BrokerProviderRetryResultDTO>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var h=Object.defineProperty;var t=(e,r)=>h(e,"name",{value:r,configurable:!0});import{CrtrClient as R}from"../../../api/client.js";import{currentNodeToken as y}from"./node-token.js";import{localClient as b}from"../../../api/node-transport.js";import{ApiError as l}from"../../../api/errors.js";import{envExecutionId as w}from"../../../shared/env.js";import{brokerSignalClient as N}from"./signal-stream.js";import{cachedBrokerNodeFields as k}from"../../../daemon/broker-signals/bus.js";import{fetchRunAttachments as P}from"./attachments-fetch.js";import{reportRefNodeId as v}from"../../../shared/inbox-entry-body.js";function g(){const e=process.env.CRTR_API_URL;if(!(e===void 0||e==="")){if(!/^https?:\/\//.test(e))throw new Error(`CRTR_API_URL must be an http(s) URL: ${e}`);return e}}t(g,"brokerApiUrl");function o(){const e=g();if(e===void 0)return b({autostart:!1});const r=y();if(r===void 0)throw new Error("broker has no node token for CRTR_API_URL");return new R({baseUrl:e,headers:{authorization:`Bearer ${r}`}})}t(o,"daemonClient");function $(e,r){return o().appendNodeLog(e,{record:r,expected_execution_id:n()})}t($,"appendBrokerLog");function D(e,r){return o().putNodeTelemetry(e,{...r,expected_execution_id:n()})}t(D,"putBrokerTelemetry");function j(e,r){return o().putNodeRecap(e,{briefing:r,expected_execution_id:n()})}t(j,"putBrokerRecap");function z(e,r){return o().readNodePassiveMessage(e,r)}t(z,"readBrokerPassiveMessage");function G(e){return o().nodePushedFinal(e,{action:"clear",expected_execution_id:n()})}t(G,"clearBrokerPushedFinal");function O(e){return o().nodePushedFinal(e,{action:"consume",expected_execution_id:n()})}t(O,"consumeBrokerPushedFinal");function q(e,r){return o().request("POST",`/v1/nodes/${encodeURIComponent(e)}/jobs/start`,{...r,expected_execution_id:n()})}t(q,"startBrokerBashJob");function X(e,r,i){return o().recordBackgroundedJob(e,r,i)}t(X,"recordBackgroundedJob");function H(e,r,i){return o().reportBashJob(e,r,{...i,expected_execution_id:n()})}t(H,"reportBrokerJob");function K(e,r){return o().request("DELETE",`/v1/nodes/${encodeURIComponent(e)}/jobs/${encodeURIComponent(r)}?foreground=1`,{expected_execution_id:n()})}t(K,"stopBrokerBashJob");function n(){const e=w();if(e===void 0||e==="")throw new Error("broker launch is missing CRTR_EXECUTION_ID");return e}t(n,"brokerExecutionId");function Q(e,r){return o().bindBrokerSession(e,{...r,executionId:n()})}t(Q,"bindBrokerSession");function V(e,r){return o().settleBroker(e,{...r,expected_execution_id:n()})}t(V,"settleBroker");function W(e){return o().postBrokerIdle(e,{expected_execution_id:n()})}t(W,"postBrokerIdle");function Y(e,r){return o().completeBrokerPark(e,{...r,expected_execution_id:n()})}t(Y,"completeBrokerPark");function Z(e){return o().recordBrokerParkActivity(e,{expected_execution_id:n()})}t(Z,"recordBrokerParkActivity");function ee(e,r){return o().recordBrokerTelemetry(e,{...r,expected_execution_id:n()})}t(ee,"recordBrokerTelemetry");const m=new Set;async function re(e,r,i){const s=o(),f=n(),a=await s.claimNodeMail(e,{execution_id:f,channel:r});if(a.action==="hold")return a;const x=a.deliveries.filter(u=>!m.has(u.entry.entry_id));if(x.length>0){await P(e);for(const u of x)m.add(u.entry.entry_id)}const p=await Promise.all(a.deliveries.map(async u=>{const c=u.entry.ref;if(c===void 0||v(c)===void 0)return u;try{let d=i.get(c);d===void 0&&(d=s.readNodeInboxReport(e,c,f).then(({content:B})=>B),i.set(c,d));const _=await d;return{...u,entry:{...u.entry,data:{...u.entry.data,report_body:_}}}}catch(d){if(i.delete(c),d instanceof l&&d.status===404)return u;throw d}}));if(p.length>0){const u=new Set(p.map(({entry:c})=>c.ref).filter(c=>c!==void 0));for(const c of i.keys())u.has(c)||i.delete(c)}return{...a,deliveries:p}}t(re,"claimBrokerMail");async function te(e,r){return await(await import("../../conversation-store/index.js")).flushConversation(),o().acknowledgeNodeMail(e,{execution_id:n(),deliveries:r})}t(te,"acknowledgeBrokerMail");function oe(e,r){return o().recordBrokerTurn(e,{...r,expected_execution_id:n()})}t(oe,"recordBrokerTurn");function ne(e,r){return o().mutateBrokerProviderRetry(e,{...r,expected_execution_id:n()})}t(ne,"mutateBrokerProviderRetry");function ie(e,r){return o().mutateBrokerFault(e,{...r,expected_execution_id:n()})}t(ie,"mutateBrokerFault");function ce(e){return o().getBrokerRecovery(e,n())}t(ce,"brokerRecovery");function ue(e,r){return o().recordNodeFault(e,r)}t(ue,"recordNodeFault");function de(e,r={}){return o().clearNodeFault(e,{...r.link===void 0?{}:{link:r.link},...r.preserveEpisode===void 0?{}:{preserve_episode:r.preserveEpisode}}).then(i=>i.cleared)}t(de,"clearNodeFault");function ae(e,r){return o().commitBrokerModel(e,{...r,expected_execution_id:n()})}t(ae,"commitBrokerModel");function C(e){return o().brokerExtensionState(e)}t(C,"brokerExtensionState");async function pe(e){const r=N();return r.state==="connected"&&r.latestNode!==void 0?k(r.latestNode):k((await C(e)).node)}t(pe,"cachedBrokerNode");function se(e,r){return o().nodeDelivery(e,{...r,expected_execution_id:n()})}t(se,"brokerDelivery");function fe(e,r){return o().commitBrokerGeneratedName(e,{...r,expected_execution_id:n()})}t(fe,"commitBrokerGeneratedName");function xe(e,r){return o().commitBrokerPersonaAck(e,{...r,expected_execution_id:n()})}t(xe,"commitBrokerPersonaAck");async function le(e,r){try{await o().pushReport(e,r)}catch(i){if(r.tier==="final"&&i instanceof l&&i.code==="already_finalized")return;throw i}}t(le,"publishBrokerReport");function ke(e){return o().relaunchRoot(e)}t(ke,"relaunchBrokerRoot");export{te as acknowledgeBrokerMail,$ as appendBrokerLog,Q as bindBrokerSession,g as brokerApiUrl,se as brokerDelivery,n as brokerExecutionId,C as brokerExtensionState,ce as brokerRecovery,pe as cachedBrokerNode,re as claimBrokerMail,G as clearBrokerPushedFinal,de as clearNodeFault,fe as commitBrokerGeneratedName,ae as commitBrokerModel,xe as commitBrokerPersonaAck,Y as completeBrokerPark,O as consumeBrokerPushedFinal,o as daemonClient,ie as mutateBrokerFault,ne as mutateBrokerProviderRetry,W as postBrokerIdle,le as publishBrokerReport,j as putBrokerRecap,D as putBrokerTelemetry,z as readBrokerPassiveMessage,X as recordBackgroundedJob,Z as recordBrokerParkActivity,ee as recordBrokerTelemetry,oe as recordBrokerTurn,ue as recordNodeFault,ke as relaunchBrokerRoot,H as reportBrokerJob,V as settleBroker,q as startBrokerBashJob,K as stopBrokerBashJob};
|
|
@@ -136,6 +136,8 @@ export declare class FaultRetry {
|
|
|
136
136
|
private maybeSwitchProviderForRetry;
|
|
137
137
|
private maybeFallbackOnUnusableModel;
|
|
138
138
|
private nextEligibleFallbackRoute;
|
|
139
|
+
/** A broker never reads credential rows: a managed provider's sign-in and cooldown come from the daemon's readiness answer. */
|
|
140
|
+
private routeAvailability;
|
|
139
141
|
private targetCannotFitContext;
|
|
140
142
|
private stageCapacityFailure;
|
|
141
143
|
private recordPendingProviderFault;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var ue=Object.defineProperty;var m=(i,e)=>ue(i,"name",{value:e,configurable:!0});import{envModelIntent as B,envNodeCwd as j,envProfileId as Y}from"../../../shared/env.js";import{isContextOverflow as q}from"@earendil-works/pi-ai";import{classify as T}from"../../fault-classifier.js";import{isDaemonTransportApiError as V}from"../../../api/errors.js";import{isModelNotFoundError as fe,isProviderUnconfiguredError as pe}from"../fault.js";import{brokerRecovery as he,mutateBrokerFault as X,mutateBrokerProviderRetry as k}from"./daemon-ops.js";import{extractCoolingDeadline as me}from"../managed-provider-cooling.js";import{extractProviderFailureDetails as ge}from"../../provider-failure.js";import{expandModelCandidates as J,modelRequestFromConfig as z,probeRouteAvailability as ye}from"../../model-routes.js";import{operationIdContext as H}from"../../events/operation-id.js";import{emitEvent as F}from"../../events/emit.js";import{CONNECTION_FAULT_RECOVERY_BODY as ve,PROVIDER_FAULT_RECOVERY_BODY as we,RUN_CONNECTION_FAULT_RETRY_BODY as Fe,formatCard as K,formatModelFallbackRecovery as be}from"../../../shared/generated-context.js";import{markFatalOnExhaust as Q,nextFaultRetry as C,policyFor as Z}from"../fault-recovery.js";import{parseModelSpec as ee}from"../model-selection.js";import{endedByAbort as te}from"../session-cycles.js";import{resolveProviderCandidates as ke}from"../../subscription-state.js";import{announceMessageOrigin as ne}from"../stamp/channel.js";import{LLM_REFUSAL_DIAGNOSTIC as _e,refusalRetryAt as Ie}from"./model-adapter.js";import{isSafetyRefusal as re}from"../../llm/refusal.js";const Ee=2147483647,ie=3e4;function Re(i,e,t){const n=Date.parse(i);return!Number.isFinite(n)||t+e-n>ie}m(Re,"runTurnRetryExpired");class _ extends Error{static{m(this,"StaleOutcome")}}const Se=1e3,Ae=3e4;function Me(i,e){return i!=="connection"?we:e?Fe:ve}m(Me,"retryCardBody");function R(i){return{link:i.link,op:i.op,kind:i.kind,retry:i.retry,message:i.message,since:i.since,operation_id:i.operation_id,...i.anchor_entry_id===void 0?{}:{anchorEntryId:i.anchor_entry_id},...i.provider_error===void 0?{}:{providerError:i.provider_error}}}m(R,"policyFault");function se(i){return i instanceof Error?i.message:String(i)}m(se,"errorText");function oe(i){return V(i)||T("pi\u2192provider",i).disposition==="auto"}m(oe,"isTransientRejection");function O(i){return{link:i.link,op:i.op,kind:i.kind,retry:i.retry,message:i.message,...i.operation_id===void 0?{}:{operation_id:i.operation_id},...i.since===void 0?{}:{since:i.since},...i.anchorEntryId===void 0?{}:{anchor_entry_id:i.anchorEntryId},...i.providerError===void 0?{}:{provider_error:i.providerError}}}m(O,"faultInput");function ae(i,e){const t=m(n=>`${n.providerId}/${n.modelId}`===e.modelSpec,"onLiveModel");return(i.find(n=>t(n)&&n.thinkingLevel===e.thinkingLevel)??i.find(t))?.rank}m(ae,"liveRouteRank");function de(i){const e=T("pi\u2192provider",i),t=i.diagnostics?.some(n=>n.type===_e)??!1;return{classified:e,disposition:t?"fatal":e.disposition}}m(de,"settledProviderFault");function Qe(i,e){if(i.stopReason!=="error"||te(i)||re(i)||q(i,e))return!1;const{classified:t,disposition:n}=de(i);return n==="auto"&&(t.kind==="connection"||t.kind==="rate-limit"||t.kind==="overloaded")}m(Qe,"willDaemonRetry");const xe=/does not support assistant message prefill|conversation must end with a user message/i;function Te(i,e){return e&&xe.test(i)}m(Te,"isPrefillRejectionDuringEpisode");class Ze{static{m(this,"FaultRetry")}deps;timer=null;failedRetryRoutes=new Set;notFoundModels=new Set;providerFallbackInFlight=null;notFoundFallbackInFlight=null;stagedCapacityFailure=null;agentStarts=0;constructor(e){this.deps=e}clearTimer(){this.timer!==null&&(clearTimeout(this.timer),this.timer=null)}reset(){this.clearTimer(),this.deps.turnEnds?.abandon(),this.providerFallbackInFlight=null,this.notFoundFallbackInFlight=null,this.stagedCapacityFailure=null}abandonTurnEnd(){this.deps.turnEnds?.abandon()}state(){return he(this.deps.nodeId)}async recordFault(e){return(await X(this.deps.nodeId,{op:"record",input:e})).fault}async clearFault(e,t=!1){await X(this.deps.nodeId,{op:"clear",...e===void 0?{}:{link:e},...t?{preserve_episode:!0}:{}})}sessionId(e){const t=e.sessionManager.getSessionId?.();return typeof t=="string"&&t!==""?t:null}async clearEpisode(e){const t=this.sessionId(e);t!==null&&await k(this.deps.nodeId,{op:"clear",session_id:t})}onEvent(e){e.type==="agent_start"&&this.agentStarts++,this.maybeSwitchProviderForRetry(e),this.maybeFallbackOnUnusableModel(e)}isActiveAutoFault(e){return e===null||e.retry.disposition!=="auto"||e.retry.by!=="daemon"?!1:e.kind==="connection"||e.kind==="rate-limit"||e.kind==="overloaded"}async publishSettledProviderFault(e){const t={agentEnd:e.stagedProviderAgentEnd,watchdogAbort:e.stagedWatchdogAbort,refreshAbort:e.stagedRefreshAbort,overflowFailure:e.stagedOverflowFailure,capacityFailure:this.stagedCapacityFailure?.generation===e?this.stagedCapacityFailure:null};this.stagedCapacityFailure=null,e.stagedProviderAgentEnd=null,e.stagedWatchdogAbort=!1,e.stagedRefreshAbort=!1,e.stagedOverflowFailure=null;const n=this.agentStarts,r=m(()=>{if(this.deps.installedGeneration()!==e||this.agentStarts!==n)throw new _},"assertCurrent");try{await this.retryWhileDaemonUnreachable("settled turn fault write",()=>this.recordStagedOutcome(e,t,r),r)}catch(s){if(!(s instanceof _))throw s}}async retryWhileDaemonUnreachable(e,t,n){let r=Se;for(;;){try{await t();return}catch(s){if(!V(s))throw s;F({level:"warn",event:"broker.runtime.diagnostic",fields:{message:`${e} waiting for the daemon: ${s.message}`}})}await new Promise(s=>setTimeout(s,r)),r=Math.min(r*2,Ae),n()}}async recordStagedOutcome(e,t,n){const{agentEnd:r,watchdogAbort:s,refreshAbort:a,overflowFailure:l,capacityFailure:c}=t,o=e.session,f=m(async b=>{n(),await this.clearEpisode(b)},"clearEpisode"),g=m(async b=>{n(),await this.recordFault(b)},"recordFault"),p=m(async(b,ce)=>{n(),await this.recordPendingProviderFault(b,ce)},"recordPendingProviderFault"),y=await this.state(),u=y.fault,h=y.episode,I=this.sessionId(o),w=this.isActiveAutoFault(u)&&u.link==="pi\u2192provider"?u:h?.state==="admitted"&&h.session_id===I&&this.isActiveAutoFault(h.fault)?h.fault:null,v=w===null?null:{since:w.since,anchorEntryId:w.anchor_entry_id,attempt:w.retry.attempt},d=[...Array.isArray(r?.messages)?r.messages:[]].reverse().find(b=>typeof b=="object"&&b!==null&&b.role==="assistant");if(c!==null||l!==null){await f(o),await g({link:"pi\u2192provider",op:"context overflow recovery",kind:"context-overflow",retry:{disposition:"fatal"},message:c?.errorMessage??l.errorMessage,anchor_entry_id:o.sessionManager.getLeafId?.()??void 0});return}if(s&&d?.stopReason==="aborted"){await p(o,{link:"pi\u2192provider",op:"generation turn",kind:"connection",retry:{disposition:"auto",by:"daemon",...v?.attempt!==void 0?{attempt:v.attempt}:{}},message:typeof d.errorMessage=="string"?d.errorMessage:"engine error (no errorMessage recorded)",...v!==null?{since:v.since}:{},anchor_entry_id:this.retryAnchor(o,v?.anchorEntryId)});return}if(d?.stopReason!=="error"){d!==void 0&&await f(o);return}if(a){await f(o);return}if(re(d)){await f(o);return}const A=typeof d.errorMessage=="string"?d.errorMessage:"engine error (no errorMessage recorded)";if(te({stopReason:"error",errorMessage:A})){await f(o);return}const E=q(d,o.model?.contextWindow),M=de(d),$=v!==null&&M.disposition!=="auto"&&Te(A,!0),le=$?{kind:"connection",disposition:"auto"}:M.classified,S=$?"auto":M.disposition,D=me(d),L=Ie(d),N=ge(d),G=typeof d.provider=="string"&&d.provider!==""?d.provider:o.model?.provider,U=typeof d.model=="string"&&d.model!==""?d.model:o.model?.id,W=N===void 0||G===void 0||U===void 0?void 0:{provider:G,model:U,...N};E&&await f(o);const x={link:"pi\u2192provider",op:"generation turn",kind:E?"context-overflow":le.kind,retry:E?{disposition:"fatal"}:S==="auto"?{disposition:"auto",by:"daemon",...D!==void 0?{nextAt:new Date(D).toISOString()}:{},...v?.attempt!==void 0?{attempt:v.attempt}:{}}:{disposition:S,...L!==void 0?{nextAt:new Date(L).toISOString()}:{}},message:A,...!E&&S==="auto"&&v!==null?{since:v.since}:{},anchor_entry_id:!E&&S==="auto"?this.retryAnchor(o,v?.anchorEntryId):o.sessionManager.getLeafId?.()??void 0,...W===void 0?{}:{provider_error:W}};x.retry.disposition==="auto"?await p(o,x):(await f(o),await g(x))}retryAnchor(e,t){const n=e.sessionManager.getLeafId?.()??void 0;return t!==void 0&&!this.hasProgressPastAnchor(e,t)?t:n}async recoverOnStartup(){const e=this.deps.installedGeneration();if(e===void 0)return"none";const t=(await this.state()).episode,n=this.sessionId(e.session);if(this.deps.cfg.newCycle===!0)return t!==null&&n!==null&&t.session_id===n&&await k(this.deps.nodeId,{op:"invalidate",session_id:n}),"none";if(t===null||n===null||t.session_id!==n)return"none";if(t.state==="admitted")if(t.fault.anchor_entry_id!==void 0&&!this.hasProgressPastAnchor(e.session,t.fault.anchor_entry_id)){if(!(await k(this.deps.nodeId,{op:"reopen",session_id:n})).applied)return"none"}else return await this.clearEpisode(e.session),"none";else if(t.state!=="pending")return"none";await this.recordFault(O(R(t.fault)));const r=await this.schedule();return r==="armed"?"retry-armed":r==="exhausted"?"fatal":"none"}hasProgressPastAnchor(e,t){const n=e.sessionManager.getBranch(),r=n.findIndex(a=>a.id===t);return(r===-1?n:n.slice(r+1)).some(a=>{if(a.type!=="message")return!1;const{message:l}=a;return l.role==="toolResult"?!0:l.role==="assistant"&&Array.isArray(l.content)&&l.content.length>0})}async schedule(){const e=this.deps.installedGeneration(),t=this.deps.currentSession();if(t.isStreaming||this.timer!==null)return this.timer!==null?"armed":"none";if(e===void 0)return this.abandonTurnEnd(),"none";const n=await this.state(),r=n.fault;if(!this.isActiveAutoFault(r)||this.sessionId(t)!==null&&!this.pendingEpisodeMatches(t,r,n))return this.clearTimer(),this.abandonTurnEnd(),"none";const s=Date.now(),a=this.faultRetryDelayMs(r,s);return a!==null&&this.deps.turnEnds?.holding()===!0&&Re(r.since,a,s)?(await this.endRunTurnOnFault(t,r,a),"none"):a!==null?(this.clearAndArmFaultRetry(a,e),this.timer!==null?"armed":"none"):(this.abandonTurnEnd(),r.retry.nextAt!==void 0||this.deps.installedGeneration()!==e||this.deps.currentSession()!==t||t.isStreaming?"none":(await this.settleExhausted(t,r),"exhausted"))}async settleExhausted(e,t){await this.recordFault(O(Q(R(t)))),await this.clearEpisode(e)}async endRunTurnOnFault(e,t,n){this.clearTimer(),this.abandonTurnEnd(),F({level:"info",event:"broker.runtime.diagnostic",fields:{message:`run turn completed on provider fault: ${t.kind} retry in ${n}ms is past the ${ie}ms turn window (since ${t.since}, attempt ${t.retry.attempt??0})`}}),await this.clearEpisode(e),await this.clearFault("pi\u2192provider")}async rearmIfStranded(){if(this.timer!==null||this.deps.installedGeneration()===void 0)return;const e=this.deps.currentSession();if(e.isStreaming)return;const t=await this.state();!this.isActiveAutoFault(t.fault)||!this.pendingEpisodeMatches(e,t.fault,t)||await this.schedule()}maybeSwitchProviderForRetry(e){if(e.type!=="auto_retry_start")return;const t=T("pi\u2192provider",e.errorMessage??"").kind;if(t!=="rate-limit"&&t!=="connection"||this.providerFallbackInFlight!==null||this.deps.cfg.modelExact===!0)return;const n=this.deps.installedGeneration();if(n===void 0)return;const r=this.deps.currentSession(),s=this.deps.currentServices(),a=this.deps.formatModelSpec(r.model,r.thinkingLevel);if(a===null)return;const l=z(this.deps.cfg.model,B(),!1);if(l===void 0)return;const c=J(l,j()??this.deps.cfg.cwd,Y()),o=ee(a),f=ae(c,o),g=f===void 0?{route:void 0,capacityExhausted:!1}:this.nextEligibleFallbackRoute(c.slice(f+1),this.deps.registryOf(s),r.getContextUsage()?.tokens,u=>!this.failedRetryRoutes.has(u.routeId));if(g.route===void 0){g.capacityExhausted&&(this.stageCapacityFailure(n,r),queueMicrotask(()=>{this.deps.installedGeneration()===n&&this.deps.currentSession()===r&&r.abortRetry()}));return}const p=g.route,y=(async()=>{const u=this.deps.registryOf(s).find(p.providerId,p.modelId);if(!u||(await r.setModel(u),this.deps.installedGeneration()!==n||this.deps.currentSession()!==r))return;const h=`${p.providerId}/${p.modelId}`===o.modelSpec?o.thinkingLevel:p.thinkingLevel;r.setThinkingLevel(h??"off"),this.failedRetryRoutes.add(p.routeId),await this.deps.broadcastModelChanged(!1)})().catch(u=>{F({level:"debug",event:"broker.runtime.diagnostic",fields:{message:`provider route fallback failed: ${u instanceof Error?u.message:String(u)}`}})}).finally(()=>{this.deps.installedGeneration()===n&&(this.providerFallbackInFlight=null)});this.providerFallbackInFlight=y}maybeFallbackOnUnusableModel(e){if(e.type!=="message_end"||e.message.role!=="assistant"||e.message.stopReason!=="error")return;const t=pe(e.message.errorMessage??"");if(!t&&!fe(e.message.errorMessage??"")||this.deps.cfg.modelExact===!0||this.notFoundFallbackInFlight!==null)return;const n=this.deps.installedGeneration();if(n===void 0)return;const r=this.deps.currentSession(),s=this.deps.currentServices(),a=this.deps.formatModelSpec(r.model,r.thinkingLevel);if(a===null)return;const l=ee(a);this.notFoundModels.add(l.modelSpec);const c=z(this.deps.cfg.model,B(),!1),o=c?J(c,j()??this.deps.cfg.cwd,Y()):[],f=ae(o,l),g=f===void 0?{route:void 0,capacityExhausted:!1}:this.nextEligibleFallbackRoute(o.slice(f+1),this.deps.registryOf(s),r.getContextUsage()?.tokens,h=>!this.notFoundModels.has(`${h.providerId}/${h.modelId}`));if(g.route===void 0){g.capacityExhausted&&this.stageCapacityFailure(n,r);return}const p=g.route,y=`${p.providerId}/${p.modelId}${p.thinkingLevel?`:${p.thinkingLevel}`:""}`,u=(async()=>{const h=this.deps.registryOf(s).find(p.providerId,p.modelId);if(h===void 0){F({level:"debug",event:"broker.runtime.diagnostic",fields:{message:`${t?"unconfigured-provider":"not_found"} fallback skipped: ${y} is not registered`}});return}if(await r.setModel(h),this.deps.installedGeneration()!==n||this.deps.currentSession()!==r)return;r.setThinkingLevel(p.thinkingLevel??"off"),await this.deps.broadcastModelChanged();const I=this.deps.formatModelSpec(r.model,r.thinkingLevel)??y;if(F({level:"debug",event:"broker.runtime.diagnostic",fields:{message:`${t?"unconfigured-provider":"not_found"} fallback: ${a} unavailable \u2192 ${I}; re-driving turn`}}),await r.agent.waitForIdle(),this.deps.installedGeneration()!==n||this.deps.currentSession()!==r)return;t&&await this.clearFault("pi\u2192provider");const w=K("recovery",{},be(a,I,t?"credential":"not-found"));ne(w,{type:"runtime",kind:"recovery"}),await this.deps.turnAdmission.admit(v=>H.fresh(()=>r.prompt(w,{preflightResult:v})))})().catch(h=>{F({level:"debug",event:"broker.runtime.diagnostic",fields:{message:`${t?"unconfigured-provider":"not_found"} fallback failed: ${h instanceof Error?h.message:String(h)}`}})}).finally(()=>{this.deps.installedGeneration()===n&&(this.notFoundFallbackInFlight=null)});this.notFoundFallbackInFlight=u}nextEligibleFallbackRoute(e,t,n,r){let s=0,a=0;for(const l of e){if(!r(l)||ke([{...l,...ye(l,t),automaticFallback:!0}]).candidates.length===0)continue;const c=t.find(l.providerId,l.modelId);if(c!==void 0){if(s++,this.targetCannotFitContext(c.contextWindow,n)){a++;continue}return{route:l,capacityExhausted:!1}}}return{route:void 0,capacityExhausted:s>0&&s===a}}targetCannotFitContext(e,t){return Number.isFinite(e)&&Number.isFinite(t)&&e<t}stageCapacityFailure(e,t){const n=t.getContextUsage()?.tokens;this.stagedCapacityFailure={generation:e,errorMessage:Number.isFinite(n)?`All available fallback models have context windows smaller than the current conversation (${n} tokens).`:"All available fallback models have context windows smaller than the current conversation."}}async recordPendingProviderFault(e,t){const n=this.sessionId(e);if(n===null){await this.recordFault(t);return}await k(this.deps.nodeId,{op:"record-pending",session_id:n,input:t})}pendingEpisodeMatches(e,t,n){const r=this.sessionId(e),s=n.episode;return r!==null&&s!==null&&s.state==="pending"&&s.session_id===r&&s.fault.fault_id===t.fault_id}faultRetryDelayMs(e,t){if(e.retry.nextAt!==void 0){const n=Date.parse(e.retry.nextAt)-t;return Number.isFinite(n)?Math.max(0,n):null}return C(R(e),t)?.delayMs??null}clearAndArmFaultRetry(e,t){if(this.deps.installedGeneration()!==t)return;this.clearTimer();const n=Math.min(Math.max(0,e),Ee),r=Math.max(0,e-n);this.timer=setTimeout(()=>{if(this.timer=null,this.deps.installedGeneration()===t){if(r>0){this.clearAndArmFaultRetry(r,t);return}this.runFaultRetry().catch(s=>{this.abandonTurnEnd(),F({level:"warn",event:"broker.runtime.diagnostic",fields:{message:`fault retry fire failed: ${s instanceof Error?s.message:String(s)}`}})})}},n),typeof this.timer.unref=="function"&&this.timer.unref()}async runFaultRetry(){await this.attemptFaultRetry()===void 0&&this.abandonTurnEnd()}async attemptFaultRetry(){const e=this.deps.installedGeneration();if(e===void 0)return;const t=e.session;if(t.isStreaming)return;const n=(await this.state()).fault;if(!this.isActiveAutoFault(n))return;let r=n;if(n.kind==="connection"&&this.deps.turnEnds===void 0){const y=await this.deps.retryProbe();if(this.deps.installedGeneration()!==e||this.deps.currentSession()!==t||t.isStreaming)return;const u=(await this.state()).fault;if(!this.isActiveAutoFault(u)||u.since!==n.since)return;if(!y)return this.clearAndArmFaultRetry(Z(u.kind).baseDelayMs,e),"rearmed";r=u}const s=this.deps.turnEnds!==void 0,a=r.retry.attempt??0,l=Z(r.kind),c=a>=l.max?null:C(R(r),Date.now());if(c===null){await this.settleExhausted(t,r);return}if(this.deps.installedGeneration()!==e||this.deps.currentSession()!==t)return;let o,f;const g=await this.deps.turnAdmission.admit(async y=>{const u=(await this.state()).fault;if(this.deps.installedGeneration()!==e||this.deps.currentSession()!==t||t.isStreaming||!this.isActiveAutoFault(u)||u.since!==r.since){y();return}const h=this.sessionId(t);if(h===null){y();return}if(!(await k(this.deps.nodeId,{op:"admit",session_id:h,fault_id:u.fault_id,retry:c.fault.retry})).applied){y();return}const w=r.anchor_entry_id;if(w!==void 0&&(t.sessionManager.getLeafId?.()??null)!==w&&!this.hasProgressPastAnchor(t,w))try{const d=await t.navigateTree(w);if(this.deps.installedGeneration()!==e||this.deps.currentSession()!==t){y();return}d.cancelled||this.deps.reWelcomeAll()}catch(d){F({level:"debug",event:"broker.runtime.diagnostic",fields:{message:`fault retry rewind skipped: ${d instanceof Error?d.message:String(d)}`}})}const v=K("recovery",s?{attempt:c.attempt}:{attempt:c.attempt,max:c.max},Me(r.kind,s));ne(v,{type:"runtime",kind:"recovery"}),this.deps.turnEnds?.beginRecovery();const P=this.agentStarts;try{await H.fresh(()=>t.prompt(v,{preflightResult:y}))}catch(d){o={error:d,faultId:u.fault_id,startsBefore:P},oe(d)||(f={code:"model_error",message:`recovery prompt rejected: ${se(d)}`});return}finally{this.deps.turnEnds?.recoveryReturned(f)}return"prompted"});if(o===void 0)return g;const p=await this.settleRejectedRecoveryPrompt(e,t,o);if(p==="stale")throw o.error;return p==="rearmed"?"rearmed":void 0}async settleRejectedRecoveryPrompt(e,t,n){const r=this.sessionId(t);if(r===null)return"stale";const s=m(()=>{if(this.deps.installedGeneration()!==e||this.deps.currentSession()!==t||t.isStreaming||this.agentStarts!==n.startsBefore)throw new _},"assertCurrent"),a=se(n.error),l=oe(n.error);try{let c;return await this.retryWhileDaemonUnreachable("rejected recovery prompt settlement",async()=>{s();const{episode:o}=await this.state();if(s(),o===null||o.state!=="admitted"||o.session_id!==r||o.fault.fault_id!==n.faultId)throw new _;const f=R(o.fault),g=l&&this.deps.turnEnds===void 0?C(f,Date.now()):null,p=g===null?Q(l?f:{...f,kind:"other",message:`recovery prompt rejected: ${a}`}):{...f,retry:{...f.retry,nextAt:g.nextAt}};if(s(),!(await k(this.deps.nodeId,{op:"settle-rejected",session_id:r,fault_id:n.faultId,reopen:g!==null,input:O(p)})).applied)throw new _;c=g?.nextAt},s),c===void 0?(F({level:"warn",event:"broker.runtime.diagnostic",fields:{message:`recovery prompt rejected, ending the retry episode: ${a}`}}),"ended"):(F({level:"warn",event:"broker.runtime.diagnostic",fields:{message:`recovery prompt rejected before any turn started, retrying at ${c}: ${a}`}}),await this.schedule(),"rearmed")}catch(c){if(!(c instanceof _))throw c;return"stale"}}}export{Ze as FaultRetry,ie as RUN_TURN_RETRY_WINDOW_MS,Te as isPrefillRejectionDuringEpisode,Me as retryCardBody,Re as runTurnRetryExpired,de as settledProviderFault,Qe as willDaemonRetry};
|
|
1
|
+
var ce=Object.defineProperty;var m=(r,e)=>ce(r,"name",{value:e,configurable:!0});import{envModelIntent as B,envNodeCwd as j,envProfileId as Y}from"../../../shared/env.js";import{isContextOverflow as q}from"@earendil-works/pi-ai";import{classify as T}from"../../fault-classifier.js";import{isDaemonTransportApiError as V}from"../../../api/errors.js";import{isModelNotFoundError as fe,isProviderUnconfiguredError as pe}from"../fault.js";import{brokerRecovery as he,daemonClient as me,mutateBrokerFault as X,mutateBrokerProviderRetry as I}from"./daemon-ops.js";import{extractCoolingDeadline as ge}from"../managed-provider-cooling.js";import{extractProviderFailureDetails as ye}from"../../provider-failure.js";import{expandModelCandidates as J,modelRequestFromConfig as z}from"../../model-routes.js";import{operationIdContext as H}from"../../events/operation-id.js";import{emitEvent as F}from"../../events/emit.js";import{CONNECTION_FAULT_RECOVERY_BODY as ve,PROVIDER_FAULT_RECOVERY_BODY as we,RUN_CONNECTION_FAULT_RETRY_BODY as Fe,formatCard as K,formatModelFallbackRecovery as be}from"../../../shared/generated-context.js";import{markFatalOnExhaust as Q,nextFaultRetry as C,policyFor as Z}from"../fault-recovery.js";import{parseModelSpec as ee}from"../model-selection.js";import{endedByAbort as te}from"../session-cycles.js";import{isManagedProvider as ke,resolveProviderCandidates as Ie}from"../../subscription-state.js";import{announceMessageOrigin as ne}from"../stamp/channel.js";import{LLM_REFUSAL_DIAGNOSTIC as _e,refusalRetryAt as Ee}from"./model-adapter.js";import{isSafetyRefusal as ie}from"../../llm/refusal.js";const Re=2147483647,re=3e4;function Se(r,e,t){const n=Date.parse(r);return!Number.isFinite(n)||t+e-n>re}m(Se,"runTurnRetryExpired");class _ extends Error{static{m(this,"StaleOutcome")}}const Ae=1e3,Me=3e4;function xe(r,e){return r!=="connection"?we:e?Fe:ve}m(xe,"retryCardBody");function R(r){return{link:r.link,op:r.op,kind:r.kind,retry:r.retry,message:r.message,since:r.since,operation_id:r.operation_id,...r.anchor_entry_id===void 0?{}:{anchorEntryId:r.anchor_entry_id},...r.provider_error===void 0?{}:{providerError:r.provider_error}}}m(R,"policyFault");function se(r){return r instanceof Error?r.message:String(r)}m(se,"errorText");function oe(r){return V(r)||T("pi\u2192provider",r).disposition==="auto"}m(oe,"isTransientRejection");function O(r){return{link:r.link,op:r.op,kind:r.kind,retry:r.retry,message:r.message,...r.operation_id===void 0?{}:{operation_id:r.operation_id},...r.since===void 0?{}:{since:r.since},...r.anchorEntryId===void 0?{}:{anchor_entry_id:r.anchorEntryId},...r.providerError===void 0?{}:{provider_error:r.providerError}}}m(O,"faultInput");function ae(r,e){const t=m(n=>`${n.providerId}/${n.modelId}`===e.modelSpec,"onLiveModel");return(r.find(n=>t(n)&&n.thinkingLevel===e.thinkingLevel)??r.find(t))?.rank}m(ae,"liveRouteRank");function de(r){const e=T("pi\u2192provider",r),t=r.diagnostics?.some(n=>n.type===_e)??!1;return{classified:e,disposition:t?"fatal":e.disposition}}m(de,"settledProviderFault");function Ze(r,e){if(r.stopReason!=="error"||te(r)||ie(r)||q(r,e))return!1;const{classified:t,disposition:n}=de(r);return n==="auto"&&(t.kind==="connection"||t.kind==="rate-limit"||t.kind==="overloaded")}m(Ze,"willDaemonRetry");const Te=/does not support assistant message prefill|conversation must end with a user message/i;function Ce(r,e){return e&&Te.test(r)}m(Ce,"isPrefillRejectionDuringEpisode");class et{static{m(this,"FaultRetry")}deps;timer=null;failedRetryRoutes=new Set;notFoundModels=new Set;providerFallbackInFlight=null;notFoundFallbackInFlight=null;stagedCapacityFailure=null;agentStarts=0;constructor(e){this.deps=e}clearTimer(){this.timer!==null&&(clearTimeout(this.timer),this.timer=null)}reset(){this.clearTimer(),this.deps.turnEnds?.abandon(),this.providerFallbackInFlight=null,this.notFoundFallbackInFlight=null,this.stagedCapacityFailure=null}abandonTurnEnd(){this.deps.turnEnds?.abandon()}state(){return he(this.deps.nodeId)}async recordFault(e){return(await X(this.deps.nodeId,{op:"record",input:e})).fault}async clearFault(e,t=!1){await X(this.deps.nodeId,{op:"clear",...e===void 0?{}:{link:e},...t?{preserve_episode:!0}:{}})}sessionId(e){const t=e.sessionManager.getSessionId?.();return typeof t=="string"&&t!==""?t:null}async clearEpisode(e){const t=this.sessionId(e);t!==null&&await I(this.deps.nodeId,{op:"clear",session_id:t})}onEvent(e){e.type==="agent_start"&&this.agentStarts++,this.maybeSwitchProviderForRetry(e),this.maybeFallbackOnUnusableModel(e)}isActiveAutoFault(e){return e===null||e.retry.disposition!=="auto"||e.retry.by!=="daemon"?!1:e.kind==="connection"||e.kind==="rate-limit"||e.kind==="overloaded"}async publishSettledProviderFault(e){const t={agentEnd:e.stagedProviderAgentEnd,watchdogAbort:e.stagedWatchdogAbort,refreshAbort:e.stagedRefreshAbort,overflowFailure:e.stagedOverflowFailure,capacityFailure:this.stagedCapacityFailure?.generation===e?this.stagedCapacityFailure:null};this.stagedCapacityFailure=null,e.stagedProviderAgentEnd=null,e.stagedWatchdogAbort=!1,e.stagedRefreshAbort=!1,e.stagedOverflowFailure=null;const n=this.agentStarts,i=m(()=>{if(this.deps.installedGeneration()!==e||this.agentStarts!==n)throw new _},"assertCurrent");try{await this.retryWhileDaemonUnreachable("settled turn fault write",()=>this.recordStagedOutcome(e,t,i),i)}catch(s){if(!(s instanceof _))throw s}}async retryWhileDaemonUnreachable(e,t,n){let i=Ae;for(;;){try{await t();return}catch(s){if(!V(s))throw s;F({level:"warn",event:"broker.runtime.diagnostic",fields:{message:`${e} waiting for the daemon: ${s.message}`}})}await new Promise(s=>setTimeout(s,i)),i=Math.min(i*2,Me),n()}}async recordStagedOutcome(e,t,n){const{agentEnd:i,watchdogAbort:s,refreshAbort:d,overflowFailure:c,capacityFailure:f}=t,o=e.session,a=m(async b=>{n(),await this.clearEpisode(b)},"clearEpisode"),g=m(async b=>{n(),await this.recordFault(b)},"recordFault"),y=m(async(b,ue)=>{n(),await this.recordPendingProviderFault(b,ue)},"recordPendingProviderFault"),u=await this.state(),p=u.fault,v=u.episode,k=this.sessionId(o),w=this.isActiveAutoFault(p)&&p.link==="pi\u2192provider"?p:v?.state==="admitted"&&v.session_id===k&&this.isActiveAutoFault(v.fault)?v.fault:null,h=w===null?null:{since:w.since,anchorEntryId:w.anchor_entry_id,attempt:w.retry.attempt},l=[...Array.isArray(i?.messages)?i.messages:[]].reverse().find(b=>typeof b=="object"&&b!==null&&b.role==="assistant");if(f!==null||c!==null){await a(o),await g({link:"pi\u2192provider",op:"context overflow recovery",kind:"context-overflow",retry:{disposition:"fatal"},message:f?.errorMessage??c.errorMessage,anchor_entry_id:o.sessionManager.getLeafId?.()??void 0});return}if(s&&l?.stopReason==="aborted"){await y(o,{link:"pi\u2192provider",op:"generation turn",kind:"connection",retry:{disposition:"auto",by:"daemon",...h?.attempt!==void 0?{attempt:h.attempt}:{}},message:typeof l.errorMessage=="string"?l.errorMessage:"engine error (no errorMessage recorded)",...h!==null?{since:h.since}:{},anchor_entry_id:this.retryAnchor(o,h?.anchorEntryId)});return}if(l?.stopReason!=="error"){l!==void 0&&await a(o);return}if(d){await a(o);return}if(ie(l)){await a(o);return}const A=typeof l.errorMessage=="string"?l.errorMessage:"engine error (no errorMessage recorded)";if(te({stopReason:"error",errorMessage:A})){await a(o);return}const E=q(l,o.model?.contextWindow),M=de(l),$=h!==null&&M.disposition!=="auto"&&Ce(A,!0),le=$?{kind:"connection",disposition:"auto"}:M.classified,S=$?"auto":M.disposition,D=ge(l),L=Ee(l),N=ye(l),G=typeof l.provider=="string"&&l.provider!==""?l.provider:o.model?.provider,U=typeof l.model=="string"&&l.model!==""?l.model:o.model?.id,W=N===void 0||G===void 0||U===void 0?void 0:{provider:G,model:U,...N};E&&await a(o);const x={link:"pi\u2192provider",op:"generation turn",kind:E?"context-overflow":le.kind,retry:E?{disposition:"fatal"}:S==="auto"?{disposition:"auto",by:"daemon",...D!==void 0?{nextAt:new Date(D).toISOString()}:{},...h?.attempt!==void 0?{attempt:h.attempt}:{}}:{disposition:S,...L!==void 0?{nextAt:new Date(L).toISOString()}:{}},message:A,...!E&&S==="auto"&&h!==null?{since:h.since}:{},anchor_entry_id:!E&&S==="auto"?this.retryAnchor(o,h?.anchorEntryId):o.sessionManager.getLeafId?.()??void 0,...W===void 0?{}:{provider_error:W}};x.retry.disposition==="auto"?await y(o,x):(await a(o),await g(x))}retryAnchor(e,t){const n=e.sessionManager.getLeafId?.()??void 0;return t!==void 0&&!this.hasProgressPastAnchor(e,t)?t:n}async recoverOnStartup(){const e=this.deps.installedGeneration();if(e===void 0)return"none";const t=(await this.state()).episode,n=this.sessionId(e.session);if(this.deps.cfg.newCycle===!0)return t!==null&&n!==null&&t.session_id===n&&await I(this.deps.nodeId,{op:"invalidate",session_id:n}),"none";if(t===null||n===null||t.session_id!==n)return"none";if(t.state==="admitted")if(t.fault.anchor_entry_id!==void 0&&!this.hasProgressPastAnchor(e.session,t.fault.anchor_entry_id)){if(!(await I(this.deps.nodeId,{op:"reopen",session_id:n})).applied)return"none"}else return await this.clearEpisode(e.session),"none";else if(t.state!=="pending")return"none";await this.recordFault(O(R(t.fault)));const i=await this.schedule();return i==="armed"?"retry-armed":i==="exhausted"?"fatal":"none"}hasProgressPastAnchor(e,t){const n=e.sessionManager.getBranch(),i=n.findIndex(d=>d.id===t);return(i===-1?n:n.slice(i+1)).some(d=>{if(d.type!=="message")return!1;const{message:c}=d;return c.role==="toolResult"?!0:c.role==="assistant"&&Array.isArray(c.content)&&c.content.length>0})}async schedule(){const e=this.deps.installedGeneration(),t=this.deps.currentSession();if(t.isStreaming||this.timer!==null)return this.timer!==null?"armed":"none";if(e===void 0)return this.abandonTurnEnd(),"none";const n=await this.state(),i=n.fault;if(!this.isActiveAutoFault(i)||this.sessionId(t)!==null&&!this.pendingEpisodeMatches(t,i,n))return this.clearTimer(),this.abandonTurnEnd(),"none";const s=Date.now(),d=this.faultRetryDelayMs(i,s);return d!==null&&this.deps.turnEnds?.holding()===!0&&Se(i.since,d,s)?(await this.endRunTurnOnFault(t,i,d),"none"):d!==null?(this.clearAndArmFaultRetry(d,e),this.timer!==null?"armed":"none"):(this.abandonTurnEnd(),i.retry.nextAt!==void 0||this.deps.installedGeneration()!==e||this.deps.currentSession()!==t||t.isStreaming?"none":(await this.settleExhausted(t,i),"exhausted"))}async settleExhausted(e,t){await this.recordFault(O(Q(R(t)))),await this.clearEpisode(e)}async endRunTurnOnFault(e,t,n){this.clearTimer(),this.abandonTurnEnd(),F({level:"info",event:"broker.runtime.diagnostic",fields:{message:`run turn completed on provider fault: ${t.kind} retry in ${n}ms is past the ${re}ms turn window (since ${t.since}, attempt ${t.retry.attempt??0})`}}),await this.clearEpisode(e),await this.clearFault("pi\u2192provider")}async rearmIfStranded(){if(this.timer!==null||this.deps.installedGeneration()===void 0)return;const e=this.deps.currentSession();if(e.isStreaming)return;const t=await this.state();!this.isActiveAutoFault(t.fault)||!this.pendingEpisodeMatches(e,t.fault,t)||await this.schedule()}maybeSwitchProviderForRetry(e){if(e.type!=="auto_retry_start")return;const t=T("pi\u2192provider",e.errorMessage??"").kind;if(t!=="rate-limit"&&t!=="connection"||this.providerFallbackInFlight!==null||this.deps.cfg.modelExact===!0)return;const n=this.deps.installedGeneration();if(n===void 0)return;const i=this.deps.currentSession(),s=this.deps.currentServices(),d=this.deps.formatModelSpec(i.model,i.thinkingLevel);if(d===null)return;const c=z(this.deps.cfg.model,B(),!1);if(c===void 0)return;const f=ee(d),o=(async()=>{const a=await J(c,j()??this.deps.cfg.cwd,Y()),g=ae(a,f),y=g===void 0?{route:void 0,capacityExhausted:!1}:await this.nextEligibleFallbackRoute(a.slice(g+1),this.deps.registryOf(s),i.getContextUsage()?.tokens,k=>!this.failedRetryRoutes.has(k.routeId));if(y.route===void 0){y.capacityExhausted&&(this.stageCapacityFailure(n,i),queueMicrotask(()=>{this.deps.installedGeneration()===n&&this.deps.currentSession()===i&&i.abortRetry()}));return}const u=y.route,p=this.deps.registryOf(s).find(u.providerId,u.modelId);if(!p||(await i.setModel(p),this.deps.installedGeneration()!==n||this.deps.currentSession()!==i))return;const v=`${u.providerId}/${u.modelId}`===f.modelSpec?f.thinkingLevel:u.thinkingLevel;i.setThinkingLevel(v??"off"),this.failedRetryRoutes.add(u.routeId),await this.deps.broadcastModelChanged(!1)})().catch(a=>{F({level:"debug",event:"broker.runtime.diagnostic",fields:{message:`provider route fallback failed: ${a instanceof Error?a.message:String(a)}`}})}).finally(()=>{this.deps.installedGeneration()===n&&(this.providerFallbackInFlight=null)});this.providerFallbackInFlight=o}maybeFallbackOnUnusableModel(e){if(e.type!=="message_end"||e.message.role!=="assistant"||e.message.stopReason!=="error")return;const t=pe(e.message.errorMessage??"");if(!t&&!fe(e.message.errorMessage??"")||this.deps.cfg.modelExact===!0||this.notFoundFallbackInFlight!==null)return;const n=this.deps.installedGeneration();if(n===void 0)return;const i=this.deps.currentSession(),s=this.deps.currentServices(),d=this.deps.formatModelSpec(i.model,i.thinkingLevel);if(d===null)return;const c=ee(d);this.notFoundModels.add(c.modelSpec);const f=z(this.deps.cfg.model,B(),!1),o=(async()=>{const a=f?await J(f,j()??this.deps.cfg.cwd,Y()):[],g=ae(a,c),y=g===void 0?{route:void 0,capacityExhausted:!1}:await this.nextEligibleFallbackRoute(a.slice(g+1),this.deps.registryOf(s),i.getContextUsage()?.tokens,h=>!this.notFoundModels.has(`${h.providerId}/${h.modelId}`));if(y.route===void 0){y.capacityExhausted&&this.stageCapacityFailure(n,i);return}const u=y.route,p=`${u.providerId}/${u.modelId}${u.thinkingLevel?`:${u.thinkingLevel}`:""}`,v=this.deps.registryOf(s).find(u.providerId,u.modelId);if(v===void 0){F({level:"debug",event:"broker.runtime.diagnostic",fields:{message:`${t?"unconfigured-provider":"not_found"} fallback skipped: ${p} is not registered`}});return}if(await i.setModel(v),this.deps.installedGeneration()!==n||this.deps.currentSession()!==i)return;i.setThinkingLevel(u.thinkingLevel??"off"),await this.deps.broadcastModelChanged();const k=this.deps.formatModelSpec(i.model,i.thinkingLevel)??p;if(F({level:"debug",event:"broker.runtime.diagnostic",fields:{message:`${t?"unconfigured-provider":"not_found"} fallback: ${d} unavailable \u2192 ${k}; re-driving turn`}}),await i.agent.waitForIdle(),this.deps.installedGeneration()!==n||this.deps.currentSession()!==i)return;t&&await this.clearFault("pi\u2192provider");const w=K("recovery",{},be(d,k,t?"credential":"not-found"));ne(w,{type:"runtime",kind:"recovery"}),await this.deps.turnAdmission.admit(h=>H.fresh(()=>i.prompt(w,{preflightResult:h})))})().catch(a=>{F({level:"debug",event:"broker.runtime.diagnostic",fields:{message:`${t?"unconfigured-provider":"not_found"} fallback failed: ${a instanceof Error?a.message:String(a)}`}})}).finally(()=>{this.deps.installedGeneration()===n&&(this.notFoundFallbackInFlight=null)});this.notFoundFallbackInFlight=o}async nextEligibleFallbackRoute(e,t,n,i){let s=0,d=0;for(const c of e){if(!i(c)||Ie([{...c,...await this.routeAvailability(c,t),automaticFallback:!0}]).candidates.length===0)continue;const f=t.find(c.providerId,c.modelId);if(f!==void 0){if(s++,this.targetCannotFitContext(f.contextWindow,n)){d++;continue}return{route:c,capacityExhausted:!1}}}return{route:void 0,capacityExhausted:s>0&&s===d}}async routeAvailability(e,t){const n=t.find(e.providerId,e.modelId);if(n===void 0)return{registered:!1,authenticated:!1};if(!ke(e.providerId))return{registered:!0,authenticated:t.hasConfiguredAuth(n)};const i=await me().getModelAuthReadiness({model:`${e.providerId}/${e.modelId}`}),s=i.rate_limited_until==null?void 0:Date.parse(i.rate_limited_until);return{registered:!0,authenticated:i.credential==="ready",...s!==void 0&&s>Date.now()?{coolingUntil:s}:{}}}targetCannotFitContext(e,t){return Number.isFinite(e)&&Number.isFinite(t)&&e<t}stageCapacityFailure(e,t){const n=t.getContextUsage()?.tokens;this.stagedCapacityFailure={generation:e,errorMessage:Number.isFinite(n)?`All available fallback models have context windows smaller than the current conversation (${n} tokens).`:"All available fallback models have context windows smaller than the current conversation."}}async recordPendingProviderFault(e,t){const n=this.sessionId(e);if(n===null){await this.recordFault(t);return}await I(this.deps.nodeId,{op:"record-pending",session_id:n,input:t})}pendingEpisodeMatches(e,t,n){const i=this.sessionId(e),s=n.episode;return i!==null&&s!==null&&s.state==="pending"&&s.session_id===i&&s.fault.fault_id===t.fault_id}faultRetryDelayMs(e,t){if(e.retry.nextAt!==void 0){const n=Date.parse(e.retry.nextAt)-t;return Number.isFinite(n)?Math.max(0,n):null}return C(R(e),t)?.delayMs??null}clearAndArmFaultRetry(e,t){if(this.deps.installedGeneration()!==t)return;this.clearTimer();const n=Math.min(Math.max(0,e),Re),i=Math.max(0,e-n);this.timer=setTimeout(()=>{if(this.timer=null,this.deps.installedGeneration()===t){if(i>0){this.clearAndArmFaultRetry(i,t);return}this.runFaultRetry().catch(s=>{this.abandonTurnEnd(),F({level:"warn",event:"broker.runtime.diagnostic",fields:{message:`fault retry fire failed: ${s instanceof Error?s.message:String(s)}`}})})}},n),typeof this.timer.unref=="function"&&this.timer.unref()}async runFaultRetry(){await this.attemptFaultRetry()===void 0&&this.abandonTurnEnd()}async attemptFaultRetry(){const e=this.deps.installedGeneration();if(e===void 0)return;const t=e.session;if(t.isStreaming)return;const n=(await this.state()).fault;if(!this.isActiveAutoFault(n))return;let i=n;if(n.kind==="connection"&&this.deps.turnEnds===void 0){const u=await this.deps.retryProbe();if(this.deps.installedGeneration()!==e||this.deps.currentSession()!==t||t.isStreaming)return;const p=(await this.state()).fault;if(!this.isActiveAutoFault(p)||p.since!==n.since)return;if(!u)return this.clearAndArmFaultRetry(Z(p.kind).baseDelayMs,e),"rearmed";i=p}const s=this.deps.turnEnds!==void 0,d=i.retry.attempt??0,c=Z(i.kind),f=d>=c.max?null:C(R(i),Date.now());if(f===null){await this.settleExhausted(t,i);return}if(this.deps.installedGeneration()!==e||this.deps.currentSession()!==t)return;let o,a;const g=await this.deps.turnAdmission.admit(async u=>{const p=(await this.state()).fault;if(this.deps.installedGeneration()!==e||this.deps.currentSession()!==t||t.isStreaming||!this.isActiveAutoFault(p)||p.since!==i.since){u();return}const v=this.sessionId(t);if(v===null){u();return}if(!(await I(this.deps.nodeId,{op:"admit",session_id:v,fault_id:p.fault_id,retry:f.fault.retry})).applied){u();return}const w=i.anchor_entry_id;if(w!==void 0&&(t.sessionManager.getLeafId?.()??null)!==w&&!this.hasProgressPastAnchor(t,w))try{const l=await t.navigateTree(w);if(this.deps.installedGeneration()!==e||this.deps.currentSession()!==t){u();return}l.cancelled||this.deps.reWelcomeAll()}catch(l){F({level:"debug",event:"broker.runtime.diagnostic",fields:{message:`fault retry rewind skipped: ${l instanceof Error?l.message:String(l)}`}})}const h=K("recovery",s?{attempt:f.attempt}:{attempt:f.attempt,max:f.max},xe(i.kind,s));ne(h,{type:"runtime",kind:"recovery"}),this.deps.turnEnds?.beginRecovery();const P=this.agentStarts;try{await H.fresh(()=>t.prompt(h,{preflightResult:u}))}catch(l){o={error:l,faultId:p.fault_id,startsBefore:P},oe(l)||(a={code:"model_error",message:`recovery prompt rejected: ${se(l)}`});return}finally{this.deps.turnEnds?.recoveryReturned(a)}return"prompted"});if(o===void 0)return g;const y=await this.settleRejectedRecoveryPrompt(e,t,o);if(y==="stale")throw o.error;return y==="rearmed"?"rearmed":void 0}async settleRejectedRecoveryPrompt(e,t,n){const i=this.sessionId(t);if(i===null)return"stale";const s=m(()=>{if(this.deps.installedGeneration()!==e||this.deps.currentSession()!==t||t.isStreaming||this.agentStarts!==n.startsBefore)throw new _},"assertCurrent"),d=se(n.error),c=oe(n.error);try{let f;return await this.retryWhileDaemonUnreachable("rejected recovery prompt settlement",async()=>{s();const{episode:o}=await this.state();if(s(),o===null||o.state!=="admitted"||o.session_id!==i||o.fault.fault_id!==n.faultId)throw new _;const a=R(o.fault),g=c&&this.deps.turnEnds===void 0?C(a,Date.now()):null,y=g===null?Q(c?a:{...a,kind:"other",message:`recovery prompt rejected: ${d}`}):{...a,retry:{...a.retry,nextAt:g.nextAt}};if(s(),!(await I(this.deps.nodeId,{op:"settle-rejected",session_id:i,fault_id:n.faultId,reopen:g!==null,input:O(y)})).applied)throw new _;f=g?.nextAt},s),f===void 0?(F({level:"warn",event:"broker.runtime.diagnostic",fields:{message:`recovery prompt rejected, ending the retry episode: ${d}`}}),"ended"):(F({level:"warn",event:"broker.runtime.diagnostic",fields:{message:`recovery prompt rejected before any turn started, retrying at ${f}: ${d}`}}),await this.schedule(),"rearmed")}catch(f){if(!(f instanceof _))throw f;return"stale"}}}export{et as FaultRetry,re as RUN_TURN_RETRY_WINDOW_MS,Ce as isPrefillRejectionDuringEpisode,xe as retryCardBody,Se as runTurnRetryExpired,de as settledProviderFault,Ze as willDaemonRetry};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var Q=Object.defineProperty;var r=(h,l)=>Q(h,"name",{value:l,configurable:!0});import{configuredLadderProviders as $,explicitModelIntent as k,nextLadderModel as H,normalizeModel as O}from"../launch.js";import{parseModelSpec as p}from"../model-selection.js";import{envModelIntent as U}from"../../../shared/env.js";import{resolveModelQuery as f}from"./frame-model-query.js";function J(h){const{registry:l,replies:M,session:n,services:L,registryOf:S,persistModelChoice:T,broadcastModelChanged:y,formatModelSpec:w}=h,{notWritable:d,ackTo:c,engineErrorTo:s}=M,m=r(()=>S(L()),"modelRegistry"),v=r((e,t)=>l.sendFrame(e,{type:"error",code:"engine_error",message:t}),"noSuchModel"),_=r(()=>{const e=U();return T(e===void 0?void 0:k(e),!0)},"persistThinkingChoice"),b=r((e,t)=>{if(d(e,"set the model"))return;const o=p(t.model);let u,i;try{i=p(O(o.modelSpec)),u=f(m(),i.modelSpec)}catch(a){s(e)(a);return}if(u===void 0){v(e,`no model matching '${t.model}' in the registry`);return}n().setModel(u).then(async()=>{const a=o.thinkingLevel??i.thinkingLevel;a!==void 0&&n().setThinkingLevel(a),await y(!0,t.intent??k(t.model),!0),c(e,"set_model")}).catch(s(e))},"setModel"),A=r((e,t)=>{d(e,"deliver a custom message")||n().sendCustomMessage({customType:t.customType,content:t.content,display:!0,...t.details!==void 0?{details:t.details}:{}},...t.deliverAs!==void 0?[{deliverAs:t.deliverAs}]:[]).then(()=>c(e,"deliver_custom_message")).catch(s(e))},"deliverCustomMessage"),C=r((e,t)=>{d(e,"cycle the model")||n().cycleModel(t.direction).then(async()=>{await y(!0,void 0,!0),c(e,"cycle_model")}).catch(s(e))},"cycleModel"),q=r((e,t)=>{if(d(e,"cycle the model ladder"))return;const o=(()=>{try{const g=m();return $(N=>g.getProviderAuthStatus(N).configured)}catch{return}})(),u=w(n().model,n().thinkingLevel)??"",i=p(H(u,t.direction==="backward"?-1:1,o));let a;try{a=f(m(),i.modelSpec)}catch(g){s(e)(g);return}if(a===void 0){v(e,`ladder model '${i.modelSpec}' not in the registry`);return}n().setModel(a).then(async()=>{i.thinkingLevel!==void 0&&n().setThinkingLevel(i.thinkingLevel),await y(!0,void 0,!0),c(e,"cycle_ladder")}).catch(s(e))},"cycleLadder"),E=r(e=>{d(e,"cycle the thinking level")||(async()=>{n().cycleThinkingLevel(),await _(),c(e,"cycle_thinking")})().catch(s(e))},"cycleThinking"),x=r((e,t)=>{if(!d(e,"dequeue messages",t.id))try{const{steering:o,followUp:u}=n().clearQueue();l.sendFrame(e,{type:"data",id:t.id,kind:"dequeue",steering:o,followUp:u})}catch(o){s(e,t.id)(o)}},"dequeue"),P=r((e,t)=>{d(e,"set the thinking level")||(async()=>{n().setThinkingLevel(t.level),await _(),c(e,"set_thinking_level")})().catch(s(e))},"setThinkingLevel"),R=r((e,t)=>{if(!d(e,"set auto-retry"))try{if(t.enabled)throw new Error("The daemon model adapter owns retries for broker sessions; pi auto-retry cannot be enabled");n().setAutoRetryEnabled(!1),c(e,"set_auto_retry")}catch(o){s(e)(o)}},"setAutoRetry"),z=r((e,t)=>{if(!d(e,"set auto-compaction"))try{n().setAutoCompactionEnabled(t.enabled),c(e,"set_auto_compaction")}catch(o){s(e)(o)}},"setAutoCompaction"),F=r((e,t)=>{d(e,"compact the session")||n().compact(t.instructions).then(()=>c(e,"compact")).catch(s(e))},"compact"),I=r((e,t)=>{if(!d(e,"rename the session"))try{n().setSessionName(t.name),c(e,"set_session_name")}catch(o){s(e)(o)}},"setSessionName");return(e,t)=>{switch(t.type){case"set_model":return b(e,t);case"deliver_custom_message":return A(e,t);case"cycle_model":return C(e,t);case"cycle_ladder":return q(e,t);case"cycle_thinking":return E(e);case"dequeue":return x(e,t);case"set_thinking_level":return P(e,t);case"set_auto_retry":return R(e,t);case"set_auto_compaction":return z(e,t);case"compact":return F(e,t);case"set_session_name":return I(e,t)}}}r(J,"createEngineControlHandler");export{J as createEngineControlHandler};
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
export declare const HELD_DEFERRED_INBOX_PROMPT_JOIN: unique symbol;
|
|
2
2
|
export declare const BROKER_IDLE_TURN_START: unique symbol;
|
|
3
3
|
export declare const BROKER_RUN_TURN_BUSY: unique symbol;
|
|
4
|
+
export declare const BROKER_DISPOSE_AND_EXIT: unique symbol;
|
|
5
|
+
/** The broker's one exit path, for an extension whose failure must end the process (a conversation store that stays down). */
|
|
6
|
+
export declare function brokerDisposeAndExit(): ((reason: string, status?: number) => void) | undefined;
|
|
4
7
|
export declare function brokerRunTurnBusy(): boolean;
|
|
5
8
|
export type HeldDeferredInboxPromptJoin = (session: {
|
|
6
9
|
sendCustomMessage: (message: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var n=Object.defineProperty;var r=(o,t)=>n(o,"name",{value:t,configurable:!0});const e=Symbol.for("@crouton-kit/crtr:held-deferred-inbox-prompt-join"),
|
|
1
|
+
var n=Object.defineProperty;var r=(o,t)=>n(o,"name",{value:t,configurable:!0});const e=Symbol.for("@crouton-kit/crtr:held-deferred-inbox-prompt-join"),i=Symbol.for("@crouton-kit/crtr:broker-idle-turn-start"),u=Symbol.for("@crouton-kit/crtr:broker-run-turn-busy"),c=Symbol.for("@crouton-kit/crtr:broker-dispose-and-exit");function s(){const o=globalThis[c];return typeof o=="function"?o:void 0}r(s,"brokerDisposeAndExit");function b(){const o=globalThis[u];return typeof o=="function"&&o()}r(b,"brokerRunTurnBusy");function p(){const o=globalThis[e];return typeof o=="function"?o:void 0}r(p,"heldDeferredInboxPromptJoin");function d(){const o=globalThis[i];return typeof o=="function"?o:void 0}r(d,"brokerIdleTurnStart");export{c as BROKER_DISPOSE_AND_EXIT,i as BROKER_IDLE_TURN_START,u as BROKER_RUN_TURN_BUSY,e as HELD_DEFERRED_INBOX_PROMPT_JOIN,s as brokerDisposeAndExit,d as brokerIdleTurnStart,b as brokerRunTurnBusy,p as heldDeferredInboxPromptJoin};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { JobReportRequest } from '../../../api/dto/delivery.js';
|
|
2
|
+
/** Job output is reported in chunks of this size; the control plane stores one blob per chunk. */
|
|
3
|
+
export declare const JOB_OUTPUT_CHUNK_BYTES: number;
|
|
4
|
+
export type PostJobReport = (jobId: string, request: Omit<JobReportRequest, 'expected_execution_id'>) => Promise<void>;
|
|
5
|
+
export declare class JobReporter {
|
|
6
|
+
private readonly contextDir;
|
|
7
|
+
private readonly post;
|
|
8
|
+
/** What was last sent for each job, so an unchanged process identity or activity sample is not sent again. */
|
|
9
|
+
private readonly sent;
|
|
10
|
+
constructor(contextDir: string, post: PostJobReport);
|
|
11
|
+
/** One pass over this node's backgrounded jobs. Never throws: a failed report is retried on the next pass. */
|
|
12
|
+
tick(): Promise<void>;
|
|
13
|
+
private report;
|
|
14
|
+
/** Report the log from `offset` on: chunks already full are final, the one holding `offset` is sent again as it grows. */
|
|
15
|
+
private uploadOutput;
|
|
16
|
+
/** Run `tick` every couple of seconds until the process ends; returns the stop function. */
|
|
17
|
+
start(): () => void;
|
|
18
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var l=Object.defineProperty;var f=(o,t)=>l(o,"name",{value:t,configurable:!0});import{existsSync as p,readFileSync as m,readdirSync as v,statSync as x}from"node:fs";import{readFileBeneath as S,writeFileBeneath as b}from"../../spaces/open-beneath.js";import{bashJobPaths as _,bashJobsDir as w,isBashJobProcessConfirmedGone as J,isSafeBashJobId as O,readJobSupervisorState as y,signalBashJob as B}from"../../bash-jobs.js";import{ApiError as g}from"../../../api/errors.js";const c=64*1024,C=2e3;function R(o){try{const t=JSON.parse(S(o.root,o.jobReported).toString("utf8"));return{offset:Number.isSafeInteger(t.offset)?t.offset:0,done:t.done===!0}}catch{return{offset:0,done:!1}}}f(R,"readReported");function u(o,t){b(o.root,o.jobReported,JSON.stringify(t),{atomic:!0})}f(u,"writeReported");class A{static{f(this,"JobReporter")}contextDir;post;sent=new Map;constructor(t,i){this.contextDir=t,this.post=i}async tick(){let t;try{t=v(w(this.contextDir)).filter(O)}catch{return}for(const i of t)try{await this.report(i)}catch(n){n instanceof g&&(n.status===404||n.status===409)||process.stderr.write(`crtr: job ${i} report failed: ${n.message}
|
|
2
|
+
`)}}async report(t){const i=_(this.contextDir,t);if(!p(i.jobBg)||!p(i.cmdSh))return;const n=R(i);if(n.done)return;const e=y(this.contextDir,t),s=this.sent.get(t)??{};this.sent.set(t,s);try{const r={...e.pgid===void 0||e.pgid===s.pgid?{}:{pgid:e.pgid},...e.pgidIdentity===void 0||e.pgidIdentity===s.identity?{}:{pgid_identity:e.pgidIdentity}},d=e.activity===void 0?void 0:JSON.stringify(e.activity),a=e.activity===void 0||d===s.activity?{}:{activity:{last_ms:e.activity.lastActivityMs,sampled_ms:e.activity.sampledAtMs,files:e.activity.files}};(Object.keys(r).length>0||Object.keys(a).length>0)&&(await this.post(t,{...r,...a}),e.pgid!==void 0&&(s.pgid=e.pgid),e.pgidIdentity!==void 0&&(s.identity=e.pgidIdentity),s.activity=d);const h=e.exitCode===void 0&&J(e.pgid,e.pgidIdentity)&&y(this.contextDir,t).exitCode===void 0;n.offset=await this.uploadOutput(t,i,n.offset),u(i,n),(e.exitCode!==void 0||h)&&(await this.post(t,e.exitCode!==void 0?{exit_code:e.exitCode}:{vanished:!0}),u(i,{...n,done:!0}),this.sent.delete(t))}catch(r){if(!(r instanceof g&&r.code==="job_not_running"))throw r;const d=e.pgid,a=e.pgidIdentity;d!==void 0&&a!==void 0&&e.exitCode===void 0&&await B(d,a,void 0),u(i,{...n,done:!0}),this.sent.delete(t)}}async uploadOutput(t,i,n){let e;try{e=x(i.jobLog).size}catch{return n}if(e<=n)return n;const s=m(i.jobLog);for(let r=Math.floor(n/c);r*c<s.length;r++){const d=s.subarray(r*c,(r+1)*c);await this.post(t,{output:{seq:r,data_base64:d.toString("base64")}}),n=r*c+d.length}return n}start(){let t=!1;const i=setInterval(()=>{t||(t=!0,this.tick().finally(()=>{t=!1}))},C);return i.unref(),()=>clearInterval(i)}}export{c as JOB_OUTPUT_CHUNK_BYTES,A as JobReporter};
|
|
@@ -20,5 +20,8 @@ export declare function refusalRetryAt(message: {
|
|
|
20
20
|
* too. */
|
|
21
21
|
export declare function wireHistory(messages: Context['messages']): Context['messages'];
|
|
22
22
|
export declare function requestBody(model: Model<any>, context: Context, options: ModelsSimpleStreamOptions, intentOverride?: string): Record<string, unknown>;
|
|
23
|
+
/** The real response under a deferred-head framing (`daemon/api/deferred-head.ts`): the magic line, keep-alive
|
|
24
|
+
* blank lines, one JSON head line, then the body unchanged. Any other response is returned as it is. */
|
|
25
|
+
export declare function unwrapDeferredHead(response: Response): Promise<Response>;
|
|
23
26
|
/** One pi stream, backed exclusively by the authenticated daemon llm route. `intent` replaces the node's own `CRTR_MODEL_INTENT` for one stream: a background one-shot of an app-paid node asks for `app/light`, not the node's rung. */
|
|
24
27
|
export declare function streamBrokerModel(model: Model<any>, context: Context, options?: ModelsSimpleStreamOptions, intent?: string): AssistantMessageEventStream;
|
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
var
|
|
2
|
-
|
|
1
|
+
var j=Object.defineProperty;var c=(e,n)=>j(e,"name",{value:n,configurable:!0});import{setTimeout as W}from"node:timers/promises";import{createAssistantMessageEventStream as J,getCurrentSystemPrompt as Y,getCurrentTools as z}from"@earendil-works/pi-ai";import{socketFetch as G}from"../../../api/node-transport.js";import{DEFER_HEAD_REQUEST_HEADER as X,DEFERRED_HEAD_CONTENT_TYPE as K,DEFERRED_HEAD_MAGIC as Q}from"../../../daemon/api/deferred-head.js";import{apiSocketPath as V}from"../../canvas/paths.js";import{currentNodeToken as Z}from"./node-token.js";import{brokerApiUrl as C}from"./daemon-ops.js";import{currentCausedBy as ee}from"./turn-cause.js";import{envModelExact as N,envModelIntent as te}from"../../../shared/env.js";import{MODEL_CONTEXT_BODY_MAX_BYTES as v}from"../../llm/body-limits.js";import{modelRequestFromConfig as ne}from"../../model-routes.js";import{parseProviderRateLimit as re,providerFailureDiagnostic as A}from"../../provider-failure.js";import{UPSTREAM_MODEL_UNAVAILABLE as S}from"../../fault-classifier.js";function Ae(e,n){e.checkAuth=async t=>e.getProvider(t)?{type:"api_key"}:void 0,e.getAvailable=async t=>e.getModels(t),e.getAvailableSnapshot=()=>e.getModels(),e.streamSimple=(t,d,o)=>ue(t,d,o,n)}c(Ae,"configureBrokerModelRuntime");const oe=300,U="crtr:llm-refusal";class k extends Error{static{c(this,"LlmRefusalError")}retryAt;rateLimit;code;status;constructor(n,t,d,o,r){super(n),this.retryAt=t,this.rateLimit=d,this.code=o,this.status=r}}class T extends Error{static{c(this,"UpstreamModelUnavailableError")}}function q(e,n){const t=e===void 0?"the request body":`the request body (${e} bytes)`;return new Error(`request_too_large: ${t} exceeds the ${n}-byte model request limit; compact the conversation to shrink the context`)}c(q,"contextTooLargeError");function D(e){const n=e.details?.rate_limit;if(!n||typeof n!="object")return;const t=re(n);if(t===void 0)return;const{provider:d,model:o}=n;return typeof d=="string"&&d!==""&&typeof o=="string"&&o!==""?{...t,model:`${d}/${o}`}:t}c(D,"refusalRateLimit");function Se(e){for(const n of e.diagnostics??[]){if(n.type!==U)continue;const t=n.details?.retryAt;if(typeof t=="number"&&Number.isFinite(t)&&t>0)return t}}c(Se,"refusalRetryAt");class B extends Error{static{c(this,"ContentFilteredError")}}function F(e){return typeof e=="string"?e:e.map(n=>n.type==="text"?{type:"text",text:n.text}:{type:"image_url",image_url:{url:`data:${n.mimeType};base64,${n.data}`}})}c(F,"wireContent");function se(e){const n=c(o=>o.role==="assistant"&&(o.stopReason==="error"||o.stopReason==="aborted"),"incomplete"),t=e.some(n)?e.filter(o=>!n(o)):e;let d=t.length;for(;d>0&&t[d-1]?.role==="assistant";)d--;return d===t.length?t:t.slice(0,d)}c(se,"wireHistory");function ie(e,n,t,d){const o=[],r=Y(n.messages),a=z(n.messages);r?o.push({role:"system",content:r}):n.systemPrompt&&o.push({role:"system",content:n.systemPrompt});for(const f of se(n.messages))f.role==="user"?o.push({role:"user",content:F(f.content)}):f.role==="toolResult"?o.push({role:"tool",content:F(f.content),tool_call_id:f.toolCallId}):f.role==="assistant"&&o.push({role:"assistant",content:f.content.filter(i=>i.type==="text").map(i=>i.text).join("")||null,tool_calls:f.content.filter(i=>i.type==="toolCall").map(i=>({id:i.id,type:"function",function:{name:i.name,arguments:JSON.stringify(i.arguments)}}))});const _=`${e.provider}/${e.id}`,y=d??te();return{model:ne(_,y,N())?.kind==="logical"?y:_,model_policy:N()?"exact":"substitute",stream:!0,messages:o,...a.length?{tools:a.map(f=>({type:"function",function:{name:f.name,description:f.description,parameters:f.parameters}}))}:{},...t.reasoning?{reasoning_effort:t.reasoning}:{},...t.temperature!==void 0?{temperature:t.temperature}:{},...t.maxTokens!==void 0?{max_tokens:t.maxTokens}:{}}}c(ie,"requestBody");function L(e,n){if(typeof n!="string")return!1;const t=n.indexOf("/");return t<1||t===n.length-1?!1:(e.provider=n.slice(0,t),e.model=n.slice(t+1),!0)}c(L,"applyServedModel");function P(e){if(e.details?.served_model!==void 0)return e.details.served_model;const n=e.details?.rate_limit;return typeof n?.provider=="string"&&typeof n.model=="string"?`${n.provider}/${n.model}`:void 0}c(P,"refusalRoute");function H(e){if(!e||typeof e!="object"||!("error"in e))throw new Error("llm returned an invalid response");const n=e.error;if(!n||typeof n.message!="string")throw new Error("llm returned an invalid refusal");return n}c(H,"parseRefusal");function ae(){const e=C();return e===void 0?"http://localhost/v1/llm":new URL("/v1/llm",e).toString()}c(ae,"llmUrl");function le(){return C()===void 0?G(V()):globalThis.fetch}c(le,"llmFetch");async function ce(e){if(!e.headers.get("content-type")?.startsWith(K))return e;if(!e.body)throw new Error("deferred head response has no body");const n=e.body.getReader();let t=new Uint8Array(0),d=!1;for(;;){const o=t.indexOf(10);if(o<0){const{value:i,done:w}=await n.read();if(w)throw new Error("deferred head response ended before its head");const h=new Uint8Array(t.length+i.length);h.set(t),h.set(i,t.length),t=h;continue}const r=new TextDecoder().decode(t.subarray(0,o)).trim();if(t=t.subarray(o+1),!d){if(`${r}
|
|
2
|
+
`!==Q)throw new Error("deferred head response has no magic line");d=!0;continue}if(r==="")continue;const a=JSON.parse(r),_=new Headers;for(const[i,w]of Object.entries(a.headers))for(const h of Array.isArray(w)?w:[w])_.append(i,h);const y=t,f=new ReadableStream({start(i){y.length>0&&i.enqueue(y)},async pull(i){const{value:w,done:h}=await n.read();h?i.close():i.enqueue(w)},cancel(i){return n.cancel(i)}});return new Response(a.status===204?null:f,{status:a.status,headers:_})}}c(ce,"unwrapDeferredHead");function de(){const e=ee();return e===void 0?{}:{"crtr-caused-by":e}}c(de,"causedByHeader");function ue(e,n,t={},d){const o=J(),r={role:"assistant",content:[],api:e.api,provider:e.provider,model:e.id,usage:{input:0,output:0,cacheRead:0,cacheWrite:0,totalTokens:0,cost:{input:0,output:0,cacheRead:0,cacheWrite:0,total:0}},stopReason:"pending",timestamp:Date.now()};return(async()=>{const a=Z();if(!a)throw new Error("llm requires a node token");const _=JSON.stringify(ie(e,n,t,d)),y=Buffer.byteLength(_);if(y>v)throw q(y,v);let f=0;for(;;){t.signal?.throwIfAborted();const i=await ce(await le()(ae(),{method:"POST",headers:{authorization:`Bearer ${a}`,"content-type":"application/json",[X]:"1",...de()},body:_,signal:t.signal}));if(!i.ok){const u=H(await i.json());if(i.status===413||u.code==="payload_too_large")throw q(y,v);if(L(r,P(u)),u.retryable!==!0)throw new k(u.message,void 0,D(u),u.code,i.status);const s=u.retry_after_s;if(typeof s!="number"||!Number.isFinite(s)||s<=0)throw u.code===S?new T(u.message):new Error(u.message);const m=oe-f;if(s>m){const p=Date.now()+s*1e3;throw new k(`${u.message} (retry after ${s}s, at ${new Date(p).toISOString()})`,p,D(u))}await W(s*1e3,void 0,{signal:t.signal}),f+=s;continue}if(!i.body)throw new Error("llm returned no stream");o.push({type:"start",partial:r});const w=i.body.getReader(),h=new TextDecoder;let x="",b="stop",O,I=!1,M=!1;const $=c(u=>{const s=JSON.parse(u);if(s.error){const l=H(s);throw L(r,P(l)),l.retryable!==!0?new k(l.message,void 0,D(l),l.code):l.code===S?new T(l.message):new Error(l.message)}if(s.served_model){if(M=!0,s.served_model.indexOf("/")<1)throw new Error("llm returned an invalid served_model");L(r,s.served_model)}const m=s.choices?.[0],p=m?.delta;if(p?.reasoning_content){const l=r.content.findIndex(R=>R.type==="thinking"),g=l<0?{type:"thinking",thinking:""}:r.content[l],E=l<0?r.content.push(g)-1:l;if(l<0&&o.push({type:"thinking_start",contentIndex:E,partial:r}),g.type!=="thinking")throw new Error("invalid thinking block");g.thinking+=p.reasoning_content,o.push({type:"thinking_delta",contentIndex:E,delta:p.reasoning_content,partial:r})}if(p?.content){const l=r.content.findIndex(R=>R.type==="text"),g=l<0?{type:"text",text:""}:r.content[l],E=l<0?r.content.push(g)-1:l;if(l<0&&o.push({type:"text_start",contentIndex:E,partial:r}),g.type!=="text")throw new Error("invalid text block");g.text+=p.content,o.push({type:"text_delta",contentIndex:E,delta:p.content,partial:r})}for(const l of p?.tool_calls??[]){const g={type:"toolCall",id:l.id,name:l.function.name,arguments:JSON.parse(l.function.arguments)},E=r.content.push(g)-1;o.push({type:"toolcall_start",contentIndex:E,partial:r}),o.push({type:"toolcall_end",contentIndex:E,toolCall:g,partial:r})}m?.finish_reason&&(b=m.finish_reason),m?.message?.refusal&&(O=m.message.refusal),s.usage&&(I=!0,r.usage={input:s.usage.prompt_tokens,output:s.usage.completion_tokens,cacheRead:s.usage.cache_read_tokens,cacheWrite:s.usage.cache_write_tokens,totalTokens:s.usage.total_tokens,cost:{input:0,output:0,cacheRead:0,cacheWrite:0,total:typeof s.usage.usd_equivalent=="number"&&Number.isFinite(s.usage.usd_equivalent)?s.usage.usd_equivalent:0}})},"apply");for(;;){const{value:u,done:s}=await w.read();if(s)break;x+=h.decode(u,{stream:!0});let m;for(;(m=x.indexOf(`
|
|
3
|
+
`))>=0;){const p=x.slice(0,m).trim();x=x.slice(m+1),p&&$(p)}}if(x+=h.decode(),x.trim()&&$(x.trim()),!I||!M)throw new Error("llm stream ended without usage or served_model");for(const[u,s]of r.content.entries())s.type==="text"&&o.push({type:"text_end",contentIndex:u,content:s.text,partial:r}),s.type==="thinking"&&o.push({type:"thinking_end",contentIndex:u,content:s.thinking,partial:r});if(b==="content_filter")throw new B(O??"Content filtered");if(!["stop","tool_calls","length"].includes(b))throw new Error(`llm returned unknown finish reason: ${b}`);r.stopReason=b==="tool_calls"?"toolUse":b==="length"?"length":"stop",o.push({type:"done",reason:r.stopReason,message:r}),o.end();return}})().catch(a=>{r.stopReason=t.signal?.aborted?"aborted":"error",r.errorMessage=a instanceof Error?a.message:String(a),a instanceof k&&(r.diagnostics=[{type:U,timestamp:Date.now(),...a.retryAt!==void 0?{details:{retryAt:a.retryAt}}:{}},...a.rateLimit!==void 0?[A({status:429,ratelimit:a.rateLimit})]:[],...a.rateLimit===void 0&&a.code==="cap_exhausted"?[A({status:a.status??402,code:a.code})]:[]]),a instanceof T&&(r.diagnostics=[A({status:503,code:S})]),a instanceof B&&r.stopReason==="error"&&(r.rawStopReason="content_filter"),o.push({type:"error",reason:r.stopReason,error:r}),o.end()}),o}c(ue,"streamBrokerModel");export{oe as LLM_BROKER_RETRY_WINDOW_S,U as LLM_REFUSAL_DIAGNOSTIC,Ae as configureBrokerModelRuntime,Se as refusalRetryAt,ie as requestBody,ue as streamBrokerModel,ce as unwrapDeferredHead,se as wireHistory};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var a=Object.defineProperty;var s=(i,t)=>a(i,"name",{value:t,configurable:!0});import{
|
|
1
|
+
var a=Object.defineProperty;var s=(i,t)=>a(i,"name",{value:t,configurable:!0});import{daemonClient as o}from"./daemon-ops.js";import{ApiError as n}from"../../../api/errors.js";const h=Symbol.for("@crouton-kit/crtr:broker-signal-client");class l{static{s(this,"BrokerSignalClient")}stateValue="disconnected";latestNodeValue;listeners=new Map;controller;retryTimer;heartbeatTimer;retryMs=250;running=!1;nodeId;executionId;get state(){return this.stateValue}get latestNode(){return this.latestNodeValue}subscribe(t,r){let e=this.listeners.get(t);return e||(e=new Set,this.listeners.set(t,e)),e.add(r),(t==="state"||t==="resync"&&this.stateValue==="connected"||t==="node"&&this.latestNodeValue!==void 0)&&r(),()=>{e.delete(r)}}start(t,r){if(this.running){if(this.nodeId===t&&this.executionId===r)return;this.stop()}this.nodeId=t,this.executionId=r,this.running=!0,this.retryMs=250,this.connect()}stop(){this.running=!1,this.controller?.abort(),this.controller=void 0,this.clearTimers(),this.setState("stopped")}emit(t){for(const r of this.listeners.get(t)??[])try{r()}catch{}}setState(t){this.stateValue!==t&&(this.stateValue=t,this.emit("state"))}clearTimers(){this.retryTimer&&clearTimeout(this.retryTimer),this.heartbeatTimer&&clearTimeout(this.heartbeatTimer),this.retryTimer=this.heartbeatTimer=void 0}armHeartbeat(t){this.heartbeatTimer&&clearTimeout(this.heartbeatTimer),this.heartbeatTimer=setTimeout(()=>t.abort(),35e3),this.heartbeatTimer.unref?.()}connect(){if(!this.running||!this.nodeId||!this.executionId)return;const t=new AbortController;this.controller=t,(async()=>{try{for await(const e of o().getBrokerSignals(this.nodeId,this.executionId,{signal:t.signal,maxRetries:0})){if(!this.running||this.controller!==t)return;this.armHeartbeat(t),this.handleLine(e)}}catch(e){if(!this.running||this.controller!==t)return;if(e instanceof n&&(e.status===404||e.status===405)){this.clearTimers(),this.controller=void 0,this.setState("unsupported");return}if(e instanceof n&&e.status===409){this.stop();return}}if(!this.running||this.controller!==t)return;this.controller=void 0,this.clearTimers(),this.setState("disconnected");const r=Math.round(this.retryMs*(.8+Math.random()*.4));this.retryMs=Math.min(this.retryMs*2,5e3),this.retryTimer=setTimeout(()=>{this.retryTimer=void 0,this.connect()},r),this.retryTimer.unref?.()})()}handleLine(t){switch(t.type){case"hello":if(t.execution_id!==this.executionId){this.stop();return}this.retryMs=250,this.latestNodeValue=t.node,this.setState("connected"),this.emit("node"),this.emit("resync");break;case"mail":this.emit("mail");break;case"node":this.latestNodeValue=t.node,this.emit("node");break;case"fault-retry":this.emit("fault-retry");break;case"ping":break}}}function m(){const i=globalThis;return i[h]??=new l}s(m,"brokerSignalClient");export{l as BrokerSignalClient,m as brokerSignalClient};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { MailEntryDTO } from '../../../api/dto/mail.js';
|
|
2
|
+
/** A message whose body overflowed the digest carries the full text in its row (`data.body_full`) and names a path as
|
|
3
|
+
* its `ref`. The broker writes the text at that path in its own filesystem so the agent reads it as it always has,
|
|
4
|
+
* and drops the copy from the entry it renders. */
|
|
5
|
+
export declare function materializeSpilledBody(entry: MailEntryDTO): MailEntryDTO;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var t=Object.defineProperty;var f=(i,r)=>t(i,"name",{value:r,configurable:!0});import{mkdirSync as d,writeFileSync as l}from"node:fs";import{dirname as o}from"node:path";function c(i){const r=i.data?.body_full;if(typeof r!="string"||i.ref===void 0||!i.ref.startsWith("/"))return i;d(o(i.ref),{recursive:!0}),l(i.ref,r,"utf8");const{body_full:a,...e}=i.data;return{...i,data:e}}f(c,"materializeSpilledBody");export{c as materializeSpilledBody};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/** Post the broker's tool-group summaries and/or consolidated turn replies, whole, to the node's row. */
|
|
2
|
+
export declare function putBrokerSummaries(nodeId: string, records: {
|
|
3
|
+
tool_summaries?: Record<string, unknown>;
|
|
4
|
+
turn_replies?: Record<string, unknown>;
|
|
5
|
+
}): Promise<void>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var t=Object.defineProperty;var o=(e,r)=>t(e,"name",{value:r,configurable:!0});import{brokerExecutionId as i,daemonClient as u}from"./daemon-ops.js";function d(e,r){return u().putNodeSummaries(e,{...r,expected_execution_id:i()})}o(d,"putBrokerSummaries");export{d as putBrokerSummaries};
|
|
@@ -2,6 +2,7 @@ import { type ToolGroupSummary } from '../../../shared/tool-groups.js';
|
|
|
2
2
|
import type { BrokerToClient } from '../broker-protocol.js';
|
|
3
3
|
/** Owns transcript tool-group state and its durable summary sidecars. */
|
|
4
4
|
export declare class ToolGroupTracker {
|
|
5
|
+
private readonly nodeId;
|
|
5
6
|
private readonly broadcast;
|
|
6
7
|
private readonly toolSummariesPath;
|
|
7
8
|
private readonly pendingToolSummaryPath;
|
|
@@ -14,6 +15,8 @@ export declare class ToolGroupTracker {
|
|
|
14
15
|
private lastToolGroupBoundaryProse;
|
|
15
16
|
private sawAssistantProse;
|
|
16
17
|
constructor(nodeId: string, broadcast: (frame: BrokerToClient) => void);
|
|
18
|
+
/** The control plane reads a dormant node's summaries from its row; a failed post only withholds them there. */
|
|
19
|
+
private postSummaries;
|
|
17
20
|
summaries(): Record<string, ToolGroupSummary>;
|
|
18
21
|
resetForSession(): void;
|
|
19
22
|
finishOpenToolGroup(settleInterruptedTools?: boolean): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var T=Object.defineProperty;var
|
|
1
|
+
var T=Object.defineProperty;var m=(a,e)=>T(a,"name",{value:e,configurable:!0});import{existsSync as S,unlinkSync as p}from"node:fs";import{join as h}from"node:path";import{nodeRunJobDir as y}from"../../canvas/paths.js";import{readConfig as G}from"../../config.js";import{emitEvent as u}from"../../events/emit.js";import{atomicWriteJson as f,readJsonIfExists as d}from"../../fs-utils.js";import{assistantVisibleText as k,isGroupBoundaryKind as _,isTrueUserMessage as P,normalizeToolGroupSummaryRecord as b}from"../../../shared/tool-groups.js";import{generatedContextText as g,parseCard as I}from"../../../shared/generated-context.js";import{headlessToolGroupSummary as w,serializeToolGroup as A}from"../tool-group-summary.js";import{putBrokerSummaries as C}from"./summaries-post.js";const E=1e3,O=1e4;function c(a){if(a===null||typeof a!="object"||Array.isArray(a))return null;const e=a;return Object.keys(e).sort().join(",")!=="key,segment,version"||e.version!==1||typeof e.key!="string"||typeof e.segment!="string"||e.key.length===0||e.key.length>E||e.segment.length===0||e.segment.length>O?null:{version:1,key:e.key,segment:e.segment}}m(c,"normalizePendingToolGroupSummary");class Y{static{m(this,"ToolGroupTracker")}nodeId;broadcast;toolSummariesPath;pendingToolSummaryPath;toolGroupSummaries=new Map;summaryAttempted;generatingToolGroups=new Map;toolGroupsByCallId=new Map;summaryTasks=new Set;openToolGroup;lastToolGroupBoundaryProse="";sawAssistantProse=!1;constructor(e,o){this.nodeId=e,this.broadcast=o,this.toolSummariesPath=h(y(e),"tool-summaries.json"),this.pendingToolSummaryPath=h(y(e),"pending-tool-summary.json");try{const s=d(this.toolSummariesPath);for(const[i,n]of Object.entries(b(s)))this.toolGroupSummaries.set(i,n)}catch{}this.summaryAttempted=new Set(this.toolGroupSummaries.keys()),this.resumePendingSummary()}postSummaries(e){C(this.nodeId,{tool_summaries:e}).catch(o=>{u({level:"warn",event:"broker.runtime.diagnostic",fields:{message:`failed to post tool summaries: ${o instanceof Error?o.message:String(o)}`}})})}summaries(){return Object.fromEntries(this.toolGroupSummaries)}resetForSession(){this.openToolGroup=void 0,this.toolGroupsByCallId.clear(),this.sawAssistantProse=!1}finishOpenToolGroup(e=!1){const o=this.openToolGroup;if(this.openToolGroup=void 0,o!==void 0){if(o.closed=!0,e){for(const s of o.pendingToolIds)this.toolGroupsByCallId.delete(s);o.pendingToolIds.clear()}o.summarizeWhenSettled=G("user").summarize_tool_calls,this.generateSettledToolGroup(o)}}observeToolGroupEvent(e){if(e.type==="compaction_end"||e.type==="auto_retry_end"&&e.success!==!0){this.finishOpenToolGroup();return}if(e.type==="message_end"){const t=e.message;if(t!==null&&typeof t=="object"){const r=t;r.role==="assistant"&&(r.stopReason==="aborted"||r.stopReason==="error")&&this.finishOpenToolGroup(!0)}return}if(e.type==="tool_execution_start"){const t=this.ensureOpenToolGroup(),r=typeof e.toolCallId=="string"?e.toolCallId:"";t.key===void 0&&r!==""&&(t.key=r),r!==""&&(t.pendingToolIds.add(r),this.toolGroupsByCallId.set(r,t)),t.toolCount+=1,t.pieces.push({type:"tool",name:typeof e.toolName=="string"?e.toolName:"tool",args:e.args});return}if(e.type==="tool_execution_end"){const t=typeof e.toolCallId=="string"?e.toolCallId:"",r=t===""?this.openToolGroup:this.toolGroupsByCallId.get(t);r!==void 0&&(r.pieces.push({type:"result",name:typeof e.toolName=="string"?e.toolName:"tool",result:e.result,isError:e.isError===!0}),t!==""&&(r.pendingToolIds.delete(t),this.toolGroupsByCallId.delete(t)),this.generateSettledToolGroup(r));return}if(e.type!=="message_start"&&e.type!=="message_update")return;const o=e.message;if(o===null||typeof o!="object")return;const s=o;if(s.role==="assistant"){e.type==="message_start"&&(this.sawAssistantProse=!1);const t=k(s);!this.sawAssistantProse&&t.trim()!==""&&(this.sawAssistantProse=!0,this.visibleBoundary(t));return}if(e.type!=="message_start")return;if(s.role==="compactionSummary"||s.role==="branchSummary"||s.role==="bashExecution"||s.role==="status"||s.role==="error"||s.customType==="crtr-cycle-divider"){this.finishOpenToolGroup();return}if(P(s)){this.visibleBoundary(g(s));return}if(s.display===!1)return;const i=g(s),n=I(s);if(n!==null&&_(n.kind)){this.visibleBoundary(i);return}const l=this.ensureOpenToolGroup();i!==""&&l.pieces.push({type:"text",text:i})}persistPendingSummary(){const e=[...this.generatingToolGroups.values()].at(-1);if(e!==void 0)try{f(this.pendingToolSummaryPath,e)}catch(o){u({level:"warn",event:"broker.runtime.diagnostic",fields:{message:`failed to persist pending tool summary: ${o instanceof Error?o.message:String(o)}`}})}}hasSummaryTasks(){return this.summaryTasks.size>0}waitForSummaryTasks(){return Promise.allSettled([...this.summaryTasks])}ensureOpenToolGroup(){return this.openToolGroup===void 0&&(this.openToolGroup={toolCount:0,pieces:[],boundaryProse:this.lastToolGroupBoundaryProse,pendingToolIds:new Set,closed:!1,summarizeWhenSettled:!1}),this.openToolGroup}visibleBoundary(e){this.finishOpenToolGroup(),this.lastToolGroupBoundaryProse=e}clearPendingToolGroupSummary(e){try{const o=c(d(this.pendingToolSummaryPath));o?.key===e.key&&o.segment===e.segment&&p(this.pendingToolSummaryPath)}catch{}}generateToolGroupSummary(e){const{key:o,segment:s}=e;if(this.summaryAttempted.has(o)||this.generatingToolGroups.has(o))return;this.summaryAttempted.add(o),this.generatingToolGroups.set(o,e);let i;i=w(s).then(n=>{if(n!==null){this.toolGroupSummaries.set(o,n);try{const l=Object.fromEntries(this.toolGroupSummaries);f(this.toolSummariesPath,l),this.postSummaries(l)}catch{this.toolGroupSummaries.delete(o);return}this.clearPendingToolGroupSummary(e),this.broadcast({type:"tool_group_summary",key:o,summary:n})}}).catch(()=>{}).finally(()=>{this.generatingToolGroups.delete(o),this.summaryTasks.delete(i)}),this.summaryTasks.add(i)}generateSettledToolGroup(e){!e.closed||e.pendingToolIds.size>0||e.key===void 0||!e.summarizeWhenSettled||this.generateToolGroupSummary({version:1,key:e.key,segment:A(e.boundaryProse,e.pieces)})}resumePendingSummary(){try{const e=c(d(this.pendingToolSummaryPath));e===null?S(this.pendingToolSummaryPath)&&(p(this.pendingToolSummaryPath),u({level:"warn",event:"broker.startup.warning",fields:{stage:"pending_tool_summary",message:"removed an invalid pending tool summary"}})):this.toolGroupSummaries.has(e.key)?p(this.pendingToolSummaryPath):this.generateToolGroupSummary(e)}catch(e){u({level:"warn",event:"broker.startup.warning",fields:{stage:"pending_tool_summary",message:e instanceof Error?e.message:String(e)}})}}}export{Y as ToolGroupTracker};
|
|
@@ -19,6 +19,7 @@ export interface TurnReplyTrackerOptions {
|
|
|
19
19
|
* and the viewer — which honours a rewrite only when all its sources are still
|
|
20
20
|
* in the turn — falls back to showing every message verbatim. */
|
|
21
21
|
export declare class TurnReplyTracker {
|
|
22
|
+
private readonly nodeId;
|
|
22
23
|
private readonly broadcast;
|
|
23
24
|
private readonly path;
|
|
24
25
|
private readonly replies;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var l=Object.defineProperty;var a=(n,e)=>l(n,"name",{value:e,configurable:!0});import{join as m}from"node:path";import{nodeRunJobDir as y}from"../../canvas/paths.js";import{readConfig as k}from"../../config.js";import{emitEvent as h}from"../../events/emit.js";import{atomicWriteJson as g,readJsonIfExists as b}from"../../fs-utils.js";import{assistantVisibleText as T,isTrueUserMessage as p}from"../../../shared/tool-groups.js";import{generatedContextText as d}from"../../../shared/generated-context.js";import{isSettledAssistant as x,messageKey as u,normalizeTurnReplyRecord as w,START_TURN_KEY as f}from"../../../shared/turn-replies.js";import{headlessTurnReply as S}from"../turn-reply-summary.js";import{putBrokerSummaries as _}from"./summaries-post.js";function c(n,e){return n!==void 0&&n.sources.length===e.length&&n.sources.every((s,t)=>s===e[t].key)}a(c,"sameSources");class C{static{a(this,"TurnReplyTracker")}nodeId;broadcast;path;replies=new Map;tasks=new Set;turn={key:f,userText:"",prose:[]};inFlight;queued;epoch=0;generate;enabled;constructor(e,s,t={}){this.nodeId=e,this.broadcast=s,this.generate=t.generate??S,this.enabled=t.enabled??(()=>k("user").consolidate_replies),this.path=m(y(e),"turn-replies.json");try{for(const[i,r]of Object.entries(w(b(this.path))))this.replies.set(i,r)}catch{}}snapshot(){return Object.fromEntries(this.replies)}seed(e){this.epoch+=1,this.queued=void 0;let s={key:f,userText:"",prose:[]};for(const t of e){if(t===null||typeof t!="object")continue;const i=t;if(p(i)){const o=u(i);o!==void 0&&(s={key:o,userText:d(i),prose:[]});continue}const r=this.proseOf(i);r!==void 0&&s.prose.push(r)}this.turn=s,this.maybeGenerate()}observe(e){if(e.type!=="message_start"&&e.type!=="message_end")return;const s=e.message;if(s===null||typeof s!="object")return;const t=s;if(e.type==="message_start"){if(!p(t))return;const r=u(t);r!==void 0&&r!==this.turn.key&&(this.turn={key:r,userText:d(t),prose:[]});return}const i=this.proseOf(t);i===void 0||this.turn.prose.some(r=>r.key===i.key)||(this.turn.prose.push(i),this.maybeGenerate())}hasTasks(){return this.tasks.size>0}async waitForTasks(){for(;this.tasks.size>0;)await Promise.allSettled([...this.tasks])}proseOf(e){if(e.role!=="assistant"||!x(e))return;const s=T(e).trim(),t=u(e);return s===""||t===void 0?void 0:{key:t,text:s}}maybeGenerate(){const{key:e,userText:s,prose:t}=this.turn;if(t.length<2||!this.enabled()||c(this.replies.get(e),t))return;const i={key:e,userText:s,prose:[...t],epoch:this.epoch};if(this.inFlight!==void 0){this.queued=i;return}this.run(i)}run(e){this.inFlight=e;let s;s=this.generate(e.userText,e.prose.map(t=>t.text)).then(t=>{if(t===null||e.epoch!==this.epoch)return;const i={version:1,sources:e.prose.map(r=>r.key),text:t};this.replies.set(e.key,i);try{const r=Object.fromEntries(this.replies);g(this.path,r),_(this.nodeId,{turn_replies:r}).catch(o=>{h({level:"warn",event:"broker.runtime.diagnostic",fields:{message:`failed to post turn replies: ${o instanceof Error?o.message:String(o)}`}})})}catch(r){h({level:"warn",event:"broker.runtime.diagnostic",fields:{message:`failed to persist turn reply: ${r instanceof Error?r.message:String(r)}`}})}this.broadcast({type:"turn_reply",key:e.key,reply:i})}).catch(()=>{}).finally(()=>{this.tasks.delete(s),this.inFlight=void 0;const t=this.queued;this.queued=void 0,t!==void 0&&!c(this.replies.get(t.key),t.prose)&&this.run(t)}),this.tasks.add(s)}}export{C as TurnReplyTracker};
|