@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,2 +1,2 @@
|
|
|
1
|
-
var N=Object.defineProperty;var c=(t,n)=>N(t,"name",{value:n,configurable:!0});import{existsSync as D}from"node:fs";import{readFile as B,writeFile as q}from"node:fs/promises";import{join as R}from"node:path";import{emitEvent as K}from"../../events/emit.js";import{exportRepo as G,importTree as J,pendingPaths as Q}from"./exchange.js";import{checkoutChain as V}from"./identity.js";import{checkoutsForCwd as X,reposForCwd as Y,warmCheckoutIdentities as Z}from"./repos.js";import{commitTree as S,fetchDocs as ee,FIRST_FETCH_MARKER as te,isAncestor as I,mergeBase as ne,openMirror as b,pushDocs as re,readTree as m,remoteDocsTip as ae,resolveRef as h,setRef as y}from"./mirror.js";import{mergeTrees as ie}from"./ref-format.js";import{withCanvasWrite as se}from"../../canvas/db.js";import{filterAsync as oe}from"../../async-array.js";const ce=2e4,L=3,A="remote-url",w="refs/crtr/docs",fe="refs/crtr/remote-docs",g="refs/crtr/imported";function v(t){try{K(t)}catch{}}c(v,"emitEvent");let T=null;const M=new Map,H=new Set;async function Me(t,n){T={lifecycle:t,db:n}}c(Me,"startRepoSync");async function P(t,n){return n.type!=="repo"?!1:await t.prepare("SELECT 1 FROM identities WHERE object = ? AND scheme = 'git'").get(n.id)!==void 0}c(P,"gitScheme");async function U(t,n){const e=new Map;for(const f of n)for(const a of V(f))a.ok&&a.scheme==="git"&&e.set(a.externalId,a.remoteUrl);if(e.size===0)return;const r=(await T.db()).prepare("SELECT external_id FROM identities WHERE object = ? AND scheme = 'git'");for(const f of t){const a=await r.get(f.id),s=a&&e.get(a.external_id);if(!s)continue;const i=await b(f.id);await q(R(i.dir,A),`${s}
|
|
2
|
-
`)}}c(U,"recordRemoteUrls");async function de(t,n){const o=await E().db(),r=await oe(t,async i=>await P(o,i));if(r.length===0)return;await U(r,[n]);const f=[];for(const i of r){const l=!H.has(i.id)&&!D(R((await b(i.id)).dir,te)),u=k(i);l&&u&&f.push(u)}if(f.length===0)return;let a;const s=new Promise(i=>{a=setTimeout(i,ce)});await Promise.race([Promise.all(f),s]),clearTimeout(a)}c(de,"noteNodeWorking");async function _e(t){try{const n=await E().db(),e=await n.prepare("SELECT cwd FROM nodes WHERE node_id = ?").get(t);if(!e)return;Z(e.cwd);const o=await se(async()=>await Y(n,e.cwd));o.length>0&&await de(o,e.cwd)}catch(n){v({level:"warn",event:"repo_sync.failed",outcome:"failed",error:n,node_id:t,fields:{step:"fetch",reason:`the boot trigger failed: ${n instanceof Error?n.message:String(n)}`}})}}c(_e,"noteNodeBooting");async function xe(t,n=[]){const e=E();if(!await P(await e.db(),t))return;if(n.length===0){k(t);return}const o=U([t],n).then(()=>{k(t)},r=>{v({level:"error",event:"repo_sync.failed",error:r,fields:{repo:t.name,step:"fetch",reason:"recording the remote URL failed"}})});e.lifecycle.registerDetached(o)}c(xe,"noteRepoDocumentsChanged");function E(){if(!T)throw new Error("repo sync is not started: crtrd must call startRepoSync first");return T}c(E,"requireEngine");function k(t){const n=E(),e=M.get(t.id)??{running:null,again:!1};if(M.set(t.id,e),e.running)return e.again=!0,e.running.then(()=>M.get(t.id)?.running??null).then(r=>r??{ok:!0,pushed:!1,imported:$()});if(!n.lifecycle.acceptsDetachedWork())return null;H.add(t.id);const o=ue(t).then(r=>(W(t,r),r),r=>{const f={ok:!1,step:"export",reason:r instanceof Error?r.message:String(r)};return W(t,f),f}).finally(()=>{e.running=null,e.again&&(e.again=!1,k(t))});return e.running=o,n.lifecycle.registerDetached(o.then(()=>{})),o}c(k,"schedule");function W(t,n){if(n.ok){const e=n.imported;v({level:"info",event:"repo_sync.completed",outcome:"succeeded",fields:{repo:t.name,pushed:n.pushed,created:e.created,revisions:e.revisions,deleted:e.deleted,needs_merge:e.needsMerge,refused:e.refused}})}else v({level:"warn",event:"repo_sync.failed",outcome:"failed",fields:{repo:t.name,step:n.step,reason:n.reason}})}c(W,"report");function $(){return{created:0,revisions:0,deleted:0,needsMerge:[],refused:[]}}c($,"emptyImport");class _ extends Error{static{c(this,"StepError")}step;constructor(n,e){super(e),this.step=n}}async function x(t,n){try{return await n()}catch(e){throw e instanceof _?e:new _(t,e instanceof Error?e.message:String(e))}}c(x,"step");async function ue(t){const n=E();try{const e=await b(t.id),o=await le(e);if(o===null)return{ok:!1,step:"fetch",reason:`no checkout of ${t.name} with an origin remote has been seen by this runtime`};let r=$();const f=c(()=>x("import",async()=>{const a=await h(e,w),s=await h(e,g);if(a===null||s===a)return;const i=s?await m(e,g):new Map,l=await n.db(),u=await m(e,w),d=await J(l,t,i,u,async p=>await X(l,p));r={created:r.created+d.created,revisions:r.revisions+d.revisions,deleted:r.deleted+d.deleted,needsMerge:[...new Set([...r.needsMerge,...d.needsMerge])],refused:[...r.refused,...d.refused]},await j(e,a,u,i,new Set(d.refused.map(p=>p.path)),s)}),"importLocal");await f(),await x("export",async()=>{const a=await h(e,w),s=a?await m(e,w):null,i=await h(e,g),l=i?await m(e,g):null,u=await G(await n.db(),t,s,l);if(a?z(s,u):u.size===0)return;const d=await S(e,u,a?[a]:[],`crtr: export ${t.name}`);await y(e,w,d,a),await j(e,d,u,l??new Map,new Set(Q(s,l)),i)});for(let a=1;;a++){const s=await ae(e,o);if(!s.ok)return{ok:!1,step:"fetch",reason:s.reason};let i=await h(e,w);if(s.value!==null&&!(i&&await we(e,s.value)&&await I(e,s.value,i))){const u=await ee(e,o);if(!u.ok)return{ok:!1,step:"fetch",reason:u.reason};const d=u.value;i=await x("merge",async()=>{if(!i||await I(e,i,d))return await y(e,w,d,i),d;const p=await ne(e,i,d),C=ie(p?await m(e,p):new Map,await m(e,w),await m(e,fe));for(const O of C.refused)r.refused.push(O);const F=await S(e,C.tree,[i,d],`crtr: merge ${t.name}`);return await y(e,w,F,i),F})}if(await f(),i===null||i===s.value)return{ok:!0,pushed:!1,imported:r};const l=await re(e,o,i);if(l.ok)return{ok:!0,pushed:!0,imported:r};if(l.reason!=="rejected")return{ok:!1,step:"push",reason:l.reason};if(a>=L)return{ok:!1,step:"push",reason:`push rejected ${L} times`}}}catch(e){if(e instanceof _)return{ok:!1,step:e.step,reason:e.message};throw e}}c(ue,"syncRepo");async function j(t,n,e,o,r,f){if(r.size===0){await y(t,g,n,f);return}const a=new Map(e);for(const s of r)o.has(s)?a.set(s,o.get(s)):a.delete(s);f!==null&&z(o,a)||await y(t,g,await S(t,a,[],"crtr: imported baseline (some files pending)"),f)}c(j,"advanceImported");async function le(t){const n=R(t.dir,A);return D(n)&&(await B(n,"utf8")).trim()||null}c(le,"readUrl");async function we(t,n){return await h(t,n)!==null}c(we,"hasCommit");function z(t,n){if(t.size!==n.size)return!1;for(const[e,o]of t)if(n.get(e)!==o)return!1;return!0}c(z,"sameTree");export{ce as FIRST_FETCH_WAIT_MS,_e as noteNodeBooting,de as noteNodeWorking,xe as noteRepoDocumentsChanged,Me as startRepoSync,ue as syncRepo};
|
|
1
|
+
var N=Object.defineProperty;var c=(t,n)=>N(t,"name",{value:n,configurable:!0});import{existsSync as D}from"node:fs";import{readFile as B,writeFile as q}from"node:fs/promises";import{join as R}from"node:path";import{emitEvent as K}from"../../events/emit.js";import{exportRepo as G,importTree as J,pendingPaths as Q}from"./exchange.js";import{checkoutChain as V}from"./identity.js";import{checkoutsForCwd as X,reposForCwd as Y,warmCheckoutIdentities as Z}from"./repos.js";import{commitTree as S,fetchDocs as ee,FIRST_FETCH_MARKER as te,isAncestor as I,mergeBase as ne,openMirror as b,pushDocs as re,readTree as m,remoteDocsTip as ae,resolveRef as h,setRef as y}from"./mirror.js";import{mergeTrees as ie}from"./ref-format.js";import{withCanvasWrite as se}from"../../canvas/db.js";import{filterAsync as oe}from"../../async-array.js";const ce=2e4,L=3,A="remote-url",w="refs/crtr/docs",fe="refs/crtr/remote-docs",g="refs/crtr/imported";function v(t){try{K(t)}catch{}}c(v,"emitEvent");let T=null;const M=new Map,H=new Set;async function Me(t,n){T={lifecycle:t,db:n}}c(Me,"startRepoSync");async function P(t,n){return n.type!=="repo"?!1:await t.prepare("SELECT 1 FROM identities WHERE object = ? AND scheme = 'git'").get(n.id)!==void 0}c(P,"gitScheme");async function U(t,n){const e=new Map;for(const f of n)for(const a of await V(f))a.ok&&a.scheme==="git"&&e.set(a.externalId,a.remoteUrl);if(e.size===0)return;const r=(await T.db()).prepare("SELECT external_id FROM identities WHERE object = ? AND scheme = 'git'");for(const f of t){const a=await r.get(f.id),s=a&&e.get(a.external_id);if(!s)continue;const i=await b(f.id);await q(R(i.dir,A),`${s}
|
|
2
|
+
`)}}c(U,"recordRemoteUrls");async function de(t,n){const o=await E().db(),r=await oe(t,async i=>await P(o,i));if(r.length===0)return;await U(r,[n]);const f=[];for(const i of r){const l=!H.has(i.id)&&!D(R((await b(i.id)).dir,te)),u=k(i);l&&u&&f.push(u)}if(f.length===0)return;let a;const s=new Promise(i=>{a=setTimeout(i,ce)});await Promise.race([Promise.all(f),s]),clearTimeout(a)}c(de,"noteNodeWorking");async function _e(t){try{const n=await E().db(),e=await n.prepare("SELECT cwd FROM nodes WHERE node_id = ?").get(t);if(!e)return;await Z(e.cwd);const o=await se(async()=>await Y(n,e.cwd));o.length>0&&await de(o,e.cwd)}catch(n){v({level:"warn",event:"repo_sync.failed",outcome:"failed",error:n,node_id:t,fields:{step:"fetch",reason:`the boot trigger failed: ${n instanceof Error?n.message:String(n)}`}})}}c(_e,"noteNodeBooting");async function xe(t,n=[]){const e=E();if(!await P(await e.db(),t))return;if(n.length===0){k(t);return}const o=U([t],n).then(()=>{k(t)},r=>{v({level:"error",event:"repo_sync.failed",error:r,fields:{repo:t.name,step:"fetch",reason:"recording the remote URL failed"}})});e.lifecycle.registerDetached(o)}c(xe,"noteRepoDocumentsChanged");function E(){if(!T)throw new Error("repo sync is not started: crtrd must call startRepoSync first");return T}c(E,"requireEngine");function k(t){const n=E(),e=M.get(t.id)??{running:null,again:!1};if(M.set(t.id,e),e.running)return e.again=!0,e.running.then(()=>M.get(t.id)?.running??null).then(r=>r??{ok:!0,pushed:!1,imported:$()});if(!n.lifecycle.acceptsDetachedWork())return null;H.add(t.id);const o=ue(t).then(r=>(W(t,r),r),r=>{const f={ok:!1,step:"export",reason:r instanceof Error?r.message:String(r)};return W(t,f),f}).finally(()=>{e.running=null,e.again&&(e.again=!1,k(t))});return e.running=o,n.lifecycle.registerDetached(o.then(()=>{})),o}c(k,"schedule");function W(t,n){if(n.ok){const e=n.imported;v({level:"info",event:"repo_sync.completed",outcome:"succeeded",fields:{repo:t.name,pushed:n.pushed,created:e.created,revisions:e.revisions,deleted:e.deleted,needs_merge:e.needsMerge,refused:e.refused}})}else v({level:"warn",event:"repo_sync.failed",outcome:"failed",fields:{repo:t.name,step:n.step,reason:n.reason}})}c(W,"report");function $(){return{created:0,revisions:0,deleted:0,needsMerge:[],refused:[]}}c($,"emptyImport");class _ extends Error{static{c(this,"StepError")}step;constructor(n,e){super(e),this.step=n}}async function x(t,n){try{return await n()}catch(e){throw e instanceof _?e:new _(t,e instanceof Error?e.message:String(e))}}c(x,"step");async function ue(t){const n=E();try{const e=await b(t.id),o=await le(e);if(o===null)return{ok:!1,step:"fetch",reason:`no checkout of ${t.name} with an origin remote has been seen by this runtime`};let r=$();const f=c(()=>x("import",async()=>{const a=await h(e,w),s=await h(e,g);if(a===null||s===a)return;const i=s?await m(e,g):new Map,l=await n.db(),u=await m(e,w),d=await J(l,t,i,u,async p=>await X(l,p));r={created:r.created+d.created,revisions:r.revisions+d.revisions,deleted:r.deleted+d.deleted,needsMerge:[...new Set([...r.needsMerge,...d.needsMerge])],refused:[...r.refused,...d.refused]},await j(e,a,u,i,new Set(d.refused.map(p=>p.path)),s)}),"importLocal");await f(),await x("export",async()=>{const a=await h(e,w),s=a?await m(e,w):null,i=await h(e,g),l=i?await m(e,g):null,u=await G(await n.db(),t,s,l);if(a?z(s,u):u.size===0)return;const d=await S(e,u,a?[a]:[],`crtr: export ${t.name}`);await y(e,w,d,a),await j(e,d,u,l??new Map,new Set(Q(s,l)),i)});for(let a=1;;a++){const s=await ae(e,o);if(!s.ok)return{ok:!1,step:"fetch",reason:s.reason};let i=await h(e,w);if(s.value!==null&&!(i&&await we(e,s.value)&&await I(e,s.value,i))){const u=await ee(e,o);if(!u.ok)return{ok:!1,step:"fetch",reason:u.reason};const d=u.value;i=await x("merge",async()=>{if(!i||await I(e,i,d))return await y(e,w,d,i),d;const p=await ne(e,i,d),C=ie(p?await m(e,p):new Map,await m(e,w),await m(e,fe));for(const O of C.refused)r.refused.push(O);const F=await S(e,C.tree,[i,d],`crtr: merge ${t.name}`);return await y(e,w,F,i),F})}if(await f(),i===null||i===s.value)return{ok:!0,pushed:!1,imported:r};const l=await re(e,o,i);if(l.ok)return{ok:!0,pushed:!0,imported:r};if(l.reason!=="rejected")return{ok:!1,step:"push",reason:l.reason};if(a>=L)return{ok:!1,step:"push",reason:`push rejected ${L} times`}}}catch(e){if(e instanceof _)return{ok:!1,step:e.step,reason:e.message};throw e}}c(ue,"syncRepo");async function j(t,n,e,o,r,f){if(r.size===0){await y(t,g,n,f);return}const a=new Map(e);for(const s of r)o.has(s)?a.set(s,o.get(s)):a.delete(s);f!==null&&z(o,a)||await y(t,g,await S(t,a,[],"crtr: imported baseline (some files pending)"),f)}c(j,"advanceImported");async function le(t){const n=R(t.dir,A);return D(n)&&(await B(n,"utf8")).trim()||null}c(le,"readUrl");async function we(t,n){return await h(t,n)!==null}c(we,"hasCommit");function z(t,n){if(t.size!==n.size)return!1;for(const[e,o]of t)if(n.get(e)!==o)return!1;return!0}c(z,"sameTree");export{ce as FIRST_FETCH_WAIT_MS,_e as noteNodeBooting,de as noteNodeWorking,xe as noteRepoDocumentsChanged,Me as startRepoSync,ue as syncRepo};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var d=Object.defineProperty;var f=(n,e)=>d(n,"name",{value:e,configurable:!0});import{join as l}from"node:path";import{CONFIG_FILE as p}from"../types.js";import{listDirs as g,pathExists as I,readJsonIfExists as b}from"./fs-utils.js";import{readPluginManifest as w}from"./manifest.js";import{awaitBundleSwap as y,bundleSwapInFlightElsewhere as h}from"./plugin-swap-lock.js";import{isCloudRole as a,requestPersonId as v}from"./canvas/person-state.js";import{materializedPluginsDir as k}from"./scoped-state/materialized-plugins.js";import{readCachedSettings as C}from"./scoped-state/person-store.js";import{pluginsDir as E}from"./scope.js";function F(n,e){const r=n==="user"?C("user").settings:b(l(e,p));return r&&r.plugins&&typeof r.plugins=="object"?r.plugins:{}}f(F,"pluginConfigForRoot");function S(n,e,r){const i=Object.keys(e);return i.every(t=>r.has(t))?[]:i.filter(t=>!r.has(t)&&h(n,t))}f(S,"swapsToWaitOut");function G(n,e){const r=n==="user"&&a()?v():void 0;if(n==="user"&&a()&&r===void 0)return[];const i=n!=="user"?l(e,"plugins"):r!==void 0?k(r):E("user");if(i===void 0||!I(i))return[];const t=F(n,e),u=m(n,i,t),s=S(e,t,new Set(u.map(o=>o.name)));if(s.length===0)return u;for(const o of s)y(e,o);return m(n,i,t)}f(G,"listInstalledPluginsInRoot");function m(n,e,r){const i=[];for(const t of g(e)){const u=l(e,t),s=w(u);if(!s)continue;const o=r[t],c=typeof o?.version=="string"?o.version:s.version;i.push({name:t,scope:n,root:u,manifest:s,enabled:typeof o?.enabled=="boolean"?o.enabled:!0,sourceMarketplace:typeof o?.source_marketplace=="string"?o.source_marketplace:void 0,version:c})}return i}f(m,"collectInstalledPlugins");export{G as listInstalledPluginsInRoot};
|
|
@@ -15,4 +15,4 @@ export interface PersistedKeybindings {
|
|
|
15
15
|
readonly overrides: SparseKeybindingOverrides<BindingId>;
|
|
16
16
|
readonly tmuxPassthrough: readonly BindingId[];
|
|
17
17
|
}
|
|
18
|
-
export declare function persistUserKeybindings(prospectiveOverrides: unknown, options?: PersistKeybindingsOptions): PersistedKeybindings
|
|
18
|
+
export declare function persistUserKeybindings(prospectiveOverrides: unknown, options?: PersistKeybindingsOptions): Promise<PersistedKeybindings>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var c=Object.defineProperty;var i=(n,e)=>c(n,"name",{value:e,configurable:!0});import{isDeepStrictEqual as
|
|
1
|
+
var c=Object.defineProperty;var i=(n,e)=>c(n,"name",{value:e,configurable:!0});import{isDeepStrictEqual as o}from"node:util";import{configPath as m,normalizeTmuxPassthrough as g,updateRawConfigAtomically as x}from"../config.js";import{normalizeSparseOverrides as b}from"./resolve.js";class l extends Error{static{i(this,"KeybindingConcurrentEditError")}latestKeybindings;latestTmuxPassthrough;constructor(e,t){super("keybindings changed on disk; reload before saving"),this.name="KeybindingConcurrentEditError",this.latestKeybindings=e,this.latestTmuxPassthrough=t}}async function O(n,e={}){const t=b(n),d=Object.hasOwn(e,"tmuxPassthrough"),u=g(e.tmuxPassthrough);let h=[];const a=m("user");if(a===null)throw new Error("user config path is unavailable");return await x("user",r=>{if(Object.hasOwn(e,"expectedKeybindings")&&!o(r.keybindings,e.expectedKeybindings)||Object.hasOwn(e,"expectedTmuxPassthrough")&&!o(r.tmux_passthrough,e.expectedTmuxPassthrough))throw new l(r.keybindings,r.tmux_passthrough);const s={...r};return delete s.canvasNav,Object.keys(t).length===0?delete s.keybindings:s.keybindings=t,d&&(u.length===0?delete s.tmux_passthrough:s.tmux_passthrough=u),h=g(s.tmux_passthrough),s}),Object.freeze({path:a,overrides:Object.freeze({...t}),tmuxPassthrough:Object.freeze([...h])})}i(O,"persistUserKeybindings");export{l as KeybindingConcurrentEditError,O as persistUserKeybindings};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/** Idempotent post-layout migration. Reports paths only; never key contents. */
|
|
2
|
-
export declare function migrateLooseKeys(dryRun?: boolean): string[]
|
|
2
|
+
export declare function migrateLooseKeys(dryRun?: boolean): Promise<string[]>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var u=Object.defineProperty;var c=(
|
|
1
|
+
var u=Object.defineProperty;var c=(o,i)=>u(o,"name",{value:i,configurable:!0});import{existsSync as p,mkdirSync as f,readFileSync as d,renameSync as l}from"node:fs";import{join as a}from"node:path";import{layoutRoot as y}from"../layout.js";import{listAppEnvNames as A,setAppEnvVar as E}from"../profiles/app-env-store.js";async function $(o=!1){if(process.platform!=="darwin")return[];const i=y(),m=a(i,"runtime","set-aside","loose-keys"),t=[];for(const n of["exa.key","composio.key","secrets.json"]){const e=a(i,n);if(!p(e))continue;const s=a(m,n);if(n==="exa.key"&&!(await A("app:terminal")).includes("EXA_API_KEY")){const r=d(e,"utf8").trim();if(!r||r.includes("\0")){t.push(`${e}: invalid or empty; left untouched`);continue}o||await E("app:terminal","EXA_API_KEY",r),t.push(`${e}: imported EXA_API_KEY into app:terminal`)}if(p(s)){t.push(`${e}: destination already exists; left untouched`);continue}o||(f(m,{recursive:!0,mode:448}),l(e,s)),t.push(`${e}: moved to ${s}`)}return t}c($,"migrateLooseKeys");export{$ as migrateLooseKeys};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { CanvasDb } from '../canvas/db.js';
|
|
2
|
+
/** The Northlight team's principal in the directory's `relations` rows. A payer it holds is house-paid: its rows carry no account and bill $0. */
|
|
3
|
+
export declare const NORTHLIGHT_TEAM = "team:apofkzuloox7";
|
|
4
|
+
export interface BillingAccount {
|
|
5
|
+
/** The principal to invoice, or null when the payer is house-paid or has no holder. */
|
|
6
|
+
account: string | null;
|
|
7
|
+
/** Whether a row for this payer can be billed: false for a house-paid payer and for one with no holder. */
|
|
8
|
+
billable: boolean;
|
|
9
|
+
}
|
|
10
|
+
export declare function billingAccountOf(db: CanvasDb, payer: string): Promise<BillingAccount>;
|
|
11
|
+
/** The `app:<id>` payers whose holder (`ledger_holder`) is one of `holders` (a `user:<id>` or a `team:<id>`): the apps whose spend is that holder's. */
|
|
12
|
+
export declare function appsHeldBy(db: CanvasDb, holders: readonly string[]): Promise<string[]>;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var t=Object.defineProperty;var a=(e,r)=>t(e,"name",{value:r,configurable:!0});const p="team:apofkzuloox7";async function c(e,r){const o=(await e.prepare("SELECT ledger_holder(?) AS holder").get(r)).holder;return o===null||o===p?{account:null,billable:!1}:{account:o,billable:!0}}a(c,"billingAccountOf");async function u(e,r){return(await e.prepare(`SELECT 'app:' || r.resource_id AS app FROM (SELECT DISTINCT resource_id FROM relations WHERE resource_type = 'app' AND relation = 'admin') r
|
|
2
|
+
WHERE ledger_holder('app:' || r.resource_id) = ANY(?::text[]) ORDER BY 1`).all(r)).map(l=>l.app)}a(u,"appsHeldBy");export{p as NORTHLIGHT_TEAM,u as appsHeldBy,c as billingAccountOf};
|
|
@@ -10,9 +10,9 @@ export interface WriteResult {
|
|
|
10
10
|
}
|
|
11
11
|
/** The take percentage of `ledger.take_pct`; 0 (the default) writes no take rows. */
|
|
12
12
|
export declare function takePct(): number;
|
|
13
|
-
/** Write one charge row
|
|
13
|
+
/** Write one charge row; the `charges` trigger (schema delta 007) adds it to `charge_totals`. A refused row is stored with
|
|
14
14
|
* usd 0 and never rolled up; a take row (written only while `ledger.take_pct` > 0) is stored and never rolled up. Inside a
|
|
15
15
|
* caller's `withCanvasWrite` it joins that transaction. */
|
|
16
16
|
export declare function writeCharge(input: ChargeInput): Promise<WriteResult>;
|
|
17
|
-
/** A stored row as the `Charge` shape (jsonb arrives as text). */
|
|
17
|
+
/** A stored row as the `Charge` shape (jsonb arrives as text from `charges`, as an object from a moved chunk). */
|
|
18
18
|
export declare function chargeOf(row: Record<string, unknown>): Charge;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var I=Object.defineProperty;var n=(e,r)=>I(e,"name",{value:r,configurable:!0});import{randomUUID as b}from"node:crypto";import{withCanvasWrite as k}from"../canvas/db.js";import{readConfig as w}from"../config.js";import{usageMonth as y}from"./months.js";const U=n((e,r)=>`receipt:${e}:${r}`,"receiptChargeId"),c="id, request, at, month, kind, what, units, usd, payer, funding, sub, grantee, node, run, provider, caused_by, vendor_ref, refused, account, billed_usd, usd_rolled_by_trigger",i="?, ?, ?, ?, ?, ?, ?::jsonb, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?::jsonb, ?, ?, true";function S(){const e=w("user").ledger?.take_pct??0;if(typeof e!="number"||!Number.isFinite(e)||e<0||e>100)throw new Error("ledger.take_pct must be a number from 0 to 100");return e}n(S,"takePct");async function D(e){const r=e.at??new Date,t=e.refused??null,o=e.id??b(),f=y(r),s=t?0:e.usd,a=S();return await k(async d=>{const u=n((g,m,N,O,h)=>[g,e.request??null,r.toISOString(),f,m,N,e.units==null?null:JSON.stringify(e.units),O,e.payer,h,e.sub??null,e.grantee,e.node??null,e.run??null,e.provider??null,e.causedBy??null,e.vendorRef??null,t===null?null:JSON.stringify(t),e.account??null,e.billedUsd??null],"row");if((await d.prepare(`INSERT INTO charges (${c}) VALUES (${i}) ON CONFLICT (id) DO NOTHING`).run(...u(o,e.kind,e.what,s,e.funding))).changes===0)return{written:!1,id:o,takeId:null};let l=null;return a>0&&t===null&&(e.kind==="model"||e.kind==="tool")&&s!==null&&s>0&&(l=`take:${o}`,await d.prepare(`INSERT INTO charges (${c}) VALUES (${i}) ON CONFLICT (id) DO NOTHING`).run(...u(l,"take",e.what,s*a/100,"take"))),{written:!0,id:o,takeId:l}})}n(D,"writeCharge");function j(e){const r=n(t=>typeof t=="string"?JSON.parse(t):typeof t=="object"?t:null,"json");return{...e,units:r(e.units),refused:r(e.refused)}}n(j,"chargeOf");export{j as chargeOf,U as receiptChargeId,S as takePct,D as writeCharge};
|
|
@@ -5,6 +5,8 @@ import type { Funding, Limit } from './types.js';
|
|
|
5
5
|
export interface CallCandidate {
|
|
6
6
|
scope: 'call';
|
|
7
7
|
payer: string;
|
|
8
|
+
/** The principal Northlight invoices for `payer`; absent means the function finds the payer's holder. */
|
|
9
|
+
account?: string | null;
|
|
8
10
|
funding: Funding;
|
|
9
11
|
sub: string | null;
|
|
10
12
|
grantee: string;
|
|
@@ -16,6 +18,7 @@ export interface CallCandidate {
|
|
|
16
18
|
export interface StartCandidate {
|
|
17
19
|
scope: 'start';
|
|
18
20
|
payer: string;
|
|
21
|
+
account?: string | null;
|
|
19
22
|
sub: string | null;
|
|
20
23
|
grantee: string;
|
|
21
24
|
}
|
|
@@ -27,7 +30,8 @@ export interface Refusal {
|
|
|
27
30
|
month: string;
|
|
28
31
|
reset_at: string;
|
|
29
32
|
}
|
|
30
|
-
/** The first limit (by id) that refuses `candidate` this month, or null. One
|
|
33
|
+
/** The first limit (by id) that refuses `candidate` this month, or null. One call to the SQL function `ledger_check`
|
|
34
|
+
* (schema delta 007), which holds the rule. */
|
|
31
35
|
export declare function findRefusal(candidate: Candidate, at?: Date): Promise<Refusal | null>;
|
|
32
36
|
/** The `user_action` a person can take for a limit of this source; absent for an operator limit. */
|
|
33
37
|
export declare function userActionOf(source: Limit['source']): 'raise_cap' | 'clear_limit' | undefined;
|
|
@@ -1,7 +1 @@
|
|
|
1
|
-
var
|
|
2
|
-
AND (l.funding IS NULL OR t.funding = l.funding) AND (l.grantee IS NULL OR t.grantee = l.grantee)
|
|
3
|
-
AND (l.provider IS NULL OR t.provider = l.provider) AND (l.sub IS NULL OR t.sub = l.sub))`;async function N(e,r=new Date){const t=m(r),s=e.sub??"",o=e.scope==="call"?`l.payer = ? AND (l.funding IS NULL OR l.funding = ?) AND (l.grantee IS NULL OR l.grantee = ?)
|
|
4
|
-
AND (l.provider IS NULL OR l.provider = ?) AND (l.sub IS NULL OR l.sub = ?)`:"l.payer = ? AND l.funding IS NULL AND l.provider IS NULL AND (l.grantee IS NULL OR l.grantee = ?) AND (l.sub IS NULL OR l.sub = ?)",u=e.scope==="call"?[e.payer,e.funding,e.grantee,e.provider??"",s]:[e.payer,e.grantee,s],i=await(await d()).prepareUncached(`SELECT * FROM (
|
|
5
|
-
SELECT l.id, l.payer, l.funding, l.grantee, l.provider, l.sub, l.usd_per_month, l.source, l.updated_at, ${g} AS spent
|
|
6
|
-
FROM limits l WHERE ${o}) q
|
|
7
|
-
WHERE q.spent >= q.usd_per_month ORDER BY q.id LIMIT 1`).get(t,...u);if(i===void 0)return null;const{spent:l,...p}=i;return{limit:p,usd:l,month:t,reset_at:L(t)}}n(N,"findRefusal");function f(e){return e==="grant_sync"?"raise_cap":e==="person"?"clear_limit":void 0}n(f,"userActionOf");function _(e){const{limit:r}=e,t=f(r.source);return new c(402,"cap_exhausted",`${r.payer} reached its monthly limit (${r.id})`,void 0,{limit:{id:r.id,payer:r.payer,filters:{funding:r.funding,grantee:r.grantee,provider:r.provider,sub:r.sub},usd_per_month:r.usd_per_month,source:r.source},usd:e.usd,reset_at:e.reset_at,spend_cap:r.usd_per_month,usd_equivalent:e.usd,...t===void 0?{}:{user_action:t}})}n(_,"refusalError");async function E(e,r){const t=await N(e,r);if(t!==null)throw _(t)}n(E,"check");const D=n(e=>({limit:e.limit.id,reason:`${e.limit.payer} reached ${e.limit.usd_per_month} USD this month (spent ${e.usd})`}),"refusedMark");export{E as check,N as findRefusal,_ as refusalError,D as refusedMark,f as userActionOf};
|
|
1
|
+
var i=Object.defineProperty;var r=(n,t)=>i(n,"name",{value:t,configurable:!0});import{openDb as u}from"../canvas/db.js";import{RunError as s}from"../runs/operations.js";import{usageMonth as c}from"./months.js";async function a(n,t=new Date){const e={...n,month:c(t)},o=await(await u()).prepare("SELECT ledger_check(?::jsonb) AS refusal").get(JSON.stringify(e));return typeof o?.refusal=="string"?JSON.parse(o.refusal):o?.refusal??null}r(a,"findRefusal");function d(n){return n==="grant_sync"?"raise_cap":n==="person"?"clear_limit":void 0}r(d,"userActionOf");function p(n){const{limit:t}=n,e=d(t.source);return new s(402,"cap_exhausted",`${t.payer??t.account} reached its monthly limit (${t.id})`,void 0,{limit:{id:t.id,payer:t.payer,account:t.account,filters:{account:t.account,funding:t.funding,grantee:t.grantee,provider:t.provider,sub:t.sub},usd_per_month:t.usd_per_month,source:t.source},usd:n.usd,reset_at:n.reset_at,spend_cap:t.usd_per_month,usd_equivalent:n.usd,...e===void 0?{}:{user_action:e}})}r(p,"refusalError");async function g(n,t){const e=await a(n,t);if(e!==null)throw p(e)}r(g,"check");const y=r(n=>({limit:n.limit.id,reason:`${n.limit.payer??n.limit.account} reached ${n.limit.usd_per_month} USD this month (spent ${n.usd})`}),"refusedMark");export{g as check,a as findRefusal,p as refusalError,y as refusedMark,d as userActionOf};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Charge } from './types.js';
|
|
2
|
+
/** The moved rows of a month (or of every month), read once per instance. A chunk row whose blob is missing throws: the rows are nowhere else. */
|
|
3
|
+
export declare class ChunkRows {
|
|
4
|
+
private readonly byMonth;
|
|
5
|
+
private all;
|
|
6
|
+
rows(month?: string): Promise<Charge[]>;
|
|
7
|
+
private load;
|
|
8
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var f=Object.defineProperty;var u=(t,e)=>f(t,"name",{value:e,configurable:!0});import{zstdDecompressSync as l}from"node:zlib";import{blobStore as h}from"../blobs/index.js";import{openDb as b}from"../canvas/db.js";import{chargeOf as p}from"./charges.js";const g=["id","request","at","month","kind","what","units","usd","payer","funding","sub","grantee","node","run","provider","caused_by","vendor_ref","refused","account","billed_usd"];class _{static{u(this,"ChunkRows")}byMonth=new Map;all;rows(e){if(e===void 0)return this.all??=this.load(void 0);let n=this.byMonth.get(e);return n===void 0&&(n=this.load(e),this.byMonth.set(e,n)),n}async load(e){const n=await(await b()).prepareUncached(`SELECT blob_key FROM charge_chunks${e===void 0?"":" WHERE month = ?"} ORDER BY month, payer`).all(...e===void 0?[]:[e]);if(n.length===0)return[];const d=await h(),r=[];for(const{blob_key:o}of n){const s=await d.get(o);if(s===null)throw new Error(`charge chunk ${o} is recorded in charge_chunks but its blob is missing`);for(const i of l(s).toString("utf8").split(`
|
|
2
|
+
`)){if(i==="")continue;const c=JSON.parse(i);r.push(p(Object.fromEntries(g.map(a=>[a,c[a]??null]))))}}return r}}export{_ as ChunkRows};
|
|
@@ -4,5 +4,6 @@ export { payerOf, type Payer, type PayerCall } from './payer.js';
|
|
|
4
4
|
export { writeCharge, receiptChargeId, takePct, chargeOf, type WriteResult } from './charges.js';
|
|
5
5
|
export { check, findRefusal, refusalError, refusedMark, userActionOf, type Candidate, type CallCandidate, type StartCandidate, type Refusal } from './check.js';
|
|
6
6
|
export { upsertLimit, deleteLimit, listLimits } from './limits.js';
|
|
7
|
-
export { usageFor, listCharges, monthTotals, assertReference, type ChargePage, type ListFilter, type MonthTotals } from './read.js';
|
|
7
|
+
export { usageFor, listCharges, monthTotals, assertReference, type Reader, type ChargePage, type ListFilter, type MonthTotals } from './read.js';
|
|
8
8
|
export { REBUILD_ALL_TOTALS, rebuildTotalsFor } from './totals.js';
|
|
9
|
+
export { appsHeldBy } from './account.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export*from"./types.js";export*from"./months.js";import{payerOf as f}from"./payer.js";import{writeCharge as a,receiptChargeId as
|
|
1
|
+
export*from"./types.js";export*from"./months.js";import{payerOf as f}from"./payer.js";import{writeCharge as a,receiptChargeId as p,takePct as i,chargeOf as m}from"./charges.js";import{check as x,findRefusal as c,refusalError as u,refusedMark as L,userActionOf as d}from"./check.js";import{upsertLimit as g,deleteLimit as n,listLimits as O}from"./limits.js";import{usageFor as k,listCharges as A,monthTotals as C,assertReference as R}from"./read.js";import{REBUILD_ALL_TOTALS as B,rebuildTotalsFor as E}from"./totals.js";import{appsHeldBy as I}from"./account.js";export{B as REBUILD_ALL_TOTALS,I as appsHeldBy,R as assertReference,m as chargeOf,x as check,n as deleteLimit,c as findRefusal,A as listCharges,O as listLimits,C as monthTotals,f as payerOf,E as rebuildTotalsFor,p as receiptChargeId,u as refusalError,L as refusedMark,i as takePct,g as upsertLimit,k as usageFor,d as userActionOf,a as writeCharge};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type WriteResult } from './charges.js';
|
|
2
|
+
import type { ChargeInput } from './types.js';
|
|
3
|
+
export declare const DEFAULT_INFRA_FREE_USD = 50;
|
|
4
|
+
export declare const infraFreeUsd: () => number;
|
|
5
|
+
/** Write a `sandbox` or `storage` row whose `billed_usd` is the part of its usd above the account's monthly allowance. A row with no
|
|
6
|
+
* billable account (house-paid, or no holder) bills 0 and takes no lock. */
|
|
7
|
+
export declare function writeInfraCharge(input: ChargeInput & {
|
|
8
|
+
usd: number;
|
|
9
|
+
}, billable: boolean): Promise<WriteResult>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var h=Object.defineProperty;var t=(r,a)=>h(r,"name",{value:a,configurable:!0});import{withCanvasWrite as l}from"../canvas/db.js";import{readConfig as E}from"../config.js";import{writeCharge as d}from"./charges.js";import{usageMonth as g}from"./months.js";const _=50,i=t(r=>Math.round(r*1e6)/1e6,"round6"),p=t(()=>E("user").ledger?.infra_free_usd_per_month??_,"infraFreeUsd");async function D(r,a){const e=i(r.usd),o=r.account??null;if(!a||o===null)return await d({...r,usd:e,billedUsd:0});const c=p(),n=g(r.at??new Date);return await l(async s=>{await s.prepare("SELECT pg_advisory_xact_lock(hashtextextended(?, 0))").get(`infra:${o}:${n}`);const u=await s.prepare("SELECT COALESCE(sum(usd), 0) AS usd FROM charges WHERE account = ? AND month = ? AND kind IN ('sandbox', 'storage') AND id <> ?").get(o,n,r.id??""),m=Number(u.usd),f=i(Math.min(e,Math.max(0,m+e-c)));return await d({...r,usd:e,billedUsd:f})})}t(D,"writeInfraCharge");export{_ as DEFAULT_INFRA_FREE_USD,p as infraFreeUsd,D as writeInfraCharge};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
var d=Object.defineProperty;var
|
|
2
|
-
ON CONFLICT (id) DO UPDATE SET payer = excluded.payer, funding = excluded.funding, grantee = excluded.grantee,
|
|
3
|
-
provider = excluded.provider, sub = excluded.sub, usd_per_month = excluded.usd_per_month, source = excluded.source, updated_at = excluded.updated_at`).run(e.id,e.payer,e.funding,e.grantee,e.provider,e.sub,e.usd_per_month,e.source,e.updated_at)}),e}
|
|
1
|
+
var d=Object.defineProperty;var u=(n,e)=>d(n,"name",{value:e,configurable:!0});import{openDb as i,withCanvasWrite as t}from"../canvas/db.js";const a="id, payer, account, funding, grantee, provider, sub, usd_per_month, source, updated_at";async function c(n){if(!Number.isFinite(n.usd_per_month)||n.usd_per_month<0)throw new RangeError("usd_per_month must be a number of at least 0");const e={account:null,funding:null,grantee:null,provider:null,sub:null,...n,updated_at:new Date().toISOString()};return await t(async r=>{await r.prepare(`INSERT INTO limits (${a}) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
2
|
+
ON CONFLICT (id) DO UPDATE SET payer = excluded.payer, account = excluded.account, funding = excluded.funding, grantee = excluded.grantee,
|
|
3
|
+
provider = excluded.provider, sub = excluded.sub, usd_per_month = excluded.usd_per_month, source = excluded.source, updated_at = excluded.updated_at`).run(e.id,e.payer,e.account,e.funding,e.grantee,e.provider,e.sub,e.usd_per_month,e.source,e.updated_at)}),e}u(c,"upsertLimit");async function p(n){return await t(async e=>(await e.prepare("DELETE FROM limits WHERE id = ?").run(n)).changes>0)}u(p,"deleteLimit");async function l(n={}){const e=[],r=[];return n.source!==void 0&&(e.push("source = ?"),r.push(n.source)),n.payer!==void 0&&(e.push("payer = ?"),r.push(n.payer)),await(await i()).prepareUncached(`SELECT ${a} FROM limits${e.length?` WHERE ${e.join(" AND ")}`:""} ORDER BY id`).all(...r)}u(l,"listLimits");export{p as deleteLimit,l as listLimits,c as upsertLimit};
|
|
@@ -17,7 +17,7 @@ export type PayerCall =
|
|
|
17
17
|
route: 'subscription' | 'key';
|
|
18
18
|
sub: string;
|
|
19
19
|
}
|
|
20
|
-
/** A tool call over HTTP: the outbound token's `payer` claim (`app:<id>` when the app pays, else the person). */
|
|
20
|
+
/** A tool call over HTTP: the outbound token's `payer` claim (`app:<id>` when the app pays, else the person). Both are `bill`: the app's holder is invoiced for an app-paid call. */
|
|
21
21
|
| {
|
|
22
22
|
call: 'tool';
|
|
23
23
|
tokenPayer: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var t=Object.defineProperty;var n=(e,r)=>t(e,"name",{value:r,configurable:!0});function
|
|
1
|
+
var t=Object.defineProperty;var n=(e,r)=>t(e,"name",{value:r,configurable:!0});function p(e){switch(e.call){case"model":return e.route==="endpoint"?{payer:e.grantee,funding:"endpoint"}:{payer:e.sub,funding:e.route};case"tool":return e.tokenPayer.startsWith("app:")?{payer:e.tokenPayer,funding:"bill"}:{payer:e.sub,funding:"bill"};case"start":return e.grantPayer==="app"?{payer:e.grantee,funding:"endpoint"}:{payer:e.sub,funding:"bill"}}}n(p,"payerOf");export{p as payerOf};
|
|
@@ -5,11 +5,18 @@ import type { Charge, Limit } from './types.js';
|
|
|
5
5
|
* `usd_equivalent` is what the grant's limit reads: every `user:` payer charge for this grantee, model and tool, refused and
|
|
6
6
|
* take rows excluded. `spend_cap` is the grant limit's `usd_per_month` for this grantee, null when none exists. */
|
|
7
7
|
export declare function usageFor(grantee: string, month?: string): Promise<SpendUsageDTO>;
|
|
8
|
+
/** Who is reading: a person sees the rows where they are `sub`, `payer` or `account`; an app the rows where it is `grantee`
|
|
9
|
+
* or `payer`. Absent means the install's person, who sees every row. */
|
|
10
|
+
export type Reader = {
|
|
11
|
+
person: string;
|
|
12
|
+
} | {
|
|
13
|
+
app: string;
|
|
14
|
+
};
|
|
8
15
|
export interface ListFilter {
|
|
9
16
|
/** Only rows of this month. */
|
|
10
17
|
month?: string;
|
|
11
|
-
/**
|
|
12
|
-
|
|
18
|
+
/** The reader; absent reads every row. */
|
|
19
|
+
reader?: Reader;
|
|
13
20
|
/** A reference: `message:<id>`, `request:<id>`, `cron_run:<id>`, `run:<id>`, or a charge id. */
|
|
14
21
|
under?: string;
|
|
15
22
|
/** Page size, 1 to 10,000; default 1,000. */
|
|
@@ -38,7 +45,10 @@ export interface MonthTotals {
|
|
|
38
45
|
}>;
|
|
39
46
|
limits: Limit[];
|
|
40
47
|
}
|
|
41
|
-
/**
|
|
42
|
-
export declare function
|
|
48
|
+
/** The payers a `user:<id>` answers for: itself, and every app held (`ledger_holder`) by it or by a team it belongs to. */
|
|
49
|
+
export declare function payersOf(owner: string): Promise<string[]>;
|
|
50
|
+
/** One month's dollars per payer and per payer and funding, from the rollup, with the limit rows. For one person: the rows of the
|
|
51
|
+
* person's `payersOf` (itself and the apps it or its teams hold now), and the limits on those payers or on the person's account. */
|
|
52
|
+
export declare function monthTotals(month?: string, person?: string): Promise<MonthTotals>;
|
|
43
53
|
/** A reference's shape, or a 400. */
|
|
44
54
|
export declare function assertReference(value: string): string;
|
package/dist/core/ledger/read.js
CHANGED
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
var
|
|
2
|
-
WHERE grantee = ? AND month = ? AND refused IS NULL AND kind <> 'take'`).all(e
|
|
3
|
-
SELECT 'request:' || c.request FROM charges c WHERE c.run = ? AND c.request IS NOT NULL)))`,params:[t,t]}}a(b,"referenceCondition");const L=a(e=>Buffer.from(JSON.stringify([e.at,e.id]),"utf8").toString("base64url"),"encodeCursor");function O(e){try{const n=JSON.parse(Buffer.from(e,"base64url").toString("utf8"));if(Array.isArray(n)&&n.length===2&&typeof n[0]=="string"&&typeof n[1]=="string")return[n[0],n[1]]}catch{}throw new h(400,"invalid_request","cursor must be a `next` value from a previous page","after")}a(O,"decodeCursor");async function C(e={}){const n=Math.min(Math.max(Math.trunc(e.limit??1e3),1),1e4),t=[],s=[];if(e.under!==void 0){const d=b(e.under);t.push(d.sql),s.push(...d.params),e.month!==void 0&&(t.push("month = ?"),s.push(e.month))}else t.push("month = ?"),s.push(e.month??l());e.grantee!==void 0&&(t.push("grantee = ?"),s.push(e.grantee)),e.after!==void 0&&(t.push("(at, id) > (?, ?)"),s.push(...O(e.after)));const o=(await(await f()).prepare(`SELECT ${N} FROM charges WHERE ${t.join(" AND ")} ORDER BY at, id LIMIT ${n+1}`).all(...s)).map(g),i=o.slice(0,n);return{charges:i,next:o.length>n?L(i[n-1]):null}}a(C,"listCharges");async function I(e=l(),n){const t=await f(),s=n===void 0?"":" AND payer = ?",o=n===void 0?[e]:[e,n],i=await t.prepare(`SELECT payer, SUM(usd) AS usd FROM charge_totals WHERE month = ?${s} GROUP BY payer ORDER BY payer`).all(...o),d=await t.prepare(`SELECT payer, funding, SUM(usd) AS usd FROM charge_totals WHERE month = ?${s} GROUP BY payer, funding ORDER BY payer, funding`).all(...o);return{month:e,by_payer:i.map(u=>({payer:u.payer,usd:Number(u.usd)})),by_funding:d.map(u=>({payer:u.payer,funding:u.funding,usd:Number(u.usd)})),limits:await E(n===void 0?{}:{payer:n})}}a(I,"monthTotals");function T(e){if(e.length===0||e.length>512)throw new h(400,"invalid_request","under must be a reference or a charge id","under");return e}a(T,"assertReference");export{T as assertReference,C as listCharges,I as monthTotals,v as usageFor};
|
|
1
|
+
var O=Object.defineProperty;var o=(t,e)=>O(t,"name",{value:e,configurable:!0});import{openDb as m}from"../canvas/db.js";import{subjectSet as S}from"../permissions/evaluator.js";import{RunError as E}from"../runs/operations.js";import{appsHeldBy as A}from"./account.js";import{chargeOf as w}from"./charges.js";import{ChunkRows as R}from"./chunks.js";import{listLimits as b}from"./limits.js";import{resetAt as L,usageMonth as _}from"./months.js";const N="id, request, at, month, kind, what, units, usd, payer, funding, sub, grantee, node, run, provider, caused_by, vendor_ref, refused, account, billed_usd";async function J(t,e=_()){const r=await m(),a=await r.prepare(`SELECT payer, what, kind, units, usd FROM charges
|
|
2
|
+
WHERE grantee = ? AND month = ? AND refused IS NULL AND kind <> 'take'`).all(t,e);for(const n of await new R().rows(e))n.grantee===t&&n.refused===null&&n.kind!=="take"&&a.push(n);const i=o(n=>{const u=new Map;for(const s of a){if(s.kind!=="model"||!s.payer.startsWith(n))continue;const f=s.units===null?{}:typeof s.units=="string"?JSON.parse(s.units):s.units,h=u.get(s.what)??{served_model:s.what,input_tokens:0,output_tokens:0,usd_equivalent:null};h.input_tokens+=f.input??0,h.output_tokens+=f.output??0,s.usd!==null&&(h.usd_equivalent=(h.usd_equivalent??0)+Number(s.usd)),u.set(s.what,h)}return[...u.values()].sort((s,f)=>s.served_model<f.served_model?-1:1)},"byModel"),p=o(n=>a.filter(u=>u.payer.startsWith(n)).reduce((u,s)=>u+Number(s.usd??0),0),"sum"),d=await r.prepare("SELECT usd_per_month FROM limits WHERE source = 'grant_sync' AND grantee = ? AND payer LIKE 'user:%' AND funding IS NULL AND provider IS NULL ORDER BY id LIMIT 1").get(t);return{grantee:t,month:e,usd_equivalent:p("user:"),by_model:i("user:"),app_paid:{usd_equivalent:p("app:"),by_model:i("app:")},spend_cap:d===void 0?null:Number(d.usd_per_month),reset_at:L(e)}}o(J,"usageFor");const M=/^(message|request|cron_run|run):(.+)$/;async function v(t,e){const r=M.exec(t);if(r===null)return{sql:"id = ?",params:[t],test:o(n=>n.id===t,"test")};if(r[1]==="message"||r[1]==="cron_run")return{sql:"caused_by = ?",params:[t],test:o(n=>n.caused_by===t,"test")};if(r[1]==="request")return{sql:"(request = ? OR caused_by = ?)",params:[r[2],t],test:o(n=>n.request===r[2]||n.caused_by===t,"test")};const a=r[2],i=await m(),p=new Set((await i.prepare("SELECT DISTINCT request FROM charges WHERE run = ? AND request IS NOT NULL").all(a)).map(n=>n.request));for(const n of await e.rows())n.run===a&&n.request!==null&&p.add(n.request);const d=new Set([a]);if(p.size>0){const n=await i.prepare("SELECT n.run_id FROM nodes n WHERE n.run_id IS NOT NULL AND n.node_id = n.run_id AND n.caused_by = ANY(?::text[])").all([...p].map(u=>`request:${u}`));for(const u of n)d.add(u.run_id)}return{sql:"run = ANY(?::text[])",params:[[...d]],test:o(n=>n.run!==null&&d.has(n.run),"test")}}o(v,"referenceMatch");function D(t){return"person"in t?{sql:"(sub = ? OR payer = ? OR account = ?)",params:[t.person,t.person,t.person]}:{sql:"(grantee = ? OR payer = ?)",params:[t.app,t.app]}}o(D,"readerCondition");const g=o((t,e)=>"person"in e?t.sub===e.person||t.payer===e.person||t.account===e.person:t.grantee===e.app||t.payer===e.app,"mayRead");async function C(t,e,r){const a=await m(),i=new Map,p=o(async d=>{const n=d.caused_by;if(n===null||!n.startsWith("request:"))return;const u=n.slice(8),s=[...(await a.prepare(`SELECT ${N} FROM charges WHERE request = ? AND id <> ?`).all(u,d.id)).map(w),...(await r.rows()).filter(f=>f.request===u&&f.id!==d.id)].sort(q);return s.find(f=>g(f,e))??s[0]},"parentOf");for(const d of t){let n=d;for(let u=0;n!==void 0&&!g(n,e)&&u<64;u+=1)n=await p(n);n!==void 0&&g(n,e)&&i.set(n.id,n)}return[...i.values()]}o(C,"visibleChain");const q=o((t,e)=>t.at<e.at?-1:t.at>e.at?1:t.id<e.id?-1:t.id>e.id?1:0,"byAtId"),T=o(t=>Buffer.from(JSON.stringify([t.at,t.id]),"utf8").toString("base64url"),"encodeCursor");function k(t){try{const e=JSON.parse(Buffer.from(t,"base64url").toString("utf8"));if(Array.isArray(e)&&e.length===2&&typeof e[0]=="string"&&typeof e[1]=="string")return[e[0],e[1]]}catch{}throw new E(400,"invalid_request","cursor must be a `next` value from a previous page","after")}o(k,"decodeCursor");async function P(t={}){const e=Math.min(Math.max(Math.trunc(t.limit??1e3),1),1e4),r=new R,a=[],i=[],p=[];let d;if(t.under!==void 0){const c=await v(t.under,r);a.push(c.sql),i.push(...c.params),p.push(c.test),t.month!==void 0&&(a.push("month = ?"),i.push(t.month),p.push(l=>l.month===t.month),d=t.month)}else{const c=t.month??_();a.push("month = ?"),i.push(c),d=c}if(t.under===void 0&&t.reader!==void 0){const c=D(t.reader);a.push(c.sql),i.push(...c.params);const l=t.reader;p.push(y=>g(y,l))}if(t.after!==void 0){const[c,l]=k(t.after);a.push("(at, id) > (?, ?)"),i.push(c,l),p.push(y=>y.at>c||y.at===c&&y.id>l)}const n=(await(await m()).prepare(`SELECT ${N} FROM charges WHERE ${a.join(" AND ")} ORDER BY at, id LIMIT ${e+1}`).all(...i)).map(w),u=(await r.rows(d)).filter(c=>p.every(l=>l(c))),s=[...n,...u].sort(q).slice(0,e+1),f=s.slice(0,e);return{charges:t.under!==void 0&&t.reader!==void 0?await C(f,t.reader,r):f,next:s.length>e?T(f[e-1]):null}}o(P,"listCharges");async function I(t){const e=await m(),{groupIds:r}=await S(e,t.slice(5));return[t,...await A(e,[t,...r])]}o(I,"payersOf");async function j(t=_(),e){const r=await m(),a=e===void 0?void 0:await I(e),i=a===void 0?"":" AND payer = ANY(?::text[])",p=a===void 0?[t]:[t,a],d=await r.prepare(`SELECT payer, SUM(usd) AS usd FROM charge_totals WHERE month = ?${i} GROUP BY payer ORDER BY payer`).all(...p),n=await r.prepare(`SELECT payer, funding, SUM(usd) AS usd FROM charge_totals WHERE month = ?${i} GROUP BY payer, funding ORDER BY payer, funding`).all(...p),u=a===void 0?await b():(await b()).filter(s=>s.payer!==null&&a.includes(s.payer)||s.account===e);return{month:t,by_payer:d.map(s=>({payer:s.payer,usd:Number(s.usd)})),by_funding:n.map(s=>({payer:s.payer,funding:s.funding,usd:Number(s.usd)})),limits:u}}o(j,"monthTotals");function z(t){if(t.length===0||t.length>512)throw new E(400,"invalid_request","under must be a reference or a charge id","under");return t}o(z,"assertReference");export{z as assertReference,P as listCharges,j as monthTotals,I as payersOf,J as usageFor};
|
|
@@ -1,21 +1,10 @@
|
|
|
1
1
|
import type { CanvasDb } from '../canvas/db.js';
|
|
2
|
-
/** `charge_totals` stores an absent `sub` or `provider` as ''. */
|
|
3
|
-
export declare const absent: (value: string | null | undefined) => string;
|
|
4
|
-
/** Add `usd` (null adds 0) to the rollup row of one charge, in the caller's transaction. Concurrent writers to one key
|
|
5
|
-
* serialize on the conflicting row, so the total is exact. */
|
|
6
|
-
export declare function addToTotals(db: CanvasDb, charge: {
|
|
7
|
-
month: string;
|
|
8
|
-
payer: string;
|
|
9
|
-
funding: string;
|
|
10
|
-
sub: string | null;
|
|
11
|
-
grantee: string;
|
|
12
|
-
provider: string | null;
|
|
13
|
-
usd: number | null;
|
|
14
|
-
}): Promise<void>;
|
|
15
2
|
/** Rebuild the whole rollup from `charges`, `billed_usd` with `usd`: a rebuild that dropped it would zero the billed totals
|
|
16
3
|
* 002's trigger keeps, and an older build that may still open the database must not do that either. Plain SQL, so the SQLite
|
|
17
4
|
* import runs it on its own client. */
|
|
18
5
|
export declare const REBUILD_ALL_TOTALS: readonly ["DELETE FROM charge_totals", "INSERT INTO charge_totals (month, payer, funding, sub, grantee, provider, usd, billed_usd) SELECT month, payer, funding, COALESCE(sub, ''), grantee, COALESCE(provider, ''), COALESCE(SUM(usd), 0), COALESCE(SUM(billed_usd), 0)\n FROM charges WHERE refused IS NULL AND kind <> 'take' GROUP BY month, payer, funding, COALESCE(sub, ''), grantee, COALESCE(provider, '')"];
|
|
19
|
-
/**
|
|
20
|
-
*
|
|
21
|
-
|
|
6
|
+
/** Rename person `from` to `to` in the rollup rows that name it as payer, sub or grantee, summing rows that now share a key.
|
|
7
|
+
* For person substitution, in the same transaction as the rename of `charges`. The rollup already holds every charge, so renaming
|
|
8
|
+
* keeps the months `ledger-r2` moved out of `charges` (a rebuild from `charges` would drop them), and the sums stay exactly what a
|
|
9
|
+
* rebuild of the rows still in `charges` plus the moved months would give. Returns the rollup rows renamed. */
|
|
10
|
+
export declare function rebuildTotalsFor(db: CanvasDb, from: string, to: string): Promise<number>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
var u=Object.defineProperty;var E=(r,n)=>u(r,"name",{value:n,configurable:!0});import{CrtrError as h}from"../errors.js";const i=`SELECT month, payer, funding, COALESCE(sub, ''), grantee, COALESCE(provider, ''), COALESCE(SUM(usd), 0), COALESCE(SUM(billed_usd), 0)
|
|
2
|
+
FROM charges WHERE refused IS NULL AND kind <> 'take'`,p="GROUP BY month, payer, funding, COALESCE(sub, ''), grantee, COALESCE(provider, '')",l=["DELETE FROM charge_totals",`INSERT INTO charge_totals (month, payer, funding, sub, grantee, provider, usd, billed_usd) ${i} ${p}`];async function L(r,n,a){const t=await r.prepare("SELECT a.month FROM charge_chunks a JOIN charge_chunks b ON b.month = a.month AND b.payer = ? WHERE a.payer = ? ORDER BY a.month LIMIT 1").get(a,n);if(t!==void 0)throw new h("person_conflict",`${n} and ${a} both have the moved month ${t.month} (charge_chunks holds one blob per month and payer), so they cannot be merged`,void 0,{from:n,to:a,month:t.month});const o=await r.prepare(`DELETE FROM charge_totals WHERE payer = ? OR sub = ? OR grantee = ?
|
|
3
|
+
RETURNING month, payer, funding, sub, grantee, provider, usd, billed_usd`).all(n,n,n),s=E(e=>e===n?a:e,"rename");for(const e of o)await r.prepare(`INSERT INTO charge_totals (month, payer, funding, sub, grantee, provider, usd, billed_usd) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
4
|
+
ON CONFLICT (month, payer, funding, sub, grantee, provider) DO UPDATE SET usd = charge_totals.usd + EXCLUDED.usd, billed_usd = charge_totals.billed_usd + EXCLUDED.billed_usd`).run(e.month,s(e.payer),e.funding,s(e.sub),s(e.grantee),e.provider,e.usd,e.billed_usd);const d=await r.prepare("UPDATE charge_chunks SET payer = ? WHERE payer = ?").run(a,n);return o.length+d.changes}E(L,"rebuildTotalsFor");export{l as REBUILD_ALL_TOTALS,L as rebuildTotalsFor};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export type ChargeKind = 'model' | 'tool' | 'sandbox' | 'job' | 'storage' | 'take';
|
|
2
2
|
export type Funding = 'bill' | 'subscription' | 'key' | 'endpoint' | 'take' | 'legacy';
|
|
3
|
-
export type LimitSource = 'grant_sync' | 'person' | 'operator';
|
|
3
|
+
export type LimitSource = 'grant_sync' | 'person' | 'operator' | 'billing' | 'card';
|
|
4
4
|
/** Why the check refused a call: the limit's id and a sentence. Stored on the refused row. */
|
|
5
5
|
export interface RefusedMark {
|
|
6
6
|
limit: string;
|
|
@@ -27,6 +27,8 @@ export interface Charge {
|
|
|
27
27
|
caused_by: string | null;
|
|
28
28
|
vendor_ref: string | null;
|
|
29
29
|
refused: RefusedMark | null;
|
|
30
|
+
account: string | null;
|
|
31
|
+
billed_usd: number | null;
|
|
30
32
|
}
|
|
31
33
|
/** What a site hands `writeCharge`. */
|
|
32
34
|
export interface ChargeInput {
|
|
@@ -50,11 +52,18 @@ export interface ChargeInput {
|
|
|
50
52
|
vendorRef?: string | null;
|
|
51
53
|
/** Set when the check refused this call: the row is stored with usd 0 and is not added to the rollup. */
|
|
52
54
|
refused?: RefusedMark | null;
|
|
55
|
+
/** The principal Northlight invoices; null when none or house-paid. */
|
|
56
|
+
account?: string | null;
|
|
57
|
+
/** The amount Northlight bills, when known at write time (a sandbox or storage row). */
|
|
58
|
+
billedUsd?: number | null;
|
|
53
59
|
}
|
|
54
60
|
/** One `limits` row. A null filter means any. */
|
|
55
61
|
export interface Limit {
|
|
56
62
|
id: string;
|
|
57
|
-
|
|
63
|
+
/** Null when `account` is set. */
|
|
64
|
+
payer: string | null;
|
|
65
|
+
/** Counts the account's own charges and those of the apps it holds. */
|
|
66
|
+
account: string | null;
|
|
58
67
|
funding: Funding | null;
|
|
59
68
|
grantee: string | null;
|
|
60
69
|
provider: string | null;
|
|
@@ -63,4 +72,4 @@ export interface Limit {
|
|
|
63
72
|
source: LimitSource;
|
|
64
73
|
updated_at: string;
|
|
65
74
|
}
|
|
66
|
-
export type LimitInput = Omit<Limit, 'updated_at' | 'funding' | 'grantee' | 'provider' | 'sub'> & Partial<Pick<Limit, 'funding' | 'grantee' | 'provider' | 'sub'>>;
|
|
75
|
+
export type LimitInput = Omit<Limit, 'updated_at' | 'funding' | 'grantee' | 'provider' | 'sub' | 'account'> & Partial<Pick<Limit, 'funding' | 'grantee' | 'provider' | 'sub' | 'account'>>;
|
package/dist/core/llm/run.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
var Ae=Object.defineProperty;var c=(e,t)=>Ae(e,"name",{value:t,configurable:!0});import{randomUUID as Re}from"node:crypto";import{streamSimple as $e}from"@earendil-works/pi-ai/compat";import{APP_FAMILY as
|
|
1
|
+
var Ae=Object.defineProperty;var c=(e,t)=>Ae(e,"name",{value:t,configurable:!0});import{randomUUID as Re}from"node:crypto";import{streamSimple as $e}from"@earendil-works/pi-ai/compat";import{probeRouteAvailability as Ie}from"../model-routes-pool.js";import{APP_FAMILY as Ce,expandModelCandidates as ue,parseModelSpec as fe}from"../model-routes.js";import{readMergedLaunchConfig as me}from"../config.js";import{openModelRegistry as Oe}from"../runtime/model-registry.js";import{MAX_RATE_LIMIT_COOLDOWN_MS as pe,coolingUntilFor as he,isManagedProvider as K,markSubscriptionRateLimited as Se,markSubscriptionSuccess as Le,readSubscriptionPool as Ee,retryAfterMsFromHeaders as z,retryAfterMsFromError as Fe,refreshSubscriptionCredential as Ne,subscriptionNeedsSuccessWrite as De}from"../subscription-state.js";import{classifyRateLimit as Pe,describeRateLimitScope as _e,rateLimitHeaders as Te}from"../rate-limit-scope.js";import{RunError as s}from"../runs/operations.js";import{recognizeProviderError as re}from"../provider-error-recognition.js";import{isSafetyRefusal as Je}from"./refusal.js";import{findRefusal as We,payerOf as ge,refusalError as Ue,refusedMark as Be,writeCharge as ye}from"../ledger/index.js";import{personIdAsync as He}from"../canvas/person.js";import{getNode as we}from"../canvas/canvas.js";import{outboundToken as Ke}from"../providers/mint.js";import{discardFile as ze}from"../providers/token-cache.js";import{ProviderError as Xe}from"../providers/errors.js";import{appCandidates as Ge}from"./app-rungs.js";function Ye(e){return typeof e=="string"||e===null||Array.isArray(e)&&e.every(t=>t&&typeof t=="object"&&(t.type==="text"&&typeof t.text=="string"||t.type==="image_url"&&typeof t.image_url?.url=="string"&&/^data:image\/(png|jpeg|gif|webp);base64,[A-Za-z0-9+/]+={0,2}$/.test(t.image_url.url)))}c(Ye,"validContent");function be(e){return Array.isArray(e)?e.map(t=>{if(t.type==="text")return t;const[,n,i]=/^data:(image\/(?:png|jpeg|gif|webp));base64,(.*)$/.exec(t.image_url.url);return{type:"image",mimeType:n,data:i}}):e??""}c(be,"imageContent");function Ze(e,t){const n=(e instanceof Error?e.message:String(e)).split("; stack=",1)[0],i=re({message:n}).kind;return i!=="connection"&&i!=="connection-only"?e:new s(503,"upstream_model_unavailable",n.slice(0,500),void 0,{served_model:t})}c(Ze,"refreshFailure");function Mt(e){if(!e||typeof e!="object"||Array.isArray(e))throw new s(400,"invalid_request","body must be an object");const t=e;if(!Array.isArray(t.messages)||!t.messages.every(n=>n&&typeof n=="object"&&["system","user","assistant","tool"].includes(n.role)&&Ye(n.content)))throw new s(400,"invalid_request","messages must be chat messages","messages");if(t.messages.some(n=>["system","assistant"].includes(n.role)&&typeof n.content!="string"&&n.content!==null))throw new s(400,"invalid_request","system and assistant content must be text","messages");if(t.model!==void 0&&typeof t.model!="string")throw new s(400,"invalid_request","model must be a string","model");if(t.model_policy!==void 0&&!["exact","substitute"].includes(t.model_policy))throw new s(400,"invalid_request","invalid model_policy","model_policy");if(t.payer!==void 0&&!["user","app"].includes(t.payer))throw new s(400,"invalid_request","invalid payer","payer");if(t.reasoning_effort!==void 0&&!["minimal","low","medium","high","xhigh","max"].includes(t.reasoning_effort))throw new s(400,"invalid_request","invalid reasoning_effort","reasoning_effort");if(t.stream!==void 0&&typeof t.stream!="boolean")throw new s(400,"invalid_request","stream must be boolean","stream");if(t.tools!==void 0&&(!Array.isArray(t.tools)||!t.tools.every(n=>n?.type==="function"&&typeof n.function?.name=="string"&&n.function.name.length>0&&(n.function.description===void 0||typeof n.function.description=="string")&&(n.function.parameters===void 0||n.function.parameters!==null&&typeof n.function.parameters=="object"&&!Array.isArray(n.function.parameters)&&n.function.parameters.type==="object"))))throw new s(400,"invalid_request","invalid tools","tools");if(t.tool_choice!==void 0&&t.tool_choice!=="auto"&&t.tool_choice!=="none"&&t.tool_choice!=="required"&&(typeof t.tool_choice!="object"||t.tool_choice===null||t.tool_choice.type!=="function"||typeof t.tool_choice.function?.name!="string"))throw new s(400,"invalid_request","invalid tool_choice","tool_choice");if(t.messages.some(n=>n.role==="assistant"&&n.tool_calls!==void 0&&(!Array.isArray(n.tool_calls)||!n.tool_calls.every(i=>i&&typeof i.id=="string"&&typeof i.function?.name=="string"&&typeof i.function.arguments=="string"&&Qe(i.function.arguments)))))throw new s(400,"invalid_request","invalid assistant tool_calls","messages");if(t.stop!==void 0&&!(typeof t.stop=="string"||Array.isArray(t.stop)&&t.stop.every(n=>typeof n=="string")))throw new s(400,"invalid_request","invalid stop","stop");if(t.seed!==void 0&&!Number.isSafeInteger(t.seed))throw new s(400,"invalid_request","invalid seed","seed");for(const[n,i]of[["temperature",t.temperature],["top_p",t.top_p],["max_tokens",t.max_tokens]])if(i!==void 0&&(typeof i!="number"||!Number.isFinite(i)||n==="temperature"&&(i<0||i>2)||n==="top_p"&&(i<0||i>1)||n==="max_tokens"&&(!Number.isSafeInteger(i)||i<1)))throw new s(400,"invalid_request",`invalid ${n}`,n);if(t.response_format!==void 0){const n=t.response_format;if(!n||typeof n!="object"||Array.isArray(n)||!["text","json_object","json_schema"].includes(n.type)||n.type==="json_schema"&&(typeof n.json_schema?.name!="string"||!n.json_schema.name||!n.json_schema.schema||typeof n.json_schema.schema!="object"||Array.isArray(n.json_schema.schema)))throw new s(400,"invalid_request","invalid response_format","response_format")}if(t.metadata!==void 0&&Buffer.byteLength(JSON.stringify(t.metadata)??"")>4096)throw new s(400,"invalid_request","metadata exceeds 4 KB","metadata");return t}c(Mt,"parseLlmRequest");function Qe(e){try{const t=JSON.parse(e);return t!==null&&typeof t=="object"&&!Array.isArray(t)}catch{return!1}}c(Qe,"isJsonObject");function Ve(e){const t=Date.now(),n=e.messages.map(r=>r.role==="system"?{role:"system",content:r.content??"",timestamp:t}:r.role==="tool"?{role:"toolResult",toolCallId:r.tool_call_id??"",toolName:"",content:typeof r.content=="string"||r.content===null?[{type:"text",text:r.content??""}]:be(r.content),isError:!1,timestamp:t}:r.role==="assistant"?{role:"assistant",content:[...r.content?[{type:"text",text:r.content}]:[],...(r.tool_calls??[]).map(_=>({type:"toolCall",id:_.id,name:_.function.name,arguments:JSON.parse(_.function.arguments)}))],api:"openai-completions",provider:"openai",model:e.model??"",usage:{input:0,output:0,cacheRead:0,cacheWrite:0,totalTokens:0,cost:{input:0,output:0,cacheRead:0,cacheWrite:0,total:0}},stopReason:"stop",timestamp:t}:{role:"user",content:be(r.content),timestamp:t}),i=n.findIndex(r=>r.role!=="system"),d=n.slice(0,i<0?n.length:i).map(r=>r.content),y=d.join(`
|
|
2
2
|
|
|
3
|
-
`),h=e.tools?.map(({function:r})=>({name:r.name,description:r.description??"",parameters:r.parameters??{type:"object",properties:{}}}));return{...y?{systemPrompt:y}:{},messages:n.slice(d.length),...h?{tools:h}:{}}}c(Ve,"contextOf");function ve(e,t,n,i){const d=c(()=>{const h=me(n,i),r=Object.values({...h.modelRoutes??{},...h.legacyModelRoutes??{}});return r.length?[h.modelLadders.defaultProvider,...h.modelRouting?.familyOrder??[],...r.map(_=>_.family)].find(_=>r.some($=>$.family===_)):h.modelLadders.defaultProvider??"anthropic"},"ownerFamily");if(!e){const h=d();return{kind:"logical",family:h,strength:"strong",spec:`${h}/strong`}}const y=/^([^/]+)\/(ultra|strong|medium|light)$/.exec(e);if(y){if(y[1]===Ie){const h=d();return{kind:"logical",family:h,strength:y[2],spec:`${h}/${y[2]}`}}return{kind:"logical",family:y[1],strength:y[2],spec:e}}return{kind:t==="exact"?"exact":"concrete",spec:e}}c(ve,"requestFor");function et(e,t){const{input:n,output:i,cacheRead:d,cacheWrite:y}=e.cost;return n===0&&i===0&&d===0&&y===0?null:Number.isFinite(t)&&t>=0?t:null}c(et,"usdEquivalent");function tt(e,t){return e.compat?.allowedFallbackModels?.find(i=>i.provider===e.provider&&i.model===t)}c(tt,"allowedFallback");function Mt(e){return e?{payer:e.payer??"user",sub:e.sub,grantee:e.grantee,inference_endpoint:e.inference_endpoint??null}:void 0}c(Mt,"llmCallerOf");function ot(e){return e instanceof Xe?e.code==="server_error"?new s(503,"upstream_model_unavailable",e.message):new s(404,"model_unavailable",e.message):e}c(ot,"mintFailure");const nt=/\bmodel is not supported when using Codex with a ChatGPT account\b/i;function rt(e,t,n){if(!(e!=="openai-codex"||t===void 0||!nt.test(t)))return new s(404,"model_unavailable",t,void 0,{served_model:n})}c(rt,"codexAccountModelRejection");function it(e){return e.get("request-id")??e.get("x-request-id")}c(it,"vendorRequestId");async function jt(e,t,n,i,d,y,h){const r=y?.payer==="app"?y:void 0;if(e.payer==="app"&&!r)throw new s(403,"payer_not_app","this grant is not app-paid");if(e.payer==="user"&&r)throw new s(400,"invalid_request","this grant is app-paid; payer cannot be user","payer");if(r&&!r.inference_endpoint)throw new s(404,"model_unavailable",`${r.grantee} is app-paid but its grant carries no inference endpoint`);const _=r?.inference_endpoint??void 0,$=d===void 0?null:r?.sub??d.sub??await He(),E=await Oe(),ie=c(u=>u.routeId!=="concrete"&&u.routeId!=="exact","configured"),se=c(u=>{const g=E.find(u.providerId,u.modelId);return g!==void 0&&(!e.reasoning_effort||g.reasoning)&&(e.seed===void 0&&e.response_format===void 0||g.api==="openai-completions")&&(e.stop===void 0||["openai-completions","anthropic-messages"].includes(g.api))},"matchesFeatures"),xe=c(()=>{const u=ve(e.model,e.model_policy,i?.cwd,i?.profileId),g=ue(u.kind==="exact"?{kind:"concrete",spec:u.spec}:u,i?.cwd,i?.profileId).filter(ie);let a;if(u.kind==="logical")a=e.model_policy==="exact"?g.filter(f=>f.family===u.family&&f.strength===u.strength).slice(0,1):g;else{const f=fe(u.spec),A=g.filter(q=>q.providerId===f?.providerId&&q.modelId===f.modelId&&(e.model_policy!=="exact"||q.thinkingLevel===f.thinkingLevel)&&se(q));if(e.model_policy==="exact")a=A.slice(0,1);else if(A.length)a=A;else{const q=me(i?.cwd,i?.profileId),k=[...Object.values(q.modelRoutes??{}).flatMap(v=>Object.entries(v.models)),...[q.modelLadders.anthropic,q.modelLadders.openai].flatMap(v=>Object.entries(v))].find(([,v])=>v===u.spec)?.[0],m=ve(void 0,"substitute",i?.cwd,i?.profileId);a=k&&m.kind==="logical"?ue({...m,strength:k,spec:u.spec},i?.cwd,i?.profileId).filter(v=>ie(v)&&v.strength===k):[]}}return a},"ownerCandidates");let C;if(_?C=Ge(_,e.model,e.model_policy==="exact").flatMap((u,g)=>{const a=fe(u.model);return a?[{routeId:"app",credentialSource:"app",family:"app",strength:u.strength,...a,rank:g}]:[]}):C=xe(),C=C.filter(se),C.length===0)throw e.model_policy==="exact"?new s(400,"substitution_refused","no eligible model route is configured"):new s(404,"model_unavailable","no eligible model route is configured");const D=`chatcmpl-${Re()}`;let O=1/0,b,X,G;const ae=c(async()=>h??(d?.node?(await we(d.node))?.caused_by??null:null)??(d?.run?(await we(d.run))?.caused_by??null:null),"causeOf");for(const u of C){if(!r&&!Ce(u,E).authenticated)continue;const g=E.find(u.providerId,u.modelId);if(!g)continue;const a=_?{...g,baseUrl:`${_.base_url}/${g.provider}`}:g,f=u.providerId,A=!r&&K(f)?Ee(f).filter(k=>!k.authFailure):[],q=A.filter(k=>he(k,a.id)<=Date.now());if(A.length&&!q.length){const k=Math.min(...A.map(m=>he(m,a.id)));k<O&&(O=k,X=`${a.provider}/${a.id}`);continue}const le=r?[void 0,void 0]:A.length?q:[void 0];for(const[k,m]of le.entries()){const v=Date.now();let de=m?.access;if(m&&m.expires<=Date.now()&&K(f)){const o=E.getProvider(f)?.auth.oauth;if(!o)throw new s(503,"upstream_model_unavailable",`no OAuth refresh for ${f}`,void 0,{served_model:`${a.provider}/${a.id}`});de=(await Ne(f,m.label,async(x,ce)=>{const H=await o.refresh({type:"oauth",refresh:x,access:"",expires:0,...ce?{clientId:ce}:{}},t??new AbortController().signal).catch(je=>{throw Ze(je,`${a.provider}/${a.id}`)}),ne=H.clientId;return{refresh:H.refresh,access:H.access,expires:H.expires,...typeof ne=="string"&&ne?{clientId:ne}:{}}})).access}const ke=Ve(e),S=m||r?void 0:await E.getApiKeyAndHeaders(a);if(S&&!S.ok)continue;const p=`${a.provider}/${a.id}`,L=e.model??p,R=r?ge({call:"model",route:"endpoint",grantee:r.grantee}):$===null?null:ge({call:"model",route:m?"subscription":"key",sub:$});if(d!==void 0&&R!==null){const o=await We({scope:"call",payer:R.payer,funding:R.funding,sub:$,grantee:d.grantee,provider:f});if(o!==null){await ye({request:d.request??D,kind:"model",what:p,usd:null,payer:R.payer,funding:R.funding,sub:$,grantee:d.grantee,node:d.node??null,run:d.run??null,provider:f,causedBy:await ae(),refused:Be(o)}),G??=o;break}}let P;if(r&&_)try{P=await Ke({audience:_.base_url,sub:r.sub,grantee:r.grantee,initiating_app:r.grantee,scope:["crtr:llm"]},{signal:t})}catch(o){throw ot(o)}let j=!1,F,Y=null,M=3e4,I;const Z=[],Q=[],T=[];let l,J;const W=c((o,w=null)=>({id:D,object:"chat.completion.chunk",created:Math.floor(v/1e3),model:p,served_model:p,requested_model:L,substituted:L!==p&&!/^([^/]+)\/(ultra|strong|medium|light)$/.test(L),choices:[{index:0,delta:o,finish_reason:w}]}),"chunk"),U=c(o=>{Z.push(o),n?.(o)},"emit"),qe=$e(a,ke,{apiKey:P?.access_token??de??(S?.ok?S.apiKey:void 0),...S?.ok?{headers:S.headers}:{},signal:t,reasoning:e.reasoning_effort??u.thinkingLevel,...e.temperature!==void 0?{temperature:e.temperature}:{},...e.max_tokens!==void 0?{maxTokens:e.max_tokens}:{},...e.top_p!==void 0?{samplingParams:{top_p:e.top_p}}:{},...e.tool_choice==="none"?{toolChoice:"none"}:{},onPayload:c(o=>{if(!o||typeof o!="object")return;const w=e.tool_choice,x=w==="required"?a.api==="anthropic-messages"?{type:"any"}:"required":typeof w=="object"&&w!==null?a.api==="anthropic-messages"?{type:"tool",name:w.function.name}:w:void 0;return{...o,...x?{tool_choice:x}:{},...e.stop!==void 0?{[a.api==="anthropic-messages"?"stop_sequences":"stop"]:typeof e.stop=="string"?[e.stop]:e.stop}:{},...e.seed!==void 0?{seed:e.seed}:{},...e.response_format!==void 0?{response_format:e.response_format}:{}}},"onPayload"),fetch:c(async(o,w)=>{const x=await fetch(o,w);return F=x.status,Y=it(x.headers)??Y,x.status===429&&(j=!0,I=x.headers,M=z(x.headers)??15e3),x},"fetch"),onResponse:c(o=>{o.status===429&&(j=!0,I=o.headers,M=z(o.headers)??15e3)},"onResponse")});try{for await(const o of qe)o.type==="text_delta"&&(Q.push(o.delta),U(W({content:o.delta}))),o.type==="thinking_delta"&&(T.push(o.delta),U(W({reasoning_content:o.delta}))),o.type==="done"&&(l=o.message),o.type==="error"&&(l=o.error)}catch(o){const w=Fe(o);I===void 0&&o&&typeof o=="object"&&"headers"in o&&Object.keys(Te(o.headers)).length&&(I=o.headers);const x=re({status:o&&typeof o=="object"&&"status"in o?o.status:void 0,message:o instanceof Error?o.message:String(o)});if(r)J=o;else{if(!j&&x.kind!=="rate-limit")throw Z.length?new s(503,"upstream_model_unavailable",o instanceof Error?o.message:String(o),void 0,{served_model:p}):o;j=!0,M=w??M}}if(r){if(F===401){if(P&&ze(P.key),k===0)continue;throw new s(404,"model_unavailable",`${_.base_url} refuses this runtime's tokens`,void 0,{served_model:p})}if(j&&z(I)===void 0)throw new s(503,"upstream_model_unavailable",`${p} was rate-limited without a retry-after`,void 0,{served_model:p});if(!j&&(J!==void 0||F!==void 0&&F>=500))throw new s(503,"upstream_model_unavailable",J instanceof Error?J.message:l?.errorMessage??"inference endpoint failed",void 0,{served_model:p})}if(!j&&l?.stopReason==="error"&&re({message:l.errorMessage}).kind==="rate-limit"&&(j=!0,M=15e3),j){const o=Pe(I,a.id);if(z(I)===void 0&&o.resetAt!==void 0&&(M=Math.max(M,o.resetAt-Date.now())),b={provider:f,model:a.id,...m?{account:m.label}:{},observation:o},console.error(`[llm] 429 from ${p}${m?` account "${m.label}"`:""}: scope=${_e(o.scope)} retry_after_ms=${M} headers=${JSON.stringify(o.headers)}`),m&&K(f)&&await Se(f,m.label,M,v,Date.now(),o.scope),Date.now()+Math.min(M,pe)<O&&(O=Date.now()+Math.min(M,pe),X=p),Q.length||T.length)throw new s(503,"service_unavailable","vendor rate limit after output began",void 0,{served_model:p});if(r)break;continue}const B=Je(l);if(F===400&&e.tool_choice!==void 0&&e.tool_choice!=="auto"&&e.tool_choice!=="none"&&/\btool[_ ]choice\b/i.test(l?.errorMessage??"")&&/not supported|does not support|unsupported|cannot|must be auto/i.test(l?.errorMessage??""))throw new s(400,"invalid_request",l.errorMessage,"tool_choice",{served_model:p});if(l?.stopReason==="error"){const o=rt(a.provider,l.errorMessage,p);if(o)throw o}if(!l||l.stopReason==="error"&&!B||l.stopReason==="aborted")throw new s(503,"upstream_model_unavailable",l?.errorMessage??"model request failed",void 0,{served_model:p});m&&K(f)&&De(m,a.id)&&await Le(f,m.label,v,a.id);const V=l.content.filter(o=>o.type==="toolCall").map(o=>({id:o.id,type:"function",function:{name:o.name,arguments:JSON.stringify(o.arguments)}})),ee=B?"content_filter":l.stopReason==="toolUse"?"tool_calls":l.stopReason==="length"?"length":"stop",te=l.responseModel?tt(a,l.responseModel):void 0,N=te?`${a.provider}/${te.model}`:p,oe={prompt_tokens:l.usage.input,completion_tokens:l.usage.output,total_tokens:l.usage.totalTokens,cache_read_tokens:l.usage.cacheRead,cache_write_tokens:l.usage.cacheWrite,usd_equivalent:et(te??a,l.usage.cost.total),served_model:N};d!==void 0&&R!==null&&await ye({request:d.request??D,kind:"model",what:N,units:{input:l.usage.input,output:l.usage.output,cache_read:l.usage.cacheRead,cache_write:l.usage.cacheWrite},usd:oe.usd_equivalent,payer:R.payer,funding:R.funding,sub:$,grantee:d.grantee,node:d.node??null,run:d.run??null,provider:f,causedBy:await ae(),vendorRef:Y});const Me={id:D,object:"chat.completion",created:Math.floor(v/1e3),model:N,served_model:N,requested_model:L,substituted:L!==N&&!/^([^/]+)\/(ultra|strong|medium|light)$/.test(L),choices:[{index:0,message:{role:"assistant",content:Q.join("")||null,...T.length?{reasoning_content:T.join("")}:{},...V.length?{tool_calls:V}:{},...B?{refusal:l.errorMessage??"Content filtered"}:{}},finish_reason:ee}],usage:oe,...e.metadata!==void 0?{metadata:e.metadata}:{}};for(const[o,w]of V.entries())U(W({tool_calls:[{index:o,...w}]}));return U({...W({},ee),...B?{choices:[{index:0,delta:{},finish_reason:ee,message:{refusal:l.errorMessage??"Content filtered"}}]}:{},usage:oe}),{completion:Me,chunks:Z}}}throw G!==void 0?Ue(G):O!==1/0?new s(429,"all_routes_exhausted","all eligible model routes are rate-limited",void 0,{retry_after_s:Math.max(1,Math.ceil((O-Date.now())/1e3)),served_model:b?`${b.provider}/${b.model}`:X,...b?{rate_limit:{provider:b.provider,model:b.model,...b.account?{account:b.account}:{},scope:_e(b.observation.scope),...b.observation.claim?{claim:b.observation.claim}:{},headers:b.observation.headers}}:{}},void 0,!0):e.model_policy==="exact"?new s(400,"substitution_refused","the requested model is unavailable"):new s(404,"model_unavailable","no usable model route is available")}c(jt,"runLlm");export{Mt as llmCallerOf,qt as parseLlmRequest,jt as runLlm};
|
|
3
|
+
`),h=e.tools?.map(({function:r})=>({name:r.name,description:r.description??"",parameters:r.parameters??{type:"object",properties:{}}}));return{...y?{systemPrompt:y}:{},messages:n.slice(d.length),...h?{tools:h}:{}}}c(Ve,"contextOf");function ve(e,t,n,i){const d=c(()=>{const h=me(n,i),r=Object.values({...h.modelRoutes??{},...h.legacyModelRoutes??{}});return r.length?[h.modelLadders.defaultProvider,...h.modelRouting?.familyOrder??[],...r.map(_=>_.family)].find(_=>r.some($=>$.family===_)):h.modelLadders.defaultProvider??"anthropic"},"ownerFamily");if(!e){const h=d();return{kind:"logical",family:h,strength:"strong",spec:`${h}/strong`}}const y=/^([^/]+)\/(ultra|strong|medium|light)$/.exec(e);if(y){if(y[1]===Ce){const h=d();return{kind:"logical",family:h,strength:y[2],spec:`${h}/${y[2]}`}}return{kind:"logical",family:y[1],strength:y[2],spec:e}}return{kind:t==="exact"?"exact":"concrete",spec:e}}c(ve,"requestFor");function et(e,t){const{input:n,output:i,cacheRead:d,cacheWrite:y}=e.cost;return n===0&&i===0&&d===0&&y===0?null:Number.isFinite(t)&&t>=0?t:null}c(et,"usdEquivalent");function tt(e,t){return e.compat?.allowedFallbackModels?.find(i=>i.provider===e.provider&&i.model===t)}c(tt,"allowedFallback");function jt(e){return e?{payer:e.payer??"user",sub:e.sub,grantee:e.grantee,inference_endpoint:e.inference_endpoint??null}:void 0}c(jt,"llmCallerOf");function ot(e){return e instanceof Xe?e.code==="server_error"?new s(503,"upstream_model_unavailable",e.message):new s(404,"model_unavailable",e.message):e}c(ot,"mintFailure");const nt=/\bmodel is not supported when using Codex with a ChatGPT account\b/i;function rt(e,t,n){if(!(e!=="openai-codex"||t===void 0||!nt.test(t)))return new s(404,"model_unavailable",t,void 0,{served_model:n})}c(rt,"codexAccountModelRejection");function it(e){return e.get("request-id")??e.get("x-request-id")}c(it,"vendorRequestId");async function At(e,t,n,i,d,y,h){const r=y?.payer==="app"?y:void 0;if(e.payer==="app"&&!r)throw new s(403,"payer_not_app","this grant is not app-paid");if(e.payer==="user"&&r)throw new s(400,"invalid_request","this grant is app-paid; payer cannot be user","payer");if(r&&!r.inference_endpoint)throw new s(404,"model_unavailable",`${r.grantee} is app-paid but its grant carries no inference endpoint`);const _=r?.inference_endpoint??void 0,$=d===void 0?null:r?.sub??d.sub??await He(),E=await Oe(),ie=c(u=>u.routeId!=="concrete"&&u.routeId!=="exact","configured"),se=c(u=>{const g=E.find(u.providerId,u.modelId);return g!==void 0&&(!e.reasoning_effort||g.reasoning)&&(e.seed===void 0&&e.response_format===void 0||g.api==="openai-completions")&&(e.stop===void 0||["openai-completions","anthropic-messages"].includes(g.api))},"matchesFeatures"),xe=c(async()=>{const u=ve(e.model,e.model_policy,i?.cwd,i?.profileId),g=(await ue(u.kind==="exact"?{kind:"concrete",spec:u.spec}:u,i?.cwd,i?.profileId)).filter(ie);let a;if(u.kind==="logical")a=e.model_policy==="exact"?g.filter(f=>f.family===u.family&&f.strength===u.strength).slice(0,1):g;else{const f=fe(u.spec),A=g.filter(q=>q.providerId===f?.providerId&&q.modelId===f.modelId&&(e.model_policy!=="exact"||q.thinkingLevel===f.thinkingLevel)&&se(q));if(e.model_policy==="exact")a=A.slice(0,1);else if(A.length)a=A;else{const q=me(i?.cwd,i?.profileId),k=[...Object.values(q.modelRoutes??{}).flatMap(v=>Object.entries(v.models)),...[q.modelLadders.anthropic,q.modelLadders.openai].flatMap(v=>Object.entries(v))].find(([,v])=>v===u.spec)?.[0],m=ve(void 0,"substitute",i?.cwd,i?.profileId);a=k&&m.kind==="logical"?(await ue({...m,strength:k,spec:u.spec},i?.cwd,i?.profileId)).filter(v=>ie(v)&&v.strength===k):[]}}return a},"ownerCandidates");let C;if(_?C=Ge(_,e.model,e.model_policy==="exact").flatMap((u,g)=>{const a=fe(u.model);return a?[{routeId:"app",credentialSource:"app",family:"app",strength:u.strength,...a,rank:g}]:[]}):C=await xe(),C=C.filter(se),C.length===0)throw e.model_policy==="exact"?new s(400,"substitution_refused","no eligible model route is configured"):new s(404,"model_unavailable","no eligible model route is configured");const D=`chatcmpl-${Re()}`;let O=1/0,b,X,G;const ae=c(async()=>h??(d?.node?(await we(d.node))?.caused_by??null:null)??(d?.run?(await we(d.run))?.caused_by??null:null),"causeOf");for(const u of C){if(!r&&!(await Ie(u,E)).authenticated)continue;const g=E.find(u.providerId,u.modelId);if(!g)continue;const a=_?{...g,baseUrl:`${_.base_url}/${g.provider}`}:g,f=u.providerId,A=!r&&K(f)?(await Ee(f)).filter(k=>!k.authFailure):[],q=A.filter(k=>he(k,a.id)<=Date.now());if(A.length&&!q.length){const k=Math.min(...A.map(m=>he(m,a.id)));k<O&&(O=k,X=`${a.provider}/${a.id}`);continue}const le=r?[void 0,void 0]:A.length?q:[void 0];for(const[k,m]of le.entries()){const v=Date.now();let de=m?.access;if(m&&m.expires<=Date.now()&&K(f)){const o=E.getProvider(f)?.auth.oauth;if(!o)throw new s(503,"upstream_model_unavailable",`no OAuth refresh for ${f}`,void 0,{served_model:`${a.provider}/${a.id}`});de=(await Ne(f,m.label,async(x,ce)=>{const H=await o.refresh({type:"oauth",refresh:x,access:"",expires:0,...ce?{clientId:ce}:{}},t??new AbortController().signal).catch(je=>{throw Ze(je,`${a.provider}/${a.id}`)}),ne=H.clientId;return{refresh:H.refresh,access:H.access,expires:H.expires,...typeof ne=="string"&&ne?{clientId:ne}:{}}})).access}const ke=Ve(e),S=m||r?void 0:await E.getApiKeyAndHeaders(a);if(S&&!S.ok)continue;const p=`${a.provider}/${a.id}`,L=e.model??p,R=r?ge({call:"model",route:"endpoint",grantee:r.grantee}):$===null?null:ge({call:"model",route:m?"subscription":"key",sub:$});if(d!==void 0&&R!==null){const o=await We({scope:"call",payer:R.payer,funding:R.funding,sub:$,grantee:d.grantee,provider:f});if(o!==null){await ye({request:d.request??D,kind:"model",what:p,usd:null,payer:R.payer,funding:R.funding,sub:$,grantee:d.grantee,node:d.node??null,run:d.run??null,provider:f,causedBy:await ae(),refused:Be(o)}),G??=o;break}}let P;if(r&&_)try{P=await Ke({audience:_.base_url,sub:r.sub,grantee:r.grantee,initiating_app:r.grantee,scope:["crtr:llm"]},{signal:t})}catch(o){throw ot(o)}let j=!1,F,Y=null,M=3e4,I;const Z=[],Q=[],T=[];let l,J;const W=c((o,w=null)=>({id:D,object:"chat.completion.chunk",created:Math.floor(v/1e3),model:p,served_model:p,requested_model:L,substituted:L!==p&&!/^([^/]+)\/(ultra|strong|medium|light)$/.test(L),choices:[{index:0,delta:o,finish_reason:w}]}),"chunk"),U=c(o=>{Z.push(o),n?.(o)},"emit"),qe=$e(a,ke,{apiKey:P?.access_token??de??(S?.ok?S.apiKey:void 0),...S?.ok?{headers:S.headers}:{},signal:t,reasoning:e.reasoning_effort??u.thinkingLevel,...e.temperature!==void 0?{temperature:e.temperature}:{},...e.max_tokens!==void 0?{maxTokens:e.max_tokens}:{},...e.top_p!==void 0?{samplingParams:{top_p:e.top_p}}:{},...e.tool_choice==="none"?{toolChoice:"none"}:{},onPayload:c(o=>{if(!o||typeof o!="object")return;const w=e.tool_choice,x=w==="required"?a.api==="anthropic-messages"?{type:"any"}:"required":typeof w=="object"&&w!==null?a.api==="anthropic-messages"?{type:"tool",name:w.function.name}:w:void 0;return{...o,...x?{tool_choice:x}:{},...e.stop!==void 0?{[a.api==="anthropic-messages"?"stop_sequences":"stop"]:typeof e.stop=="string"?[e.stop]:e.stop}:{},...e.seed!==void 0?{seed:e.seed}:{},...e.response_format!==void 0?{response_format:e.response_format}:{}}},"onPayload"),fetch:c(async(o,w)=>{const x=await fetch(o,w);return F=x.status,Y=it(x.headers)??Y,x.status===429&&(j=!0,I=x.headers,M=z(x.headers)??15e3),x},"fetch"),onResponse:c(o=>{o.status===429&&(j=!0,I=o.headers,M=z(o.headers)??15e3)},"onResponse")});try{for await(const o of qe)o.type==="text_delta"&&(Q.push(o.delta),U(W({content:o.delta}))),o.type==="thinking_delta"&&(T.push(o.delta),U(W({reasoning_content:o.delta}))),o.type==="done"&&(l=o.message),o.type==="error"&&(l=o.error)}catch(o){const w=Fe(o);I===void 0&&o&&typeof o=="object"&&"headers"in o&&Object.keys(Te(o.headers)).length&&(I=o.headers);const x=re({status:o&&typeof o=="object"&&"status"in o?o.status:void 0,message:o instanceof Error?o.message:String(o)});if(r)J=o;else{if(!j&&x.kind!=="rate-limit")throw Z.length?new s(503,"upstream_model_unavailable",o instanceof Error?o.message:String(o),void 0,{served_model:p}):o;j=!0,M=w??M}}if(r){if(F===401){if(P&&ze(P.key),k===0)continue;throw new s(404,"model_unavailable",`${_.base_url} refuses this runtime's tokens`,void 0,{served_model:p})}if(j&&z(I)===void 0)throw new s(503,"upstream_model_unavailable",`${p} was rate-limited without a retry-after`,void 0,{served_model:p});if(!j&&(J!==void 0||F!==void 0&&F>=500))throw new s(503,"upstream_model_unavailable",J instanceof Error?J.message:l?.errorMessage??"inference endpoint failed",void 0,{served_model:p})}if(!j&&l?.stopReason==="error"&&re({message:l.errorMessage}).kind==="rate-limit"&&(j=!0,M=15e3),j){const o=Pe(I,a.id);if(z(I)===void 0&&o.resetAt!==void 0&&(M=Math.max(M,o.resetAt-Date.now())),b={provider:f,model:a.id,...m?{account:m.label}:{},observation:o},console.error(`[llm] 429 from ${p}${m?` account "${m.label}"`:""}: scope=${_e(o.scope)} retry_after_ms=${M} headers=${JSON.stringify(o.headers)}`),m&&K(f)&&await Se(f,m.label,M,v,Date.now(),o.scope),Date.now()+Math.min(M,pe)<O&&(O=Date.now()+Math.min(M,pe),X=p),Q.length||T.length)throw new s(503,"service_unavailable","vendor rate limit after output began",void 0,{served_model:p});if(r)break;continue}const B=Je(l);if(F===400&&e.tool_choice!==void 0&&e.tool_choice!=="auto"&&e.tool_choice!=="none"&&/\btool[_ ]choice\b/i.test(l?.errorMessage??"")&&/not supported|does not support|unsupported|cannot|must be auto/i.test(l?.errorMessage??""))throw new s(400,"invalid_request",l.errorMessage,"tool_choice",{served_model:p});if(l?.stopReason==="error"){const o=rt(a.provider,l.errorMessage,p);if(o)throw o}if(!l||l.stopReason==="error"&&!B||l.stopReason==="aborted")throw new s(503,"upstream_model_unavailable",l?.errorMessage??"model request failed",void 0,{served_model:p});m&&K(f)&&De(m,a.id)&&await Le(f,m.label,v,a.id);const V=l.content.filter(o=>o.type==="toolCall").map(o=>({id:o.id,type:"function",function:{name:o.name,arguments:JSON.stringify(o.arguments)}})),ee=B?"content_filter":l.stopReason==="toolUse"?"tool_calls":l.stopReason==="length"?"length":"stop",te=l.responseModel?tt(a,l.responseModel):void 0,N=te?`${a.provider}/${te.model}`:p,oe={prompt_tokens:l.usage.input,completion_tokens:l.usage.output,total_tokens:l.usage.totalTokens,cache_read_tokens:l.usage.cacheRead,cache_write_tokens:l.usage.cacheWrite,usd_equivalent:et(te??a,l.usage.cost.total),served_model:N};d!==void 0&&R!==null&&await ye({request:d.request??D,kind:"model",what:N,units:{input:l.usage.input,output:l.usage.output,cache_read:l.usage.cacheRead,cache_write:l.usage.cacheWrite},usd:oe.usd_equivalent,payer:R.payer,funding:R.funding,sub:$,grantee:d.grantee,node:d.node??null,run:d.run??null,provider:f,causedBy:await ae(),vendorRef:Y});const Me={id:D,object:"chat.completion",created:Math.floor(v/1e3),model:N,served_model:N,requested_model:L,substituted:L!==N&&!/^([^/]+)\/(ultra|strong|medium|light)$/.test(L),choices:[{index:0,message:{role:"assistant",content:Q.join("")||null,...T.length?{reasoning_content:T.join("")}:{},...V.length?{tool_calls:V}:{},...B?{refusal:l.errorMessage??"Content filtered"}:{}},finish_reason:ee}],usage:oe,...e.metadata!==void 0?{metadata:e.metadata}:{}};for(const[o,w]of V.entries())U(W({tool_calls:[{index:o,...w}]}));return U({...W({},ee),...B?{choices:[{index:0,delta:{},finish_reason:ee,message:{refusal:l.errorMessage??"Content filtered"}}]}:{},usage:oe}),{completion:Me,chunks:Z}}}throw G!==void 0?Ue(G):O!==1/0?new s(429,"all_routes_exhausted","all eligible model routes are rate-limited",void 0,{retry_after_s:Math.max(1,Math.ceil((O-Date.now())/1e3)),served_model:b?`${b.provider}/${b.model}`:X,...b?{rate_limit:{provider:b.provider,model:b.model,...b.account?{account:b.account}:{},scope:_e(b.observation.scope),...b.observation.claim?{claim:b.observation.claim}:{},headers:b.observation.headers}}:{}},void 0,!0):e.model_policy==="exact"?new s(400,"substitution_refused","the requested model is unavailable"):new s(404,"model_unavailable","no usable model route is available")}c(At,"runLlm");export{jt as llmCallerOf,Mt as parseLlmRequest,At as runLlm};
|