@north-light/cli 0.3.530 → 0.3.531
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/clients/attach/session/connection.js +1 -1
- package/dist/clients/attach/session/reconnect.js +1 -1
- package/dist/clients/attach/viewer.js +3 -3
- package/dist/core/async-array.d.ts +7 -0
- package/dist/core/async-array.js +1 -0
- package/dist/core/audit.d.ts +1 -1
- package/dist/core/audit.js +2 -2
- package/dist/core/canvas/attention.d.ts +4 -4
- package/dist/core/canvas/attention.js +1 -1
- package/dist/core/canvas/boot.d.ts +4 -4
- package/dist/core/canvas/boot.js +1 -1
- package/dist/core/canvas/canvas.d.ts +59 -59
- package/dist/core/canvas/canvas.js +19 -19
- package/dist/core/canvas/context-strip.js +2 -2
- package/dist/core/canvas/crons.d.ts +27 -27
- package/dist/core/canvas/crons.js +11 -11
- package/dist/core/canvas/daemon-actions.d.ts +10 -10
- package/dist/core/canvas/daemon-actions.js +8 -8
- package/dist/core/canvas/daemon-owner.d.ts +3 -3
- package/dist/core/canvas/daemon-owner.js +2 -2
- package/dist/core/canvas/db.d.ts +19 -30
- package/dist/core/canvas/db.js +3 -2
- package/dist/core/canvas/deliveries.d.ts +16 -16
- package/dist/core/canvas/deliveries.js +24 -24
- package/dist/core/canvas/executions.d.ts +8 -8
- package/dist/core/canvas/executions.js +1 -1
- package/dist/core/canvas/focuses.d.ts +8 -8
- package/dist/core/canvas/focuses.js +1 -1
- package/dist/core/canvas/history.d.ts +3 -3
- package/dist/core/canvas/history.js +9 -9
- package/dist/core/canvas/install-id.d.ts +1 -1
- package/dist/core/canvas/install-id.js +1 -1
- package/dist/core/canvas/managed-worktree-sweep-candidates.d.ts +1 -1
- package/dist/core/canvas/managed-worktree-sweep-candidates.js +2 -2
- package/dist/core/canvas/memory-reads.d.ts +6 -6
- package/dist/core/canvas/memory-reads.js +1 -1
- package/dist/core/canvas/nav-model.d.ts +13 -13
- package/dist/core/canvas/nav-model.js +1 -1
- package/dist/core/canvas/node-agent-paths.d.ts +6 -6
- package/dist/core/canvas/node-agent-paths.js +1 -1
- package/dist/core/canvas/node-tokens.d.ts +7 -7
- package/dist/core/canvas/node-tokens.js +3 -3
- package/dist/core/canvas/outcome-actions.d.ts +5 -5
- package/dist/core/canvas/outcome-actions.js +3 -3
- package/dist/core/canvas/recovery.d.ts +26 -26
- package/dist/core/canvas/recovery.js +2 -2
- package/dist/core/canvas/render-source.d.ts +1 -1
- package/dist/core/canvas/render-source.js +1 -1
- package/dist/core/canvas/sessions.d.ts +10 -10
- package/dist/core/canvas/sessions.js +4 -4
- package/dist/core/canvas/source.js +1 -1
- package/dist/core/canvas/structured-requests.d.ts +15 -15
- package/dist/core/canvas/structured-requests.js +5 -5
- package/dist/core/canvas/tree.d.ts +9 -9
- package/dist/core/canvas/tree.js +5 -5
- package/dist/core/canvas/waits.d.ts +13 -13
- package/dist/core/canvas/waits.js +6 -6
- package/dist/core/canvas/worktrees.d.ts +15 -15
- package/dist/core/canvas/worktrees.js +1 -1
- package/dist/core/command-hooks/transport/exec-lifecycle.js +1 -1
- package/dist/core/conversation-store/file-store.d.ts +7 -7
- package/dist/core/conversation-store/file-store.js +9 -9
- package/dist/core/conversation-store/index.d.ts +16 -14
- package/dist/core/conversation-store/index.js +1 -1
- package/dist/core/conversation-store/listener.js +5 -5
- package/dist/core/conversation-store/patch.d.ts +3 -1
- package/dist/core/conversation-store/patch.js +1 -1
- package/dist/core/feed/feed.js +3 -3
- package/dist/core/feed/inbox.d.ts +2 -2
- package/dist/core/feed/inbox.js +1 -1
- package/dist/core/feed/messages.d.ts +11 -12
- package/dist/core/feed/messages.js +5 -5
- package/dist/core/feed/reports.d.ts +4 -4
- package/dist/core/feed/reports.js +2 -2
- package/dist/core/grants/cover.d.ts +1 -1
- package/dist/core/grants/cover.js +1 -1
- package/dist/core/grants/local.d.ts +1 -1
- package/dist/core/grants/local.js +1 -1
- package/dist/core/grants/mirror.d.ts +19 -19
- package/dist/core/grants/mirror.js +2 -2
- package/dist/core/grants/on-sync.d.ts +1 -1
- package/dist/core/grants/on-sync.js +1 -1
- package/dist/core/grants/remove.js +1 -1
- package/dist/core/grants/sync.js +1 -1
- package/dist/core/graph/access.d.ts +17 -17
- package/dist/core/graph/access.js +3 -3
- package/dist/core/graph/custom.d.ts +16 -16
- package/dist/core/graph/custom.js +9 -9
- package/dist/core/graph/deletion.d.ts +3 -7
- package/dist/core/graph/deletion.js +4 -4
- package/dist/core/graph/documents.d.ts +24 -27
- package/dist/core/graph/documents.js +7 -7
- package/dist/core/graph/edges.d.ts +13 -13
- package/dist/core/graph/edges.js +1 -1
- package/dist/core/graph/events.d.ts +7 -9
- package/dist/core/graph/events.js +8 -8
- package/dist/core/graph/exposures.d.ts +6 -6
- package/dist/core/graph/exposures.js +4 -4
- package/dist/core/graph/jobs.d.ts +6 -8
- package/dist/core/graph/jobs.js +2 -2
- package/dist/core/graph/kinds/action.js +1 -1
- package/dist/core/graph/kinds/custom.js +2 -2
- package/dist/core/graph/kinds/document.d.ts +1 -0
- package/dist/core/graph/kinds/document.js +4 -4
- package/dist/core/graph/kinds/dto.d.ts +2 -2
- package/dist/core/graph/kinds/dto.js +1 -1
- package/dist/core/graph/kinds/job.js +2 -2
- package/dist/core/graph/kinds/kind.d.ts +6 -8
- package/dist/core/graph/kinds/kind.js +1 -1
- package/dist/core/graph/kinds/node.js +5 -5
- package/dist/core/graph/kinds/owner.js +2 -2
- package/dist/core/graph/kinds/registry.d.ts +6 -9
- package/dist/core/graph/kinds/registry.js +1 -1
- package/dist/core/graph/names.d.ts +6 -6
- package/dist/core/graph/names.js +3 -3
- package/dist/core/graph/object-waits.d.ts +4 -7
- package/dist/core/graph/object-waits.js +1 -1
- package/dist/core/graph/objects.d.ts +14 -14
- package/dist/core/graph/objects.js +9 -9
- package/dist/core/graph/package-docs.d.ts +2 -7
- package/dist/core/graph/package-docs.js +5 -5
- package/dist/core/graph/package-kinds.d.ts +2 -5
- package/dist/core/graph/package-kinds.js +1 -1
- package/dist/core/graph/package-reconcile.d.ts +2 -5
- package/dist/core/graph/package-reconcile.js +1 -1
- package/dist/core/graph/reader.d.ts +18 -18
- package/dist/core/graph/reader.js +3 -3
- package/dist/core/graph/receivers.d.ts +4 -4
- package/dist/core/graph/receivers.js +5 -5
- package/dist/core/graph/repo-sync/exchange.d.ts +3 -7
- package/dist/core/graph/repo-sync/exchange.js +2 -2
- package/dist/core/graph/repo-sync/repos.d.ts +7 -5
- package/dist/core/graph/repo-sync/repos.js +3 -3
- package/dist/core/graph/repo-sync/sync.d.ts +3 -6
- package/dist/core/graph/repo-sync/sync.js +2 -2
- package/dist/core/graph/rules.d.ts +5 -5
- package/dist/core/graph/rules.js +3 -3
- package/dist/core/graph/spaces/app.js +1 -1
- package/dist/core/graph/spaces/index.d.ts +4 -5
- package/dist/core/graph/spaces/index.js +1 -1
- package/dist/core/graph/spaces/own-memory.d.ts +4 -4
- package/dist/core/graph/spaces/own-memory.js +1 -1
- package/dist/core/graph/spaces/person.js +3 -3
- package/dist/core/graph/spaces/repo.d.ts +1 -1
- package/dist/core/graph/spaces/repo.js +1 -1
- package/dist/core/graph/watches.d.ts +15 -15
- package/dist/core/graph/watches.js +10 -10
- package/dist/core/human/feedback-companion.d.ts +2 -2
- package/dist/core/human/feedback-companion.js +1 -1
- package/dist/core/human/feedback.d.ts +3 -3
- package/dist/core/human/feedback.js +1 -1
- package/dist/core/human/requests.d.ts +34 -33
- package/dist/core/human/requests.js +20 -20
- package/dist/core/human/scan.d.ts +2 -2
- package/dist/core/human/scan.js +1 -1
- package/dist/core/human/tickets.d.ts +9 -9
- package/dist/core/human/tickets.js +1 -1
- package/dist/core/llm/app-rungs.d.ts +1 -1
- package/dist/core/llm/app-rungs.js +1 -1
- package/dist/core/llm/run.js +1 -1
- package/dist/core/peer/directory.d.ts +1 -1
- package/dist/core/peer/directory.js +1 -1
- package/dist/core/peer/envelope.d.ts +3 -3
- package/dist/core/peer/envelope.js +1 -1
- package/dist/core/peer/home.d.ts +7 -7
- package/dist/core/peer/home.js +2 -2
- package/dist/core/peer/ingest.d.ts +6 -6
- package/dist/core/peer/ingest.js +1 -1
- package/dist/core/peer/outbox-store.d.ts +14 -14
- package/dist/core/peer/outbox-store.js +5 -5
- package/dist/core/peer/receiver.d.ts +2 -2
- package/dist/core/peer/receiver.js +1 -1
- package/dist/core/peer/stubs.d.ts +10 -10
- package/dist/core/peer/stubs.js +1 -1
- package/dist/core/providers/approval.d.ts +2 -2
- package/dist/core/providers/approval.js +2 -2
- package/dist/core/providers/audit.d.ts +3 -3
- package/dist/core/providers/audit.js +2 -2
- package/dist/core/providers/bundles.js +2 -2
- package/dist/core/providers/call.d.ts +2 -2
- package/dist/core/providers/call.js +1 -1
- package/dist/core/providers/files.d.ts +1 -1
- package/dist/core/providers/files.js +1 -1
- package/dist/core/providers/mint.js +1 -1
- package/dist/core/providers/receipts.d.ts +1 -1
- package/dist/core/providers/receipts.js +2 -2
- package/dist/core/review/birth.js +1 -1
- package/dist/core/review/comments.d.ts +19 -19
- package/dist/core/review/comments.js +5 -5
- package/dist/core/review/companion.d.ts +1 -1
- package/dist/core/review/companion.js +1 -1
- package/dist/core/review/document.d.ts +3 -3
- package/dist/core/review/document.js +2 -2
- package/dist/core/review/fork.js +2 -2
- package/dist/core/review/realize.js +1 -1
- package/dist/core/review/remap.d.ts +2 -2
- package/dist/core/review/remap.js +4 -4
- package/dist/core/review/stage.d.ts +1 -1
- package/dist/core/review/stage.js +1 -1
- package/dist/core/review/store.d.ts +21 -21
- package/dist/core/review/store.js +1 -1
- package/dist/core/runs/activity.d.ts +1 -1
- package/dist/core/runs/activity.js +5 -5
- package/dist/core/runs/confinement.d.ts +7 -7
- package/dist/core/runs/confinement.js +2 -2
- package/dist/core/runs/events.d.ts +12 -12
- package/dist/core/runs/events.js +4 -4
- package/dist/core/runs/operations.d.ts +11 -11
- package/dist/core/runs/operations.js +5 -5
- package/dist/core/runs/questions.d.ts +10 -10
- package/dist/core/runs/questions.js +3 -3
- package/dist/core/runtime/auth-reload.js +1 -1
- package/dist/core/runtime/bearings.d.ts +5 -5
- package/dist/core/runtime/bearings.js +6 -6
- package/dist/core/runtime/broker-inventory.js +1 -1
- package/dist/core/runtime/broker-request.js +1 -1
- package/dist/core/runtime/broker.js +1 -1
- package/dist/core/runtime/close.d.ts +3 -3
- package/dist/core/runtime/close.js +1 -1
- package/dist/core/runtime/deliver-live.js +1 -1
- package/dist/core/runtime/fleet.d.ts +2 -2
- package/dist/core/runtime/host.d.ts +3 -3
- package/dist/core/runtime/host.js +3 -3
- package/dist/core/runtime/kickoff.d.ts +12 -12
- package/dist/core/runtime/kickoff.js +17 -17
- package/dist/core/runtime/launch-target.d.ts +1 -1
- package/dist/core/runtime/launch-target.js +1 -1
- package/dist/core/runtime/ledger.d.ts +3 -3
- package/dist/core/runtime/ledger.js +3 -3
- package/dist/core/runtime/lifecycle.d.ts +1 -1
- package/dist/core/runtime/lifecycle.js +2 -2
- package/dist/core/runtime/memory-admission.js +1 -1
- package/dist/core/runtime/model-swap.d.ts +2 -2
- package/dist/core/runtime/model-swap.js +1 -1
- package/dist/core/runtime/node-read.d.ts +1 -1
- package/dist/core/runtime/node-read.js +2 -2
- package/dist/core/runtime/nodes.d.ts +6 -6
- package/dist/core/runtime/nodes.js +1 -1
- package/dist/core/runtime/outcome-document.d.ts +1 -1
- package/dist/core/runtime/outcome-document.js +1 -1
- package/dist/core/runtime/persona.d.ts +3 -3
- package/dist/core/runtime/persona.js +2 -2
- package/dist/core/runtime/placement.d.ts +11 -11
- package/dist/core/runtime/placement.js +1 -1
- package/dist/core/runtime/promote.d.ts +3 -3
- package/dist/core/runtime/promote.js +1 -1
- package/dist/core/runtime/recycle.js +1 -1
- package/dist/core/runtime/reopen.d.ts +5 -5
- package/dist/core/runtime/reopen.js +1 -1
- package/dist/core/runtime/reset.d.ts +4 -4
- package/dist/core/runtime/reset.js +1 -1
- package/dist/core/runtime/revive-all.d.ts +2 -2
- package/dist/core/runtime/revive-all.js +1 -1
- package/dist/core/runtime/revive.d.ts +4 -4
- package/dist/core/runtime/revive.js +2 -2
- package/dist/core/runtime/roadmap.d.ts +6 -6
- package/dist/core/runtime/roadmap.js +5 -5
- package/dist/core/runtime/session-branch.d.ts +1 -1
- package/dist/core/runtime/session-branch.js +1 -1
- package/dist/core/runtime/session-list-cache.js +1 -1
- package/dist/core/runtime/situational-live.js +1 -1
- package/dist/core/runtime/spawn.d.ts +2 -2
- package/dist/core/runtime/spawn.js +2 -2
- package/dist/core/runtime/stop-guard.d.ts +2 -2
- package/dist/core/runtime/stop-guard.js +3 -3
- package/dist/core/runtime/warm-pool.d.ts +2 -2
- package/dist/core/runtime/warm-pool.js +1 -1
- package/dist/core/spaces/mounts.d.ts +2 -2
- package/dist/core/spaces/mounts.js +1 -1
- package/dist/core/spaces/permissions.d.ts +1 -1
- package/dist/core/spaces/permissions.js +1 -1
- package/dist/core/spaces/process.d.ts +1 -1
- package/dist/core/spaces/process.js +1 -1
- package/dist/core/spaces/space.js +1 -1
- package/dist/core/spaces/stop.d.ts +3 -3
- package/dist/core/spaces/stop.js +2 -2
- package/dist/core/spaces/users.d.ts +6 -6
- package/dist/core/spaces/users.js +1 -1
- package/dist/core/storage/attachments.d.ts +2 -2
- package/dist/core/storage/attachments.js +1 -1
- package/dist/core/storage/shares.d.ts +2 -2
- package/dist/core/storage/shares.js +1 -1
- package/dist/core/storage/tables.d.ts +21 -21
- package/dist/core/storage/tables.js +3 -3
- package/dist/core/substrate/delivery/corpus.d.ts +5 -8
- package/dist/core/substrate/delivery/corpus.js +3 -3
- package/dist/core/substrate/delivery/deliver.d.ts +10 -15
- package/dist/core/substrate/delivery/deliver.js +3 -3
- package/dist/core/substrate/delivery/plan.d.ts +2 -12
- package/dist/core/substrate/delivery/plan.js +3 -3
- package/dist/core/substrate/delivery/render-boot.d.ts +4 -4
- package/dist/core/substrate/delivery/render-boot.js +18 -18
- package/dist/core/substrate/delivery/render-event.d.ts +7 -14
- package/dist/core/substrate/delivery/render-event.js +4 -4
- package/dist/core/substrate/subject.d.ts +2 -2
- package/dist/core/substrate/subject.js +1 -1
- package/dist/core/usage/ledger.d.ts +6 -6
- package/dist/core/usage/ledger.js +4 -4
- package/dist/core/worktree-close.js +4 -4
- package/dist/core/worktree-mutation-async.js +7 -7
- package/dist/core/worktree-quarantine.js +1 -1
- package/dist/core/worktree-sweep.d.ts +1 -1
- package/dist/core/worktree-sweep.js +6 -6
- package/dist/core/worktree.d.ts +5 -5
- package/dist/core/worktree.js +13 -13
- package/dist/daemon/analytics/compute.d.ts +2 -2
- package/dist/daemon/analytics/compute.js +1 -1
- package/dist/daemon/api/app-listener.d.ts +4 -4
- package/dist/daemon/api/app-listener.js +13 -13
- package/dist/daemon/api/bridge.js +5 -5
- package/dist/daemon/api/document-listener.js +6 -6
- package/dist/daemon/api/handlers/analytics.js +1 -1
- package/dist/daemon/api/handlers/attach.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 +1 -1
- package/dist/daemon/api/handlers/broker-ops.js +1 -1
- package/dist/daemon/api/handlers/broker-recovery.d.ts +1 -1
- package/dist/daemon/api/handlers/broker-recovery.js +1 -1
- package/dist/daemon/api/handlers/broker-signals.d.ts +2 -2
- package/dist/daemon/api/handlers/broker-signals.js +2 -2
- package/dist/daemon/api/handlers/canvas.d.ts +1 -1
- package/dist/daemon/api/handlers/canvas.js +4 -4
- package/dist/daemon/api/handlers/chat-inventory.js +1 -1
- package/dist/daemon/api/handlers/crons.js +1 -1
- package/dist/daemon/api/handlers/custom-objects.d.ts +4 -4
- package/dist/daemon/api/handlers/custom-objects.js +3 -3
- package/dist/daemon/api/handlers/delivery-retry.js +1 -1
- package/dist/daemon/api/handlers/delivery.js +1 -1
- package/dist/daemon/api/handlers/docs.d.ts +4 -4
- package/dist/daemon/api/handlers/docs.js +1 -1
- package/dist/daemon/api/handlers/feedback-comments.js +3 -3
- package/dist/daemon/api/handlers/files.js +1 -1
- package/dist/daemon/api/handlers/focus.js +1 -1
- package/dist/daemon/api/handlers/health.js +3 -3
- 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-page.d.ts +1 -1
- package/dist/daemon/api/handlers/inbox-page.js +1 -1
- package/dist/daemon/api/handlers/inbox.d.ts +1 -1
- package/dist/daemon/api/handlers/inbox.js +1 -1
- package/dist/daemon/api/handlers/llm.d.ts +1 -1
- package/dist/daemon/api/handlers/llm.js +3 -3
- package/dist/daemon/api/handlers/memory-reads.js +1 -1
- package/dist/daemon/api/handlers/memory.d.ts +5 -5
- package/dist/daemon/api/handlers/memory.js +5 -5
- package/dist/daemon/api/handlers/messages.js +2 -2
- package/dist/daemon/api/handlers/node-events.d.ts +2 -2
- 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 +2 -2
- package/dist/daemon/api/handlers/nodes.d.ts +1 -1
- package/dist/daemon/api/handlers/nodes.js +1 -1
- package/dist/daemon/api/handlers/objects.js +3 -3
- package/dist/daemon/api/handlers/package-docs.js +1 -1
- package/dist/daemon/api/handlers/plugin-app-token.d.ts +1 -1
- package/dist/daemon/api/handlers/plugin-app-token.js +1 -1
- package/dist/daemon/api/handlers/profiles.d.ts +3 -3
- package/dist/daemon/api/handlers/profiles.js +1 -1
- package/dist/daemon/api/handlers/providers.d.ts +1 -1
- package/dist/daemon/api/handlers/providers.js +1 -1
- package/dist/daemon/api/handlers/questions.js +1 -1
- package/dist/daemon/api/handlers/reports.d.ts +1 -1
- package/dist/daemon/api/handlers/reports.js +5 -5
- package/dist/daemon/api/handlers/review-comments.js +1 -1
- package/dist/daemon/api/handlers/reviews.js +1 -1
- package/dist/daemon/api/handlers/runs.js +1 -1
- package/dist/daemon/api/handlers/structured-requests.js +1 -1
- package/dist/daemon/api/handlers/subscriptions.js +1 -1
- package/dist/daemon/api/handlers/transfer.js +1 -1
- package/dist/daemon/api/map.d.ts +3 -3
- package/dist/daemon/api/map.js +1 -1
- package/dist/daemon/api/principal.d.ts +1 -1
- package/dist/daemon/api/principal.js +1 -1
- package/dist/daemon/api/reader.d.ts +5 -5
- package/dist/daemon/api/reader.js +1 -1
- package/dist/daemon/api/router.d.ts +5 -5
- package/dist/daemon/api/router.js +1 -1
- package/dist/daemon/api/server.js +1 -1
- package/dist/daemon/broker-signals/bus.d.ts +1 -1
- package/dist/daemon/broker-signals/bus.js +1 -1
- package/dist/daemon/companion-retire.js +1 -1
- package/dist/daemon/cron/armed-context.d.ts +2 -2
- package/dist/daemon/cron/armed-context.js +1 -1
- package/dist/daemon/cron/authority.d.ts +2 -2
- package/dist/daemon/cron/authority.js +1 -1
- package/dist/daemon/cron/disposition.js +1 -1
- package/dist/daemon/cron/ended.d.ts +1 -1
- package/dist/daemon/cron/ended.js +2 -2
- package/dist/daemon/cron/escalation.js +3 -3
- package/dist/daemon/cron/folders.d.ts +1 -1
- package/dist/daemon/cron/folders.js +1 -1
- package/dist/daemon/cron/held.d.ts +1 -1
- package/dist/daemon/cron/held.js +1 -1
- package/dist/daemon/cron/lease-recovery.d.ts +1 -1
- package/dist/daemon/cron/lease-recovery.js +1 -1
- package/dist/daemon/cron/passes.d.ts +2 -2
- package/dist/daemon/cron/passes.js +1 -1
- package/dist/daemon/cron/run-socket.d.ts +1 -1
- package/dist/daemon/cron/run-socket.js +1 -1
- package/dist/daemon/cron/settle.js +1 -1
- package/dist/daemon/cron/sinks.d.ts +1 -1
- package/dist/daemon/cron/sinks.js +2 -2
- package/dist/daemon/cron-run.d.ts +12 -3
- package/dist/daemon/cron-run.js +2 -2
- package/dist/daemon/crtrd.js +6 -6
- package/dist/daemon/delivery/run-delivery.js +1 -1
- package/dist/daemon/due-sources.d.ts +3 -3
- package/dist/daemon/due-sources.js +1 -1
- package/dist/daemon/due.d.ts +3 -3
- package/dist/daemon/due.js +7 -7
- package/dist/daemon/fleet.d.ts +2 -2
- package/dist/daemon/fleet.js +11 -11
- package/dist/daemon/human/finish.js +3 -3
- package/dist/daemon/human/settle.d.ts +1 -1
- package/dist/daemon/human/settle.js +1 -1
- package/dist/daemon/human/sweep.js +1 -1
- package/dist/daemon/joined-owner.d.ts +2 -2
- package/dist/daemon/joined-owner.js +1 -1
- package/dist/daemon/messaging/node-message.js +1 -1
- package/dist/daemon/park-activity.d.ts +2 -2
- package/dist/daemon/park-activity.js +1 -1
- package/dist/daemon/peer/authority.js +1 -1
- package/dist/daemon/peer/forward.d.ts +6 -6
- package/dist/daemon/peer/forward.js +1 -1
- package/dist/daemon/peer/handlers.js +1 -1
- package/dist/daemon/peer/ingress.d.ts +4 -4
- package/dist/daemon/peer/ingress.js +1 -1
- package/dist/daemon/peer/outbox.d.ts +2 -2
- package/dist/daemon/peer/outbox.js +1 -1
- package/dist/daemon/peer/relay-service.js +1 -1
- package/dist/daemon/plugin-objects/read-leaf.d.ts +2 -2
- package/dist/daemon/plugin-objects/read-leaf.js +2 -2
- package/dist/daemon/profile-delete.js +1 -1
- package/dist/daemon/readiness.d.ts +2 -2
- package/dist/daemon/readiness.js +1 -1
- package/dist/daemon/reconcilers/action-lane.d.ts +1 -1
- package/dist/daemon/reconcilers/action-lane.js +1 -1
- package/dist/daemon/reconcilers/bash-deadline.js +2 -2
- package/dist/daemon/reconcilers/broker-supervision.d.ts +1 -1
- package/dist/daemon/reconcilers/broker-supervision.js +4 -4
- package/dist/daemon/reconcilers/controller-death.d.ts +1 -1
- package/dist/daemon/reconcilers/controller-death.js +1 -1
- package/dist/daemon/reconcilers/cron-lane.d.ts +1 -1
- package/dist/daemon/reconcilers/cron-lane.js +1 -1
- package/dist/daemon/reconcilers/delivery-lane.d.ts +1 -1
- package/dist/daemon/reconcilers/delivery-lane.js +2 -2
- package/dist/daemon/reconcilers/fault-retry-backstop.d.ts +3 -3
- package/dist/daemon/reconcilers/fault-retry-backstop.js +1 -1
- package/dist/daemon/reconcilers/grove-instance-sweep.d.ts +2 -2
- package/dist/daemon/reconcilers/grove-instance-sweep.js +1 -1
- package/dist/daemon/reconcilers/live-obligation.d.ts +6 -6
- package/dist/daemon/reconcilers/live-obligation.js +1 -1
- package/dist/daemon/reconcilers/managed-worktree-sweep.js +1 -1
- package/dist/daemon/reconcilers/node-deadline.d.ts +1 -1
- package/dist/daemon/reconcilers/node-deadline.js +1 -1
- package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.js +1 -1
- package/dist/daemon/reconcilers/node-lifecycle/respawn-policy.d.ts +3 -3
- package/dist/daemon/reconcilers/node-lifecycle/respawn-policy.js +1 -1
- package/dist/daemon/reconcilers/node-lifecycle/terminating.js +1 -1
- package/dist/daemon/reconcilers/node-lifecycle/tick.js +1 -1
- package/dist/daemon/reconcilers/node-lifecycle/wants-execution.d.ts +1 -1
- package/dist/daemon/reconcilers/node-lifecycle/wants-execution.js +1 -1
- package/dist/daemon/reconcilers/pending-review-submit.d.ts +1 -1
- package/dist/daemon/reconcilers/pending-review-submit.js +1 -1
- package/dist/daemon/reconcilers/storage-due-work.js +1 -1
- package/dist/daemon/reconcilers/storage-maintenance.d.ts +1 -1
- package/dist/daemon/reconcilers/storage-maintenance.js +2 -2
- package/dist/daemon/reconcilers/structured-request-lane.d.ts +1 -1
- package/dist/daemon/reconcilers/structured-request-lane.js +1 -1
- package/dist/daemon/review/comment-notify.js +2 -2
- package/dist/daemon/review/companion.d.ts +3 -3
- package/dist/daemon/review/companion.js +1 -1
- package/dist/daemon/review/finish.js +1 -1
- package/dist/daemon/review/sweep.js +1 -1
- package/dist/daemon/run-notices.d.ts +4 -4
- package/dist/daemon/run-notices.js +1 -1
- package/dist/daemon/runs/append-section.d.ts +2 -2
- package/dist/daemon/runs/append-section.js +2 -2
- package/dist/daemon/runs/observer.d.ts +2 -2
- package/dist/daemon/runs/observer.js +2 -2
- package/dist/daemon/structured-requests/boot.d.ts +1 -1
- package/dist/daemon/structured-requests/boot.js +1 -1
- package/dist/daemon/structured-requests/effects.js +1 -1
- package/dist/daemon/structured-requests/sidecar.d.ts +1 -1
- package/dist/daemon/structured-requests/sidecar.js +1 -1
- package/dist/migrations/004-canvas-documents/apply.d.ts +3 -3
- package/dist/migrations/004-canvas-documents/apply.js +1 -1
- package/dist/migrations/004-canvas-documents/index.d.ts +2 -2
- package/dist/migrations/004-canvas-documents/index.js +2 -2
- package/dist/migrations/activation.js +2 -2
- package/docs/public-api.md +11 -0
- package/package.json +3 -2
- package/packages/crouter-identity/package.json +1 -1
- package/runtime.lock.json +12 -12
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
var ue=Object.defineProperty;var
|
|
2
|
-
`),
|
|
1
|
+
var ue=Object.defineProperty;var r=(e,t)=>ue(e,"name",{value:t,configurable:!0});import{prepared as l}from"../sqlite-statements.js";import{createHash as le,randomBytes as L}from"node:crypto";import{existsSync as y,mkdirSync as D,readFileSync as Y,readdirSync as _e,realpathSync as j,statSync as pe,writeFileSync as me}from"node:fs";import{basename as k,join as _}from"node:path";import{z as d}from"zod";import{crtrHome as V,isSafeNodeId as fe,nodesRoot as b}from"../canvas/paths.js";import{withCanvasWrite as Q,openDb as c}from"../canvas/db.js";import{syncDirectory as Ee,syncFile as ye}from"../fs-utils.js";import{newNodeId as ge}from"../runtime/nodes.js";import{pageManifestPath as Ne,pageModulePath as he,pagePath as qe}from"./convention.js";import{preparePageSource as Te}from"./page-authoring.js";import{pageAwaitsResponse as be,pageDeliverySchema as Se,pageIsNoticeSql as we,validatePageManifest as z}from"./page-schema.js";import{appendWaitingOnUser as Ae}from"../runs/questions.js";function G(e){return e===1||e===!0}r(G,"bool");function Z(e){return{request_id:e.request_id,kind:e.kind,inbox_ticket_id:e.inbox_ticket_id,request_dir:e.request_dir,presentation_dir:e.presentation_dir,requester_node_id:e.requester_node_id,companion_node_id:e.companion_node_id,idempotency_key:e.idempotency_key,state:e.state,outcome:e.outcome,inbox_listed:G(e.inbox_listed),settleable:G(e.settleable),title:e.title,subtitle:e.subtitle,file:e.file,specification_json:e.specification_json,action_json:e.action_json,progress_json:e.progress_json,feedback_json:e.feedback_json,result_json:e.result_json,anchor_base_sha256:e.anchor_base_sha256,anchor_base_bytes:e.anchor_base_bytes===null?null:Buffer.from(e.anchor_base_bytes),created_at:e.created_at,opened_at:e.opened_at,submit_requested_at:e.submit_requested_at,settled_at:e.settled_at,settlement_delivery_id:e.settlement_delivery_id,action_delivery_id:e.action_delivery_id,submit_note_delivery_id:e.submit_note_delivery_id,projected_at:e.projected_at,projection_error:e.projection_error,companion_retired_at:e.companion_retired_at,updated_at:e.updated_at}}r(Z,"recordFromRow");async function h(e,t,...i){const s=await e.prepareUncached(`SELECT * FROM human_requests WHERE ${t}`).get(...i);return s===void 0?null:Z(s)}r(h,"one");async function q(e,t,i=[],s="created_at ASC, request_id ASC"){return(await e.prepareUncached(`SELECT * FROM human_requests WHERE ${t} ORDER BY ${s}`).all(...i)).map(Z)}r(q,"many");function ee(){return _(V(),"requests")}r(ee,"humanRequestsRoot");function C(e){if(!fe(e))throw new TypeError(`request_id must be a safe path segment: ${e}`);const t=ee();return D(t,{recursive:!0,mode:448}),_(j(t),e)}r(C,"requestDir");function U(){return L(32).toString("hex")}r(U,"randomTicketId");function P(e,t){return le("sha256").update(`${j(e)}\0${t}`,"utf8").digest("hex")}r(P,"legacyTicketId");const De={writeFile(e,t){me(e,t,{flag:"wx",mode:384})},syncFile:ye,syncDirectory:Ee};function Re(e){return _(e,"revisions")}r(Re,"revisionRoot");function te(e,t,i=De){D(e,{recursive:!0,mode:448});const s=Re(e);D(s,{recursive:!0,mode:448});const n=_(s,L(16).toString("hex"));D(n,{mode:448});const o=qe(n,t.manifest.dialect);if(i.writeFile(o,t.document),i.syncFile(o),t.manifest.dialect==="jsx"){const a=he(n);i.writeFile(a,t.module),i.syncFile(a)}const u=Ne(n);return i.writeFile(u,`${JSON.stringify(t.manifest,null,2)}
|
|
2
|
+
`),i.syncFile(u),i.syncDirectory(n),i.syncDirectory(s),i.syncDirectory(e),i.syncDirectory(ee()),n}r(te,"publishPageRevision");function it(e){if(e.kind!=="page"||e.presentation_dir===null)throw new Error(`page request has no selected presentation: ${e.request_id}`);return e.presentation_dir}r(it,"presentationDir");async function rt(e){const t=e.request_id??await ge(),i=C(t),s=te(i,e.prepared),n=new Date().toISOString(),o=e.prepared.manifest;return await Q(async u=>{await u.prepare(`
|
|
3
3
|
INSERT INTO human_requests (
|
|
4
4
|
request_id, kind, inbox_ticket_id, request_dir, presentation_dir, requester_node_id, state, inbox_listed,
|
|
5
5
|
settleable, title, subtitle, specification_json, action_json, created_at, updated_at
|
|
6
6
|
) VALUES (?, 'page', ?, ?, ?, ?, 'open', ?, ?, ?, ?, ?, ?, ?, ?)
|
|
7
|
-
`).run(t,e.inbox_ticket_id??U(),
|
|
7
|
+
`).run(t,e.inbox_ticket_id??U(),i,s,e.requester_node_id??null,o.delivery.inbox?1:0,o.delivery.inbox||o.delivery.reply?1:0,o.title,o.subtitle??null,JSON.stringify(o),e.action_json??null,n,n);const a=await h(u,"request_id = ?",t);if(a===null)throw new Error(`page request insert did not produce a row: ${t}`);return await Ae(u,a),a})}r(rt,"createPageRequest");async function st(e){return await Q(async t=>{const i=await t.prepare(`
|
|
8
8
|
INSERT INTO human_requests (
|
|
9
9
|
request_id, kind, inbox_ticket_id, request_dir, requester_node_id, companion_node_id,
|
|
10
10
|
idempotency_key, state, inbox_listed, settleable, title, subtitle, file,
|
|
11
11
|
specification_json, anchor_base_sha256, anchor_base_bytes, created_at, updated_at
|
|
12
12
|
) VALUES (?, 'review', ?, ?, ?, ?, ?, 'binding', ?, 1, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
13
13
|
ON CONFLICT(idempotency_key) DO NOTHING
|
|
14
|
-
`).run(e.request_id,U(),e.request_dir,e.requester_node_id,e.companion_node_id,e.idempotency_key,e.inbox_listed?1:0,e.title??
|
|
15
|
-
AND n.run_id IS NOT NULL AND n.grantee IS NOT NULL AND n.grantee <> 'app:terminal'))`;function lt(){return
|
|
14
|
+
`).run(e.request_id,U(),e.request_dir,e.requester_node_id,e.companion_node_id,e.idempotency_key,e.inbox_listed?1:0,e.title??k(e.file),e.subtitle??null,e.file,JSON.stringify(e.specification),e.anchor_base_sha256,e.anchor_base_bytes,e.created_at,e.created_at),s=await h(t,"idempotency_key = ?",e.idempotency_key);if(s===null)throw new Error(`review binding insert did not produce a row: ${e.idempotency_key}`);return{request_id:s.request_id,won:i.changes>0}})}r(st,"commitBindingRequest");async function ot(e){return await h(await c(),"request_id = ?",e)}r(ot,"getRequest");async function at(e){return await h(await c(),"inbox_ticket_id = ?",e)}r(at,"getRequestByInboxTicket");async function dt(e){let t=e;try{t=j(e)}catch{}return await h(await c(),"request_dir = ?",t)}r(dt,"getRequestByDirectory");async function ct(e){return await h(await c(),"companion_node_id = ? AND state <> 'binding'",e)}r(ct,"getRequestByCompanion");async function ut(e){return await h(await c(),"idempotency_key = ?",e)}r(ut,"getRequestByIdempotencyKey");const ve=r(e=>`COALESCE(${e}.requester_node_id, CASE WHEN ${e}.kind = 'page' AND ${we(`${e}.specification_json`)} THEN json_extract(${e}.specification_json, '$.source.nodeId') END)`,"askingNodeSql"),ne=`NOT (kind = 'page' AND EXISTS (SELECT 1 FROM node_rows n WHERE n.node_id = ${ve("human_requests")}
|
|
15
|
+
AND n.run_id IS NOT NULL AND n.grantee IS NOT NULL AND n.grantee <> 'app:terminal'))`;async function lt(){return await q(await c(),`state = 'open' AND inbox_listed = 1 AND ${ne}`,[],"created_at DESC, request_id DESC")}r(lt,"listOpenInboxRequests");async function _t(){return(await q(await c(),`state = 'open' AND requester_node_id IS NOT NULL AND ((inbox_listed = 1 AND ${ne}) OR (kind = 'page' AND inbox_listed = 0 AND settleable = 1))`,[],"created_at ASC, request_id ASC")).filter(e=>e.inbox_listed||be(JSON.parse(e.specification_json)))}r(_t,"listPendingAsks");async function Oe(e){return await q(await c(),"state = 'open' AND requester_node_id = ?",[e],"created_at DESC, request_id DESC")}r(Oe,"openRequestsByRequester");async function pt(e){return(await Oe(e)).some(t=>t.kind==="review"?!0:JSON.parse(t.specification_json).delivery?.reply===!0)}r(pt,"hasOpenReplyBearingRequestByRequester");async function mt(){return await q(await c(),"state = 'open' AND inbox_listed = 1 AND requester_node_id IS NOT NULL",[],"created_at DESC, request_id DESC")}r(mt,"listOpenReplyBearingRequests");async function ft(){return await q(await c(),"kind = 'review' AND state = 'binding'")}r(ft,"listBindingRequests");async function Et(){return await q(await c(),"kind = 'review' AND state = 'open' AND submit_requested_at IS NOT NULL")}r(Et,"listSubmitRequestedRequests");async function yt(){return await q(await c(),"kind = 'review' AND state = 'settled' AND projected_at IS NULL")}r(yt,"listUnprojectedReviews");async function gt(e={}){const t=["1"],i=[];for(const[s,n]of Object.entries(e))n!==void 0&&(t.push(s==="page_source_node_id"?"CASE WHEN json_valid(specification_json) THEN json_extract(specification_json, '$.source.nodeId') END = ?":`${s} = ?`),i.push(n));return await q(await c(),t.join(" AND "),i)}r(gt,"listRequests");async function Nt(){return await(await c()).prepare(`
|
|
16
16
|
SELECT 1 FROM human_requests INDEXED BY idx_human_requests_page_result_exception
|
|
17
17
|
WHERE kind = 'page' AND result_json IS NOT NULL AND
|
|
18
18
|
CASE WHEN json_valid(result_json) THEN
|
|
@@ -20,37 +20,37 @@ var ue=Object.defineProperty;var i=(e,t)=>ue(e,"name",{value:t,configurable:!0})
|
|
|
20
20
|
AND json_type(result_json, '$.summary') IS NOT 'text'
|
|
21
21
|
ELSE 1 END
|
|
22
22
|
LIMIT 1
|
|
23
|
-
`).get()!==void 0}
|
|
23
|
+
`).get()!==void 0}r(Nt,"hasPageResultException");async function ht(){return await(await c()).prepare(`
|
|
24
24
|
SELECT request_id, specification_json FROM human_requests INDEXED BY idx_human_requests_page_invalid_spec
|
|
25
25
|
WHERE kind = 'page' AND (NOT json_valid(specification_json)
|
|
26
26
|
OR CASE WHEN json_valid(specification_json) THEN json_type(specification_json) != 'object' END)
|
|
27
27
|
ORDER BY created_at ASC, request_id ASC LIMIT 1
|
|
28
|
-
`).get()??null}
|
|
28
|
+
`).get()??null}r(ht,"firstInvalidPageSpecification");async function qt(e,t){return(await(await c()).prepare("UPDATE human_requests SET state = 'open', opened_at = ?, updated_at = ? WHERE request_id = ? AND state = 'binding'").run(t,t,e)).changes>0}r(qt,"openRequest");async function Tt(e,t,i){return(await(await c()).prepare(`
|
|
29
29
|
UPDATE human_requests SET state = 'settled', outcome = 'canceled', result_json = ?, settled_at = ?, updated_at = ?
|
|
30
30
|
WHERE request_id = ? AND kind = 'review' AND state = 'binding'
|
|
31
|
-
`).run(JSON.stringify({schema:"humanloop.cancel/v1",kind:"canceled",canceledAt:t,reason:
|
|
31
|
+
`).run(JSON.stringify({schema:"humanloop.cancel/v1",kind:"canceled",canceledAt:t,reason:i}),t,t,e)).changes>0}r(Tt,"cancelBindingRequest");async function bt(e,t){return(await(await c()).prepare("UPDATE human_requests SET submit_requested_at = ?, updated_at = ? WHERE request_id = ? AND kind = 'review' AND state = 'open' AND submit_requested_at IS NULL").run(t,t,e)).changes>0}r(bt,"requestSubmit");async function St(e,t){return(await e.prepare(`
|
|
32
32
|
UPDATE human_requests SET state = 'settled', outcome = ?, result_json = ?, settled_at = ?,
|
|
33
33
|
progress_json = NULL, updated_at = ?
|
|
34
34
|
WHERE request_id = ? AND state = 'open'
|
|
35
|
-
`).run(t.outcome,t.result_json,t.settled_at,t.settled_at,t.request_id).changes===0?null:
|
|
35
|
+
`).run(t.outcome,t.result_json,t.settled_at,t.settled_at,t.request_id)).changes===0?null:await h(e,"request_id = ?",t.request_id)}r(St,"settleRequestLocked");async function wt(e,t,i){await e.prepare("UPDATE human_requests SET settlement_delivery_id = ?, action_delivery_id = ?, updated_at = ? WHERE request_id = ?").run(i.settlement_delivery_id??null,i.action_delivery_id??null,new Date().toISOString(),t)}r(wt,"setSettlementDeliveryMarksLocked");async function At(e,t,i){return(await e.prepare("UPDATE human_requests SET submit_note_delivery_id = ?, updated_at = ? WHERE request_id = ? AND state = 'open' AND submit_note_delivery_id IS NULL").run(i,new Date().toISOString(),t)).changes>0}r(At,"setSubmitNoteDeliveryLocked");async function Dt(e,t){return(await(await c()).prepare(`
|
|
36
36
|
UPDATE human_requests SET presentation_dir = ?, specification_json = ?, title = ?, subtitle = ?, inbox_listed = ?, settleable = ?, updated_at = ?
|
|
37
37
|
WHERE request_id = ? AND kind = 'page' AND state = 'open'
|
|
38
|
-
`).run(t.presentation_dir,t.specification_json,t.title,t.subtitle,t.inbox_listed?1:0,t.settleable?1:0,new Date().toISOString(),e).changes>0
|
|
38
|
+
`).run(t.presentation_dir,t.specification_json,t.title,t.subtitle,t.inbox_listed?1:0,t.settleable?1:0,new Date().toISOString(),e)).changes>0}r(Dt,"revisePageRequest");async function Rt(e,t){return(await(await c()).prepare(`
|
|
39
39
|
UPDATE human_requests SET progress_json = ?, updated_at = ?
|
|
40
40
|
WHERE inbox_ticket_id = ? AND kind = 'page' AND state = 'open' AND settleable = 1
|
|
41
|
-
`).run(JSON.stringify({kind:"page",responses:t,savedAt:new Date().toISOString()}),new Date().toISOString(),e).changes>0
|
|
41
|
+
`).run(JSON.stringify({kind:"page",responses:t,savedAt:new Date().toISOString()}),new Date().toISOString(),e)).changes>0}r(Rt,"writeProgress");async function vt(e,t){await(await c()).prepare("UPDATE human_requests SET projected_at = ?, projection_error = NULL, updated_at = ? WHERE request_id = ?").run(t,t,e)}r(vt,"markProjected");async function Ot(e,t){await(await c()).prepare("UPDATE human_requests SET projection_error = ?, updated_at = ? WHERE request_id = ? AND projected_at IS NULL").run(t,new Date().toISOString(),e)}r(Ot,"markProjectionError");async function jt(e,t){await(await c()).prepare("UPDATE human_requests SET companion_retired_at = ?, updated_at = ? WHERE request_id = ? AND companion_retired_at IS NULL").run(t,t,e)}r(jt,"markCompanionRetired");async function It(e){const t=await(await c()).prepare("SELECT anchor_base_bytes, anchor_base_sha256 FROM human_requests WHERE request_id = ?").get(e);return t===void 0||t.anchor_base_bytes===null||t.anchor_base_sha256===null?null:{bytes:Buffer.from(t.anchor_base_bytes),sha256:t.anchor_base_sha256}}r(It,"readAnchorBase");async function xt(e,t,i,s){await e.prepare("UPDATE human_requests SET anchor_base_bytes = ?, anchor_base_sha256 = ?, updated_at = ? WHERE request_id = ?").run(i,s,new Date().toISOString(),t)}r(xt,"replaceAnchorBaseLocked");function je(e){if(typeof e!="object"||e===null)throw new Error("result is not an object");const t=e;return t.kind==="canceled"?{outcome:t.disposition==="dismissed"?"dismissed":"canceled",settledAt:String(t.canceledAt)}:{outcome:"answered",settledAt:String(t.completedAt)}}r(je,"legacyPageResult");function A(e){try{return JSON.parse(Y(e,"utf8"))}catch(t){throw new Error(`corrupt required input: ${e}`,{cause:t})}}r(A,"readJson");function H(){return L(16).toString("hex")}r(H,"migrationId");function Ie(e){return Number(l(e,"SELECT COALESCE(MAX(seq), 0) AS seq FROM messages").get().seq)+1}r(Ie,"nextMessageSeq");function xe(e,t,i,s){return(s==="page"?l(e,`SELECT d.delivery_id FROM deliveries d JOIN messages m ON m.message_id = d.message_id
|
|
42
42
|
WHERE d.destination_kind = 'node_inbox' AND d.destination_id = ? AND m.sender_node_id = ?
|
|
43
|
-
AND m.disposition IN ('human-answer', 'human-canceled') LIMIT 1`).get(
|
|
44
|
-
WHERE d.destination_kind = 'node_inbox' AND d.destination_id = ? AND m.body_json LIKE ? LIMIT 1`).get(
|
|
43
|
+
AND m.disposition IN ('human-answer', 'human-canceled') LIMIT 1`).get(i,t):l(e,`SELECT d.delivery_id FROM deliveries d JOIN messages m ON m.message_id = d.message_id
|
|
44
|
+
WHERE d.destination_kind = 'node_inbox' AND d.destination_id = ? AND m.body_json LIKE ? LIMIT 1`).get(i,`%"review_id":"${t}"%`))?.delivery_id??null}r(xe,"importedTerminalDelivery");function ie(e,t,i){if(t===null||i===null)return!1;const s=l(e,"SELECT status, final_report FROM nodes WHERE node_id = ?").get(t);return s?.status==="canceled"||i==="approved"&&s?.status==="done"&&s.final_report!==null}r(ie,"companionRetirementProven");function re(e){if(typeof e!="object"||e===null)return"no reason was given";const t=e.reason;return typeof t=="string"&&t!==""?t:"no reason was given"}r(re,"migratedCancellationReason");function Le(e,t){const i=e.outcome==="canceled"||e.outcome==="dismissed";return[e.kind==="review"?i?`Review ${e.requestId} was canceled \u2014 ${re(t)}.`:`Review ${e.requestId} was approved by the user.`:i?`Human request ${e.requestId} was canceled \u2014 ${re(t)}.`:`Human request ${e.requestId} was answered.`,...e.kind==="review"?[`The review result is at ${e.requestDir}/result.json.`]:[],`Result:
|
|
45
45
|
${JSON.stringify(t,null,2)}`].join(`
|
|
46
46
|
|
|
47
|
-
`)}
|
|
47
|
+
`)}r(Le,"migratedTerminalBody");function ke(e,t){const i=H(),s=H(),n=Date.parse(t.settledAt),o=Number.isFinite(n)?n:0,u=t.outcome==="answered"||t.outcome==="approved"?"human-answer":"human-canceled",a=JSON.parse(t.resultJson),p=Le(t,a);return l(e,`INSERT INTO messages
|
|
48
48
|
(message_id, seq, operation_id, created_at, sender_node_id, sender_name, kind, label, body_ref, body_json, disposition)
|
|
49
|
-
VALUES (?, ?, ?, ?, NULL, 'crtrd', 'completed', ?, NULL, ?, ?)`).run(
|
|
50
|
-
`,1)[0],JSON.stringify({body:p,result:
|
|
49
|
+
VALUES (?, ?, ?, ?, NULL, 'crtrd', 'completed', ?, NULL, ?, ?)`).run(i,Ie(e),H(),t.settledAt,p.split(`
|
|
50
|
+
`,1)[0],JSON.stringify({body:p,result:a}),u),l(e,`INSERT INTO deliveries
|
|
51
51
|
(delivery_id, message_id, destination_kind, destination_id, urgency, wake, state, attempts, created_at, updated_at)
|
|
52
|
-
VALUES (?, ?, 'node_inbox', ?, 'normal', 1, 'pending', 0, ?, ?)`).run(s,
|
|
53
|
-
`}
|
|
52
|
+
VALUES (?, ?, 'node_inbox', ?, 'normal', 1, 'pending', 0, ?, ?)`).run(s,i,t.requesterNodeId,o,o),s}r(ke,"createMigratedTerminalDelivery");function se(e,t){if(t.requesterNodeId===null||t.outcome===null||t.resultJson===null||t.settledAt===null)return null;const i=xe(e,t.requestId,t.requesterNodeId,t.kind);return i!==null?i:t.deliveredAt!==null&&t.deliveredAt!==void 0?null:ke(e,{requestId:t.requestId,requesterNodeId:t.requesterNodeId,kind:t.kind,outcome:t.outcome,resultJson:t.resultJson,settledAt:t.settledAt,requestDir:t.requestDir})}r(se,"terminalDeliveryMark");const Ce=d.object({sessionName:d.string().optional(),askedBy:d.string().optional(),blockedSince:d.string().optional(),profileName:d.string().optional(),nodeId:d.string().optional()}).strict(),Ue=d.object({id:d.string().regex(/^[A-Za-z0-9_-]{1,64}$/).optional(),kind:d.string().min(1),step:d.number().int().nonnegative(),config:d.record(d.string(),d.unknown()),unvalidated:d.literal(!0).optional(),display:d.literal(!0).optional()}).strict(),Pe=d.object({schema:d.literal("crtr.page/v1"),dialect:d.enum(["md","html","jsx"]),title:d.string().trim().min(1),subtitle:d.string().optional(),placement:d.enum(["inline","panel"]),document:d.enum(["page.md","page.html","page.tsx"]),steps:d.number().int().positive(),slots:d.array(Ue),source:Ce.optional()}).strict().superRefine((e,t)=>{const i=e.dialect==="md"?"page.md":e.dialect==="html"?"page.html":"page.tsx";e.document!==i&&t.addIssue({code:"custom",path:["document"],message:"document must agree with dialect"}),e.dialect==="md"&&e.steps!==1&&t.addIssue({code:"custom",path:["steps"],message:"md pages have exactly one step"})});function He(e){if(e.source===void 0)return;const{blockedSince:t,...i}=e.source,s={...i,...t!==void 0&&d.string().datetime({offset:!0}).safeParse(t).success?{emittedAt:t}:{}};return Object.keys(s).length===0?void 0:s}r(He,"legacyPresentationSource");function $e(e,t,i){return`export default function LegacyPage() { return <Page title={${JSON.stringify(e)}}${t===void 0?"":` subtitle={${JSON.stringify(t)}}`}><pre>{${JSON.stringify(i)}}</pre></Page>; }
|
|
53
|
+
`}r($e,"legacyReplayDocument");function oe(e){return Array.isArray(e.slots)?{...e,slots:e.slots.map(t=>{if(typeof t!="object"||t===null||Array.isArray(t))return t;const i=t;if(i.kind!=="text"||typeof i.config!="object"||i.config===null||Array.isArray(i.config))return t;const{editable:s,...n}=i.config;return{...i,config:n}})}:e}r(oe,"withoutLegacyTextEditable");function Xe(e,t){const i=_(e,"page.json"),s=Pe.safeParse(t);if(!s.success)throw new Error(s.error.message);const n=s.data,o=He(n),u={placement:n.placement,inbox:!0,reply:n.source?.blockedSince!==void 0};z(oe({schema:"crtr.page/v2",dialect:"jsx",title:n.title,...n.subtitle===void 0?{}:{subtitle:n.subtitle},delivery:u,document:"page.tsx",steps:n.steps,slots:n.slots,...o===void 0?{}:{source:o}}));const a=_(e,n.document);if(!y(a))throw new Error(`corrupt required input: ${a}`);const p=Y(a,"utf8"),f=Te({dialect:"jsx",document:$e(n.title,n.subtitle,p),source:o,delivery:u});if(o!==void 0)return f;const{source:E,...g}=f.manifest;return{...f,manifest:g}}r(Xe,"migrateLegacyPage");function Lt(e){e.exec(`
|
|
54
54
|
CREATE TABLE human_requests (
|
|
55
55
|
request_id TEXT PRIMARY KEY, kind TEXT NOT NULL CHECK (kind IN ('page','review')),
|
|
56
56
|
inbox_ticket_id TEXT NOT NULL UNIQUE, request_dir TEXT NOT NULL, presentation_dir TEXT,
|
|
@@ -73,10 +73,10 @@ ${JSON.stringify(t,null,2)}`].join(`
|
|
|
73
73
|
CREATE INDEX idx_human_requests_submit ON human_requests(state, submit_requested_at);
|
|
74
74
|
CREATE INDEX idx_human_requests_file ON human_requests(file);
|
|
75
75
|
CREATE INDEX idx_human_requests_requester ON human_requests(requester_node_id);
|
|
76
|
-
`);const t=
|
|
76
|
+
`);const t=l(e,`INSERT INTO human_requests (
|
|
77
77
|
request_id, kind, inbox_ticket_id, request_dir, presentation_dir, requester_node_id, companion_node_id, idempotency_key,
|
|
78
78
|
state, outcome, inbox_listed, settleable, title, subtitle, file, specification_json, action_json,
|
|
79
79
|
progress_json, feedback_json, result_json, anchor_base_sha256, anchor_base_bytes, created_at, opened_at,
|
|
80
80
|
submit_requested_at, settled_at, settlement_delivery_id, action_delivery_id, projected_at, projection_error,
|
|
81
81
|
companion_retired_at, updated_at
|
|
82
|
-
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`);if(
|
|
82
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`);if(l(e,"SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'reviews'").get()!==void 0){const s=l(e,"SELECT * FROM reviews").all();for(const n of s){const o=n.state,u=o==="approved"||o==="canceled",a=o==="canceled"&&n.result_json===null?JSON.stringify({schema:"humanloop.cancel/v1",kind:"canceled",canceledAt:n.canceled_at,...n.cancel_reason===""||n.cancel_reason===null?{}:{reason:n.cancel_reason},...n.cancel_actor===null?{}:{actor:n.cancel_actor}}):n.result_json;if(u&&a===null)throw new Error(`corrupt required input: reviews/${n.review_id} has no terminal result`);const p=n.bridge_node_id===null?_(V(),"reviews",n.review_id):_(b(),n.bridge_node_id),f={origin_kind:n.origin_kind,bridge_node_id:n.bridge_node_id,origin_session_file:n.origin_session_file,origin_session_id:n.origin_session_id,origin_leaf_id:n.origin_leaf_id,model_spec:n.model_spec,branch_file:n.branch_file,baseline_sha256:n.baseline_sha256,baseline_bytes:n.baseline_bytes,captured_at:n.captured_at,output_path:n.output_path},E=u?o==="approved"?"approved":"canceled":null,g=u?o==="approved"?n.approved_at:n.canceled_at:null,S=se(e,{requestId:n.review_id,requesterNodeId:n.origin_node_id,kind:"review",outcome:E,resultJson:a,settledAt:g,requestDir:p,deliveredAt:n.delivered_at}),R=ie(e,n.companion_node_id,E)?g:null;t.run(n.review_id,"review",n.origin_kind==="ticket"?P(b(),k(p)):U(),p,null,n.origin_node_id,n.companion_node_id,n.idempotency_key,u?"settled":o,E,n.origin_kind==="ticket"?1:0,1,k(n.file),n.subtitle,n.file,JSON.stringify(f),null,null,null,a,n.anchor_base_sha256,n.anchor_base_bytes,n.created,n.opened_at,n.submit_requested_at,g,S,null,n.projected_at,n.projection_error,R,n.created)}e.exec("DROP TABLE reviews")}for(const s of y(b())?_e(b(),{withFileTypes:!0}):[]){if(!s.isDirectory())continue;const n=_(b(),s.name),o=_(n,"page.json"),u=_(n,"review.json");if(!y(o)){if(y(u))continue;continue}if(l(e,"SELECT 1 FROM human_requests WHERE request_id = ?").get(s.name)!==void 0)continue;let a,p,f,E;try{const m=A(o);if(typeof m!="object"||m===null||Array.isArray(m))throw new Error("page manifest must be an object");a=m,a.schema==="crtr.page/v1"?(p=Xe(n,m),a=p.manifest):a.schema==="crtr.page/v2"&&(a=oe(a));const w=Se.safeParse(a.delivery);if(typeof a.title!="string"||!w.success)throw new Error(w.success?"page title must be a string":w.error.message);E=w.data,f=z(a)}catch(m){const w=m instanceof Error&&m.cause instanceof Error?m.cause.message:m instanceof Error?m.message:String(m);console.warn(`skipping legacy page ${o}: ${w}`);continue}let g=j(n);p!==void 0&&(g=te(C(s.name),p));const S=f.source,R=_(n,"response.json"),v=y(R)?A(R):null,N=v===null?null:je(v),ae=l(e,"SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'deliveries'").get()===void 0?null:l(e,"SELECT delivery_id FROM deliveries WHERE idempotency_key = ?").get(`human-action:${P(b(),s.name)}`),$=_(n,"action.json"),X=_(n,"progress.json"),I=_(n,"feedback-comments.json"),x=_(n,"reply-route.json"),T=y(I)?A(I):null;if(T!==null&&(typeof T!="object"||typeof T.companionNodeId<"u"&&typeof T.companionNodeId!="string"))throw new Error(`corrupt required input: ${I}`);const O=y(x)?A(x):null;if(O!==null&&(typeof O!="object"||typeof O.bridge_node_id!="string"))throw new Error(`corrupt required input: ${x}`);const M=O?.bridge_node_id,W=(typeof M!="string"||l(e,"SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'nodes'").get()===void 0?null:l(e,"SELECT parent FROM nodes WHERE node_id = ?").get(M))?.parent??(typeof S?.nodeId=="string"?S.nodeId:null),F=T?.companionNodeId,J=typeof S?.emittedAt=="string"?S.emittedAt:pe(o).mtime.toISOString(),B=v===null?null:JSON.stringify(v),de=se(e,{requestId:s.name,requesterNodeId:W,kind:"page",outcome:N?.outcome??null,resultJson:B,settledAt:N?.settledAt??null,requestDir:n}),ce=ie(e,F??null,N?.outcome??null)?N?.settledAt??null:null,K=C(s.name);D(K,{recursive:!0,mode:448}),t.run(s.name,"page",P(b(),s.name),K,g,W,F??null,null,N===null?"open":"settled",N?.outcome??null,E.inbox?1:0,E.inbox||E.reply?1:0,f.title,f.subtitle??null,null,JSON.stringify(f),y($)?JSON.stringify(A($)):null,y(X)&&N===null?JSON.stringify(A(X)):null,T===null?null:JSON.stringify(T),B,null,null,J,null,null,N?.settledAt??null,de,ae?.delivery_id??null,null,null,ce,J)}const i=l(e,"SELECT request_id FROM human_requests WHERE state = 'settled' AND result_json IS NULL").get();if(i!==void 0)throw new Error(`human request migration produced terminal row without result: ${i.request_id}`);if(l(e,"SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'review_comments'").get()!==void 0){const s=l(e,"SELECT review_id FROM review_comments WHERE review_id NOT IN (SELECT request_id FROM human_requests WHERE kind = 'review') LIMIT 1").get();if(s!==void 0)throw new Error(`review comment has no migrated review request: ${s.review_id}`)}}r(Lt,"migrateHumanRequestsState");export{ne as NOT_OTHER_APP_QUESTION,ve as askingNodeSql,Tt as cancelBindingRequest,st as commitBindingRequest,rt as createPageRequest,ht as firstInvalidPageSpecification,ot as getRequest,ct as getRequestByCompanion,dt as getRequestByDirectory,ut as getRequestByIdempotencyKey,at as getRequestByInboxTicket,pt as hasOpenReplyBearingRequestByRequester,Nt as hasPageResultException,ee as humanRequestsRoot,ft as listBindingRequests,lt as listOpenInboxRequests,mt as listOpenReplyBearingRequests,_t as listPendingAsks,gt as listRequests,Et as listSubmitRequestedRequests,yt as listUnprojectedReviews,jt as markCompanionRetired,vt as markProjected,Ot as markProjectionError,Lt as migrateHumanRequestsState,qt as openRequest,Oe as openRequestsByRequester,it as presentationDir,te as publishPageRevision,It as readAnchorBase,xt as replaceAnchorBaseLocked,C as requestDir,bt as requestSubmit,Dt as revisePageRequest,wt as setSettlementDeliveryMarksLocked,At as setSubmitNoteDeliveryLocked,St as settleRequestLocked,Rt as writeProgress};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { PageTicketSummary, TicketSummary } from './types.js';
|
|
2
2
|
/** SQL-backed inbox discovery. Files in request_dir are presentation projections only. */
|
|
3
|
-
export declare function scanInbox(): TicketSummary[]
|
|
3
|
+
export declare function scanInbox(): Promise<TicketSummary[]>;
|
|
4
4
|
export type PageHistoryEntry = PageTicketSummary;
|
|
5
5
|
/** SQL-backed page history, including terminal requests. */
|
|
6
|
-
export declare function scanPageHistory(nodeId?: string): PageHistoryEntry[]
|
|
6
|
+
export declare function scanPageHistory(nodeId?: string): Promise<PageHistoryEntry[]>;
|
package/dist/core/human/scan.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var l=Object.defineProperty;var n=(e,t)=>l(e,"name",{value:t,configurable:!0});import{pageAwaitsResponse as p,pageOverviewActions as u}from"./page-schema.js";import{firstInvalidPageSpecification as m,hasPageResultException as f,listOpenInboxRequests as _,listRequests as g}from"./requests.js";function
|
|
1
|
+
var l=Object.defineProperty;var n=(e,t)=>l(e,"name",{value:t,configurable:!0});import{pageAwaitsResponse as p,pageOverviewActions as u}from"./page-schema.js";import{firstInvalidPageSpecification as m,hasPageResultException as f,listOpenInboxRequests as _,listRequests as g}from"./requests.js";function c(e){try{const t=JSON.parse(e.specification_json);if(typeof t!="object"||t===null)throw new Error("not an object");return t}catch(t){throw new Error(`corrupt human request specification: ${e.request_id}`,{cause:t})}}n(c,"specification");function d(e){const t=c(e),{recommendedOptions:i,fastAction:o}=u(t),a=e.result_json===null?null:JSON.parse(e.result_json),s=e.state!=="settled"?e.settleable?"pending":"passive":e.outcome==="canceled"||e.outcome==="dismissed"?"canceled":"resolved";return{dir:e.request_dir,id:e.request_id,inboxTicketId:e.inbox_ticket_id,kind:"page",title:e.title,subtitle:e.subtitle??"",dialect:t.dialect,placement:t.delivery.placement,inbox:e.inbox_listed,steps:t.steps,slotKinds:t.slots.map(r=>r.kind),awaitsResponse:p(t),source:t.source??{},emittedAt:typeof t.source?.emittedAt=="string"?t.source.emittedAt:e.created_at,recommendedOptions:i,...o===void 0||s!=="pending"?{}:{fastAction:o},state:s,...a?.kind==="page"?{answerDigest:a.summary.replace(/\s+/g," ").trim()}:{}}}n(d,"pageSummary");function k(e){const t=c(e),i={nodeId:e.requester_node_id??void 0};return{dir:e.request_dir,id:e.request_id,inboxTicketId:e.inbox_ticket_id,kind:"review",title:e.title,subtitle:e.subtitle??"",file:e.file??"",output:typeof t.output_path=="string"?t.output_path:`${e.request_dir}/result.json`,source:i,blockedSince:e.created_at}}n(k,"reviewSummary");async function y(){return(await _()).map(e=>e.kind==="page"?d(e):k(e)).sort((e,t)=>(t.kind==="page"?t.emittedAt:t.blockedSince).localeCompare(e.kind==="page"?e.emittedAt:e.blockedSince)||e.id.localeCompare(t.id))}n(y,"scanInbox");async function A(e){const t=e!==void 0&&(await m()!==null||await f());return(await g({kind:"page",page_source_node_id:t?void 0:e})).map(d).filter(i=>!t||i.source.nodeId===e).sort((i,o)=>Date.parse(i.emittedAt)-Date.parse(o.emittedAt)||i.id.localeCompare(o.id))}n(A,"scanPageHistory");export{y as scanInbox,A as scanPageHistory};
|
|
@@ -4,26 +4,26 @@ import { type PageManifest, type PageResponses } from './page-schema.js';
|
|
|
4
4
|
/** Strict decoder for the canonical SQL terminal result. A corrupt result throws
|
|
5
5
|
* rather than being treated as absent, because that would hide data loss from
|
|
6
6
|
* the caller that owns the failure boundary. */
|
|
7
|
-
export declare function readTicketResult(dir: string): TicketResult | null
|
|
7
|
+
export declare function readTicketResult(dir: string): Promise<TicketResult | null>;
|
|
8
8
|
/** Publish an immutable revision, then atomically select it with its matching specification. */
|
|
9
|
-
export declare function publishPage(dir: string, prepared: PreparedPage): {
|
|
9
|
+
export declare function publishPage(dir: string, prepared: PreparedPage): Promise<{
|
|
10
10
|
id: string;
|
|
11
11
|
dir: string;
|
|
12
12
|
kind: 'page';
|
|
13
13
|
manifest: PageManifest;
|
|
14
|
-
}
|
|
14
|
+
}>;
|
|
15
15
|
/** Resolve a stable request directory to the SQL-selected immutable page revision. */
|
|
16
|
-
export declare function selectedPageDir(dir: string): string
|
|
16
|
+
export declare function selectedPageDir(dir: string): Promise<string>;
|
|
17
17
|
/** Validate a final page response against its ticket's reply contract. */
|
|
18
18
|
export declare function validateFinalPageResponses(manifest: PageManifest, responses: unknown): PageResponses;
|
|
19
19
|
/** Validate a page resolution against its SQL-selected immutable revision. */
|
|
20
|
-
export declare function validatePageTicketResponses(dir: string, responses: unknown): PageResponses
|
|
20
|
+
export declare function validatePageTicketResponses(dir: string, responses: unknown): Promise<PageResponses>;
|
|
21
21
|
/** Page state is derived from the SQL request row. */
|
|
22
|
-
export declare function pageTicketState(dir: string): 'pending' | 'resolved' | 'canceled' | 'passive'
|
|
22
|
+
export declare function pageTicketState(dir: string): Promise<'pending' | 'resolved' | 'canceled' | 'passive'>;
|
|
23
23
|
/** Autosave partial page work. Every supplied response is validated; omitted components are permitted. */
|
|
24
|
-
export declare function writePageProgress(dir: string, responses: unknown): PageResponses
|
|
24
|
+
export declare function writePageProgress(dir: string, responses: unknown): Promise<PageResponses>;
|
|
25
25
|
/** Saved partial work from the request row, or null when none exists. */
|
|
26
|
-
export declare function readPageProgress(dir: string): PageResponses | null
|
|
26
|
+
export declare function readPageProgress(dir: string): Promise<PageResponses | null>;
|
|
27
27
|
export interface PageTicket {
|
|
28
28
|
dir: string;
|
|
29
29
|
id: string;
|
|
@@ -36,7 +36,7 @@ export interface PageTicket {
|
|
|
36
36
|
progress: PageResponses | null;
|
|
37
37
|
}
|
|
38
38
|
/** Read one addressable page ticket — pending, resolved or canceled alike. */
|
|
39
|
-
export declare function readPageTicket(dir: string): PageTicket
|
|
39
|
+
export declare function readPageTicket(dir: string): Promise<PageTicket>;
|
|
40
40
|
export interface CompletePageOptions {
|
|
41
41
|
completedAt?: string;
|
|
42
42
|
actor?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var b=Object.defineProperty;var i=(t,e)=>b(t,"name",{value:e,configurable:!0});import{mkdirSync as y,readFileSync as d,realpathSync as q}from"node:fs";import{basename as _,isAbsolute as P,resolve as k}from"node:path";import{z as n}from"zod";import{pageModulePath as R,pagePath as S}from"./convention.js";import{parsePage as p}from"./page.js";import{validatePageResponses as E,validatePartialPageResponses as m}from"./page-schema.js";import{signalInboxActivity as g}from"./root.js";import{createPageRequest as x,getRequestByDirectory as l,presentationDir as f,publishPageRevision as j,revisePageRequest as A,writeProgress as T}from"./requests.js";const $=n.object({id:n.string().min(1),line:n.number().int().positive(),endLine:n.number().int().positive(),quote:n.string().optional(),colStart:n.number().int().nonnegative().optional(),colEnd:n.number().int().nonnegative().optional(),lineText:n.string(),comment:n.string().min(1),createdAt:n.string().min(1)}).strict(),o=n.string().datetime({offset:!0}),I=n.object({file:n.string().min(1).refine(P,"file must be absolute").refine(t=>k(t)===t,"file must be canonical"),submitted:n.literal(!0),approved:n.boolean(),comments:n.array($),submittedAt:o,savedAt:o,reviewId:n.string().optional(),changed:n.boolean().optional(),baselineSha256:n.string().optional(),approvedSha256:n.string().optional(),companionNodeId:n.string().optional(),commentsTotal:n.number().int().nonnegative().optional(),commentsUnresolved:n.number().int().nonnegative().optional()}).strict().superRefine((t,e)=>{t.comments.forEach((r,s)=>{r.endLine<r.line&&e.addIssue({code:"custom",message:"endLine must be >= line",path:["comments",s,"endLine"]}),r.colStart===void 0!=(r.colEnd===void 0)&&e.addIssue({code:"custom",message:"columns must be supplied together",path:["comments",s]}),r.line===r.endLine&&r.colStart!==void 0&&r.colEnd!==void 0&&r.colEnd<=r.colStart&&e.addIssue({code:"custom",message:"colEnd must exceed colStart",path:["comments",s,"colEnd"]})})}),w=n.record(n.string(),n.unknown()),L=n.object({schema:n.literal("crtr.page-response/v1"),kind:n.literal("page"),responses:n.record(n.string(),w),summary:n.string(),completedAt:o,actor:n.string().optional()}).strict(),Z=n.object({kind:n.literal("page"),responses:n.record(n.string(),w),savedAt:o}).strict(),O=n.object({schema:n.literal("humanloop.review-response/v1"),kind:n.literal("review"),result:I,completedAt:o}).strict(),N=n.object({schema:n.literal("humanloop.cancel/v1"),kind:n.literal("canceled"),canceledAt:o,reason:n.string().optional(),actor:n.string().optional(),disposition:n.enum(["canceled","dismissed"]).optional()}).strict();async function ee(t){const e=await l(t);if(e===null)throw new Error(`unknown human request directory: ${t}`);if(e.state!=="settled"||e.result_json===null)return null;let r;try{r=JSON.parse(e.result_json)}catch(v){throw new Error(`corrupt human request result: ${e.request_id}`,{cause:v})}const s=L.safeParse(r);if(s.success)return s.data;const u=O.safeParse(r);if(u.success)return u.data;const a=N.safeParse(r);if(a.success)return a.data;throw new Error(`human request has an invalid terminal result: ${e.request_id}`)}i(ee,"readTicketResult");async function te(t,e){y(t,{recursive:!0,mode:448});const r=q(t),s=await l(r);if(s===null){const a=await x({request_id:_(r),prepared:e});return g(),{id:a.request_id,dir:a.request_dir,kind:"page",manifest:e.manifest}}const u=j(r,e);if(!await A(s.request_id,{presentation_dir:u,specification_json:JSON.stringify(e.manifest),title:e.manifest.title,subtitle:e.manifest.subtitle??null,inbox_listed:e.manifest.delivery.inbox,settleable:e.manifest.delivery.inbox||e.manifest.delivery.reply}))throw new Error(`page request is not open: ${s.request_id}`);return g(),{id:s.request_id,dir:r,kind:"page",manifest:e.manifest}}i(te,"publishPage");async function c(t){const e=await l(t);if(e===null||e.kind!=="page")throw new Error(`unknown page request directory: ${t}`);return e}i(c,"pageRequest");async function D(t){return f(await c(t))}i(D,"selectedPageDir");async function F(t){return p(await D(t))}i(F,"requirePage");async function h(t){const e=await F(t);if(!e.delivery.inbox&&!e.delivery.reply)throw new Error("page_has_no_response_lifecycle");return e}i(h,"requireSettleablePage");function H(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)&&Object.keys(t).length===0}i(H,"isEmptyResponseMap");function J(t,e){return!t.delivery.reply&&H(e)?m(t,e):E(t,e)}i(J,"validateFinalPageResponses");async function C(t,e){return J(await h(t),e)}i(C,"validateFinalPageTicketResponses");async function ne(t,e){return await C(t,e)}i(ne,"validatePageTicketResponses");async function M(t){const e=await c(t);return e.settleable?e.state!=="settled"?"pending":e.outcome==="canceled"||e.outcome==="dismissed"?"canceled":"resolved":"passive"}i(M,"pageTicketState");async function re(t,e){const r=await c(t),s=m(await h(t),e);if(!await T(r.inbox_ticket_id,s))throw new Error(`page request is not open and settleable: ${r.request_id}`);return s}i(re,"writePageProgress");async function z(t){const e=await c(t);if(e.progress_json===null)return null;try{const r=JSON.parse(e.progress_json);if(r.kind!=="page")throw new Error("wrong kind");return r.responses}catch(r){throw new Error(`page progress is malformed for ${e.request_id}`,{cause:r})}}i(z,"readPageProgress");async function se(t){const e=await c(t),r=f(e),s=p(r);return{dir:e.request_dir,id:e.request_id,manifest:s,document:d(S(r,s.dialect),"utf8"),...s.dialect==="jsx"?{module:d(R(r),"utf8")}:{module:void 0},state:await M(e.request_dir),progress:s.delivery.inbox||s.delivery.reply?await z(e.request_dir):null}}i(se,"readPageTicket");function ie(t,e,r,s={}){throw new Error("page completion must use settleHumanRequest")}i(ie,"completePage");function oe(t,e,r,s={}){throw new Error("page completion must use settleHumanRequest")}i(oe,"takeoverAndCompletePage");function ae(t,e={}){throw new Error("page cancellation must use settleHumanRequest")}i(ae,"cancelTicket");function ce(t){throw new Error("review projection must use projectReviewResult")}i(ce,"projectReviewOutput");export{ae as cancelTicket,ie as completePage,M as pageTicketState,ce as projectReviewOutput,te as publishPage,z as readPageProgress,se as readPageTicket,ee as readTicketResult,D as selectedPageDir,oe as takeoverAndCompletePage,J as validateFinalPageResponses,ne as validatePageTicketResponses,re as writePageProgress};
|
|
@@ -13,4 +13,4 @@ export declare function resolveAppRung(endpoint: InferenceEndpoint, requested: s
|
|
|
13
13
|
export declare function appCandidates(endpoint: InferenceEndpoint, requested: string | undefined, exact?: boolean): AppRung[];
|
|
14
14
|
/** The rung an app-paid grant's node runs on for `requested` (RT-RTE-24), or null when the grant is user-paid or
|
|
15
15
|
* absent. Every path that chooses a node's model (spawn, `node config --model`) resolves through here. */
|
|
16
|
-
export declare function appRungForGrant(grantId: string | null | undefined, requested: string | undefined, exact?: boolean): AppRung | null
|
|
16
|
+
export declare function appRungForGrant(grantId: string | null | undefined, requested: string | undefined, exact?: boolean): Promise<AppRung | null>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var h=Object.defineProperty;var
|
|
1
|
+
var h=Object.defineProperty;var s=(e,r)=>h(e,"name",{value:r,configurable:!0});import{defaultModelLaddersConfig as x}from"../../types.js";import{MODEL_STRENGTHS as b,stripThinkingSuffix as p}from"../runtime/model-selection.js";import{modelTokenStrength as w}from"../runtime/launch.js";import{RunError as u}from"../runs/operations.js";import{grantRecord as O}from"../grants/mirror.js";const o=b;function l(e,r){const t=o.indexOf(r);return o.filter(n=>e.rungs[n]!==void 0).sort((n,i)=>Math.abs(o.indexOf(n)-t)-Math.abs(o.indexOf(i)-t)||o.indexOf(n)-o.indexOf(i)).map(n=>({strength:n,model:e.rungs[n]}))}s(l,"rungsByDistance");function d(e,r){const t=l(e,r)[0];if(t===void 0)throw new u(404,"model_unavailable","the app's inference endpoint declares no rung");return t}s(d,"rungAt");function g(e,r,t=!1){if(r===void 0||r==="")return d(e,"strong");const n=w(r)??void 0;if(n!==void 0)return d(e,n);const i=p(r),f=o.find(a=>e.rungs[a]===i);if(f!==void 0)return{strength:f,model:e.rungs[f]};if(t)throw new u(400,"substitution_refused",`model '${r}' is not one of this app's inference rungs`);const c=x(),m=[...Object.entries(c.anthropic),...Object.entries(c.openai)].find(([,a])=>p(a)===i);return d(e,m?.[0]??"strong")}s(g,"resolveAppRung");function v(e,r,t=!1){const n=g(e,r,t);if(t)return[n];const i=l(e,n.strength).filter(f=>f.strength!==n.strength);return[n,...i]}s(v,"appCandidates");async function y(e,r,t=!1){const n=e?await O(e):null;if(n?.payer!=="app")return null;if(!n.inference_endpoint)throw new u(404,"model_unavailable",`${n.grantee} is app-paid but its grant carries no inference endpoint`);return g(n.inference_endpoint,r,t)}s(y,"appRungForGrant");export{v as appCandidates,y as appRungForGrant,g as resolveAppRung,d as rungAt};
|
package/dist/core/llm/run.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
var be=Object.defineProperty;var u=(e,t)=>be(e,"name",{value:t,configurable:!0});import{randomUUID as ve}from"node:crypto";import{streamSimple as we}from"@earendil-works/pi-ai/compat";import{expandModelCandidates as ie,parseModelSpec as se,probeRouteAvailability as xe}from"../model-routes.js";import{readMergedLaunchConfig as ae}from"../config.js";import{openModelRegistry as ke}from"../runtime/model-registry.js";import{MAX_RATE_LIMIT_COOLDOWN_MS as de,coolingUntilFor as le,isManagedProvider as H,markSubscriptionRateLimited as je,markSubscriptionSuccess as Me,readSubscriptionPool as Ae,retryAfterMsFromHeaders as K,retryAfterMsFromError as qe,refreshSubscriptionCredential as $e,subscriptionNeedsSuccessWrite as Re}from"../subscription-state.js";import{classifyRateLimit as Ie,describeRateLimitScope as ce,rateLimitHeaders as Ce}from"../rate-limit-scope.js";import{RunError as i}from"../runs/operations.js";import{recognizeProviderError as Y}from"../provider-error-recognition.js";import{isSafetyRefusal as Se}from"./refusal.js";import{assertUnderCap as Oe,recordModelUsage as ue}from"../usage/ledger.js";import{outboundToken as Le}from"../providers/mint.js";import{discardFile as Ee}from"../providers/token-cache.js";import{ProviderError as Ne}from"../providers/errors.js";import{appCandidates as De}from"./app-rungs.js";function Fe(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)))}u(Fe,"validContent");function fe(e){return Array.isArray(e)?e.map(t=>{if(t.type==="text")return t;const[,n,r]=/^data:(image\/(?:png|jpeg|gif|webp));base64,(.*)$/.exec(t.image_url.url);return{type:"image",mimeType:n,data:r}}):e??""}u(fe,"imageContent");function Te(e,t){const n=(e instanceof Error?e.message:String(e)).split("; stack=",1)[0],r=Y({message:n}).kind;return r!=="connection"&&r!=="connection-only"?e:new i(503,"upstream_model_unavailable",n.slice(0,500),void 0,{served_model:t})}u(Te,"refreshFailure");function lt(e){if(!e||typeof e!="object"||Array.isArray(e))throw new i(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)&&Fe(n.content)))throw new i(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 i(400,"invalid_request","system and assistant content must be text","messages");if(t.model!==void 0&&typeof t.model!="string")throw new i(400,"invalid_request","model must be a string","model");if(t.model_policy!==void 0&&!["exact","substitute"].includes(t.model_policy))throw new i(400,"invalid_request","invalid model_policy","model_policy");if(t.payer!==void 0&&!["user","app"].includes(t.payer))throw new i(400,"invalid_request","invalid payer","payer");if(t.reasoning_effort!==void 0&&!["minimal","low","medium","high","xhigh","max"].includes(t.reasoning_effort))throw new i(400,"invalid_request","invalid reasoning_effort","reasoning_effort");if(t.stream!==void 0&&typeof t.stream!="boolean")throw new i(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 i(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 i(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(r=>r&&typeof r.id=="string"&&typeof r.function?.name=="string"&&typeof r.function.arguments=="string"&&Pe(r.function.arguments)))))throw new i(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 i(400,"invalid_request","invalid stop","stop");if(t.seed!==void 0&&!Number.isSafeInteger(t.seed))throw new i(400,"invalid_request","invalid seed","seed");for(const[n,r]of[["temperature",t.temperature],["top_p",t.top_p],["max_tokens",t.max_tokens]])if(r!==void 0&&(typeof r!="number"||!Number.isFinite(r)||n==="temperature"&&(r<0||r>2)||n==="top_p"&&(r<0||r>1)||n==="max_tokens"&&(!Number.isSafeInteger(r)||r<1)))throw new i(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 i(400,"invalid_request","invalid response_format","response_format")}if(t.metadata!==void 0&&Buffer.byteLength(JSON.stringify(t.metadata)??"")>4096)throw new i(400,"invalid_request","metadata exceeds 4 KB","metadata");return t}u(lt,"parseLlmRequest");function Pe(e){try{const t=JSON.parse(e);return t!==null&&typeof t=="object"&&!Array.isArray(t)}catch{return!1}}u(Pe,"isJsonObject");function Ue(e){const t=Date.now(),n=e.messages.map(s=>s.role==="system"?{role:"system",content:s.content??"",timestamp:t}:s.role==="tool"?{role:"toolResult",toolCallId:s.tool_call_id??"",toolName:"",content:typeof s.content=="string"||s.content===null?[{type:"text",text:s.content??""}]:fe(s.content),isError:!1,timestamp:t}:s.role==="assistant"?{role:"assistant",content:[...s.content?[{type:"text",text:s.content}]:[],...(s.tool_calls??[]).map(g=>({type:"toolCall",id:g.id,name:g.function.name,arguments:JSON.parse(g.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:fe(s.content),timestamp:t}),r=n.findIndex(s=>s.role!=="system"),w=n.slice(0,r<0?n.length:r).map(s=>s.content),y=w.join(`
|
|
2
2
|
|
|
3
|
-
`),l=e.tools?.map(({function:s})=>({name:s.name,description:s.description??"",parameters:s.parameters??{type:"object",properties:{}}}));return{...y?{systemPrompt:y}:{},messages:n.slice(w.length),...l?{tools:l}:{}}}u(Ue,"contextOf");function me(e,t,n,r){if(!e){const y=ae(n,r),l=Object.values({...y.modelRoutes??{},...y.legacyModelRoutes??{}}),s=l.length?[y.modelLadders.defaultProvider,...y.modelRouting?.familyOrder??[],...l.map(g=>g.family)].find(g=>l.some(E=>E.family===g)):y.modelLadders.defaultProvider??"anthropic";return{kind:"logical",family:s,strength:"strong",spec:`${s}/strong`}}const w=/^([^/]+)\/(ultra|strong|medium|light)$/.exec(e);return w?{kind:"logical",family:w[1],strength:w[2],spec:e}:{kind:t==="exact"?"exact":"concrete",spec:e}}u(me,"requestFor");function Je(e,t){const{input:n,output:r,cacheRead:w,cacheWrite:y}=e.cost;return n===0&&r===0&&w===0&&y===0?null:Number.isFinite(t)&&t>=0?t:null}u(Je,"usdEquivalent");function We(e,t){return e.compat?.allowedFallbackModels?.find(r=>r.provider===e.provider&&r.model===t)}u(We,"allowedFallback");function ct(e){return e?{payer:e.payer??"user",sub:e.sub,grantee:e.grantee,inference_endpoint:e.inference_endpoint??null}:void 0}u(ct,"llmCallerOf");function He(e){return e instanceof Ne?e.code==="server_error"?new i(503,"upstream_model_unavailable",e.message):new i(404,"model_unavailable",e.message):e}u(He,"mintFailure");const Ke=/\bmodel is not supported when using Codex with a ChatGPT account\b/i;function ze(e,t,n){if(!(e!=="openai-codex"||t===void 0||!Ke.test(t)))return new i(404,"model_unavailable",t,void 0,{served_model:n})}u(ze,"codexAccountModelRejection");async function ut(e,t,n,r,w,y){const l=y?.payer==="app"?y:void 0;if(e.payer==="app"&&!l)throw new i(403,"payer_not_app","this grant is not app-paid");if(e.payer==="user"&&l)throw new i(400,"invalid_request","this grant is app-paid; payer cannot be user","payer");if(l&&!l.inference_endpoint)throw new i(404,"model_unavailable",`${l.grantee} is app-paid but its grant carries no inference endpoint`);const s=l?.inference_endpoint??void 0;l||Oe(w);const g=await ke(),E=u(c=>c.routeId!=="concrete"&&c.routeId!=="exact","configured"),ee=u(c=>{const h=g.find(c.providerId,c.modelId);return h!==void 0&&(!e.reasoning_effort||h.reasoning)&&(e.seed===void 0&&e.response_format===void 0||h.api==="openai-completions")&&(e.stop===void 0||["openai-completions","anthropic-messages"].includes(h.api))},"matchesFeatures"),pe=u(()=>{const c=me(e.model,e.model_policy,r?.cwd,r?.profileId),h=ie(c.kind==="exact"?{kind:"concrete",spec:c.spec}:c,r?.cwd,r?.profileId).filter(E);let a;if(c.kind==="logical")a=e.model_policy==="exact"?h.filter(m=>m.family===c.family&&m.strength===c.strength).slice(0,1):h;else{const m=se(c.spec),q=h.filter(j=>j.providerId===m?.providerId&&j.modelId===m.modelId&&(e.model_policy!=="exact"||j.thinkingLevel===m.thinkingLevel)&&ee(j));if(e.model_policy==="exact")a=q.slice(0,1);else if(q.length)a=q;else{const j=ae(r?.cwd,r?.profileId),x=[...Object.values(j.modelRoutes??{}).flatMap(v=>Object.entries(v.models)),...[j.modelLadders.anthropic,j.modelLadders.openai].flatMap(v=>Object.entries(v))].find(([,v])=>v===c.spec)?.[0],f=me(void 0,"substitute",r?.cwd,r?.profileId);a=x&&f.kind==="logical"?ie({...f,strength:x,spec:c.spec},r?.cwd,r?.profileId).filter(v=>E(v)&&v.strength===x):[]}}return a},"ownerCandidates");let R;if(s?R=De(s,e.model,e.model_policy==="exact").flatMap((c,h)=>{const a=se(c.model);return a?[{routeId:"app",credentialSource:"app",family:"app",strength:c.strength,...a,rank:h}]:[]}):R=pe(),R=R.filter(ee),R.length===0)throw e.model_policy==="exact"?new i(400,"substitution_refused","no eligible model route is configured"):new i(404,"model_unavailable","no eligible model route is configured");const te=`chatcmpl-${ve()}`;let I=1/0,b,z;for(const c of R){if(!l&&!xe(c,g).authenticated)continue;const h=g.find(c.providerId,c.modelId);if(!h)continue;const a=s?{...h,baseUrl:`${s.base_url}/${h.provider}`}:h,m=c.providerId,q=!l&&H(m)?Ae(m).filter(x=>!x.authFailure):[],j=q.filter(x=>le(x,a.id)<=Date.now());if(q.length&&!j.length){const x=Math.min(...q.map(f=>le(f,a.id)));x<I&&(I=x,z=`${a.provider}/${a.id}`);continue}const oe=l?[void 0,void 0]:q.length?j:[void 0];for(const[x,f]of oe.entries()){const v=Date.now();let ne=f?.access;if(f&&f.expires<=Date.now()&&H(m)){const o=g.getProvider(m)?.auth.oauth;if(!o)throw new i(503,"upstream_model_unavailable",`no OAuth refresh for ${m}`,void 0,{served_model:`${a.provider}/${a.id}`});ne=(await $e(m,f.label,async(k,re)=>{const W=await o.refresh({type:"oauth",refresh:k,access:"",expires:0,...re?{clientId:re}:{}},t??new AbortController().signal).catch(ge=>{throw Te(ge,`${a.provider}/${a.id}`)}),V=W.clientId;return{refresh:W.refresh,access:W.access,expires:W.expires,...typeof V=="string"&&V?{clientId:V}:{}}})).access}const he=Ue(e);let N;if(l&&s)try{N=await Le({audience:s.base_url,sub:l.sub,grantee:l.grantee,initiating_app:l.grantee,scope:["crtr:llm"]},{signal:t})}catch(o){throw He(o)}const C=f||l?void 0:await g.getApiKeyAndHeaders(a);if(C&&!C.ok)continue;const p=`${a.provider}/${a.id}`,S=e.model??p;let A=!1,L,M=3e4,$;const B=[],X=[],D=[];let d,F;const T=u((o,_=null)=>({id:te,object:"chat.completion.chunk",created:Math.floor(v/1e3),model:p,served_model:p,requested_model:S,substituted:S!==p&&!/^([^/]+)\/(ultra|strong|medium|light)$/.test(S),choices:[{index:0,delta:o,finish_reason:_}]}),"chunk"),P=u(o=>{B.push(o),n?.(o)},"emit"),_e=we(a,he,{apiKey:N?.access_token??ne??(C?.ok?C.apiKey:void 0),...C?.ok?{headers:C.headers}:{},signal:t,reasoning:e.reasoning_effort??c.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:u(o=>{if(!o||typeof o!="object")return;const _=e.tool_choice,k=_==="required"?a.api==="anthropic-messages"?{type:"any"}:"required":typeof _=="object"&&_!==null?a.api==="anthropic-messages"?{type:"tool",name:_.function.name}:_:void 0;return{...o,...k?{tool_choice:k}:{},...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:u(async(o,_)=>{const k=await fetch(o,_);return L=k.status,k.status===429&&(A=!0,$=k.headers,M=K(k.headers)??15e3),k},"fetch"),onResponse:u(o=>{o.status===429&&(A=!0,$=o.headers,M=K(o.headers)??15e3)},"onResponse")});try{for await(const o of _e)o.type==="text_delta"&&(X.push(o.delta),P(T({content:o.delta}))),o.type==="thinking_delta"&&(D.push(o.delta),P(T({reasoning_content:o.delta}))),o.type==="done"&&(d=o.message),o.type==="error"&&(d=o.error)}catch(o){const _=qe(o);$===void 0&&o&&typeof o=="object"&&"headers"in o&&Object.keys(Ce(o.headers)).length&&($=o.headers);const k=Y({status:o&&typeof o=="object"&&"status"in o?o.status:void 0,message:o instanceof Error?o.message:String(o)});if(l)F=o;else{if(!A&&k.kind!=="rate-limit")throw B.length?new i(503,"upstream_model_unavailable",o instanceof Error?o.message:String(o),void 0,{served_model:p}):o;A=!0,M=_??M}}if(l){if(L===401){if(N&&Ee(N.key),x===0)continue;throw new i(404,"model_unavailable",`${s.base_url} refuses this runtime's tokens`,void 0,{served_model:p})}if(A&&K($)===void 0)throw new i(503,"upstream_model_unavailable",`${p} was rate-limited without a retry-after`,void 0,{served_model:p});if(!A&&(F!==void 0||L!==void 0&&L>=500))throw new i(503,"upstream_model_unavailable",F instanceof Error?F.message:d?.errorMessage??"inference endpoint failed",void 0,{served_model:p})}if(!A&&d?.stopReason==="error"&&Y({message:d.errorMessage}).kind==="rate-limit"&&(A=!0,M=15e3),A){const o=Ie($,a.id);if(K($)===void 0&&o.resetAt!==void 0&&(M=Math.max(M,o.resetAt-Date.now())),b={provider:m,model:a.id,...f?{account:f.label}:{},observation:o},console.error(`[llm] 429 from ${p}${f?` account "${f.label}"`:""}: scope=${ce(o.scope)} retry_after_ms=${M} headers=${JSON.stringify(o.headers)}`),f&&H(m)&&await je(m,f.label,M,v,Date.now(),o.scope),Date.now()+Math.min(M,de)<I&&(I=Date.now()+Math.min(M,de),z=p),X.length||D.length)throw new i(503,"service_unavailable","vendor rate limit after output began",void 0,{served_model:p});if(l)break;continue}const U=Se(d);if(L===400&&e.tool_choice!==void 0&&e.tool_choice!=="auto"&&e.tool_choice!=="none"&&/\btool[_ ]choice\b/i.test(d?.errorMessage??"")&&/not supported|does not support|unsupported|cannot|must be auto/i.test(d?.errorMessage??""))throw new i(400,"invalid_request",d.errorMessage,"tool_choice",{served_model:p});if(d?.stopReason==="error"){const o=ze(a.provider,d.errorMessage,p);if(o)throw o}if(!d||d.stopReason==="error"&&!U||d.stopReason==="aborted")throw new i(503,"upstream_model_unavailable",d?.errorMessage??"model request failed",void 0,{served_model:p});f&&H(m)&&Re(f,a.id)&&await Me(m,f.label,v,a.id);const G=d.content.filter(o=>o.type==="toolCall").map(o=>({id:o.id,type:"function",function:{name:o.name,arguments:JSON.stringify(o.arguments)}})),Z=U?"content_filter":d.stopReason==="toolUse"?"tool_calls":d.stopReason==="length"?"length":"stop",Q=d.responseModel?We(a,d.responseModel):void 0,O=Q?`${a.provider}/${Q.model}`:p,J={prompt_tokens:d.usage.input,completion_tokens:d.usage.output,total_tokens:d.usage.totalTokens,cache_read_tokens:d.usage.cacheRead,cache_write_tokens:d.usage.cacheWrite,usd_equivalent:Je(Q??a,d.usage.cost.total),served_model:O};l?ue(l.grantee,"app",O,d.usage,J.usd_equivalent):w&&ue(w.grantee,"user",O,d.usage,J.usd_equivalent);const ye={id:te,object:"chat.completion",created:Math.floor(v/1e3),model:O,served_model:O,requested_model:S,substituted:S!==O&&!/^([^/]+)\/(ultra|strong|medium|light)$/.test(S),choices:[{index:0,message:{role:"assistant",content:X.join("")||null,...D.length?{reasoning_content:D.join("")}:{},...G.length?{tool_calls:G}:{},...U?{refusal:d.errorMessage??"Content filtered"}:{}},finish_reason:Z}],usage:J,...e.metadata!==void 0?{metadata:e.metadata}:{}};for(const[o,_]of G.entries())P(T({tool_calls:[{index:o,..._}]}));return P({...T({},Z),...U?{choices:[{index:0,delta:{},finish_reason:Z,message:{refusal:d.errorMessage??"Content filtered"}}]}:{},usage:J}),{completion:ye,chunks:B}}}throw I!==1/0?new i(429,"all_routes_exhausted","all eligible model routes are rate-limited",void 0,{retry_after_s:Math.max(1,Math.ceil((I-Date.now())/1e3)),served_model:b?`${b.provider}/${b.model}`:z,...b?{rate_limit:{provider:b.provider,model:b.model,...b.account?{account:b.account}:{},scope:ce(b.observation.scope),...b.observation.claim?{claim:b.observation.claim}:{},headers:b.observation.headers}}:{}},void 0,!0):e.model_policy==="exact"?new i(400,"substitution_refused","the requested model is unavailable"):new i(404,"model_unavailable","no usable model route is available")}u(ut,"runLlm");export{ct as llmCallerOf,lt as parseLlmRequest,ut as runLlm};
|
|
3
|
+
`),l=e.tools?.map(({function:s})=>({name:s.name,description:s.description??"",parameters:s.parameters??{type:"object",properties:{}}}));return{...y?{systemPrompt:y}:{},messages:n.slice(w.length),...l?{tools:l}:{}}}u(Ue,"contextOf");function me(e,t,n,r){if(!e){const y=ae(n,r),l=Object.values({...y.modelRoutes??{},...y.legacyModelRoutes??{}}),s=l.length?[y.modelLadders.defaultProvider,...y.modelRouting?.familyOrder??[],...l.map(g=>g.family)].find(g=>l.some(E=>E.family===g)):y.modelLadders.defaultProvider??"anthropic";return{kind:"logical",family:s,strength:"strong",spec:`${s}/strong`}}const w=/^([^/]+)\/(ultra|strong|medium|light)$/.exec(e);return w?{kind:"logical",family:w[1],strength:w[2],spec:e}:{kind:t==="exact"?"exact":"concrete",spec:e}}u(me,"requestFor");function Je(e,t){const{input:n,output:r,cacheRead:w,cacheWrite:y}=e.cost;return n===0&&r===0&&w===0&&y===0?null:Number.isFinite(t)&&t>=0?t:null}u(Je,"usdEquivalent");function We(e,t){return e.compat?.allowedFallbackModels?.find(r=>r.provider===e.provider&&r.model===t)}u(We,"allowedFallback");function ct(e){return e?{payer:e.payer??"user",sub:e.sub,grantee:e.grantee,inference_endpoint:e.inference_endpoint??null}:void 0}u(ct,"llmCallerOf");function He(e){return e instanceof Ne?e.code==="server_error"?new i(503,"upstream_model_unavailable",e.message):new i(404,"model_unavailable",e.message):e}u(He,"mintFailure");const Ke=/\bmodel is not supported when using Codex with a ChatGPT account\b/i;function ze(e,t,n){if(!(e!=="openai-codex"||t===void 0||!Ke.test(t)))return new i(404,"model_unavailable",t,void 0,{served_model:n})}u(ze,"codexAccountModelRejection");async function ut(e,t,n,r,w,y){const l=y?.payer==="app"?y:void 0;if(e.payer==="app"&&!l)throw new i(403,"payer_not_app","this grant is not app-paid");if(e.payer==="user"&&l)throw new i(400,"invalid_request","this grant is app-paid; payer cannot be user","payer");if(l&&!l.inference_endpoint)throw new i(404,"model_unavailable",`${l.grantee} is app-paid but its grant carries no inference endpoint`);const s=l?.inference_endpoint??void 0;l||await Oe(w);const g=await ke(),E=u(c=>c.routeId!=="concrete"&&c.routeId!=="exact","configured"),ee=u(c=>{const h=g.find(c.providerId,c.modelId);return h!==void 0&&(!e.reasoning_effort||h.reasoning)&&(e.seed===void 0&&e.response_format===void 0||h.api==="openai-completions")&&(e.stop===void 0||["openai-completions","anthropic-messages"].includes(h.api))},"matchesFeatures"),pe=u(()=>{const c=me(e.model,e.model_policy,r?.cwd,r?.profileId),h=ie(c.kind==="exact"?{kind:"concrete",spec:c.spec}:c,r?.cwd,r?.profileId).filter(E);let a;if(c.kind==="logical")a=e.model_policy==="exact"?h.filter(m=>m.family===c.family&&m.strength===c.strength).slice(0,1):h;else{const m=se(c.spec),q=h.filter(j=>j.providerId===m?.providerId&&j.modelId===m.modelId&&(e.model_policy!=="exact"||j.thinkingLevel===m.thinkingLevel)&&ee(j));if(e.model_policy==="exact")a=q.slice(0,1);else if(q.length)a=q;else{const j=ae(r?.cwd,r?.profileId),x=[...Object.values(j.modelRoutes??{}).flatMap(v=>Object.entries(v.models)),...[j.modelLadders.anthropic,j.modelLadders.openai].flatMap(v=>Object.entries(v))].find(([,v])=>v===c.spec)?.[0],f=me(void 0,"substitute",r?.cwd,r?.profileId);a=x&&f.kind==="logical"?ie({...f,strength:x,spec:c.spec},r?.cwd,r?.profileId).filter(v=>E(v)&&v.strength===x):[]}}return a},"ownerCandidates");let R;if(s?R=De(s,e.model,e.model_policy==="exact").flatMap((c,h)=>{const a=se(c.model);return a?[{routeId:"app",credentialSource:"app",family:"app",strength:c.strength,...a,rank:h}]:[]}):R=pe(),R=R.filter(ee),R.length===0)throw e.model_policy==="exact"?new i(400,"substitution_refused","no eligible model route is configured"):new i(404,"model_unavailable","no eligible model route is configured");const te=`chatcmpl-${ve()}`;let I=1/0,b,z;for(const c of R){if(!l&&!xe(c,g).authenticated)continue;const h=g.find(c.providerId,c.modelId);if(!h)continue;const a=s?{...h,baseUrl:`${s.base_url}/${h.provider}`}:h,m=c.providerId,q=!l&&H(m)?Ae(m).filter(x=>!x.authFailure):[],j=q.filter(x=>le(x,a.id)<=Date.now());if(q.length&&!j.length){const x=Math.min(...q.map(f=>le(f,a.id)));x<I&&(I=x,z=`${a.provider}/${a.id}`);continue}const oe=l?[void 0,void 0]:q.length?j:[void 0];for(const[x,f]of oe.entries()){const v=Date.now();let ne=f?.access;if(f&&f.expires<=Date.now()&&H(m)){const o=g.getProvider(m)?.auth.oauth;if(!o)throw new i(503,"upstream_model_unavailable",`no OAuth refresh for ${m}`,void 0,{served_model:`${a.provider}/${a.id}`});ne=(await $e(m,f.label,async(k,re)=>{const W=await o.refresh({type:"oauth",refresh:k,access:"",expires:0,...re?{clientId:re}:{}},t??new AbortController().signal).catch(ge=>{throw Te(ge,`${a.provider}/${a.id}`)}),V=W.clientId;return{refresh:W.refresh,access:W.access,expires:W.expires,...typeof V=="string"&&V?{clientId:V}:{}}})).access}const he=Ue(e);let N;if(l&&s)try{N=await Le({audience:s.base_url,sub:l.sub,grantee:l.grantee,initiating_app:l.grantee,scope:["crtr:llm"]},{signal:t})}catch(o){throw He(o)}const C=f||l?void 0:await g.getApiKeyAndHeaders(a);if(C&&!C.ok)continue;const p=`${a.provider}/${a.id}`,S=e.model??p;let A=!1,L,M=3e4,$;const B=[],X=[],D=[];let d,F;const T=u((o,_=null)=>({id:te,object:"chat.completion.chunk",created:Math.floor(v/1e3),model:p,served_model:p,requested_model:S,substituted:S!==p&&!/^([^/]+)\/(ultra|strong|medium|light)$/.test(S),choices:[{index:0,delta:o,finish_reason:_}]}),"chunk"),P=u(o=>{B.push(o),n?.(o)},"emit"),_e=we(a,he,{apiKey:N?.access_token??ne??(C?.ok?C.apiKey:void 0),...C?.ok?{headers:C.headers}:{},signal:t,reasoning:e.reasoning_effort??c.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:u(o=>{if(!o||typeof o!="object")return;const _=e.tool_choice,k=_==="required"?a.api==="anthropic-messages"?{type:"any"}:"required":typeof _=="object"&&_!==null?a.api==="anthropic-messages"?{type:"tool",name:_.function.name}:_:void 0;return{...o,...k?{tool_choice:k}:{},...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:u(async(o,_)=>{const k=await fetch(o,_);return L=k.status,k.status===429&&(A=!0,$=k.headers,M=K(k.headers)??15e3),k},"fetch"),onResponse:u(o=>{o.status===429&&(A=!0,$=o.headers,M=K(o.headers)??15e3)},"onResponse")});try{for await(const o of _e)o.type==="text_delta"&&(X.push(o.delta),P(T({content:o.delta}))),o.type==="thinking_delta"&&(D.push(o.delta),P(T({reasoning_content:o.delta}))),o.type==="done"&&(d=o.message),o.type==="error"&&(d=o.error)}catch(o){const _=qe(o);$===void 0&&o&&typeof o=="object"&&"headers"in o&&Object.keys(Ce(o.headers)).length&&($=o.headers);const k=Y({status:o&&typeof o=="object"&&"status"in o?o.status:void 0,message:o instanceof Error?o.message:String(o)});if(l)F=o;else{if(!A&&k.kind!=="rate-limit")throw B.length?new i(503,"upstream_model_unavailable",o instanceof Error?o.message:String(o),void 0,{served_model:p}):o;A=!0,M=_??M}}if(l){if(L===401){if(N&&Ee(N.key),x===0)continue;throw new i(404,"model_unavailable",`${s.base_url} refuses this runtime's tokens`,void 0,{served_model:p})}if(A&&K($)===void 0)throw new i(503,"upstream_model_unavailable",`${p} was rate-limited without a retry-after`,void 0,{served_model:p});if(!A&&(F!==void 0||L!==void 0&&L>=500))throw new i(503,"upstream_model_unavailable",F instanceof Error?F.message:d?.errorMessage??"inference endpoint failed",void 0,{served_model:p})}if(!A&&d?.stopReason==="error"&&Y({message:d.errorMessage}).kind==="rate-limit"&&(A=!0,M=15e3),A){const o=Ie($,a.id);if(K($)===void 0&&o.resetAt!==void 0&&(M=Math.max(M,o.resetAt-Date.now())),b={provider:m,model:a.id,...f?{account:f.label}:{},observation:o},console.error(`[llm] 429 from ${p}${f?` account "${f.label}"`:""}: scope=${ce(o.scope)} retry_after_ms=${M} headers=${JSON.stringify(o.headers)}`),f&&H(m)&&await je(m,f.label,M,v,Date.now(),o.scope),Date.now()+Math.min(M,de)<I&&(I=Date.now()+Math.min(M,de),z=p),X.length||D.length)throw new i(503,"service_unavailable","vendor rate limit after output began",void 0,{served_model:p});if(l)break;continue}const U=Se(d);if(L===400&&e.tool_choice!==void 0&&e.tool_choice!=="auto"&&e.tool_choice!=="none"&&/\btool[_ ]choice\b/i.test(d?.errorMessage??"")&&/not supported|does not support|unsupported|cannot|must be auto/i.test(d?.errorMessage??""))throw new i(400,"invalid_request",d.errorMessage,"tool_choice",{served_model:p});if(d?.stopReason==="error"){const o=ze(a.provider,d.errorMessage,p);if(o)throw o}if(!d||d.stopReason==="error"&&!U||d.stopReason==="aborted")throw new i(503,"upstream_model_unavailable",d?.errorMessage??"model request failed",void 0,{served_model:p});f&&H(m)&&Re(f,a.id)&&await Me(m,f.label,v,a.id);const G=d.content.filter(o=>o.type==="toolCall").map(o=>({id:o.id,type:"function",function:{name:o.name,arguments:JSON.stringify(o.arguments)}})),Z=U?"content_filter":d.stopReason==="toolUse"?"tool_calls":d.stopReason==="length"?"length":"stop",Q=d.responseModel?We(a,d.responseModel):void 0,O=Q?`${a.provider}/${Q.model}`:p,J={prompt_tokens:d.usage.input,completion_tokens:d.usage.output,total_tokens:d.usage.totalTokens,cache_read_tokens:d.usage.cacheRead,cache_write_tokens:d.usage.cacheWrite,usd_equivalent:Je(Q??a,d.usage.cost.total),served_model:O};l?await ue(l.grantee,"app",O,d.usage,J.usd_equivalent):w&&await ue(w.grantee,"user",O,d.usage,J.usd_equivalent);const ye={id:te,object:"chat.completion",created:Math.floor(v/1e3),model:O,served_model:O,requested_model:S,substituted:S!==O&&!/^([^/]+)\/(ultra|strong|medium|light)$/.test(S),choices:[{index:0,message:{role:"assistant",content:X.join("")||null,...D.length?{reasoning_content:D.join("")}:{},...G.length?{tool_calls:G}:{},...U?{refusal:d.errorMessage??"Content filtered"}:{}},finish_reason:Z}],usage:J,...e.metadata!==void 0?{metadata:e.metadata}:{}};for(const[o,_]of G.entries())P(T({tool_calls:[{index:o,..._}]}));return P({...T({},Z),...U?{choices:[{index:0,delta:{},finish_reason:Z,message:{refusal:d.errorMessage??"Content filtered"}}]}:{},usage:J}),{completion:ye,chunks:B}}}throw I!==1/0?new i(429,"all_routes_exhausted","all eligible model routes are rate-limited",void 0,{retry_after_s:Math.max(1,Math.ceil((I-Date.now())/1e3)),served_model:b?`${b.provider}/${b.model}`:z,...b?{rate_limit:{provider:b.provider,model:b.model,...b.account?{account:b.account}:{},scope:ce(b.observation.scope),...b.observation.claim?{claim:b.observation.claim}:{},headers:b.observation.headers}}:{}},void 0,!0):e.model_policy==="exact"?new i(400,"substitution_refused","the requested model is unavailable"):new i(404,"model_unavailable","no usable model route is available")}u(ut,"runLlm");export{ct as llmCallerOf,lt as parseLlmRequest,ut as runLlm};
|
|
@@ -67,7 +67,7 @@ export declare const directory: DirectoryClient;
|
|
|
67
67
|
export declare const listMachines: () => Promise<Machine[]>;
|
|
68
68
|
export declare const machineReach: (machineId: string) => Promise<Machine | null>;
|
|
69
69
|
/** The URL peers call this machine at, as the directory last reported it from a status call; null before the first one. */
|
|
70
|
-
export declare function machineUrl(): string | null
|
|
70
|
+
export declare function machineUrl(): Promise<string | null>;
|
|
71
71
|
/** Tell the directory this machine is up (its plugins and crtr version) and store the URL it answers with as `machine_url`.
|
|
72
72
|
* Returns the stored URL, or null when this daemon has no directory identity. Throws `DirectoryError` when the directory fails. */
|
|
73
73
|
export declare function reportMachineStatus(client?: DirectoryClient): Promise<MachineStatus | null>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var v=Object.defineProperty;var o=(t,e)=>v(t,"name",{value:e,configurable:!0});import{normalizeMachineId as m,rememberMachineName as p}from"./names.js";import{openDb as _}from"../canvas/db.js";import{readConfig as M}from"../config.js";import{runtimeClient as g}from"../grants/sync.js";import{crtrVersion as C}from"../../shared/crtr-version.js";import{installedPluginIds as I}from"../directory/join.js";import{peerTokens as R}from"./token.js";const S=5*6e4,A=1e4;class c extends Error{static{o(this,"DirectoryError")}status;constructor(e,i){super(i),this.status=e,this.name="DirectoryError"}}function E(t){if(!t||typeof t!="object")return null;const{kind:e,relay:i}=t;return e==="stable"?{kind:"stable"}:e==="relay"&&typeof i=="string"?{kind:"relay",relay:i}:null}o(E,"asReach");function T(t){const e=t,i=E(e?.reach);if(!e||typeof e.machine_id!="string"||typeof e.url!="string"||i===null)throw new c(502,"the directory answered a machine record with a missing machine_id, url or reach");return{machine_id:e.machine_id,name:typeof e.name=="string"?e.name:e.machine_id,url:e.url.replace(/\/$/,""),reach:i,crtr_version:typeof e.crtr_version=="string"?e.crtr_version:null,last_seen:typeof e.last_seen=="string"?e.last_seen:null,kind:e.kind==="device"?"device":"runtime",plugins:Array.isArray(e.plugins)?e.plugins.filter(u=>typeof u=="string"):[],...typeof e.is_default=="boolean"?{is_default:e.is_default}:{}}}o(T,"asMachine");function b(t,e){const i=new Map;let u=null;async function f(s,a,r){const n=t.issuer();if(n===null)throw new c(0,"this daemon has no directory");const d=n.replace(/\/$/,"");for(let y=0;;y++){let l;try{const h=await t.tokens.get(d);l=await t.fetch(`${d}${a}`,{method:s,headers:{authorization:`Bearer ${h}`,...r===void 0?{}:{"content-type":"application/json"}},...r===void 0?{}:{body:JSON.stringify(r)},signal:AbortSignal.timeout(A)})}catch(h){throw new c(0,`the directory could not be reached: ${h instanceof Error?h.message:String(h)}`)}if(l.status===401&&y===0){t.tokens.drop(d);continue}if(!l.ok)throw new c(l.status,`directory ${s} ${a} answered ${l.status}`);try{return await l.json()}catch{throw new c(502,`directory ${s} ${a} answered a body that is not JSON`)}}}return o(f,"call"),{async list(){const s=await f("GET","/v1/machines");if(!Array.isArray(s))throw new c(502,"the directory answered a machine list that is not an array");const a=s.map(T),r=t.now();for(const n of a)i.set(n.machine_id,{machine:n,at:r}),p(n.machine_id,n.name);return u={machines:a,at:r},a},lastList(){return u===null?null:u.machines},async reach(s){const a=m(s),r=i.get(a);if(r&&t.now()-r.at<S)return r.machine;try{const n=T(await f("GET",`/v1/machines/${encodeURIComponent(a)}/reach`));return i.set(a,{machine:n,at:t.now()}),p(n.machine_id,n.name),n}catch(n){if(n instanceof c&&n.status===404)return i.delete(a),null;if(r&&n instanceof c&&n.status===0)return r.machine;throw n}},async status(s){const a=e(),r=await f("PUT",`/v1/machines/${encodeURIComponent(a)}/status`,s);if(!r||typeof r.machine_id!="string"||typeof r.url!="string")throw new c(502,"the directory answered a status record with a missing machine_id or url");return{machine_id:r.machine_id,url:r.url.replace(/\/$/,""),reach:E(r.reach)}},invalidate(s){s===void 0?(i.clear(),u=null):i.delete(m(s))}}}o(b,"createDirectoryClient");function k(){return m(g().runtime)}o(k,"ownMachineId");function x(){return M("user").runtime?.issuer??null}o(x,"directoryIssuer");const w=b({issuer:x,tokens:R,fetch:o((t,e)=>fetch(t,e),"fetch"),now:Date.now},k),F=o(()=>w.list(),"listMachines"),G=o(t=>w.reach(t),"machineReach"),$="machine_url";async function J(){return(await(await _()).prepare("SELECT value FROM runtime_state WHERE key = ?").get($))?.value??null}o(J,"machineUrl");async function O(t){await(await _()).prepare("INSERT INTO runtime_state (key, value) VALUES (?, ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value").run($,t)}o(O,"storeMachineUrl");async function V(t=w){if(x()===null)return null;try{g()}catch{return null}const e=await t.status({plugins:I(),crtr_version:C()});if(e.machine_id!==k())throw new c(502,"the directory answered a status for another machine");return await O(e.url),e}o(V,"reportMachineStatus");export{A as DIRECTORY_CALL_TIMEOUT_MS,c as DirectoryError,S as REACH_TTL_MS,b as createDirectoryClient,w as directory,x as directoryIssuer,F as listMachines,G as machineReach,J as machineUrl,m as normalizeMachineId,k as ownMachineId,V as reportMachineStatus};
|
|
@@ -31,14 +31,14 @@ export interface EnvelopeContext {
|
|
|
31
31
|
/** This machine's id (`runtime:<id>`). */
|
|
32
32
|
via?: string;
|
|
33
33
|
/** A node's run place. */
|
|
34
|
-
placeOf?: (nodeId: string) => RunPlace | null
|
|
34
|
+
placeOf?: (nodeId: string) => Promise<RunPlace | null>;
|
|
35
35
|
}
|
|
36
36
|
/** The envelope for a call made by `principal` on this machine. Broker → its app, node, stored scopes and run place; cron → its app, anchor node
|
|
37
37
|
* (null when unanchored), stored scopes and origin run; person → no inner `act`. */
|
|
38
|
-
export declare function envelopeFor(principal: EnvelopeCaller, context?: EnvelopeContext): Envelope
|
|
38
|
+
export declare function envelopeFor(principal: EnvelopeCaller, context?: EnvelopeContext): Promise<Envelope>;
|
|
39
39
|
export declare function encodeEnvelope(envelope: Envelope): string;
|
|
40
40
|
/** Parse and validate a `Crtr-Envelope` header value. Throws `EnvelopeError` for anything that is not the documented shape. */
|
|
41
41
|
export declare function decodeEnvelope(header: string): Envelope;
|
|
42
42
|
/** The envelope for a `provider.call` made by `caller` to a device machine: the account owner (`sub`), this machine, and the calling app and node
|
|
43
43
|
* (a person has no inner `act`). The device shows it in its recent-activity list and checks nothing in it. */
|
|
44
|
-
export declare function envelopeForProviderCaller(caller: ProviderCaller, sub: string, context?: Pick<EnvelopeContext, 'via' | 'placeOf'>): Envelope
|
|
44
|
+
export declare function envelopeForProviderCaller(caller: ProviderCaller, sub: string, context?: Pick<EnvelopeContext, 'via' | 'placeOf'>): Promise<Envelope>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var p=Object.defineProperty;var
|
|
1
|
+
var p=Object.defineProperty;var c=(e,o)=>p(e,"name",{value:o,configurable:!0});import{joinedOwner as b}from"../directory/join.js";import{runPlace as d}from"../runs/confinement.js";import{ownMachineId as f}from"./directory.js";const y="Crtr-Envelope",h=16*1024;class r extends Error{static{c(this,"EnvelopeError")}constructor(o){super(o),this.name="EnvelopeError"}}async function _(e,o={}){const n=o.via??f(),s=e.class==="person"?"":e.sub,t=o.owner??(s.startsWith("user:")?s:b());if(t==null)throw new r("this machine has no account owner to make a peer call for");if(e.class==="person")return{sub:t,act:{sub:n}};if(e.class==="broker"){const a=await(o.placeOf??(async u=>await d(u)))(e.node);return{sub:t,act:{sub:n,act:{sub:e.app,node:e.node,node_scopes:e.scopes===null?null:[...e.scopes],place:a}}}}return{sub:t,act:{sub:n,act:{sub:e.app,node:e.anchor,node_scopes:e.scopes===null?null:[...e.scopes],place:{run:e.origin_run??"",isolated:e.isolated}}}}}c(_,"envelopeFor");function g(e){return Buffer.from(JSON.stringify(e),"utf8").toString("base64url")}c(g,"encodeEnvelope");const l=c(e=>typeof e=="string"&&e!=="","isString"),i=c(e=>typeof e=="object"&&e!==null&&!Array.isArray(e),"isRecord");function S(e){if(e.length>h)throw new r("the envelope is too large");if(!/^[A-Za-z0-9_-]+$/.test(e))throw new r("the envelope is not base64url");let o;try{o=JSON.parse(Buffer.from(e,"base64url").toString("utf8"))}catch{throw new r("the envelope is not JSON")}if(!i(o)||!l(o.sub)||!o.sub.startsWith("user:"))throw new r("the envelope names no user");const n=o.act;if(!i(n)||!l(n.sub)||!n.sub.startsWith("runtime:"))throw new r("the envelope names no calling machine");const s=n.act;if(s===void 0)return{sub:o.sub,act:{sub:n.sub}};if(!i(s)||!l(s.sub)||!s.sub.startsWith("app:"))throw new r("the envelope names no calling app");const{node:t,node_scopes:a,place:u}=s;if(t!==null&&!l(t))throw new r("the envelope node is not a node id");if(a!==null&&!(Array.isArray(a)&&a.every(l)))throw new r("the envelope node_scopes is not a list of scopes");if(u!==null&&!(i(u)&&typeof u.run=="string"&&typeof u.isolated=="boolean"))throw new r("the envelope place is malformed");return{sub:o.sub,act:{sub:n.sub,act:{sub:s.sub,node:t,node_scopes:a,place:u===null?null:{run:u.run,isolated:u.isolated}}}}}c(S,"decodeEnvelope");async function O(e,o,n={}){const s=n.via??f();if(e.class==="person"||e.grantee===null)return{sub:o,act:{sub:s}};const t=e.node_id===null?null:await(n.placeOf??(async a=>await d(a)))(e.node_id);return{sub:o,act:{sub:s,act:{sub:e.grantee,node:e.node_id,node_scopes:e.nodeScopes===null?null:[...e.nodeScopes],place:t}}}}c(O,"envelopeForProviderCaller");export{y as ENVELOPE_HEADER,r as EnvelopeError,h as MAX_ENVELOPE_BYTES,S as decodeEnvelope,g as encodeEnvelope,_ as envelopeFor,O as envelopeForProviderCaller};
|
package/dist/core/peer/home.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { DatabaseSync } from 'node:sqlite';
|
|
2
1
|
import { type PeerRequest, type PeerResult } from './client.js';
|
|
3
2
|
import { type Machine } from './directory.js';
|
|
3
|
+
import type { CanvasDb } from '../canvas/db.js';
|
|
4
4
|
export type HomeAnswer = {
|
|
5
5
|
where: 'here';
|
|
6
6
|
} | {
|
|
@@ -26,15 +26,15 @@ export interface HomeDeps {
|
|
|
26
26
|
joined(): boolean;
|
|
27
27
|
}
|
|
28
28
|
export declare const defaultHomeDeps: HomeDeps;
|
|
29
|
-
export declare function cachedLocation(db:
|
|
30
|
-
export declare function rememberLocation(db:
|
|
31
|
-
export declare function dropLocation(db:
|
|
29
|
+
export declare function cachedLocation(db: CanvasDb, id: string): Promise<string | null>;
|
|
30
|
+
export declare function rememberLocation(db: CanvasDb, id: string, machine: string, now?: number): Promise<void>;
|
|
31
|
+
export declare function dropLocation(db: CanvasDb, id: string): Promise<void>;
|
|
32
32
|
/** Ask every other machine "do you hold `id`?". First `here`/`moved` wins; unreachable machines are listed. */
|
|
33
|
-
export declare function locate(db:
|
|
33
|
+
export declare function locate(db: CanvasDb, id: string, deps?: HomeDeps, skip?: string): Promise<HomeAnswer>;
|
|
34
34
|
/** Where `id` lives. `hint` is the machine the request names (`?machine=`). */
|
|
35
|
-
export declare function homeOf(db:
|
|
35
|
+
export declare function homeOf(db: CanvasDb, id: string, opts?: {
|
|
36
36
|
hint?: string | null;
|
|
37
37
|
deps?: HomeDeps;
|
|
38
38
|
}): Promise<HomeAnswer>;
|
|
39
39
|
/** A cached or hinted machine said `404 not_here`: forget it and ask everyone else. */
|
|
40
|
-
export declare function relocate(db:
|
|
40
|
+
export declare function relocate(db: CanvasDb, id: string, wrong: string, deps?: HomeDeps): Promise<HomeAnswer>;
|
package/dist/core/peer/home.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var
|
|
2
|
-
ON CONFLICT(id) DO UPDATE SET machine_id = excluded.machine_id, learned_at = excluded.learned_at`).run(r,
|
|
1
|
+
var _=Object.defineProperty;var t=(n,a)=>_(n,"name",{value:a,configurable:!0});import{getById as y}from"../graph/objects.js";import{isUnreachable as E,peerCall as b}from"./client.js";import{directoryIssuer as x,listMachines as O,normalizeMachineId as d,ownMachineId as T}from"./directory.js";import{stubOf as I}from"./stubs.js";const l={call:t((n,a)=>b(n,a),"call"),machines:O,self:T,now:Date.now,joined:t(()=>x()!==null,"joined")};async function L(n,a){return(await n.prepare("SELECT machine_id FROM peer_locations WHERE id = ?").get(a))?.machine_id??null}t(L,"cachedLocation");async function g(n,a,r,i=Date.now()){await n.prepare(`INSERT INTO peer_locations (id, machine_id, learned_at) VALUES (?, ?, ?)
|
|
2
|
+
ON CONFLICT(id) DO UPDATE SET machine_id = excluded.machine_id, learned_at = excluded.learned_at`).run(a,r,i)}t(g,"rememberLocation");async function D(n,a){await n.prepare("DELETE FROM peer_locations WHERE id = ?").run(a)}t(D,"dropLocation");async function f(n,a,r=l,i){if(!r.joined())return{where:"nowhere"};let c;try{c=await r.machines()}catch(e){return{where:"unknown",unreachable:[`directory (${e instanceof Error?e.message:String(e)})`]}}const s=r.self(),p=c.filter(e=>e.machine_id!==s&&e.machine_id!==i&&e.kind!=="device"),m=await Promise.all(p.map(async e=>{const o=await r.call(e.machine_id,{method:"POST",path:"/v1/peer/locate",body:{id:a}});if(E(o))return{m:e,state:"unreachable"};const h=o.body;return o.status===200&&h?.answer==="here"?{m:e,state:"here",machine:e.machine_id}:o.status===200&&h?.answer==="moved"&&typeof h.machine=="string"?{m:e,state:"here",machine:d(h.machine)}:o.status===200&&h?.answer==="no"?{m:e,state:"no"}:{m:e,state:"unreachable"}})),u=m.find(e=>e.state==="here");if(u&&"machine"in u)return await g(n,a,u.machine,r.now()),{where:"machine",machine:u.machine,source:"locate"};const w=m.filter(e=>e.state==="unreachable").map(e=>e.m.name||e.m.machine_id);return w.length>0?{where:"unknown",unreachable:w}:{where:"nowhere"}}t(f,"locate");async function j(n,a,r={}){const i=await y(n,a);if(i!==null){const s=await I(n,i);return s===null?{where:"here"}:{where:"machine",machine:s.home_machine,source:"stub"}}if(!(r.deps??l).joined())return{where:"nowhere"};if(r.hint)return{where:"machine",machine:d(r.hint),source:"hint"};const c=await L(n,a);return c!==null?{where:"machine",machine:c,source:"cache"}:f(n,a,r.deps)}t(j,"homeOf");async function k(n,a,r,i=l){return await D(n,a),f(n,a,i,r)}t(k,"relocate");export{L as cachedLocation,l as defaultHomeDeps,D as dropLocation,j as homeOf,f as locate,k as relocate,g as rememberLocation};
|