@tangle-network/agent-app 0.45.53 → 0.45.55
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/README.md +1 -1
- package/dist/alerting/index.d.ts +5 -175
- package/dist/alerting/slack.d.ts +176 -0
- package/dist/app-auth/index.d.ts +14 -17
- package/dist/assets/index.d.ts +2 -504
- package/dist/assets/schema.d.ts +264 -0
- package/dist/assets/types.d.ts +237 -0
- package/dist/assistant/AssistantDock.d.ts +56 -0
- package/dist/assistant/AssistantHistory.d.ts +41 -0
- package/dist/assistant/AssistantPanel.d.ts +84 -0
- package/dist/assistant/ProposalCard.d.ts +41 -0
- package/dist/assistant/ResizeHandle.d.ts +19 -0
- package/dist/assistant/client-context.d.ts +20 -0
- package/dist/assistant/client.d.ts +117 -0
- package/dist/assistant/index.d.ts +19 -848
- package/dist/assistant/launcher.d.ts +23 -0
- package/dist/assistant/persistence.d.ts +26 -0
- package/dist/assistant/presentation.d.ts +99 -0
- package/dist/assistant/provider-label.d.ts +7 -0
- package/dist/assistant/reducer.d.ts +130 -0
- package/dist/assistant/sse.d.ts +24 -0
- package/dist/assistant/time-ago.d.ts +6 -0
- package/dist/assistant/transcript.d.ts +97 -0
- package/dist/assistant/types.d.ts +291 -0
- package/dist/assistant/use-stick-to-bottom.d.ts +28 -0
- package/dist/assistant/useAssistantChat.d.ts +63 -0
- package/dist/assistant/useAssistantModels.d.ts +22 -0
- package/dist/assistant/useAssistantThreads.d.ts +47 -0
- package/dist/assistant/usePanelPrefs.d.ts +55 -0
- package/dist/billing/index.d.ts +19 -21
- package/dist/brand/index.d.ts +16 -10
- package/dist/brand-extraction/extract.d.ts +34 -0
- package/dist/brand-extraction/index.d.ts +12 -214
- package/dist/brand-extraction/map.d.ts +58 -0
- package/dist/brand-extraction/types.d.ts +119 -0
- package/dist/catalog/index.d.ts +11 -101
- package/dist/chat-react/composer-mode-controls.d.ts +14 -0
- package/dist/chat-react/entry-composer.d.ts +92 -0
- package/dist/chat-react/index.d.ts +22 -118
- package/dist/chat-react/types.d.ts +11 -0
- package/dist/chat-routes/attachment-store.d.ts +84 -0
- package/dist/chat-routes/attachment-upload.d.ts +84 -0
- package/dist/chat-routes/attachment-validation.d.ts +95 -0
- package/dist/chat-routes/binary-sniff.d.ts +45 -0
- package/dist/chat-routes/completed-sandbox-turn.d.ts +25 -0
- package/dist/chat-routes/detached-turn.d.ts +197 -0
- package/dist/chat-routes/dispatch-parts.d.ts +101 -0
- package/dist/chat-routes/draft-persistence.d.ts +189 -0
- package/dist/chat-routes/durable-projection.d.ts +18 -0
- package/dist/chat-routes/file-index.d.ts +115 -0
- package/dist/chat-routes/index.d.ts +25 -1840
- package/dist/chat-routes/model-failover-stream.d.ts +206 -0
- package/dist/chat-routes/promote-file-part.d.ts +84 -0
- package/dist/chat-routes/resolve-attachments.d.ts +72 -0
- package/dist/chat-routes/sandbox-producer.d.ts +146 -0
- package/dist/chat-routes/sandbox-turn-usage.d.ts +4 -0
- package/dist/{stale-turn-lock-DucQzvXu.d.ts → chat-routes/stale-turn-lock.d.ts} +7 -9
- package/dist/chat-routes/turn-routes.d.ts +540 -0
- package/dist/chat-routes/upload.d.ts +84 -0
- package/dist/{wire-DOZ-O6hD.d.ts → chat-routes/wire.d.ts} +41 -44
- package/dist/chat-store/core.d.ts +19 -0
- package/dist/chat-store/index.d.ts +22 -322
- package/dist/{parts-BqIHMdyu.d.ts → chat-store/parts.d.ts} +49 -47
- package/dist/chat-store/schema.d.ts +157 -0
- package/dist/chat-store/store.d.ts +177 -0
- package/dist/config/index.d.ts +13 -18
- package/dist/crypto/index.d.ts +10 -12
- package/dist/crypto/web-token.d.ts +22 -0
- package/dist/design-canvas/apply.d.ts +70 -0
- package/dist/design-canvas/drizzle-store.d.ts +29 -0
- package/dist/design-canvas/drizzle.d.ts +7 -575
- package/dist/{export-presets-mgVulRaV.d.ts → design-canvas/export-presets.d.ts} +18 -22
- package/dist/design-canvas/index.d.ts +22 -268
- package/dist/design-canvas/mcp-entry.d.ts +15 -0
- package/dist/design-canvas/mcp-handler.d.ts +34 -0
- package/dist/design-canvas/mcp-tools.d.ts +30 -0
- package/dist/{model-DnfO_PdJ.d.ts → design-canvas/model.d.ts} +33 -35
- package/dist/{operations-ByJ6yXOW.d.ts → design-canvas/operations.d.ts} +21 -25
- package/dist/design-canvas/schema.d.ts +558 -0
- package/dist/{store-CqfDtnPQ.d.ts → design-canvas/store.d.ts} +8 -12
- package/dist/design-canvas/templates.d.ts +72 -0
- package/dist/design-canvas/validate.d.ts +32 -0
- package/dist/design-canvas-react/components/BleedTrimOverlay.d.ts +22 -0
- package/dist/design-canvas-react/components/BrandKnot.d.ts +11 -0
- package/dist/design-canvas-react/components/CanvasEmptyState.d.ts +32 -0
- package/dist/design-canvas-react/components/CanvasInsertPanel.d.ts +53 -0
- package/dist/{lazy-DrkVyDpe.d.ts → design-canvas-react/components/DesignCanvas.d.ts} +27 -20
- package/dist/design-canvas-react/components/DesignCanvasEditor.d.ts +23 -0
- package/dist/design-canvas-react/components/ElementNode.d.ts +51 -0
- package/dist/design-canvas-react/components/ExportControl.d.ts +21 -0
- package/dist/design-canvas-react/components/GridLayer.d.ts +47 -0
- package/dist/design-canvas-react/components/InlineTextEditor.d.ts +25 -0
- package/dist/design-canvas-react/components/LayersPanel.d.ts +20 -0
- package/dist/design-canvas-react/components/PagesStrip.d.ts +34 -0
- package/dist/design-canvas-react/components/Rulers.d.ts +31 -0
- package/dist/design-canvas-react/components/SelectionLayer.d.ts +51 -0
- package/dist/design-canvas-react/components/SnapGuidesOverlay.d.ts +25 -0
- package/dist/design-canvas-react/components/Toolbar.d.ts +64 -0
- package/dist/design-canvas-react/components/Workspace.d.ts +92 -0
- package/dist/design-canvas-react/components/ZoomControls.d.ts +14 -0
- package/dist/design-canvas-react/components/glyphs.d.ts +46 -0
- package/dist/design-canvas-react/components/icon-button.d.ts +22 -0
- package/dist/design-canvas-react/components/index.d.ts +27 -0
- package/dist/design-canvas-react/components/layer-tree.d.ts +34 -0
- package/dist/design-canvas-react/components/ruler-math.d.ts +78 -0
- package/dist/design-canvas-react/components/transform-math.d.ts +168 -0
- package/dist/{command-stack-TNPWJCzW.d.ts → design-canvas-react/contracts.d.ts} +16 -63
- package/dist/design-canvas-react/engine/command-stack.d.ts +43 -0
- package/dist/design-canvas-react/engine/commands.d.ts +154 -0
- package/dist/design-canvas-react/engine/selection.d.ts +48 -0
- package/dist/design-canvas-react/engine/snap.d.ts +24 -0
- package/dist/design-canvas-react/engine/zoom-pan.d.ts +18 -0
- package/dist/design-canvas-react/engine.d.ts +21 -399
- package/dist/design-canvas-react/export-math.d.ts +104 -0
- package/dist/design-canvas-react/export.d.ts +89 -0
- package/dist/design-canvas-react/index.d.ts +16 -586
- package/dist/design-canvas-react/insert-builders.d.ts +61 -0
- package/dist/design-canvas-react/lazy.d.ts +21 -6
- package/dist/documents/docx.d.ts +50 -0
- package/dist/documents/extract.d.ts +87 -0
- package/dist/documents/index.d.ts +26 -232
- package/dist/documents/media-type.d.ts +33 -0
- package/dist/documents/pdf-inspector.d.ts +5 -9
- package/dist/{types-DrBidf3O.d.ts → documents/types.d.ts} +13 -15
- package/dist/documents/zip.d.ts +56 -0
- package/dist/eval/calibration.d.ts +106 -0
- package/dist/eval/index.d.ts +8 -116
- package/dist/eval-campaign/index.d.ts +11 -12
- package/dist/{trust-gate-Dcm5xSva.d.ts → eval-campaign/trust-gate.d.ts} +5 -9
- package/dist/forms/blank.d.ts +48 -0
- package/dist/forms/fill.d.ts +105 -0
- package/dist/forms/index.d.ts +58 -332
- package/dist/forms/registry.d.ts +115 -0
- package/dist/forms/verify.d.ts +58 -0
- package/dist/harness/index.d.ts +21 -19
- package/dist/intakes/api.d.ts +5 -11
- package/dist/{completion-CvcNUz07.d.ts → intakes/completion.d.ts} +7 -11
- package/dist/intakes/context-sufficiency.d.ts +113 -0
- package/dist/intakes/drizzle/schema.d.ts +338 -0
- package/dist/intakes/drizzle/store.d.ts +75 -0
- package/dist/intakes/drizzle.d.ts +12 -391
- package/dist/intakes/index.d.ts +23 -113
- package/dist/{model-C8U0HZxL.d.ts → intakes/model.d.ts} +15 -17
- package/dist/intakes-react/components/BrandMark.d.ts +10 -0
- package/dist/intakes-react/components/IntakeInterview.d.ts +15 -0
- package/dist/intakes-react/components/index.d.ts +1 -0
- package/dist/intakes-react/contracts.d.ts +42 -0
- package/dist/intakes-react/index.d.ts +12 -47
- package/dist/intakes-react/lazy.d.ts +9 -8
- package/dist/integrations/index.d.ts +10 -12
- package/dist/{contract-OxG_jVMx.d.ts → interactions/contract.d.ts} +40 -42
- package/dist/interactions/index.d.ts +16 -256
- package/dist/interactions/route.d.ts +151 -0
- package/dist/interactions/sidecar.d.ts +100 -0
- package/dist/knowledge/index.d.ts +7 -11
- package/dist/knowledge-loop/index.d.ts +13 -20
- package/dist/legibility/checks/empty-state.d.ts +59 -0
- package/dist/legibility/checks/reachability.d.ts +103 -0
- package/dist/legibility/checks/silent-failure.d.ts +57 -0
- package/dist/legibility/checks/success.d.ts +38 -0
- package/dist/legibility/checks/vocabulary.d.ts +65 -0
- package/dist/legibility/cli-args.d.ts +30 -0
- package/dist/legibility/cli.d.ts +25 -0
- package/dist/legibility/index.d.ts +10 -530
- package/dist/legibility/report.d.ts +22 -0
- package/dist/legibility/scan.d.ts +29 -0
- package/dist/legibility/source.d.ts +132 -0
- package/dist/legibility/suppress.d.ts +36 -0
- package/dist/legibility/types.d.ts +168 -0
- package/dist/legibility/walk-sources.d.ts +21 -0
- package/dist/{agent-activity-C8ZG0F0M.d.ts → missions/agent-activity.d.ts} +3 -5
- package/dist/missions/engine.d.ts +251 -0
- package/dist/missions/events.d.ts +195 -0
- package/dist/missions/index.d.ts +12 -765
- package/dist/missions/plan-parse.d.ts +50 -0
- package/dist/missions/service.d.ts +265 -0
- package/dist/{failover-D-3UXXTb.d.ts → model-resolution/failover.d.ts} +10 -12
- package/dist/model-resolution/index.d.ts +15 -18
- package/dist/object-store/index.d.ts +15 -17
- package/dist/openui/action.d.ts +54 -0
- package/dist/openui/authoring.d.ts +25 -0
- package/dist/openui/index.d.ts +24 -206
- package/dist/openui/route.d.ts +124 -0
- package/dist/openui/segments.d.ts +71 -0
- package/dist/openui/values.d.ts +82 -0
- package/dist/openui-react/index.d.ts +9 -13
- package/dist/peer-floors/check.d.ts +9 -190
- package/dist/peer-floors/cli.d.ts +2 -3
- package/dist/peer-floors/dependency-source.d.ts +178 -0
- package/dist/plans/index.d.ts +13 -14
- package/dist/{billing-BuNlaKlE.d.ts → platform/billing.d.ts} +28 -32
- package/dist/platform/guards.d.ts +79 -0
- package/dist/platform/hub.d.ts +107 -0
- package/dist/platform/index.d.ts +7 -112
- package/dist/{sso-Cm00S61u.d.ts → platform/sso.d.ts} +15 -97
- package/dist/preflight/cli.d.ts +3 -6
- package/dist/preflight/index.d.ts +16 -18
- package/dist/preset-cloudflare/headers.d.ts +12 -0
- package/dist/preset-cloudflare/index.d.ts +22 -74
- package/dist/preset-cloudflare/workflow-instance.d.ts +35 -0
- package/dist/profile/budget.d.ts +72 -0
- package/dist/profile/fingerprint.d.ts +65 -0
- package/dist/profile/index.d.ts +27 -19
- package/dist/prompt/index.d.ts +3 -5
- package/dist/record/drizzle/schema.d.ts +488 -0
- package/dist/record/drizzle/store.d.ts +224 -0
- package/dist/record/drizzle.d.ts +10 -679
- package/dist/record/fold.d.ts +99 -0
- package/dist/record/index.d.ts +13 -13
- package/dist/{fold-DACU7gtf.d.ts → record/model.d.ts} +22 -124
- package/dist/record/ulid.d.ts +12 -0
- package/dist/redact/index.d.ts +14 -16
- package/dist/run/index.d.ts +11 -16
- package/dist/runtime/agent.d.ts +23 -0
- package/dist/runtime/certified-delivery.d.ts +57 -0
- package/dist/runtime/index.d.ts +17 -367
- package/dist/runtime/loop.d.ts +58 -0
- package/dist/runtime/model-catalog.d.ts +103 -0
- package/dist/{model-CdCDfBA9.d.ts → runtime/model.d.ts} +25 -27
- package/dist/runtime/openai-stream.d.ts +126 -0
- package/dist/runtime/surface-profile.d.ts +115 -0
- package/dist/sandbox/binary-read.d.ts +63 -0
- package/dist/sandbox/diagnostics.d.ts +69 -0
- package/dist/sandbox/index.d.ts +103 -1085
- package/dist/sandbox/model.d.ts +179 -0
- package/dist/sandbox/outcome.d.ts +10 -0
- package/dist/sandbox/prewarm-claim-d1.d.ts +80 -0
- package/dist/sandbox/prewarm.d.ts +193 -0
- package/dist/sandbox/recovery.d.ts +216 -0
- package/dist/sandbox/terminal-connection.d.ts +145 -0
- package/dist/sandbox/workspace-sandbox-manager.d.ts +44 -0
- package/dist/sequences/apply.d.ts +54 -0
- package/dist/sequences/captions.d.ts +91 -0
- package/dist/sequences/drizzle-store.d.ts +36 -0
- package/dist/sequences/drizzle.d.ts +7 -1252
- package/dist/sequences/exports.d.ts +138 -0
- package/dist/sequences/index.d.ts +19 -340
- package/dist/sequences/mcp-entry.d.ts +15 -0
- package/dist/sequences/mcp-handler.d.ts +39 -0
- package/dist/sequences/mcp-tools.d.ts +47 -0
- package/dist/{store-B7LLlk9p.d.ts → sequences/model.d.ts} +26 -110
- package/dist/sequences/operations.d.ts +126 -0
- package/dist/sequences/schema.d.ts +1231 -0
- package/dist/sequences/store.d.ts +81 -0
- package/dist/sequences/validate.d.ts +98 -0
- package/dist/sequences-react/components/BrandMark.d.ts +10 -0
- package/dist/sequences-react/components/PreviewCanvas.d.ts +26 -0
- package/dist/sequences-react/components/SnapIndicatorLine.d.ts +11 -0
- package/dist/sequences-react/components/TimelineClipChip.d.ts +80 -0
- package/dist/sequences-react/components/TimelineEditor.d.ts +44 -0
- package/dist/sequences-react/components/TimelineEmptyState.d.ts +21 -0
- package/dist/sequences-react/components/TimelineGhostLanes.d.ts +14 -0
- package/dist/sequences-react/components/TimelinePlayhead.d.ts +11 -0
- package/dist/sequences-react/components/TimelineRuler.d.ts +16 -0
- package/dist/sequences-react/components/TimelineSmallScreenGate.d.ts +12 -0
- package/dist/sequences-react/components/TimelineTrackRow.d.ts +51 -0
- package/dist/sequences-react/components/ZoomControl.d.ts +15 -0
- package/dist/sequences-react/components/composite-command.d.ts +8 -0
- package/dist/sequences-react/components/glyphs.d.ts +26 -0
- package/dist/sequences-react/components/index.d.ts +31 -0
- package/dist/sequences-react/components/interaction-math.d.ts +103 -0
- package/dist/sequences-react/contracts.d.ts +187 -0
- package/dist/sequences-react/engine/command-stack.d.ts +18 -0
- package/dist/sequences-react/engine/commands.d.ts +146 -0
- package/dist/sequences-react/engine/playback.d.ts +18 -0
- package/dist/sequences-react/engine/snap.d.ts +29 -0
- package/dist/sequences-react/engine/zoom.d.ts +29 -0
- package/dist/sequences-react/index.d.ts +20 -880
- package/dist/sequences-react/lazy.d.ts +8 -0
- package/dist/sequences-react/media/frame-provider.d.ts +70 -0
- package/dist/sequences-react/media/transcription.d.ts +33 -0
- package/dist/sequences-react/media/waveform.d.ts +34 -0
- package/dist/session-shell/index.d.ts +31 -204
- package/dist/session-shell/nav-guard.d.ts +170 -0
- package/dist/session-shell/path.d.ts +19 -0
- package/dist/signoff/cli.d.ts +4 -7
- package/dist/signoff/config.d.ts +12 -0
- package/dist/signoff/exec.d.ts +44 -0
- package/dist/signoff/index.d.ts +56 -14
- package/dist/signoff/invoked-as-script.d.ts +25 -0
- package/dist/signoff/node-version.d.ts +50 -0
- package/dist/signoff/proof-attach.d.ts +88 -0
- package/dist/signoff/proof-cli.d.ts +1 -0
- package/dist/signoff/proof-fixture.d.ts +13 -0
- package/dist/signoff/proof-from-report.d.ts +22 -0
- package/dist/signoff/proof-git.d.ts +57 -0
- package/dist/signoff/proof-record.d.ts +202 -0
- package/dist/signoff/proof-verify.d.ts +103 -0
- package/dist/signoff/proof.d.ts +35 -310
- package/dist/signoff/report.d.ts +7 -0
- package/dist/{run-D80hoLKh.d.ts → signoff/run.d.ts} +3 -6
- package/dist/signoff/schedule.d.ts +55 -0
- package/dist/signoff/seeds.d.ts +50 -0
- package/dist/signoff/store.d.ts +22 -0
- package/dist/{types-Bd6uW9vQ.d.ts → signoff/types.d.ts} +15 -17
- package/dist/signoff/workflow-pin.d.ts +56 -0
- package/dist/signoff/workspace.d.ts +40 -0
- package/dist/skills/index.d.ts +28 -32
- package/dist/skills-placement/index.d.ts +7 -11
- package/dist/spend/budget.d.ts +123 -0
- package/dist/spend/ceiling.d.ts +51 -0
- package/dist/spend/cli-args.d.ts +20 -0
- package/dist/spend/cli.d.ts +1 -0
- package/dist/spend/fixtures/incident-parked-time.d.ts +55 -0
- package/dist/spend/index.d.ts +38 -1144
- package/dist/spend/liveness.d.ts +131 -0
- package/dist/spend/ownership.d.ts +87 -0
- package/dist/spend/reconcile.d.ts +109 -0
- package/dist/spend/reference.d.ts +42 -0
- package/dist/spend/report.d.ts +12 -0
- package/dist/spend/store.d.ts +123 -0
- package/dist/spend/types.d.ts +466 -0
- package/dist/store/index.d.ts +10 -12
- package/dist/stories/app-shell/fixtures.d.ts +43 -0
- package/dist/stories/app-shell/shell.d.ts +81 -0
- package/dist/stories/assistant/fixtures.d.ts +73 -0
- package/dist/stories/chat/fixtures.d.ts +70 -0
- package/dist/stories/chat/markdown.d.ts +11 -0
- package/dist/stories/chat/run-drill-in.d.ts +19 -0
- package/dist/stories/chat-controls/fixtures.d.ts +116 -0
- package/dist/stories/design-canvas/fixtures.d.ts +57 -0
- package/dist/stories/fixtures/canvas.d.ts +10 -0
- package/dist/stories/fixtures/catalog.d.ts +7 -0
- package/dist/stories/fixtures/chat.d.ts +39 -0
- package/dist/stories/fixtures/index.d.ts +4 -0
- package/dist/stories/fixtures/sequences.d.ts +17 -0
- package/dist/stories/panels/fixtures.d.ts +63 -0
- package/dist/stories/sequences/fixtures.d.ts +30 -0
- package/dist/stories/studio/fixtures.d.ts +22 -0
- package/dist/stream/index.d.ts +10 -56
- package/dist/{stream-normalizer-DKRxyVlZ.d.ts → stream/stream-normalizer.d.ts} +23 -26
- package/dist/{turn-buffer-COMQUwO2.d.ts → stream/turn-buffer.d.ts} +21 -23
- package/dist/stream/turn-identity.d.ts +49 -0
- package/dist/studio/generation.d.ts +179 -0
- package/dist/studio/index.d.ts +12 -181
- package/dist/studio-react/avatar-composer.d.ts +8 -0
- package/dist/studio-react/composer-hero.d.ts +12 -0
- package/dist/studio-react/composer-shell.d.ts +18 -0
- package/dist/studio-react/generation-card.d.ts +9 -0
- package/dist/studio-react/generation-detail-modal.d.ts +11 -0
- package/dist/studio-react/generation-detail.d.ts +6 -0
- package/dist/studio-react/generation-grid.d.ts +15 -0
- package/dist/studio-react/image-composer.d.ts +8 -0
- package/dist/studio-react/index.d.ts +32 -245
- package/dist/studio-react/library-drawer.d.ts +12 -0
- package/dist/studio-react/library-panel.d.ts +15 -0
- package/dist/studio-react/publish-package-composer.d.ts +18 -0
- package/dist/studio-react/result-canvas.d.ts +6 -0
- package/dist/studio-react/speech-composer.d.ts +4 -0
- package/dist/studio-react/studio-header.d.ts +5 -0
- package/dist/studio-react/studio-sheet.d.ts +12 -0
- package/dist/studio-react/studio-workspace.d.ts +23 -0
- package/dist/studio-react/transcription-composer.d.ts +12 -0
- package/dist/studio-react/type-config.d.ts +11 -0
- package/dist/studio-react/use-studio-generations.d.ts +20 -0
- package/dist/studio-react/video-composer.d.ts +10 -0
- package/dist/tangle/index.d.ts +7 -9
- package/dist/teams/drizzle/access.d.ts +82 -0
- package/dist/{invitations-schema-_fI7HkJP.d.ts → teams/drizzle/invitations-schema.d.ts} +39 -27
- package/dist/teams/drizzle/personal-organization.d.ts +41 -0
- package/dist/{access-490O6aOU.d.ts → teams/drizzle/schema.d.ts} +57 -122
- package/dist/teams/drizzle.d.ts +12 -44
- package/dist/teams/index.d.ts +20 -44
- package/dist/teams/invitations-api.d.ts +17 -21
- package/dist/{invitations-DoYMvXea.d.ts → teams/invitations.d.ts} +14 -18
- package/dist/teams/invite.d.ts +42 -0
- package/dist/teams/members-api.d.ts +12 -16
- package/dist/teams/resend.d.ts +3 -13
- package/dist/{roles-B4nU3jDi.d.ts → teams/roles.d.ts} +18 -20
- package/dist/teams-react/components/BrandMark.d.ts +10 -0
- package/dist/teams-react/components/InvitationsPanel.d.ts +13 -0
- package/dist/teams-react/components/InviteAcceptPage.d.ts +10 -0
- package/dist/teams-react/components/MembersPanel.d.ts +14 -0
- package/dist/teams-react/components/RoleSelect.d.ts +17 -0
- package/dist/teams-react/components/index.d.ts +3 -0
- package/dist/teams-react/contracts.d.ts +134 -0
- package/dist/teams-react/index.d.ts +12 -143
- package/dist/teams-react/lazy.d.ts +11 -11
- package/dist/test-setup.d.ts +1 -0
- package/dist/theme/index.d.ts +6 -104
- package/dist/theme/tailwind-preset.d.ts +1 -2
- package/dist/theme/theme.d.ts +106 -0
- package/dist/theme-contract/cli.d.ts +21 -0
- package/dist/theme-contract/index.d.ts +4 -6
- package/dist/{auth-BYtiazA4.d.ts → tools/auth.d.ts} +8 -11
- package/dist/tools/capability.d.ts +54 -0
- package/dist/tools/dispatch.d.ts +37 -0
- package/dist/tools/errors.d.ts +8 -0
- package/dist/tools/gating.d.ts +62 -0
- package/dist/tools/http.d.ts +27 -0
- package/dist/tools/index.d.ts +12 -217
- package/dist/{mcp-rpc-DYwPlYbZ.d.ts → tools/mcp-rpc.d.ts} +7 -9
- package/dist/{mcp-xxoZZfor.d.ts → tools/mcp.d.ts} +14 -16
- package/dist/tools/openai.d.ts +28 -0
- package/dist/tools/registry.d.ts +39 -0
- package/dist/tools/runtime.d.ts +22 -0
- package/dist/{types-B25Mib1r.d.ts → tools/types.d.ts} +15 -83
- package/dist/{flow-types-CJxEmaRy.d.ts → trace/flow-types.d.ts} +2 -4
- package/dist/trace/index.d.ts +11 -148
- package/dist/trace/mission-flow.d.ts +82 -0
- package/dist/trace/mission-trace.d.ts +52 -0
- package/dist/turn-health/classify.d.ts +207 -0
- package/dist/turn-health/index.d.ts +29 -637
- package/dist/turn-health/lifecycle.d.ts +75 -0
- package/dist/turn-health/sink.d.ts +122 -0
- package/dist/turn-health/sweep.d.ts +245 -0
- package/dist/turn-stream/adapters.d.ts +257 -0
- package/dist/turn-stream/core.d.ts +293 -0
- package/dist/turn-stream/do.d.ts +144 -0
- package/dist/turn-stream/index.d.ts +62 -738
- package/dist/turn-stream/memory.d.ts +41 -0
- package/dist/vault/ConfirmDialog.d.ts +22 -0
- package/dist/vault/VaultPane.d.ts +15 -0
- package/dist/{VaultPane-BDP6SB_K.d.ts → vault/contracts.d.ts} +15 -22
- package/dist/vault/index.d.ts +15 -22
- package/dist/vault/lazy.d.ts +9 -7
- package/dist/vault/server.d.ts +8 -10
- package/dist/web/free-route-limit.d.ts +187 -0
- package/dist/web/index.d.ts +15 -207
- package/dist/{rate-limit-BOVmJRXZ.d.ts → web/rate-limit.d.ts} +3 -5
- package/dist/web-react/agent-session-controls.d.ts +105 -0
- package/dist/web-react/async/async-view.d.ts +69 -0
- package/dist/web-react/async/index.d.ts +13 -305
- package/dist/web-react/async/state.d.ts +107 -0
- package/dist/web-react/async/use-async-resource.d.ts +41 -0
- package/dist/web-react/async/use-confirmed-mutation.d.ts +90 -0
- package/dist/web-react/brand-mark.d.ts +11 -0
- package/dist/web-react/chat-attachments.d.ts +21 -0
- package/dist/web-react/chat-composer.d.ts +174 -0
- package/dist/web-react/chat-interactions.d.ts +1 -0
- package/dist/web-react/chat-mentions.d.ts +48 -0
- package/dist/web-react/chat-stream.d.ts +106 -0
- package/dist/web-react/class-names.d.ts +10 -0
- package/dist/web-react/controls.d.ts +265 -0
- package/dist/web-react/durable-chat-cards.d.ts +40 -0
- package/dist/web-react/durable-interaction-submit.d.ts +22 -0
- package/dist/web-react/durable-plan-card.d.ts +13 -0
- package/dist/web-react/durable-plan-flow.d.ts +77 -0
- package/dist/web-react/harness-glyphs.d.ts +28 -0
- package/dist/web-react/index.d.ts +80 -2347
- package/dist/web-react/inert.d.ts +39 -0
- package/dist/web-react/insight-card.d.ts +203 -0
- package/dist/web-react/interaction-card-support.d.ts +115 -0
- package/dist/web-react/interaction-plan-card.d.ts +39 -0
- package/dist/web-react/interaction-question-card.d.ts +100 -0
- package/dist/web-react/message-attachments.d.ts +56 -0
- package/dist/web-react/mission-activity.d.ts +96 -0
- package/dist/web-react/motion.d.ts +43 -0
- package/dist/web-react/provenance-model.d.ts +195 -0
- package/dist/web-react/provenance.d.ts +82 -0
- package/dist/web-react/provider-logo.d.ts +14 -0
- package/dist/web-react/record-grid-model.d.ts +257 -0
- package/dist/web-react/record-grid.d.ts +108 -0
- package/dist/web-react/sandbox-terminal.d.ts +90 -0
- package/dist/web-react/seat-paywall.d.ts +47 -0
- package/dist/web-react/session-history.d.ts +196 -0
- package/dist/web-react/smooth-text.d.ts +29 -0
- package/dist/web-react/sparkline.d.ts +150 -0
- package/dist/web-react/terminal.d.ts +1 -92
- package/dist/web-react/use-chat-interactions.d.ts +78 -0
- package/dist/web-react/use-composer-attachments.d.ts +111 -0
- package/dist/web-react/use-file-mentions.d.ts +94 -0
- package/dist/web-react/work-product.d.ts +105 -0
- package/dist/work-product/claim-support.d.ts +288 -0
- package/dist/work-product/index.d.ts +16 -849
- package/dist/work-product/provenance.d.ts +61 -0
- package/dist/{queue-VTBA5ONX.d.ts → work-product/queue.d.ts} +10 -12
- package/dist/work-product/quote.d.ts +139 -0
- package/dist/work-product/route.d.ts +88 -0
- package/dist/work-product/service.d.ts +123 -0
- package/dist/work-product/tools.d.ts +144 -0
- package/dist/{types-CCeYywdS.d.ts → work-product/types.d.ts} +29 -31
- package/dist/work-product-react/index.d.ts +19 -8
- package/dist/workspace-react/index.d.ts +8 -11
- package/package.json +5 -4
- package/dist/agent-session-controls-CmlXwp_H.d.ts +0 -384
- package/dist/apply-6wlMOLf8.d.ts +0 -280
- package/dist/attachment-validation-BfJDBU1g.d.ts +0 -261
- package/dist/budget-BOucfcb_.d.ts +0 -142
- package/dist/values-C7RidJuI.d.ts +0 -156
package/dist/sandbox/index.d.ts
CHANGED
|
@@ -1,1004 +1,19 @@
|
|
|
1
1
|
import { Sandbox } from '@tangle-network/sandbox/core';
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
} | {
|
|
16
|
-
succeeded: false;
|
|
17
|
-
error: Error;
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
/** Define configuration options for resolving a provider and its model with optional API keys and routing details */
|
|
21
|
-
interface ProviderResolutionConfig {
|
|
22
|
-
routerBaseUrl?: string;
|
|
23
|
-
apiKey?: string;
|
|
24
|
-
providerName?: string;
|
|
25
|
-
modelName?: string;
|
|
26
|
-
defaultModel?: string;
|
|
27
|
-
openaiApiKey?: string;
|
|
28
|
-
allowKeylessModel?: boolean;
|
|
29
|
-
}
|
|
30
|
-
/** Represent a fully configured model with optional API key and base URL for sandbox platform integration */
|
|
31
|
-
interface ResolvedModel {
|
|
32
|
-
model: string;
|
|
33
|
-
provider: string;
|
|
34
|
-
apiKey?: string;
|
|
35
|
-
baseUrl?: string;
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* Why a model failed to resolve into something transportable to the sandbox
|
|
39
|
-
* platform. `no_provider` — a model id exists but no provider name could be
|
|
40
|
-
* derived (no explicit `providerName`, and no key present to infer one from).
|
|
41
|
-
* `no_api_key` — a provider AND model both resolved, but no credential is
|
|
42
|
-
* configured and the caller did not opt into `allowKeylessModel`.
|
|
43
|
-
*/
|
|
44
|
-
type ModelSelectionError = 'no_provider' | 'no_api_key';
|
|
45
|
-
/**
|
|
46
|
-
* Which precedence slot supplied the failed/succeeded model id:
|
|
47
|
-
* `override` — the caller's per-turn `{ model }` argument.
|
|
48
|
-
* `config` — `provider.modelName`.
|
|
49
|
-
* `default` — `provider.defaultModel` (only ever consulted for an
|
|
50
|
-
* openai/openai-compat provider shape).
|
|
51
|
-
*/
|
|
52
|
-
type ModelSelectionSource = 'override' | 'config' | 'default';
|
|
53
|
-
/**
|
|
54
|
-
* A model id was named (by override, config, or default) but is not
|
|
55
|
-
* transportable to the sandbox platform. Carries enough to explain WHY
|
|
56
|
-
* without the caller re-deriving the override/config/default precedence
|
|
57
|
-
* chain itself (that re-derivation is how gtm-agent#665 happened — a caller
|
|
58
|
-
* guessed loudness from the wrong slot and dropped a user-selected model).
|
|
59
|
-
*/
|
|
60
|
-
type ModelSelectionFailure = {
|
|
61
|
-
succeeded: false;
|
|
62
|
-
error: 'no_provider';
|
|
63
|
-
model: string;
|
|
64
|
-
source: ModelSelectionSource;
|
|
65
|
-
} | {
|
|
66
|
-
succeeded: false;
|
|
67
|
-
error: 'no_api_key';
|
|
68
|
-
model: string;
|
|
69
|
-
provider: string;
|
|
70
|
-
source: ModelSelectionSource;
|
|
71
|
-
};
|
|
72
|
-
/**
|
|
73
|
-
* The three-state outcome of resolving a model: `{ succeeded: true, value:
|
|
74
|
-
* undefined }` means NOTHING was requested (the legitimate box-default
|
|
75
|
-
* configuration — not an error); `{ succeeded: true, value: ResolvedModel }`
|
|
76
|
-
* means a fully transportable model resolved; anything else is a
|
|
77
|
-
* {@link ModelSelectionFailure} — a model WAS named but can't be sent.
|
|
78
|
-
*/
|
|
79
|
-
type ModelSelection = {
|
|
80
|
-
succeeded: true;
|
|
81
|
-
value: ResolvedModel | undefined;
|
|
82
|
-
} | ModelSelectionFailure;
|
|
83
|
-
/**
|
|
84
|
-
* Resolve a provider + model configuration into a typed three-state outcome
|
|
85
|
-
* that separates "nothing requested" from "something requested but
|
|
86
|
-
* untransportable" — the distinction {@link resolveModel} collapses and the
|
|
87
|
-
* one that caused gtm-agent#665 (a validated user-selected model silently
|
|
88
|
-
* dropped, box default substituted, durable row still recording the user's
|
|
89
|
-
* choice).
|
|
90
|
-
*
|
|
91
|
-
* Precedence (identical to the legacy `resolveModel`, byte-for-byte):
|
|
92
|
-
* provider is computed first (`providerName`, else inferred `openai-compat`
|
|
93
|
-
* from a present key, else inferred `openai` from a present
|
|
94
|
-
* `openaiApiKey`, else unresolved); the model id is `override.model` else
|
|
95
|
-
* `config.modelName` else — ONLY when the provider is `openai` or
|
|
96
|
-
* `openai-compat` — `config.defaultModel`; the api key is
|
|
97
|
-
* `override.modelApiKey` else `config.apiKey` else — only for provider
|
|
98
|
-
* `openai` — `config.openaiApiKey`.
|
|
99
|
-
*
|
|
100
|
-
* Two behavioral deltas from the legacy function:
|
|
101
|
-
* 1. Every string field (`routerBaseUrl`, `apiKey`, `providerName`,
|
|
102
|
-
* `modelName`, `defaultModel`, `openaiApiKey`, `override.model`,
|
|
103
|
-
* `override.modelApiKey`) is normalized through {@link trimOrNull} first,
|
|
104
|
-
* so `''` (and whitespace-only strings) are treated as absent instead of
|
|
105
|
-
* poisoning the `??` precedence chain — the issue's second stated defect.
|
|
106
|
-
* This also means a value is trimmed (`' gpt-5 '` resolves to `'gpt-5'`).
|
|
107
|
-
* 2. The outcome is three-state instead of collapsing to `undefined`: no
|
|
108
|
-
* model derivable from any slot → `{ succeeded: true, value: undefined }`
|
|
109
|
-
* (still the legitimate "let the box pick its own default" case, NOT an
|
|
110
|
-
* error); a model id resolved but no provider could be derived → a
|
|
111
|
-
* `no_provider` failure; a model + provider resolved but no api key (and
|
|
112
|
-
* `allowKeylessModel` was not set) → a `no_api_key` failure. Both failure
|
|
113
|
-
* arms carry `source` so a caller can apply a loudness policy without
|
|
114
|
-
* re-deriving which precedence slot supplied the model.
|
|
115
|
-
*/
|
|
116
|
-
declare function resolveModelSelection(config: ProviderResolutionConfig | undefined, override?: {
|
|
117
|
-
model?: string;
|
|
118
|
-
modelApiKey?: string;
|
|
119
|
-
}): ModelSelection;
|
|
120
|
-
/**
|
|
121
|
-
* Resolve and return the appropriate model configuration based on provider
|
|
122
|
-
* settings and optional overrides.
|
|
123
|
-
*
|
|
124
|
-
* Migration note (intentionally NOT tagged `@deprecated`): this is a thin,
|
|
125
|
-
* source-compatible wrapper over {@link resolveModelSelection} that collapses
|
|
126
|
-
* its three-state outcome back down to `ResolvedModel | undefined`, exactly
|
|
127
|
-
* as before. It stays correct for the common case (no explicit model requested, or a
|
|
128
|
-
* fully-transportable one), but it CANNOT distinguish "nothing was
|
|
129
|
-
* requested" from "a named model could not be transported" — the ambiguity
|
|
130
|
-
* that caused gtm-agent#665. Prefer {@link resolveModelSelection} directly,
|
|
131
|
-
* or {@link requireTransportableModel} for the fail-loud-on-explicit-model
|
|
132
|
-
* policy the internal sandbox callers use. Not tagged `@deprecated`: it
|
|
133
|
-
* remains the correct call for a caller that never sets an explicit
|
|
134
|
-
* override and only wants "the box's default is fine" semantics; a hard
|
|
135
|
-
* deprecation is a later-major decision, not this fix's.
|
|
136
|
-
*
|
|
137
|
-
* The only behavior change on this entry point versus before is the
|
|
138
|
-
* empty-string bugfix that comes free through delegation (issue #302's
|
|
139
|
-
* second defect) — every signature and the `undefined` return semantics are
|
|
140
|
-
* unchanged.
|
|
141
|
-
*/
|
|
142
|
-
declare function resolveModel(config: ProviderResolutionConfig | undefined, override?: {
|
|
143
|
-
model?: string;
|
|
144
|
-
modelApiKey?: string;
|
|
145
|
-
}): ResolvedModel | undefined;
|
|
146
|
-
/**
|
|
147
|
-
* Thrown by {@link requireTransportableModel} when a model that was
|
|
148
|
-
* EXPLICITLY requested via a per-turn `{ model }` override cannot be
|
|
149
|
-
* transported to the sandbox platform. The message names the model, which
|
|
150
|
-
* precedence slot supplied it, what's missing, and the fix, and states
|
|
151
|
-
* plainly that the requested model was NOT sent to the box (the failure mode
|
|
152
|
-
* this error exists to make impossible to miss — gtm-agent#665 silently
|
|
153
|
-
* substituted the box default instead of a user-selected model).
|
|
154
|
-
*
|
|
155
|
-
* The error class itself carries no opinion about *when* it should be
|
|
156
|
-
* thrown — it is constructed from any {@link ModelSelectionFailure},
|
|
157
|
-
* regardless of `source`. A caller wanting a stricter policy (e.g. also
|
|
158
|
-
* fail-loud on an untransportable configured `provider.modelName`) can call
|
|
159
|
-
* {@link resolveModelSelection} directly and throw this itself.
|
|
160
|
-
*/
|
|
161
|
-
declare class SandboxModelResolutionError extends Error {
|
|
162
|
-
readonly code: ModelSelectionError;
|
|
163
|
-
readonly model: string;
|
|
164
|
-
readonly provider?: string;
|
|
165
|
-
readonly source: ModelSelectionSource;
|
|
166
|
-
constructor(failure: ModelSelectionFailure, context: string);
|
|
167
|
-
}
|
|
168
|
-
/**
|
|
169
|
-
* Shared fail-loud policy for the sandbox platform's three internal model
|
|
170
|
-
* callers (`ensureWorkspaceSandbox`'s `backendModelAtCreate`,
|
|
171
|
-
* `streamSandboxPrompt`, `driveSandboxTurn`): a `ModelSelection` in, a plain
|
|
172
|
-
* `ResolvedModel | undefined` out, so downstream code is unchanged from
|
|
173
|
-
* before this fix.
|
|
174
|
-
*
|
|
175
|
-
* The policy: success delegates straight through. A failure whose `source`
|
|
176
|
-
* is `'override'` means a PER-TURN model was explicitly selected THIS turn
|
|
177
|
-
* (a live, user-driven choice — passed as `{ model }`) and could not be
|
|
178
|
-
* sent; substituting the box default there is exactly the gtm-agent#665
|
|
179
|
-
* defect, so it throws {@link SandboxModelResolutionError} rather than
|
|
180
|
-
* silently falling back.
|
|
181
|
-
*
|
|
182
|
-
* A failure whose `source` is `'config'` or `'default'` means a
|
|
183
|
-
* *configured* `provider.modelName` / `provider.defaultModel` couldn't
|
|
184
|
-
* resolve — nobody made a choice this turn; the value came from board
|
|
185
|
-
* config that may simply describe "the platform supplies the credential."
|
|
186
|
-
* Shipped consumers rely on exactly that: tax-agent ships a shell with
|
|
187
|
-
* `provider: { providerName: 'openai-compat', modelName, routerBaseUrl }`
|
|
188
|
-
* and no `apiKey`/`allowKeylessModel`, with a contract test asserting
|
|
189
|
-
* `ensureWorkspaceSandbox` creation SUCCEEDS with the model silently
|
|
190
|
-
* dropped so the sandbox platform mints its own in-container credential
|
|
191
|
-
* (`apps/web/tests/sandbox-service-contract.test.ts`). A config-loud policy
|
|
192
|
-
* here would break every fresh tax sandbox provisioning and every tax turn.
|
|
193
|
-
* So both `'config'` and `'default'` keep the pre-#302 logged-skip
|
|
194
|
-
* behavior: `console.error` and drop, letting the box use its own default.
|
|
195
|
-
* A product wanting strict enforcement of a configured `provider.modelName`
|
|
196
|
-
* can call {@link resolveModelSelection} directly and apply its own policy.
|
|
197
|
-
*/
|
|
198
|
-
declare function requireTransportableModel(selection: ModelSelection, context: string): ResolvedModel | undefined;
|
|
199
|
-
|
|
200
|
-
/**
|
|
201
|
-
* Reading arbitrary bytes out of a sandbox over an exec channel that only
|
|
202
|
-
* speaks text.
|
|
203
|
-
*
|
|
204
|
-
* `box.exec` returns stdout as a string, so a binary file has to be encoded to
|
|
205
|
-
* survive the trip: `wc -c` gives the on-disk length, `base64` gives the
|
|
206
|
-
* payload, and the decoded byte count is checked against the stat. That last
|
|
207
|
-
* check is the point of the module — an exec channel that caps or clips its
|
|
208
|
-
* output still reports `exitCode: 0` with a short buffer, which decodes into a
|
|
209
|
-
* perfectly valid but TRUNCATED file. Verifying the length turns that silent
|
|
210
|
-
* corruption into a loud failure at the boundary.
|
|
211
|
-
*
|
|
212
|
-
* Both helpers return typed outcomes; callers must inspect `succeeded` before
|
|
213
|
-
* touching `value`.
|
|
214
|
-
*/
|
|
215
|
-
/** The `box.exec` surface these helpers use — structural, so a caller can pass
|
|
216
|
-
* the sandbox SDK's `SandboxInstance` directly or a narrower test double. */
|
|
217
|
-
interface SandboxExecChannel {
|
|
218
|
-
exec(command: string, options?: {
|
|
219
|
-
sessionId?: string;
|
|
220
|
-
}): Promise<{
|
|
221
|
-
stdout: string;
|
|
222
|
-
stderr: string;
|
|
223
|
-
exitCode: number;
|
|
224
|
-
}>;
|
|
225
|
-
}
|
|
226
|
-
/** Define options to execute code within a sandbox environment with optional session control */
|
|
227
|
-
interface SandboxExecOptions {
|
|
228
|
-
/** Run inside a named session rather than the box's default one. */
|
|
229
|
-
sessionId?: string;
|
|
230
|
-
}
|
|
231
|
-
/** Resolve the outcome of a sandbox file size check with success status and value or error message */
|
|
232
|
-
type SandboxFileSizeOutcome = {
|
|
233
|
-
succeeded: true;
|
|
234
|
-
value: number;
|
|
235
|
-
} | {
|
|
236
|
-
succeeded: false;
|
|
237
|
-
error: string;
|
|
238
|
-
};
|
|
239
|
-
/** Represent the outcome of reading sandbox file bytes with success status and corresponding data or error */
|
|
240
|
-
type SandboxFileBytesOutcome = {
|
|
241
|
-
succeeded: true;
|
|
242
|
-
value: {
|
|
243
|
-
bytes: Uint8Array;
|
|
244
|
-
size: number;
|
|
245
|
-
};
|
|
246
|
-
} | {
|
|
247
|
-
succeeded: false;
|
|
248
|
-
error: string;
|
|
249
|
-
};
|
|
250
|
-
/** Wraps a value in single quotes for `sh`, closing and reopening the quote
|
|
251
|
-
* around each embedded quote (`'` → `'"'"'`). Every path these helpers
|
|
252
|
-
* interpolate into a command goes through this — in-box filenames are
|
|
253
|
-
* arbitrary, so spaces, quotes and `$` are ordinary content, not syntax. */
|
|
254
|
-
declare function shellQuote(value: string): string;
|
|
255
|
-
/** Stats a sandbox file's byte length via `wc -c`. A caller enforcing a size
|
|
256
|
-
* cap must check this BEFORE {@link readSandboxBinaryBytes}, so an oversize
|
|
257
|
-
* file is rejected without paying for a base64 round trip of it. */
|
|
258
|
-
declare function statSandboxFileSize(box: SandboxExecChannel, absolutePath: string, options?: SandboxExecOptions): Promise<SandboxFileSizeOutcome>;
|
|
259
|
-
/** Reads a sandbox file as base64 and decodes it, verifying the decoded byte
|
|
260
|
-
* length against `expectedSize` (from a prior {@link statSandboxFileSize}). A
|
|
261
|
-
* mismatch is reported, never returned as a short buffer. */
|
|
262
|
-
declare function readSandboxBinaryBytes(box: SandboxExecChannel, absolutePath: string, expectedSize: number, options?: SandboxExecOptions): Promise<SandboxFileBytesOutcome>;
|
|
263
|
-
|
|
264
|
-
/**
|
|
265
|
-
* What an app does after the platform hands back a sandbox it cannot use.
|
|
266
|
-
*
|
|
267
|
-
* `replaceUnbringableBox` (see `./index`) decides whether to abandon a dead box.
|
|
268
|
-
* This decides everything around that: which box key the next attempt uses,
|
|
269
|
-
* whether the old box's snapshot is safe to restore from, whether an owner has
|
|
270
|
-
* to confirm the loss first, and what the person waiting is told. It is
|
|
271
|
-
* bookkeeping, not I/O — the app supplies storage through
|
|
272
|
-
* {@link WorkspaceSandboxRecoveryStore}.
|
|
273
|
-
*
|
|
274
|
-
* ── Why the tables ──────────────────────────────────────────────────────────
|
|
275
|
-
* Every fact about an action or a code lives in ACTIONS/CODES below, and the
|
|
276
|
-
* types are DERIVED from those tables. That is deliberate, and it is the whole
|
|
277
|
-
* reliability argument for this module.
|
|
278
|
-
*
|
|
279
|
-
* The hand-maintained alternative — a union type plus a separate `x === 'a' ||
|
|
280
|
-
* x === 'b' || …` list per question — silently drops anything not on the list.
|
|
281
|
-
* A recovery recorded under an unlisted action is written to storage, read
|
|
282
|
-
* back, discarded as malformed, and the workspace re-provisions the box it just
|
|
283
|
-
* abandoned. Nothing throws. The fix looks correct, ships, and does nothing.
|
|
284
|
-
* That failure was hit twice inside one change before this module existed.
|
|
285
|
-
*
|
|
286
|
-
* With the tables, adding an action or code is a compile error until every
|
|
287
|
-
* question about it is answered. There is no list to forget.
|
|
288
|
-
*/
|
|
289
|
-
/** The box exists and still holds unsnapshotted state, so discarding it is an
|
|
290
|
-
* owner's decision, not the runtime's. */
|
|
291
|
-
declare const EGRESS_PROXY_RECOVERY_REQUIRED = "EGRESS_PROXY_RECOVERY_REQUIRED";
|
|
292
|
-
declare const EGRESS_PROXY_RECOVERY_PHASE = "egress_proxy_recovery";
|
|
293
|
-
/** The platform no longer has the box. Nothing to confirm, delete, or restore. */
|
|
294
|
-
declare const WORKSPACE_SANDBOX_MISSING = "WORKSPACE_SANDBOX_MISSING";
|
|
295
|
-
/** The box exists but its host has no free slot, so it can never be resumed
|
|
296
|
-
* where it is. A replacement can be placed on a host with room. */
|
|
297
|
-
declare const WORKSPACE_SANDBOX_HOST_EXHAUSTED = "WORKSPACE_SANDBOX_HOST_EXHAUSTED";
|
|
298
|
-
/** The platform ran its own recovery, failed, and asked for a replacement.
|
|
299
|
-
* Covers every way a box ends up unbringable with no more specific cause. */
|
|
300
|
-
declare const WORKSPACE_SANDBOX_UNRECOVERABLE = "WORKSPACE_SANDBOX_UNRECOVERABLE";
|
|
301
|
-
declare const WORKSPACE_SANDBOX_SNAPSHOT_MAX_AGE_MS: number;
|
|
302
|
-
/**
|
|
303
|
-
* Every recovery cause, and the one thing the runtime must know about each:
|
|
304
|
-
* whether the box it names can still be read from.
|
|
305
|
-
*
|
|
306
|
-
* `snapshotUsable: false` is not a preference. A snapshot is addressed by the
|
|
307
|
-
* sandbox it was taken from, so when that sandbox cannot be started the restore
|
|
308
|
-
* fails exactly the way the resume did — and an app that tried it would turn a
|
|
309
|
-
* recoverable workspace into a stuck one.
|
|
310
|
-
*/
|
|
311
|
-
declare const CODES: {
|
|
312
|
-
readonly EGRESS_PROXY_RECOVERY_REQUIRED: {
|
|
313
|
-
readonly snapshotUsable: true;
|
|
314
|
-
};
|
|
315
|
-
readonly WORKSPACE_SANDBOX_MISSING: {
|
|
316
|
-
readonly snapshotUsable: false;
|
|
317
|
-
};
|
|
318
|
-
readonly WORKSPACE_SANDBOX_HOST_EXHAUSTED: {
|
|
319
|
-
readonly snapshotUsable: false;
|
|
320
|
-
};
|
|
321
|
-
readonly WORKSPACE_SANDBOX_UNRECOVERABLE: {
|
|
322
|
-
readonly snapshotUsable: false;
|
|
323
|
-
};
|
|
324
|
-
};
|
|
325
|
-
type WorkspaceSandboxRecoveryCode = keyof typeof CODES;
|
|
326
|
-
/**
|
|
327
|
-
* Every recovery action, and whether it means a replacement box has been
|
|
328
|
-
* CHOSEN — the single question that decides which box key the next provisioning
|
|
329
|
-
* attempt uses.
|
|
330
|
-
*
|
|
331
|
-
* `replacementChosen: false` covers the states where a key may be recorded but
|
|
332
|
-
* must not be used yet: an owner has been asked and has not answered, or has
|
|
333
|
-
* answered no. Handing back a key in those states replaces a box the owner
|
|
334
|
-
* declined to lose.
|
|
335
|
-
*/
|
|
336
|
-
declare const ACTIONS: {
|
|
337
|
-
readonly confirmation_required: {
|
|
338
|
-
readonly replacementChosen: false;
|
|
339
|
-
};
|
|
340
|
-
readonly deletion_declined: {
|
|
341
|
-
readonly replacementChosen: false;
|
|
342
|
-
};
|
|
343
|
-
readonly replacement_authorized: {
|
|
344
|
-
readonly replacementChosen: false;
|
|
345
|
-
};
|
|
346
|
-
readonly snapshot_replacement_authorized: {
|
|
347
|
-
readonly replacementChosen: false;
|
|
348
|
-
};
|
|
349
|
-
readonly replacement_started: {
|
|
350
|
-
readonly replacementChosen: true;
|
|
351
|
-
};
|
|
352
|
-
readonly replacement_completed: {
|
|
353
|
-
readonly replacementChosen: true;
|
|
354
|
-
};
|
|
355
|
-
readonly snapshot_replacement_started: {
|
|
356
|
-
readonly replacementChosen: true;
|
|
357
|
-
};
|
|
358
|
-
readonly snapshot_restore_failed: {
|
|
359
|
-
readonly replacementChosen: true;
|
|
360
|
-
};
|
|
361
|
-
readonly snapshot_replacement_completed: {
|
|
362
|
-
readonly replacementChosen: true;
|
|
363
|
-
};
|
|
364
|
-
readonly missing_replacement_started: {
|
|
365
|
-
readonly replacementChosen: true;
|
|
366
|
-
};
|
|
367
|
-
readonly missing_replacement_completed: {
|
|
368
|
-
readonly replacementChosen: true;
|
|
369
|
-
};
|
|
370
|
-
readonly unrecoverable_replacement_started: {
|
|
371
|
-
readonly replacementChosen: true;
|
|
372
|
-
};
|
|
373
|
-
readonly unrecoverable_replacement_completed: {
|
|
374
|
-
readonly replacementChosen: true;
|
|
375
|
-
};
|
|
376
|
-
};
|
|
377
|
-
type WorkspaceSandboxRecoveryAction = keyof typeof ACTIONS;
|
|
378
|
-
type WorkspaceSandboxSnapshotAvailability = 'available' | 'missing' | 'stale';
|
|
379
|
-
type WorkspaceSandboxSnapshotFreshness = 'fresh' | 'stale' | 'unknown';
|
|
380
|
-
/** A snapshot the app took of a box, addressed by the box it came from. */
|
|
381
|
-
interface WorkspaceSandboxSnapshot {
|
|
382
|
-
fromSandboxId: string;
|
|
383
|
-
createdAt: string;
|
|
384
|
-
[key: string]: unknown;
|
|
385
|
-
}
|
|
386
|
-
interface WorkspaceSandboxSnapshotAssessment {
|
|
387
|
-
availability: WorkspaceSandboxSnapshotAvailability;
|
|
388
|
-
freshness: WorkspaceSandboxSnapshotFreshness;
|
|
389
|
-
snapshot?: WorkspaceSandboxSnapshot;
|
|
390
|
-
}
|
|
391
|
-
interface WorkspaceSandboxRecoveryState {
|
|
392
|
-
code: WorkspaceSandboxRecoveryCode;
|
|
393
|
-
sandboxId: string;
|
|
394
|
-
detectedAt: string;
|
|
395
|
-
snapshot: WorkspaceSandboxSnapshotAssessment;
|
|
396
|
-
action: WorkspaceSandboxRecoveryAction;
|
|
397
|
-
replacementBoxKey?: string;
|
|
398
|
-
replacementSandboxId?: string;
|
|
399
|
-
confirmedAt?: string;
|
|
400
|
-
}
|
|
401
|
-
type WorkspaceSandboxRecoveryDecision = 'replace' | 'decline';
|
|
402
|
-
/** Raised when chat cannot continue until an owner decides about the box. */
|
|
403
|
-
declare class WorkspaceSandboxRecoveryRequiredError extends Error {
|
|
404
|
-
readonly code = "EGRESS_PROXY_RECOVERY_REQUIRED";
|
|
405
|
-
readonly status = 409;
|
|
406
|
-
readonly phase = "egress_proxy_recovery";
|
|
407
|
-
readonly recovery: WorkspaceSandboxRecoveryState;
|
|
408
|
-
constructor(recovery: WorkspaceSandboxRecoveryState, cause: Error);
|
|
409
|
-
}
|
|
410
|
-
declare function isEgressProxyRecoveryRequiredError(error: unknown): boolean;
|
|
411
|
-
declare function isWorkspaceSandboxSnapshotRestoreError(error: unknown): boolean;
|
|
412
|
-
/**
|
|
413
|
-
* Judge a snapshot against the box being replaced.
|
|
414
|
-
*
|
|
415
|
-
* Fresh means BOTH that it came from this exact sandbox and that it is inside
|
|
416
|
-
* the age bound — a snapshot from a different box restores someone else's
|
|
417
|
-
* filesystem, which is worse than starting empty.
|
|
418
|
-
*/
|
|
419
|
-
declare function assessWorkspaceSandboxSnapshot(snapshot: WorkspaceSandboxSnapshot | undefined, sandboxId: string, now?: number): WorkspaceSandboxSnapshotAssessment;
|
|
420
|
-
declare function isWorkspaceSandboxRecoveryAction(value: unknown): value is WorkspaceSandboxRecoveryAction;
|
|
421
|
-
declare function isWorkspaceSandboxRecoveryCode(value: unknown): value is WorkspaceSandboxRecoveryCode;
|
|
422
|
-
declare function isWorkspaceSandboxRecoveryState(value: unknown): value is WorkspaceSandboxRecoveryState;
|
|
423
|
-
declare function workspaceSandboxRecoveryFromError(error: unknown): WorkspaceSandboxRecoveryState | undefined;
|
|
424
|
-
/** What to tell the person waiting. Never names the product, so an app can
|
|
425
|
-
* surface it verbatim. */
|
|
426
|
-
declare function workspaceSandboxRecoveryMessage(recovery: WorkspaceSandboxRecoveryState): string;
|
|
427
|
-
declare function workspaceSandboxRecoveryRecommendedActions(recovery: WorkspaceSandboxRecoveryState): string[];
|
|
428
|
-
/** Flat key/value shape for a log line — no nesting, no secrets. */
|
|
429
|
-
declare function workspaceSandboxRecoveryDiagnostic(recovery: WorkspaceSandboxRecoveryState): Record<string, string | undefined>;
|
|
430
|
-
/**
|
|
431
|
-
* The box key the next provisioning attempt should use, or undefined to keep
|
|
432
|
-
* using the workspace's own key.
|
|
433
|
-
*
|
|
434
|
-
* Reads {@link ACTIONS} rather than a hand-kept list, because the failure mode
|
|
435
|
-
* of a hand-kept list here is invisible: the key is recorded, silently ignored,
|
|
436
|
-
* and provisioning goes back to the box the app just decided to abandon.
|
|
437
|
-
*/
|
|
438
|
-
declare function preferredWorkspaceSandboxRecoveryBoxKey(recovery: WorkspaceSandboxRecoveryState | undefined): string | undefined;
|
|
439
|
-
/** Whether the replacement should be restored from the old box's snapshot. */
|
|
440
|
-
declare function shouldRestoreWorkspaceSandboxRecovery(recovery: WorkspaceSandboxRecoveryState | undefined): boolean;
|
|
441
|
-
/**
|
|
442
|
-
* Where an app keeps recovery state. One row per workspace, last write wins —
|
|
443
|
-
* a recovery is a current situation, not a history.
|
|
444
|
-
*/
|
|
445
|
-
interface WorkspaceSandboxRecoveryStore {
|
|
446
|
-
read: (workspaceId: string) => Promise<WorkspaceSandboxRecoveryState | undefined>;
|
|
447
|
-
write: (workspaceId: string, recovery: WorkspaceSandboxRecoveryState) => Promise<void>;
|
|
448
|
-
}
|
|
449
|
-
interface WorkspaceSandboxRecoveryManager {
|
|
450
|
-
read: (workspaceId: string) => Promise<WorkspaceSandboxRecoveryState | undefined>;
|
|
451
|
-
record: (workspaceId: string, recovery: WorkspaceSandboxRecoveryState) => Promise<void>;
|
|
452
|
-
/** Record an owner's decision. Returns undefined when the stored recovery does
|
|
453
|
-
* not name this sandbox — a decision about a box that has already been
|
|
454
|
-
* replaced must not resurrect it. */
|
|
455
|
-
decide: (args: {
|
|
456
|
-
workspaceId: string;
|
|
457
|
-
sandboxId: string;
|
|
458
|
-
decision: WorkspaceSandboxRecoveryDecision;
|
|
459
|
-
replacementBoxKey?: string;
|
|
460
|
-
}) => Promise<WorkspaceSandboxRecoveryState | undefined>;
|
|
461
|
-
/** Mark a replacement finished and name the box that took over. */
|
|
462
|
-
complete: (args: {
|
|
463
|
-
workspaceId: string;
|
|
464
|
-
replacementSandboxId: string;
|
|
465
|
-
}) => Promise<WorkspaceSandboxRecoveryState | undefined>;
|
|
466
|
-
}
|
|
467
|
-
/**
|
|
468
|
-
* Bind the recovery bookkeeping to an app's storage.
|
|
469
|
-
*
|
|
470
|
-
* The app owns persistence — a D1 column, a KV key, a Postgres row — and
|
|
471
|
-
* nothing else. Every rule about which action means what stays here, so it
|
|
472
|
-
* cannot drift between apps.
|
|
473
|
-
*/
|
|
474
|
-
declare function createWorkspaceSandboxRecoveryManager(store: WorkspaceSandboxRecoveryStore): WorkspaceSandboxRecoveryManager;
|
|
475
|
-
/** Every declared action, for exhaustiveness tests in apps and here. */
|
|
476
|
-
declare const WORKSPACE_SANDBOX_RECOVERY_ACTIONS: readonly WorkspaceSandboxRecoveryAction[];
|
|
477
|
-
/** Every declared cause. */
|
|
478
|
-
declare const WORKSPACE_SANDBOX_RECOVERY_CODES: readonly WorkspaceSandboxRecoveryCode[];
|
|
479
|
-
|
|
480
|
-
interface SafeSandboxErrorCause {
|
|
481
|
-
name?: string;
|
|
482
|
-
message?: string;
|
|
483
|
-
code?: string | number;
|
|
484
|
-
status?: string | number;
|
|
485
|
-
phase?: string;
|
|
486
|
-
endpoint?: string;
|
|
487
|
-
origin?: string;
|
|
488
|
-
retryAfterMs?: number;
|
|
489
|
-
sidecarVersion?: string;
|
|
490
|
-
containerImage?: string;
|
|
491
|
-
}
|
|
492
|
-
interface SafeSandboxErrorDiagnostics {
|
|
493
|
-
message: string;
|
|
494
|
-
causes: SafeSandboxErrorCause[];
|
|
495
|
-
truncated: boolean;
|
|
496
|
-
truncatedAtDepth?: number;
|
|
497
|
-
cycle: boolean;
|
|
498
|
-
}
|
|
499
|
-
declare function serializeSandboxProvisioningError(error: unknown, options?: {
|
|
500
|
-
maxDepth?: number;
|
|
501
|
-
}): SafeSandboxErrorDiagnostics;
|
|
502
|
-
declare function formatSandboxProvisioningSupportDetails(diagnostics: SafeSandboxErrorDiagnostics): string;
|
|
503
|
-
declare function isSandboxAuthFailure(diagnostics: SafeSandboxErrorDiagnostics): boolean;
|
|
504
|
-
declare function isSandboxApiBearerAuthFailure(diagnostics: SafeSandboxErrorDiagnostics): boolean;
|
|
505
|
-
/**
|
|
506
|
-
* True when the sandbox API answered 404 for a specific sandbox resource — the
|
|
507
|
-
* box behind a persisted sandbox id no longer exists.
|
|
508
|
-
*
|
|
509
|
-
* A sandbox id is a cache of where a workspace's box lives, not the workspace's
|
|
510
|
-
* identity: the platform reaps, suspends, and loses boxes as ordinary lifecycle
|
|
511
|
-
* events. Callers use this to discard the dead id and provision a replacement,
|
|
512
|
-
* so the match is deliberately narrow — a 404 from the runtime sidecar
|
|
513
|
-
* (`/runtime/...`, a missing file or session inside a live box) is NOT this.
|
|
514
|
-
*/
|
|
515
|
-
declare function isSandboxApiSandboxMissingFailure(diagnostics: SafeSandboxErrorDiagnostics): boolean;
|
|
516
|
-
/**
|
|
517
|
-
* True when a resume failed because the host the box is pinned to cannot seat
|
|
518
|
-
* it — the host's slot budget is exhausted, not the box's fault and not
|
|
519
|
-
* something waiting fixes.
|
|
520
|
-
*
|
|
521
|
-
* A box lives on one host. When that host fills, every future resume for every
|
|
522
|
-
* box on it fails identically and permanently, so a workspace whose box landed
|
|
523
|
-
* on a full host is bricked until it is placed somewhere else. Callers use this
|
|
524
|
-
* the same way they use {@link isSandboxApiSandboxMissingFailure}: discard the
|
|
525
|
-
* dead id and provision a replacement, which the orchestrator is free to place
|
|
526
|
-
* on a host with room. The workspace itself is preserved — it lives in the
|
|
527
|
-
* Vault, not in the box's filesystem.
|
|
528
|
-
*
|
|
529
|
-
* Matched on the message because the sandbox API returns a generic
|
|
530
|
-
* `SERVER_ERROR` for it; a dedicated code upstream would replace this.
|
|
531
|
-
*/
|
|
532
|
-
declare function isSandboxHostCapacityFailure(diagnostics: SafeSandboxErrorDiagnostics): boolean;
|
|
533
|
-
declare function formatSandboxProvisioningUserMessage(diagnostics: SafeSandboxErrorDiagnostics): string;
|
|
534
|
-
|
|
535
|
-
/** Define the shape of a workspace sandbox instance including its connection details and status. */
|
|
536
|
-
interface WorkspaceSandboxInstanceLike {
|
|
537
|
-
id: string;
|
|
538
|
-
name?: string;
|
|
539
|
-
status?: string;
|
|
540
|
-
connection?: {
|
|
541
|
-
runtimeUrl?: string;
|
|
542
|
-
sidecarUrl?: string;
|
|
543
|
-
authToken?: string;
|
|
544
|
-
sidecarToken?: string;
|
|
545
|
-
authTokenExpiresAt?: string;
|
|
546
|
-
} | null;
|
|
547
|
-
}
|
|
548
|
-
/** Define the context containing workspace and user identifiers for sandbox environment operations. */
|
|
549
|
-
interface WorkspaceSandboxEnsureContext {
|
|
550
|
-
workspaceId: string;
|
|
551
|
-
userId: string;
|
|
552
|
-
}
|
|
553
|
-
/** Define configuration options for managing workspace sandboxes. */
|
|
554
|
-
interface WorkspaceSandboxManagerOptions<TClient, TBox extends WorkspaceSandboxInstanceLike, TEnsureOptions = void> {
|
|
555
|
-
getClient: (ctx: WorkspaceSandboxEnsureContext) => Promise<TClient> | TClient;
|
|
556
|
-
nameForWorkspace: (workspaceId: string, ctx: WorkspaceSandboxEnsureContext) => string;
|
|
557
|
-
listSandboxes: (client: TClient, ctx: WorkspaceSandboxEnsureContext) => Promise<TBox[]>;
|
|
558
|
-
createSandbox: (args: {
|
|
559
|
-
client: TClient;
|
|
560
|
-
ctx: WorkspaceSandboxEnsureContext;
|
|
561
|
-
name: string;
|
|
562
|
-
options: TEnsureOptions;
|
|
563
|
-
listError?: unknown;
|
|
564
|
-
}) => Promise<TBox>;
|
|
565
|
-
waitForRunning?: (box: TBox, ctx: WorkspaceSandboxEnsureContext) => Promise<void>;
|
|
566
|
-
prepareExisting?: (box: TBox, ctx: WorkspaceSandboxEnsureContext, options: TEnsureOptions) => Promise<TBox | void>;
|
|
567
|
-
prepareCreated?: (box: TBox, ctx: WorkspaceSandboxEnsureContext, options: TEnsureOptions) => Promise<TBox | void>;
|
|
568
|
-
onListError?: (error: unknown, ctx: WorkspaceSandboxEnsureContext) => void;
|
|
569
|
-
}
|
|
570
|
-
/** Manage workspace sandboxes by ensuring their creation and retrieval for specified users. */
|
|
571
|
-
interface WorkspaceSandboxManager<TBox extends WorkspaceSandboxInstanceLike, TEnsureOptions = void> {
|
|
572
|
-
ensureWorkspaceSandbox: (workspaceId: string, userId: string, options?: TEnsureOptions) => Promise<TBox>;
|
|
573
|
-
}
|
|
574
|
-
/**
|
|
575
|
-
* Create a generic name-keyed sandbox lifecycle manager for products that
|
|
576
|
-
* drive their own SDK or box types.
|
|
577
|
-
*/
|
|
578
|
-
declare function createWorkspaceSandboxManager<TClient, TBox extends WorkspaceSandboxInstanceLike, TEnsureOptions = void>(opts: WorkspaceSandboxManagerOptions<TClient, TBox, TEnsureOptions>): WorkspaceSandboxManager<TBox, TEnsureOptions>;
|
|
579
|
-
|
|
580
|
-
/**
|
|
581
|
-
* Browser-direct scoped-token terminal connection route (#341/#349).
|
|
582
|
-
*
|
|
583
|
-
* Epic #343 / decision #341: the fleet's terminal transport is browser-direct
|
|
584
|
-
* — the product's server authenticates the request and provisions/resolves
|
|
585
|
-
* the sandbox exactly once, mints a short-lived SDK scoped token
|
|
586
|
-
* (`box.mintScopedToken`), and hands the browser just enough to connect
|
|
587
|
-
* `TerminalView` straight to the sidecar. No worker relays terminal bytes.
|
|
588
|
-
* The deprecated same-origin relay was removed in #350 after the fleet
|
|
589
|
-
* migrated, leaving this as the package's only terminal transport.
|
|
590
|
-
*
|
|
591
|
-
* VERIFIED PLATFORM CONTRACT (`@tangle-network/sandbox` 0.15.2 + the
|
|
592
|
-
* orchestrator/sidecar enforcement source, verified 2026-07-30):
|
|
593
|
-
*
|
|
594
|
-
* 1. Only a `scope: 'session-runtime'` token carries the `terminal`
|
|
595
|
-
* capability (`cap: ["read", "workspace", "terminal"]`). `'project'` and
|
|
596
|
-
* `'session'` mint SessionGateway READ tokens (HS256, `typ: "read"`, no
|
|
597
|
-
* `cap` claim at all — a different token family the sidecar rejects
|
|
598
|
-
* outright); `'read-only'` carries `cap: ["read"]` only. **No scope other
|
|
599
|
-
* than `'session-runtime'` can ever open a terminal**, which is why this
|
|
600
|
-
* route no longer takes `scope` as a parameter — it is pinned.
|
|
601
|
-
* 2. The orchestrator's terminal WS gate fails closed unless the token's
|
|
602
|
-
* `sid` claim EQUALS the `<connectionId>` path segment of
|
|
603
|
-
* `/terminals/<connectionId>/ws`
|
|
604
|
-
* (`verifyScopedSidecarCapability(sidecar, token, "terminal", connectionId)`).
|
|
605
|
-
* So `mintScopedToken({ scope: 'session-runtime', sessionId })` MUST be
|
|
606
|
-
* called with `sessionId === connectionId` — the exact id `TerminalView`
|
|
607
|
-
* will dial. That is why this route threads a `connectionId` end to end
|
|
608
|
-
* instead of deriving its own session id.
|
|
609
|
-
* 3. The browser-safe terminal base is the mint result's `sidecarProxyUrl`
|
|
610
|
-
* (`/v1/sidecar-proxy/{id}` on the Sandbox API) — **not**
|
|
611
|
-
* `box.connection.runtimeUrl`. The SDK's own `_attachTerminal` is the
|
|
612
|
-
* reference implementation:
|
|
613
|
-
* `mintScopedToken({ scope: 'session-runtime', sessionId: connectionId })`
|
|
614
|
-
* then dial `${scoped.sidecarProxyUrl}/terminals/${connectionId}/ws`.
|
|
615
|
-
* Pointing `TerminalView` at `runtimeUrl` fails auth regardless of scope —
|
|
616
|
-
* only the sidecar-proxy hop decodes the browser's
|
|
617
|
-
* `bearer.<base64url>` WS subprotocol.
|
|
618
|
-
*
|
|
619
|
-
* HISTORICAL NOTE: an earlier shape of this route (and legal-agent's
|
|
620
|
-
* production route it was modeled on, `scope: 'project'` +
|
|
621
|
-
* `connection.runtimeUrl`) predates the platform's terminal-auth hardening —
|
|
622
|
-
* the terminal capability gate (2026-06-19), the scoped-token terminal WS
|
|
623
|
-
* path (2026-07-15), and the `sid`-binding fail-closed check
|
|
624
|
-
* (2026-07-17/18). That shape does not authenticate on the current platform
|
|
625
|
-
* and is not a valid spec for the token path anymore.
|
|
626
|
-
*
|
|
627
|
-
* SECURITY POSTURE: unlike the read-only session-gateway streaming token
|
|
628
|
-
* (`box.mintScopedToken({scope:'session'})` paired with
|
|
629
|
-
* `SessionGatewayClient`), the token this route mints grants **command
|
|
630
|
-
* execution** in the sandbox once handed to `TerminalView`. Its safety rests
|
|
631
|
-
* on a **short TTL** (default 15 minutes, the SDK's own max — still a caller
|
|
632
|
-
* parameter) and, structurally, the narrowest scope the platform offers: one
|
|
633
|
-
* box (`ensureSandbox` resolved it for THIS user), one terminal connection
|
|
634
|
-
* (`session-runtime` bound to a single `sid`). Widening the TTL default
|
|
635
|
-
* without an explicit reason is a security regression, not a convenience.
|
|
636
|
-
*
|
|
637
|
-
* Wire contract: the browser passes the response's `sidecarUrl` as
|
|
638
|
-
* `TerminalView`'s `apiUrl` prop, `token` as its token prop, and the
|
|
639
|
-
* response's echoed `connectionId` as `TerminalView`'s `connectionId` prop —
|
|
640
|
-
* the token's `sid` is bound to exactly that id, so any other value fails the
|
|
641
|
-
* WS upgrade. sandbox-ui sends the token as a `bearer.<base64url>` WebSocket
|
|
642
|
-
* subprotocol (browsers cannot set `Authorization` on a WS handshake).
|
|
643
|
-
* `useSandboxTerminalConnection` (`../web-react/sandbox-terminal`) carries
|
|
644
|
-
* `connectionId` through automatically.
|
|
645
|
-
*/
|
|
646
|
-
/** The structural surface this route needs from an SDK sandbox box — no `@tangle-network/sandbox` class import (invariant 3). */
|
|
647
|
-
interface TerminalConnectionBoxLike {
|
|
648
|
-
id: string;
|
|
649
|
-
status?: string;
|
|
650
|
-
connection?: {
|
|
651
|
-
runtimeUrl?: string;
|
|
652
|
-
};
|
|
653
|
-
mintScopedToken(opts: {
|
|
654
|
-
scope: string;
|
|
655
|
-
sessionId?: string;
|
|
656
|
-
ttlMinutes?: number;
|
|
657
|
-
}): Promise<{
|
|
658
|
-
token: string;
|
|
659
|
-
expiresAt: Date;
|
|
660
|
-
sidecarProxyUrl: string;
|
|
661
|
-
}>;
|
|
662
|
-
}
|
|
663
|
-
/** Configuration for {@link createSandboxTerminalConnectionRoute}. */
|
|
664
|
-
interface SandboxTerminalConnectionRouteOptions<TBox extends TerminalConnectionBoxLike, TUser> {
|
|
665
|
-
/**
|
|
666
|
-
* Authenticate the incoming request. Return the authenticated user, or a
|
|
667
|
-
* `Response` to short-circuit the route (e.g. a 401) — that Response is
|
|
668
|
-
* returned to the caller verbatim.
|
|
669
|
-
*/
|
|
670
|
-
requireUser(request: Request): Promise<TUser | Response>;
|
|
671
|
-
/**
|
|
672
|
-
* Resolve (provisioning if needed) the sandbox this user's terminal should
|
|
673
|
-
* connect to. Domain-specific provisioning (workspace- vs user-scoped,
|
|
674
|
-
* naming, reuse) stays entirely in the product's implementation of this
|
|
675
|
-
* seam — the route only reacts to success/failure.
|
|
676
|
-
*/
|
|
677
|
-
ensureSandbox(user: TUser, request: Request): Promise<TBox>;
|
|
678
|
-
/** `box.mintScopedToken` TTL in minutes. Default `15` (the SDK's own max). */
|
|
679
|
-
ttlMinutes?: number;
|
|
680
|
-
/**
|
|
681
|
-
* Resolve the terminal connection id the minted token's `sid` is bound to
|
|
682
|
-
* — this MUST be the same id `TerminalView` dials
|
|
683
|
-
* (`tabTerminalConnectionId()`), because the orchestrator's terminal WS
|
|
684
|
-
* gate fails closed unless `sid === <connectionId>` in
|
|
685
|
-
* `/terminals/<connectionId>/ws`.
|
|
686
|
-
*
|
|
687
|
-
* `requested` is `new URL(request.url).searchParams.get('connectionId')`.
|
|
688
|
-
* The default resolver returns `requested` unchanged. A product may
|
|
689
|
-
* validate/namespace the id here (e.g. a per-user prefix in a shared box)
|
|
690
|
-
* — if it rewrites the id, the client MUST use the response's echoed
|
|
691
|
-
* `connectionId`, since the sid binding makes any other id fail the WS
|
|
692
|
-
* upgrade.
|
|
693
|
-
*
|
|
694
|
-
* A resolved falsy/empty value fails the request with a 400 before any
|
|
695
|
-
* sandbox work happens.
|
|
696
|
-
*/
|
|
697
|
-
resolveConnectionId?: (ctx: {
|
|
698
|
-
request: Request;
|
|
699
|
-
user: TUser;
|
|
700
|
-
box: TBox;
|
|
701
|
-
requested: string | null;
|
|
702
|
-
}) => string | null | undefined | Promise<string | null | undefined>;
|
|
703
|
-
}
|
|
704
|
-
/**
|
|
705
|
-
* Build the browser-direct terminal connection route: `GET` handler that
|
|
706
|
-
* authenticates, resolves the sandbox, mints a scoped token pinned to
|
|
707
|
-
* `scope: 'session-runtime'` (the ONLY scope the platform grants the
|
|
708
|
-
* `terminal` capability to), and returns exactly what the browser needs to
|
|
709
|
-
* connect `TerminalView` directly to the sidecar — no worker in the data
|
|
710
|
-
* path once the terminal is open.
|
|
711
|
-
*
|
|
712
|
-
* Response shapes:
|
|
713
|
-
* - `requireUser` returns a `Response` → that `Response`, verbatim.
|
|
714
|
-
* - `ensureSandbox` throws → `500 {error}` (the thrown message surfaced).
|
|
715
|
-
* - `box.connection?.runtimeUrl` missing → `503 {error, status: box.status}`
|
|
716
|
-
* — this is a READINESS gate only; the URL returned to the client on
|
|
717
|
-
* success is always the mint's `sidecarProxyUrl`, never `runtimeUrl`.
|
|
718
|
-
* - resolved connection id is falsy/empty → `400 {error}`.
|
|
719
|
-
* - `box.mintScopedToken` rejects → `503 {error}`.
|
|
720
|
-
* - success → `200 {sidecarUrl, token, expiresAt, status, sandboxId, connectionId}`.
|
|
721
|
-
* `connectionId` is the id the token's `sid` is bound to — the client MUST
|
|
722
|
-
* hand this (not its own) to `TerminalView`.
|
|
723
|
-
*/
|
|
724
|
-
declare function createSandboxTerminalConnectionRoute<TBox extends TerminalConnectionBoxLike, TUser>(opts: SandboxTerminalConnectionRouteOptions<TBox, TUser>): (request: Request) => Promise<Response>;
|
|
725
|
-
|
|
726
|
-
/**
|
|
727
|
-
* `createSandboxPrewarmer` — "this user just opened this project; start warming
|
|
728
|
-
* their box" as a shell primitive, so every agent-app product gets the same
|
|
729
|
-
* answer instead of forking one.
|
|
730
|
-
*
|
|
731
|
-
* WHY THIS IS SHELL, NOT ENGINE. The engine rule asks whether the capability
|
|
732
|
-
* makes sense without a specific app's side channel. "Warm a box" does — but
|
|
733
|
-
* `@tangle-network/sandbox` has no notion of a WORKSPACE. It keys boxes by an
|
|
734
|
-
* opaque sandbox id; the workspace→box mapping, the harness match, and the
|
|
735
|
-
* profile materialisation all live in `ensureWorkspaceSandbox` here. A
|
|
736
|
-
* prewarmer is that mapping plus a scheduling policy, so it belongs beside it.
|
|
737
|
-
* It is deliberately NOT a new subpath: it composes `peekWorkspaceSandbox` and
|
|
738
|
-
* `ensureWorkspaceSandbox` directly and needs exactly the peers `/sandbox`
|
|
739
|
-
* already needs, so a separate entry would add a second place to look for "how
|
|
740
|
-
* do I get a box" and buy no peer isolation (the reason `/work-product-react`
|
|
741
|
-
* is split out).
|
|
742
|
-
*
|
|
743
|
-
* WHAT IT IS NOT. It does not make cold starts fast — they already are.
|
|
744
|
-
* Measured on the real platform (staging-sandbox, n=5, 2026-07-28): a box goes
|
|
745
|
-
* from nothing to terminal-ready in 2.34–3.19 s (median 2.73 s), and an
|
|
746
|
-
* already-running box answers in 1.16–2.29 s (median 1.35 s). Prewarming buys
|
|
747
|
-
* ~1.4 s. The reason it matters is not latency: it is that a product which
|
|
748
|
-
* only ever provisions lazily, on a path whose guard never passes, never
|
|
749
|
-
* provisions AT ALL — and the UI then shows a spinner over a box that does not
|
|
750
|
-
* exist and is not being created. That is the failure this primitive removes.
|
|
751
|
-
*
|
|
752
|
-
* ── COST POSTURE (read before adopting) ────────────────────────────────────
|
|
753
|
-
* A warmed box is a REAL charge. It bills from creation until the platform's
|
|
754
|
-
* idle timeout reclaims it — `SandboxRuntimeConfig`'s create-time
|
|
755
|
-
* `idleTimeoutSeconds`, not anything this module sets. A product warming on
|
|
756
|
-
* every project open pays that timeout for every user who opens and bounces.
|
|
757
|
-
* With a 3600 s idle timeout against a ~131 s mean session life, a bounce
|
|
758
|
-
* costs an hour of box time to save ~1.4 s. THAT TRADE IS USUALLY WRONG.
|
|
759
|
-
*
|
|
760
|
-
* So the levers are explicit and the defaults are the cheap ones:
|
|
761
|
-
* - `mode: 'resume-only'` (DEFAULT) never creates a box that does not exist.
|
|
762
|
-
* It only revives one the user already has, so the spend is bounded by
|
|
763
|
-
* boxes the user already caused. This is the safe fleet default.
|
|
764
|
-
* - `mode: 'create-or-resume'` is the owner-requested behaviour — warm on
|
|
765
|
-
* open even for a first-time user. Opt in per product, and lower the
|
|
766
|
-
* shell's `idleTimeoutSeconds` when you do.
|
|
767
|
-
* - `shouldPrewarm(scope)` is the product's own policy hook (paid tier only,
|
|
768
|
-
* returning user only, has-documents only …). Returning false costs nothing.
|
|
769
|
-
* - `failureCooldownMs` stops a hard-failing workspace from retry-storming;
|
|
770
|
-
* every retry is another create attempt, which is more spend.
|
|
771
|
-
* Warm with the SAME harness the next turn will use. `ensureWorkspaceSandbox`
|
|
772
|
-
* DELETES and recreates a name-matched box whose harness differs, so warming
|
|
773
|
-
* `opencode` and then turning `claude-code` pays for two boxes and is slower
|
|
774
|
-
* than not warming at all. The prewarm key includes the harness so the two are
|
|
775
|
-
* never deduped into one.
|
|
776
|
-
*
|
|
777
|
-
* ── SINGLE-FLIGHT (measured, not assumed) ──────────────────────────────────
|
|
778
|
-
* The sandbox platform does NOT dedupe by box name. Two concurrent
|
|
779
|
-
* `POST /v1/sandboxes` with an identical name both returned HTTP 201 and left
|
|
780
|
-
* two running boxes (verified against staging-sandbox, 2026-07-28). So two
|
|
781
|
-
* tabs, or two isolates, racing a warm genuinely leak a box — a prewarm that
|
|
782
|
-
* races is worse than no prewarm. Hence two layers:
|
|
783
|
-
* 1. an in-process map, which is free and catches same-isolate races
|
|
784
|
-
* (double-mount, two requests on one isolate);
|
|
785
|
-
* 2. a `claim` store the product supplies, which is the only thing that can
|
|
786
|
-
* make this correct ACROSS isolates — the usual deployment target here is
|
|
787
|
-
* Cloudflare Workers, where "same isolate" guarantees nothing.
|
|
788
|
-
* `claim` is REQUIRED, with `'single-isolate-only'` as the explicit opt-out,
|
|
789
|
-
* so nobody gets the unsafe behaviour by forgetting a field. Say it out loud
|
|
790
|
-
* or supply a store.
|
|
791
|
-
*
|
|
792
|
-
* ── FAILURE IS LOUD, NEVER FATAL ───────────────────────────────────────────
|
|
793
|
-
* A failed warm degrades to exactly today's lazy path: the next real request
|
|
794
|
-
* calls `ensureWorkspaceSandbox` itself. It never throws into the caller's
|
|
795
|
-
* render path — `completion` RESOLVES with `{ ok: false }` rather than
|
|
796
|
-
* rejecting, because an unhandled rejection handed to `waitUntil` can fail the
|
|
797
|
-
* request it rode in on. But it is never silent: every failure fires
|
|
798
|
-
* `onEvent({ type: 'failed' })` and is readable afterwards through
|
|
799
|
-
* `readiness()` as `{ status: 'failed' }`. The bug class this whole module
|
|
800
|
-
* exists to kill is a soft failure that surfaces as an unusable panel ten
|
|
801
|
-
* minutes later, so a warm that dies must leave a trace a product can render.
|
|
802
|
-
*/
|
|
803
|
-
|
|
804
|
-
/** The workspace a warm targets. Mirrors `EnsureWorkspaceSandboxOptions`'
|
|
805
|
-
* identity fields — the prewarmer forwards them verbatim so a warmed box is
|
|
806
|
-
* byte-identical to the one the lazy path would have built. */
|
|
807
|
-
interface SandboxPrewarmScope {
|
|
808
|
-
workspaceId: string;
|
|
809
|
-
userId?: string;
|
|
810
|
-
/** Must match the harness the next turn will use — see the cost note above. */
|
|
811
|
-
harness: Harness;
|
|
812
|
-
billingOwnerId?: string;
|
|
813
|
-
}
|
|
814
|
-
/**
|
|
815
|
-
* Cross-isolate claim. `acquire` must be atomic (a D1 conditional insert, a DO,
|
|
816
|
-
* a KV `put` with `onlyIf`) — a read-then-write is exactly the race this exists
|
|
817
|
-
* to close. `ttlSeconds` bounds a claim leaked by an isolate that died
|
|
818
|
-
* mid-warm; without expiry a single crash wedges a workspace forever.
|
|
819
|
-
*/
|
|
820
|
-
interface PrewarmClaimStore {
|
|
821
|
-
/** True when THIS caller now owns the right to warm `key`. */
|
|
822
|
-
acquire(key: string, ttlSeconds: number): Promise<boolean>;
|
|
823
|
-
/** Best-effort release. A throw here is swallowed — the TTL is the backstop. */
|
|
824
|
-
release(key: string): Promise<void>;
|
|
825
|
-
/** Optional: lets `readiness()` report `warming` for a warm running in
|
|
826
|
-
* ANOTHER isolate. Without it, `warming` is only visible in the isolate
|
|
827
|
-
* that started it, and every other one reports `absent`. */
|
|
828
|
-
isHeld?(key: string): Promise<boolean>;
|
|
829
|
-
}
|
|
830
|
-
/** What `prewarm()` decided. Every value except `started` means no box was
|
|
831
|
-
* created and nothing was spent on this call. */
|
|
832
|
-
type PrewarmOutcome = 'started' | 'already-running' | 'already-warming' | 'warming-elsewhere' | 'declined-by-policy' | 'cooling-down' | 'absent-and-resume-only';
|
|
833
|
-
/** Terminal result of a warm this caller owns. Never a rejection. */
|
|
834
|
-
interface PrewarmResult {
|
|
835
|
-
ok: boolean;
|
|
836
|
-
boxId?: string;
|
|
837
|
-
error?: string;
|
|
838
|
-
/** Wall time of the warm itself, for the product's own timing trace. */
|
|
839
|
-
ms: number;
|
|
840
|
-
}
|
|
841
|
-
interface PrewarmDecision {
|
|
842
|
-
outcome: PrewarmOutcome;
|
|
843
|
-
/** Present ONLY when `outcome === 'started'`. Hand it to `ctx.waitUntil` so a
|
|
844
|
-
* client disconnect cannot kill the warm. Never rejects. */
|
|
845
|
-
completion?: Promise<PrewarmResult>;
|
|
846
|
-
}
|
|
847
|
-
/** Readiness for the UI. `ready`/`warming` reuse the vocabulary
|
|
848
|
-
* `createSandboxFileIndexRoute` (`/chat-routes`) and `useFileMentions`
|
|
849
|
-
* (`/web-react`) already speak, so a product renders ONE warming state rather
|
|
850
|
-
* than inventing a second spinner for boxes. */
|
|
851
|
-
type SandboxReadiness = {
|
|
852
|
-
status: 'ready';
|
|
853
|
-
boxId: string;
|
|
854
|
-
} | {
|
|
855
|
-
status: 'warming';
|
|
856
|
-
} | {
|
|
857
|
-
status: 'absent';
|
|
858
|
-
} | {
|
|
859
|
-
status: 'failed';
|
|
860
|
-
error: string;
|
|
861
|
-
retryAfterMs: number;
|
|
862
|
-
};
|
|
863
|
-
type PrewarmEvent = {
|
|
864
|
-
type: 'started';
|
|
865
|
-
key: string;
|
|
866
|
-
workspaceId: string;
|
|
867
|
-
} | {
|
|
868
|
-
type: 'succeeded';
|
|
869
|
-
key: string;
|
|
870
|
-
workspaceId: string;
|
|
871
|
-
boxId: string;
|
|
872
|
-
ms: number;
|
|
873
|
-
} | {
|
|
874
|
-
type: 'failed';
|
|
875
|
-
key: string;
|
|
876
|
-
workspaceId: string;
|
|
877
|
-
error: string;
|
|
878
|
-
ms: number;
|
|
879
|
-
} | {
|
|
880
|
-
type: 'skipped';
|
|
881
|
-
key: string;
|
|
882
|
-
workspaceId: string;
|
|
883
|
-
outcome: PrewarmOutcome;
|
|
884
|
-
};
|
|
885
|
-
interface SandboxPrewarmerOptions {
|
|
886
|
-
/** Cross-isolate single-flight, or the explicit acknowledgement that you are
|
|
887
|
-
* accepting per-isolate dedupe only. No default — see the header. */
|
|
888
|
-
claim: PrewarmClaimStore | 'single-isolate-only';
|
|
889
|
-
/** `'resume-only'` (default) never creates a box that does not exist.
|
|
890
|
-
* `'create-or-resume'` warms from nothing — the expensive one. */
|
|
891
|
-
mode?: 'resume-only' | 'create-or-resume';
|
|
892
|
-
/** Product policy gate. Not called when a box is already running. */
|
|
893
|
-
shouldPrewarm?(scope: SandboxPrewarmScope): boolean | Promise<boolean>;
|
|
894
|
-
/** Observability seam. A failed warm MUST be visible somewhere. */
|
|
895
|
-
onEvent?(event: PrewarmEvent): void;
|
|
896
|
-
/** Claim lifetime. Default 180 s — comfortably over a cold create. */
|
|
897
|
-
claimTtlSeconds?: number;
|
|
898
|
-
/** Suppress re-warming a workspace that just failed. Default 60_000 ms. */
|
|
899
|
-
failureCooldownMs?: number;
|
|
900
|
-
/** Clock seam for tests. */
|
|
901
|
-
now?(): number;
|
|
902
|
-
}
|
|
903
|
-
interface SandboxPrewarmer {
|
|
904
|
-
/**
|
|
905
|
-
* Non-blocking warm. The returned promise settles as soon as the DECISION is
|
|
906
|
-
* known (at most one `list()` against the platform, plus a claim `acquire`);
|
|
907
|
-
* the provisioning itself rides on `completion`. On a render path either
|
|
908
|
-
* ignore the returned promise or run the whole call inside `waitUntil` — do
|
|
909
|
-
* not await `completion` before responding.
|
|
910
|
-
*/
|
|
911
|
-
prewarm(scope: SandboxPrewarmScope): Promise<PrewarmDecision>;
|
|
912
|
-
/** Zero-provisioning status read for a UI. Never creates or resumes. */
|
|
913
|
-
readiness(scope: SandboxPrewarmScope): Promise<SandboxReadiness>;
|
|
914
|
-
/** Clear a recorded failure so the next `prewarm` retries immediately. */
|
|
915
|
-
clearFailure(scope: SandboxPrewarmScope): void;
|
|
916
|
-
}
|
|
917
|
-
declare function createSandboxPrewarmer(shell: SandboxRuntimeConfig, options: SandboxPrewarmerOptions): SandboxPrewarmer;
|
|
918
|
-
|
|
919
|
-
/**
|
|
920
|
-
* `createD1PrewarmClaimStore` — the cross-isolate half of
|
|
921
|
-
* `createSandboxPrewarmer`'s single-flight, implemented once.
|
|
922
|
-
*
|
|
923
|
-
* WHY THIS SHIPS HERE. `SandboxPrewarmerOptions.claim` is REQUIRED and has no
|
|
924
|
-
* default, which is correct — the unsafe behaviour must be said out loud. But
|
|
925
|
-
* "required with no implementation" is how five products end up hand-rolling
|
|
926
|
-
* five subtly different atomic leases, and a lease that is subtly wrong is
|
|
927
|
-
* indistinguishable from one that works until two tabs leak a box. Every
|
|
928
|
-
* agent-app product deploys to Cloudflare Workers with a D1 binding, so the
|
|
929
|
-
* store is the same code in all of them: it is mechanism, not domain, and it
|
|
930
|
-
* belongs beside the prewarmer.
|
|
931
|
-
*
|
|
932
|
-
* The measured stake (staging-sandbox, 2026-07-28): two concurrent
|
|
933
|
-
* `POST /v1/sandboxes` with an identical name BOTH returned HTTP 201 and left
|
|
934
|
-
* two running boxes. The platform does not dedupe by name, so nothing below
|
|
935
|
-
* this line is defensive programming — an unclaimed race genuinely doubles
|
|
936
|
-
* spend.
|
|
937
|
-
*
|
|
938
|
-
* ── ATOMICITY IS THE WHOLE POINT ───────────────────────────────────────────
|
|
939
|
-
* `acquire` is ONE statement. A `SELECT` followed by an `INSERT` is exactly the
|
|
940
|
-
* race this exists to close: both isolates read "free", both write, both warm.
|
|
941
|
-
* The upsert's `DO UPDATE ... WHERE expires_at <= now` means an unexpired claim
|
|
942
|
-
* makes the conflict path a no-op, and `RETURNING` then yields no row — so the
|
|
943
|
-
* loser learns it lost from the same statement that would have made it the
|
|
944
|
-
* winner. `RETURNING` is used rather than `meta.changes` because a no-op upsert
|
|
945
|
-
* reporting `changes: 0` is a SQLite detail, whereas "no row came back" is the
|
|
946
|
-
* statement telling you directly.
|
|
947
|
-
*
|
|
948
|
-
* ── STRUCTURAL, NOT A DEPENDENCY ───────────────────────────────────────────
|
|
949
|
-
* The binding is taken as the narrow shape actually used (`prepare().bind()`,
|
|
950
|
-
* `.first()`, `.run()`), per the package's structural-over-hard-dep rule. No
|
|
951
|
-
* `@cloudflare/workers-types` import, so `/sandbox` stays importable in a plain
|
|
952
|
-
* node test. A real `D1Database` satisfies it.
|
|
953
|
-
*
|
|
954
|
-
* ── THE TABLE IS THE PRODUCT'S MIGRATION, NOT A LAZY CREATE ────────────────
|
|
955
|
-
* The store never runs DDL. A `CREATE TABLE IF NOT EXISTS` on every project
|
|
956
|
-
* open costs a round trip on the exact path this feature exists to keep fast,
|
|
957
|
-
* and it hides schema drift instead of failing on it. `PREWARM_CLAIM_TABLE_DDL`
|
|
958
|
-
* is exported so a product pastes it into a real migration. If the table is
|
|
959
|
-
* missing, `acquire` throws — and the prewarmer treats a throwing claim as a
|
|
960
|
-
* failed warm: it records the failure, emits `onEvent({type:'failed'})`, and
|
|
961
|
-
* degrades to the lazy path. Fail-closed and loud, never a silent double-warm.
|
|
962
|
-
*/
|
|
963
|
-
/** The columns and statements this store uses, and nothing else. A real
|
|
964
|
-
* `D1Database` structurally satisfies it. */
|
|
965
|
-
interface PrewarmClaimD1Like {
|
|
966
|
-
prepare(query: string): {
|
|
967
|
-
bind(...values: unknown[]): {
|
|
968
|
-
first<T = Record<string, unknown>>(): Promise<T | null>;
|
|
969
|
-
run(): Promise<unknown>;
|
|
970
|
-
};
|
|
971
|
-
};
|
|
972
|
-
}
|
|
973
|
-
interface D1PrewarmClaimStoreOptions {
|
|
974
|
-
/** Defaults to `sandbox_prewarm_claims`. Must be a bare SQL identifier — it
|
|
975
|
-
* is interpolated, because a table name cannot be a bound parameter. */
|
|
976
|
-
table?: string;
|
|
977
|
-
/** Clock seam for tests. */
|
|
978
|
-
now?(): number;
|
|
979
|
-
}
|
|
980
|
-
declare const DEFAULT_PREWARM_CLAIM_TABLE = "sandbox_prewarm_claims";
|
|
981
|
-
/** Paste into a migration. `expires_at` is epoch MILLISECONDS, matching
|
|
982
|
-
* `Date.now()`, so no unit conversion sits between the lease and its clock. */
|
|
983
|
-
declare const PREWARM_CLAIM_TABLE_DDL = "CREATE TABLE IF NOT EXISTS sandbox_prewarm_claims (\n key TEXT PRIMARY KEY,\n expires_at INTEGER NOT NULL\n)";
|
|
984
|
-
/**
|
|
985
|
-
* A `PrewarmClaimStore` backed by one D1 table.
|
|
986
|
-
*
|
|
987
|
-
* ```ts
|
|
988
|
-
* const prewarmer = createSandboxPrewarmer(shell, {
|
|
989
|
-
* claim: createD1PrewarmClaimStore(env.DB),
|
|
990
|
-
* mode: 'create-or-resume',
|
|
991
|
-
* })
|
|
992
|
-
* ```
|
|
993
|
-
*/
|
|
994
|
-
declare function createD1PrewarmClaimStore(db: PrewarmClaimD1Like, options?: D1PrewarmClaimStoreOptions): {
|
|
995
|
-
acquire(key: string, ttlSeconds: number): Promise<boolean>;
|
|
996
|
-
release(key: string): Promise<void>;
|
|
997
|
-
isHeld(key: string): Promise<boolean>;
|
|
998
|
-
};
|
|
999
|
-
|
|
2
|
+
import type { EgressPolicy, MintScopedTokenOptions, SandboxInstance, ScopedTokenScope, StorageConfig, TurnDriveResult, ProvisionEvent } from '@tangle-network/sandbox';
|
|
3
|
+
import type { AgentProfile, AgentProfileFileMount, AgentProfileMcpServer, ReasoningEffort } from '@tangle-network/agent-interface';
|
|
4
|
+
import { type AppToolName, type AppToolContext, type ToolHeaderNames } from '../tools/index';
|
|
5
|
+
import { type Harness } from '../harness/index';
|
|
6
|
+
import { type TangleExecutionEnvironment } from '../runtime/model';
|
|
7
|
+
import { type Outcome } from './outcome';
|
|
8
|
+
import { type ProfileFingerprint } from '../profile/fingerprint';
|
|
9
|
+
import { type ComposeProfileBudget } from '../profile/budget';
|
|
10
|
+
import { resolveModel, resolveModelSelection, requireTransportableModel, SandboxModelResolutionError, type ProviderResolutionConfig, type ResolvedModel, type ModelSelection, type ModelSelectionFailure, type ModelSelectionError, type ModelSelectionSource } from './model';
|
|
11
|
+
export type { Outcome } from './outcome';
|
|
12
|
+
export * from './binary-read';
|
|
13
|
+
export { resolveModel, resolveModelSelection, requireTransportableModel, SandboxModelResolutionError, };
|
|
14
|
+
export type { ProviderResolutionConfig, ResolvedModel, ModelSelection, ModelSelectionFailure, ModelSelectionError, ModelSelectionSource, };
|
|
1000
15
|
/** Define client credentials for accessing the sandbox environment with API key and base URL */
|
|
1001
|
-
interface SandboxClientCredentials {
|
|
16
|
+
export interface SandboxClientCredentials {
|
|
1002
17
|
apiKey: string;
|
|
1003
18
|
baseUrl: string;
|
|
1004
19
|
}
|
|
@@ -1007,9 +22,9 @@ interface SandboxClientCredentials {
|
|
|
1007
22
|
* (development/test/staging/production) so env classification stays in one place
|
|
1008
23
|
* (see resolveTangleExecutionEnvironment in runtime/model).
|
|
1009
24
|
*/
|
|
1010
|
-
type SandboxCredentialEnvironment = TangleExecutionEnvironment;
|
|
25
|
+
export type SandboxCredentialEnvironment = TangleExecutionEnvironment;
|
|
1011
26
|
/** Resolve options for obtaining sandbox client credentials from environment variables and classification */
|
|
1012
|
-
interface ResolveSandboxClientCredentialsOptions {
|
|
27
|
+
export interface ResolveSandboxClientCredentialsOptions {
|
|
1013
28
|
/**
|
|
1014
29
|
* Environment object to read from. Defaults to process.env when available.
|
|
1015
30
|
*/
|
|
@@ -1050,9 +65,9 @@ interface ResolveSandboxClientCredentialsOptions {
|
|
|
1050
65
|
}) => SandboxClientCredentials | null | undefined | Promise<SandboxClientCredentials | null | undefined>;
|
|
1051
66
|
}
|
|
1052
67
|
/** Resolve sandbox client credentials based on environment and provided options asynchronously */
|
|
1053
|
-
declare function resolveSandboxClientCredentials(options?: ResolveSandboxClientCredentialsOptions): Promise<SandboxClientCredentials>;
|
|
68
|
+
export declare function resolveSandboxClientCredentials(options?: ResolveSandboxClientCredentialsOptions): Promise<SandboxClientCredentials>;
|
|
1054
69
|
/** Define configuration parameters for sandbox resource allocation and lifecycle management */
|
|
1055
|
-
interface SandboxResourceConfig {
|
|
70
|
+
export interface SandboxResourceConfig {
|
|
1056
71
|
image: string;
|
|
1057
72
|
cpuCores: number;
|
|
1058
73
|
memoryMB: number;
|
|
@@ -1061,34 +76,34 @@ interface SandboxResourceConfig {
|
|
|
1061
76
|
idleTimeoutSeconds: number;
|
|
1062
77
|
}
|
|
1063
78
|
/** Define the context for building a sandbox including workspace, integrations, and optional user ID */
|
|
1064
|
-
interface SandboxBuildContext {
|
|
79
|
+
export interface SandboxBuildContext {
|
|
1065
80
|
workspaceId: string;
|
|
1066
81
|
connectedIntegrationIds: string[];
|
|
1067
82
|
userId?: string;
|
|
1068
83
|
}
|
|
1069
84
|
/** Hosts required when a product installs its pinned Python tooling at boot. */
|
|
1070
|
-
declare const PYPI_EGRESS_DOMAINS: readonly ["pypi.org", "files.pythonhosted.org", "pypi.python.org"];
|
|
1071
|
-
declare function buildProductEgressPolicy(publicOrigin: string | URL, extraDomains?: readonly string[]): EgressPolicy;
|
|
1072
|
-
|
|
85
|
+
export declare const PYPI_EGRESS_DOMAINS: readonly ["pypi.org", "files.pythonhosted.org", "pypi.python.org"];
|
|
86
|
+
export declare function buildProductEgressPolicy(publicOrigin: string | URL, extraDomains?: readonly string[]): EgressPolicy;
|
|
87
|
+
export type { StorageConfig };
|
|
1073
88
|
/** Define a scope containing workspace and optional user identifiers for sandbox environments */
|
|
1074
|
-
interface SandboxScope {
|
|
89
|
+
export interface SandboxScope {
|
|
1075
90
|
workspaceId: string;
|
|
1076
91
|
userId?: string;
|
|
1077
92
|
}
|
|
1078
93
|
/** Define the specification for restoring a sandbox from a snapshot or another sandbox ID */
|
|
1079
|
-
interface SandboxRestoreSpec {
|
|
94
|
+
export interface SandboxRestoreSpec {
|
|
1080
95
|
fromSnapshot: string;
|
|
1081
96
|
fromSandboxId: string;
|
|
1082
97
|
}
|
|
1083
98
|
/** Describe the failure details when resuming a stopped sandbox instance */
|
|
1084
|
-
interface StoppedSandboxResumeFailure {
|
|
99
|
+
export interface StoppedSandboxResumeFailure {
|
|
1085
100
|
box: SandboxInstance;
|
|
1086
101
|
error: Error;
|
|
1087
102
|
scope: SandboxScope;
|
|
1088
103
|
boxKey: string;
|
|
1089
104
|
}
|
|
1090
105
|
/** Define the structure for resuming a stopped sandbox with replacement key and optional restore options */
|
|
1091
|
-
interface StoppedSandboxResumeRecovery {
|
|
106
|
+
export interface StoppedSandboxResumeRecovery {
|
|
1092
107
|
replacementBoxKey: string;
|
|
1093
108
|
restore?: SandboxRestoreSpec | null;
|
|
1094
109
|
}
|
|
@@ -1098,9 +113,9 @@ interface StoppedSandboxResumeRecovery {
|
|
|
1098
113
|
* fleet's shared OpenCode, Claude Code, and Codex terminal path; products with
|
|
1099
114
|
* another harness can override it.
|
|
1100
115
|
*/
|
|
1101
|
-
declare const DEFAULT_SIDECAR_PROCESS_PATTERN = "opencode|claude|codex";
|
|
116
|
+
export declare const DEFAULT_SIDECAR_PROCESS_PATTERN = "opencode|claude|codex";
|
|
1102
117
|
/** Define configuration for liveness probes including sidecar process pattern and optional timeouts */
|
|
1103
|
-
interface LivenessProbeConfig {
|
|
118
|
+
export interface LivenessProbeConfig {
|
|
1104
119
|
sidecarProcessPattern?: (harness: Harness) => string;
|
|
1105
120
|
execTimeoutMs?: number;
|
|
1106
121
|
psTimeoutMs?: number;
|
|
@@ -1116,7 +131,7 @@ interface LivenessProbeConfig {
|
|
|
1116
131
|
cacheTtlMs?: number;
|
|
1117
132
|
}
|
|
1118
133
|
/** Define options for composing a user profile including prompts, files, servers, and name */
|
|
1119
|
-
interface ProfileComposeOptions {
|
|
134
|
+
export interface ProfileComposeOptions {
|
|
1120
135
|
systemPrompt?: string;
|
|
1121
136
|
extraFiles?: AgentProfileFileMount[];
|
|
1122
137
|
extraMcp?: Record<string, AgentProfileMcpServer>;
|
|
@@ -1137,7 +152,7 @@ interface ProfileComposeOptions {
|
|
|
1137
152
|
harness: Harness;
|
|
1138
153
|
}
|
|
1139
154
|
/** Define runtime configuration methods for sandbox environments including credentials, metadata, and permissions */
|
|
1140
|
-
interface SandboxRuntimeConfig {
|
|
155
|
+
export interface SandboxRuntimeConfig {
|
|
1141
156
|
credentials: (scope?: SandboxScope) => SandboxClientCredentials | null | Promise<SandboxClientCredentials | null>;
|
|
1142
157
|
name: (workspaceId: string) => string;
|
|
1143
158
|
metadata: (harness: Harness) => Record<string, unknown>;
|
|
@@ -1208,19 +223,19 @@ interface SandboxRuntimeConfig {
|
|
|
1208
223
|
promptBudget?: ComposeProfileBudget;
|
|
1209
224
|
}
|
|
1210
225
|
/** Define default resource limits and settings for sandbox environments */
|
|
1211
|
-
declare const DEFAULT_SANDBOX_RESOURCES: SandboxResourceConfig;
|
|
226
|
+
export declare const DEFAULT_SANDBOX_RESOURCES: SandboxResourceConfig;
|
|
1212
227
|
/** Resolve a synchronous sandbox client from provided runtime configuration credentials */
|
|
1213
|
-
declare function getClient(shell: SandboxRuntimeConfig): Sandbox;
|
|
228
|
+
export declare function getClient(shell: SandboxRuntimeConfig): Sandbox;
|
|
1214
229
|
/** Reset the process-local sandbox client and liveness-verification caches. */
|
|
1215
|
-
declare function resetClientCache(): void;
|
|
230
|
+
export declare function resetClientCache(): void;
|
|
1216
231
|
/** Describe an application tool with its name, unique key, and description */
|
|
1217
|
-
interface AppToolDescriptor {
|
|
232
|
+
export interface AppToolDescriptor {
|
|
1218
233
|
tool: AppToolName;
|
|
1219
234
|
key: string;
|
|
1220
235
|
description: string;
|
|
1221
236
|
}
|
|
1222
237
|
/** Define options for building MCP server configurations in the app tool environment */
|
|
1223
|
-
interface BuildAppToolMcpServersOptions {
|
|
238
|
+
export interface BuildAppToolMcpServersOptions {
|
|
1224
239
|
tools: AppToolDescriptor[];
|
|
1225
240
|
baseUrl: string;
|
|
1226
241
|
/**
|
|
@@ -1238,9 +253,9 @@ interface BuildAppToolMcpServersOptions {
|
|
|
1238
253
|
headerNames?: ToolHeaderNames;
|
|
1239
254
|
}
|
|
1240
255
|
/** Build a mapping of MCP server profiles keyed by tool identifiers from provided options */
|
|
1241
|
-
declare function buildAppToolMcpServers(options: BuildAppToolMcpServersOptions): Record<string, AgentProfileMcpServer>;
|
|
256
|
+
export declare function buildAppToolMcpServers(options: BuildAppToolMcpServersOptions): Record<string, AgentProfileMcpServer>;
|
|
1242
257
|
/** Define options for ensuring a workspace sandbox with provisioning and progress handling */
|
|
1243
|
-
interface EnsureWorkspaceSandboxOptions {
|
|
258
|
+
export interface EnsureWorkspaceSandboxOptions {
|
|
1244
259
|
workspaceId: string;
|
|
1245
260
|
userId?: string;
|
|
1246
261
|
harness: Harness;
|
|
@@ -1250,7 +265,7 @@ interface EnsureWorkspaceSandboxOptions {
|
|
|
1250
265
|
spend?: SandboxSpendHooks;
|
|
1251
266
|
}
|
|
1252
267
|
/** What `/sandbox` reports once a box is provisioned, reused, or resumed. */
|
|
1253
|
-
interface SandboxProvisionedObservation {
|
|
268
|
+
export interface SandboxProvisionedObservation {
|
|
1254
269
|
readonly workspaceId: string;
|
|
1255
270
|
readonly userId?: string;
|
|
1256
271
|
/** The platform's sandbox id — the join key to every settlement row. */
|
|
@@ -1272,7 +287,7 @@ interface SandboxProvisionedObservation {
|
|
|
1272
287
|
* `onProvisioned` is an OBSERVER: its failures are swallowed, because
|
|
1273
288
|
* bookkeeping must never take down the provisioning it is bookkeeping.
|
|
1274
289
|
*/
|
|
1275
|
-
interface SandboxSpendHooks {
|
|
290
|
+
export interface SandboxSpendHooks {
|
|
1276
291
|
/** Runs before any create, resume, or reuse. Throw to refuse provisioning. */
|
|
1277
292
|
beforeProvision?(input: {
|
|
1278
293
|
workspaceId: string;
|
|
@@ -1300,49 +315,49 @@ interface SandboxSpendHooks {
|
|
|
1300
315
|
}): void;
|
|
1301
316
|
}
|
|
1302
317
|
/** Define the specification for a sandbox tool including its name, content, and optional executability */
|
|
1303
|
-
interface SandboxToolSpec {
|
|
318
|
+
export interface SandboxToolSpec {
|
|
1304
319
|
name: string;
|
|
1305
320
|
content: string;
|
|
1306
321
|
executable?: boolean;
|
|
1307
322
|
}
|
|
1308
323
|
/** Define options for resolving sandbox tool paths including appName, baseDir, and binDir */
|
|
1309
|
-
interface SandboxToolPathOptions {
|
|
324
|
+
export interface SandboxToolPathOptions {
|
|
1310
325
|
appName: string;
|
|
1311
326
|
baseDir?: string;
|
|
1312
327
|
binDir?: string;
|
|
1313
328
|
}
|
|
1314
329
|
/** Define options for building sandbox tool file mounts including tool specifications and paths */
|
|
1315
|
-
interface BuildSandboxToolFileMountsOptions extends SandboxToolPathOptions {
|
|
330
|
+
export interface BuildSandboxToolFileMountsOptions extends SandboxToolPathOptions {
|
|
1316
331
|
tools: readonly SandboxToolSpec[];
|
|
1317
332
|
}
|
|
1318
333
|
/** Resolve the root directory path for a sandbox tool based on provided options */
|
|
1319
|
-
declare function sandboxToolRootDir(options: SandboxToolPathOptions): string;
|
|
334
|
+
export declare function sandboxToolRootDir(options: SandboxToolPathOptions): string;
|
|
1320
335
|
/** Resolve the binary directory path for a sandbox tool based on provided options */
|
|
1321
|
-
declare function sandboxToolBinDir(options: SandboxToolPathOptions): string;
|
|
336
|
+
export declare function sandboxToolBinDir(options: SandboxToolPathOptions): string;
|
|
1322
337
|
/** Resolve the file system path to a specified sandbox tool based on given options */
|
|
1323
|
-
declare function sandboxToolPath(options: SandboxToolPathOptions & {
|
|
338
|
+
export declare function sandboxToolPath(options: SandboxToolPathOptions & {
|
|
1324
339
|
toolName: string;
|
|
1325
340
|
}): string;
|
|
1326
341
|
/** Build file mounts for sandbox tools based on provided options and tool configurations */
|
|
1327
|
-
declare function buildSandboxToolFileMounts(options: BuildSandboxToolFileMountsOptions): AgentProfileFileMount[];
|
|
342
|
+
export declare function buildSandboxToolFileMounts(options: BuildSandboxToolFileMountsOptions): AgentProfileFileMount[];
|
|
1328
343
|
/** Build a shell script that sets up and exports the sandbox tool binary directory in user profiles */
|
|
1329
|
-
declare function buildSandboxToolPathSetupScript(options: SandboxToolPathOptions): string;
|
|
344
|
+
export declare function buildSandboxToolPathSetupScript(options: SandboxToolPathOptions): string;
|
|
1330
345
|
/** Resolve the sandbox environment PATH setup by executing the configuration script with given options */
|
|
1331
|
-
declare function runSandboxToolPathSetup(box: SandboxInstance, options: SandboxToolPathOptions): Promise<Outcome<void>>;
|
|
346
|
+
export declare function runSandboxToolPathSetup(box: SandboxInstance, options: SandboxToolPathOptions): Promise<Outcome<void>>;
|
|
1332
347
|
/** Split profile files into inline deferred files and a lean profile without them */
|
|
1333
|
-
declare function splitDeferredProfileFiles(profile: AgentProfile): {
|
|
348
|
+
export declare function splitDeferredProfileFiles(profile: AgentProfile): {
|
|
1334
349
|
leanProfile: AgentProfile;
|
|
1335
350
|
deferredFiles: AgentProfileFileMount[];
|
|
1336
351
|
};
|
|
1337
|
-
type SandboxExistingBoxStage = 'reused' | 'resumed';
|
|
1338
|
-
type SandboxEgressPolicySource = Awaited<ReturnType<SandboxInstance['egress']['get']>>['source'];
|
|
352
|
+
export type SandboxExistingBoxStage = 'reused' | 'resumed';
|
|
353
|
+
export type SandboxEgressPolicySource = Awaited<ReturnType<SandboxInstance['egress']['get']>>['source'];
|
|
1339
354
|
/**
|
|
1340
355
|
* Thrown when an existing sandbox cannot be proven to have the requested
|
|
1341
356
|
* outbound network policy. The sandbox is preserved and its policy is not
|
|
1342
357
|
* changed. The caller explicitly decides whether to preserve, migrate, or
|
|
1343
358
|
* replace the sandbox.
|
|
1344
359
|
*/
|
|
1345
|
-
declare class SandboxEgressPolicyMismatchError extends Error {
|
|
360
|
+
export declare class SandboxEgressPolicyMismatchError extends Error {
|
|
1346
361
|
readonly stage: SandboxExistingBoxStage;
|
|
1347
362
|
readonly boxName: string;
|
|
1348
363
|
readonly currentPolicy: EgressPolicy;
|
|
@@ -1350,67 +365,68 @@ declare class SandboxEgressPolicyMismatchError extends Error {
|
|
|
1350
365
|
readonly desiredPolicy: EgressPolicy;
|
|
1351
366
|
constructor(stage: SandboxExistingBoxStage, boxName: string, currentPolicy: EgressPolicy, currentSource: SandboxEgressPolicySource, desiredPolicy: EgressPolicy);
|
|
1352
367
|
}
|
|
1353
|
-
|
|
368
|
+
export * from './recovery';
|
|
369
|
+
export { serializeSandboxProvisioningError, formatSandboxProvisioningSupportDetails, formatSandboxProvisioningUserMessage, isSandboxAuthFailure, isSandboxApiBearerAuthFailure, isSandboxApiSandboxMissingFailure, isSandboxHostCapacityFailure, type SafeSandboxErrorCause, type SafeSandboxErrorDiagnostics, } from './diagnostics';
|
|
1354
370
|
/** Represent an error thrown when sandbox runtime authentication refresh fails for a specific stage and name */
|
|
1355
|
-
declare class SandboxRuntimeAuthRefreshError extends Error {
|
|
371
|
+
export declare class SandboxRuntimeAuthRefreshError extends Error {
|
|
1356
372
|
constructor(stage: SandboxExistingBoxStage, name: string, detail: string, cause?: unknown);
|
|
1357
373
|
}
|
|
1358
374
|
/** Which step of the state-preserving stop→resume recovery failed. `stop` with a
|
|
1359
375
|
* driver-unsupported cause means the platform cannot restart this box (the
|
|
1360
376
|
* `tangle` driver exposes create/delete only); `probe` means the box restarted
|
|
1361
377
|
* but is still unresponsive. */
|
|
1362
|
-
type SandboxRecoveryPhase = 'stop' | 'resume' | 'probe';
|
|
378
|
+
export type SandboxRecoveryPhase = 'stop' | 'resume' | 'probe';
|
|
1363
379
|
/**
|
|
1364
380
|
* Thrown when an unresponsive box could not be recovered by a state-preserving
|
|
1365
381
|
* restart. Contract: this error is only ever thrown with the workspace intact —
|
|
1366
382
|
* recovery never deletes. The caller decides what to do next (retry, surface to
|
|
1367
383
|
* the user, or explicitly replace via `forceNew`).
|
|
1368
384
|
*/
|
|
1369
|
-
declare class SandboxRecoveryFailedError extends Error {
|
|
385
|
+
export declare class SandboxRecoveryFailedError extends Error {
|
|
1370
386
|
readonly boxKey: string;
|
|
1371
387
|
readonly stage: SandboxExistingBoxStage;
|
|
1372
388
|
readonly phase: SandboxRecoveryPhase;
|
|
1373
389
|
constructor(stage: SandboxExistingBoxStage, boxKey: string, phase: SandboxRecoveryPhase, detail: string, cause?: unknown);
|
|
1374
390
|
}
|
|
1375
391
|
/** Define options to control execution timeout, pacing, and retry behavior when writing profile files */
|
|
1376
|
-
interface WriteProfileFilesOptions {
|
|
392
|
+
export interface WriteProfileFilesOptions {
|
|
1377
393
|
execTimeoutMs?: number;
|
|
1378
394
|
paceMs?: number;
|
|
1379
395
|
maxRetries?: number;
|
|
1380
396
|
}
|
|
1381
397
|
/** Write profile files to a sandbox with pacing, retries, and optional execution timeout handling */
|
|
1382
|
-
declare function writeProfileFilesToBox(box: SandboxInstance, files: AgentProfileFileMount[], options?: WriteProfileFilesOptions): Promise<Outcome<void>>;
|
|
398
|
+
export declare function writeProfileFilesToBox(box: SandboxInstance, files: AgentProfileFileMount[], options?: WriteProfileFilesOptions): Promise<Outcome<void>>;
|
|
1383
399
|
/** Stable content hash of the deferred file corpus (path + inline content).
|
|
1384
400
|
* Unchanged corpus ⇒ same hash; a new/edited/removed skill ⇒ different hash.
|
|
1385
401
|
* Exported for the reuse-skip test. */
|
|
1386
|
-
declare function deferredCorpusHash(files: AgentProfileFileMount[]): string;
|
|
402
|
+
export declare function deferredCorpusHash(files: AgentProfileFileMount[]): string;
|
|
1387
403
|
/** Gate on the provision body: the platform orchestrator caps the create
|
|
1388
404
|
* payload at 256 KiB; 240 KB leaves headroom for transport framing. An
|
|
1389
405
|
* over-cap payload fails provisioning 100% of the time (a 282 KB payload
|
|
1390
406
|
* shipped once and no sandbox could ever be created). */
|
|
1391
|
-
declare const PROVISION_PAYLOAD_MAX_BYTES = 240000;
|
|
407
|
+
export declare const PROVISION_PAYLOAD_MAX_BYTES = 240000;
|
|
1392
408
|
/** Per-variable env gate: the kernel rejects any single `NAME=value` env entry
|
|
1393
409
|
* over MAX_ARG_STRLEN (131072 bytes) with E2BIG, killing every exec inside
|
|
1394
410
|
* the box. 120 KB leaves headroom for the name and framing. */
|
|
1395
|
-
declare const ENV_VALUE_MAX_BYTES = 120000;
|
|
411
|
+
export declare const ENV_VALUE_MAX_BYTES = 120000;
|
|
1396
412
|
/** Default wait for a box to reach `running`. Overridable per shell via
|
|
1397
413
|
* {@link SandboxRuntimeConfig.provisionTimeoutMs}. */
|
|
1398
|
-
declare const DEFAULT_PROVISION_TIMEOUT_MS = 120000;
|
|
414
|
+
export declare const DEFAULT_PROVISION_TIMEOUT_MS = 120000;
|
|
1399
415
|
/** Total env gate: the whole environment block shares the payload budget with
|
|
1400
416
|
* the profile; past 200 KB the provision body cannot stay under the cap. */
|
|
1401
|
-
declare const ENV_TOTAL_MAX_BYTES = 200000;
|
|
417
|
+
export declare const ENV_TOTAL_MAX_BYTES = 200000;
|
|
1402
418
|
/** Structural slice of the profile the payload gate reads: it only measures
|
|
1403
419
|
* the profile's serialized size and names `resources.files` in the breakdown,
|
|
1404
420
|
* so callers composing a payload outside the SDK (products, tests) can pass a
|
|
1405
421
|
* plain object without casting through `AgentProfile`. */
|
|
1406
|
-
interface ProvisionProfileSection {
|
|
422
|
+
export interface ProvisionProfileSection {
|
|
1407
423
|
resources?: {
|
|
1408
424
|
files?: readonly unknown[];
|
|
1409
425
|
};
|
|
1410
426
|
}
|
|
1411
427
|
/** The provision-payload sections the size gates need to see. Structural so
|
|
1412
428
|
* the gate is testable without the SDK's (unexported) create-payload type. */
|
|
1413
|
-
interface ProvisionPayloadSections {
|
|
429
|
+
export interface ProvisionPayloadSections {
|
|
1414
430
|
env?: Record<string, string>;
|
|
1415
431
|
secrets?: readonly string[];
|
|
1416
432
|
/** `profile` may also be a named-profile string ref (the SDK's
|
|
@@ -1425,18 +441,18 @@ interface ProvisionPayloadSections {
|
|
|
1425
441
|
* breakdown (profile/files/env/secrets) so the offending channel is named, not
|
|
1426
442
|
* guessed.
|
|
1427
443
|
*/
|
|
1428
|
-
declare function assertProvisionPayloadWithinCap(payload: ProvisionPayloadSections): void;
|
|
444
|
+
export declare function assertProvisionPayloadWithinCap(payload: ProvisionPayloadSections): void;
|
|
1429
445
|
/**
|
|
1430
446
|
* Throw when any single env value exceeds {@link ENV_VALUE_MAX_BYTES} or the
|
|
1431
447
|
* whole env block exceeds {@link ENV_TOTAL_MAX_BYTES}, naming the offending
|
|
1432
448
|
* variable. This is the E2BIG incident class: the box may even provision, but
|
|
1433
449
|
* every exec inside it dies on the oversized entry.
|
|
1434
450
|
*/
|
|
1435
|
-
declare function assertEnvWithinLimits(env: Record<string, string>): void;
|
|
451
|
+
export declare function assertEnvWithinLimits(env: Record<string, string>): void;
|
|
1436
452
|
/** What a peek can find. `not-running` carries the platform's own state string
|
|
1437
453
|
* (`stopped`, `starting`, `failed`, …) — narrowing it to a union here would
|
|
1438
454
|
* drop states the platform adds later, and every caller wants it for a log. */
|
|
1439
|
-
type PeekWorkspaceSandboxOutcome = {
|
|
455
|
+
export type PeekWorkspaceSandboxOutcome = {
|
|
1440
456
|
status: 'running';
|
|
1441
457
|
box: SandboxInstance;
|
|
1442
458
|
} | {
|
|
@@ -1477,16 +493,16 @@ type PeekWorkspaceSandboxOutcome = {
|
|
|
1477
493
|
* platform never reported. Callers that must tolerate it say so explicitly
|
|
1478
494
|
* (the stale-turn-lock policy documents "a throw is treated as unreachable").
|
|
1479
495
|
*/
|
|
1480
|
-
declare function peekWorkspaceSandbox(shell: SandboxRuntimeConfig, options: {
|
|
496
|
+
export declare function peekWorkspaceSandbox(shell: SandboxRuntimeConfig, options: {
|
|
1481
497
|
workspaceId: string;
|
|
1482
498
|
userId?: string;
|
|
1483
499
|
}): Promise<PeekWorkspaceSandboxOutcome>;
|
|
1484
500
|
/** Resolve or create a workspace sandbox instance with optional reuse and progress tracking */
|
|
1485
|
-
declare function ensureWorkspaceSandbox(shell: SandboxRuntimeConfig, options: EnsureWorkspaceSandboxOptions): Promise<SandboxInstance>;
|
|
501
|
+
export declare function ensureWorkspaceSandbox(shell: SandboxRuntimeConfig, options: EnsureWorkspaceSandboxOptions): Promise<SandboxInstance>;
|
|
1486
502
|
/** Extract a single element type from the array parameter of SandboxInstance's streamPrompt method */
|
|
1487
|
-
type PromptInputPart = Extract<Parameters<SandboxInstance['streamPrompt']>[0], readonly unknown[]>[number];
|
|
503
|
+
export type PromptInputPart = Extract<Parameters<SandboxInstance['streamPrompt']>[0], readonly unknown[]>[number];
|
|
1488
504
|
/** Build a single string combining conversation history and the current user message */
|
|
1489
|
-
declare function flattenHistory(message: string, history?: Array<{
|
|
505
|
+
export declare function flattenHistory(message: string, history?: Array<{
|
|
1490
506
|
role: 'user' | 'assistant';
|
|
1491
507
|
content: string;
|
|
1492
508
|
}>): string;
|
|
@@ -1495,16 +511,16 @@ declare function flattenHistory(message: string, history?: Array<{
|
|
|
1495
511
|
* transcript is folded into the first text part (image/file parts carry no
|
|
1496
512
|
* text to prepend to) rather than replacing the message wholesale.
|
|
1497
513
|
*/
|
|
1498
|
-
declare function mergeHistoryIntoParts(parts: PromptInputPart[], history?: Array<{
|
|
514
|
+
export declare function mergeHistoryIntoParts(parts: PromptInputPart[], history?: Array<{
|
|
1499
515
|
role: 'user' | 'assistant';
|
|
1500
516
|
content: string;
|
|
1501
517
|
}>): PromptInputPart[];
|
|
1502
518
|
/** Resolve conflicts and merge extra MCP profiles into the app tool MCP without overwriting existing keys */
|
|
1503
|
-
declare function mergeExtraMcp(appToolMcp: Record<string, AgentProfileMcpServer>, baseProfileMcp: Record<string, AgentProfileMcpServer>, extra: Record<string, AgentProfileMcpServer> | undefined): Record<string, AgentProfileMcpServer>;
|
|
519
|
+
export declare function mergeExtraMcp(appToolMcp: Record<string, AgentProfileMcpServer>, baseProfileMcp: Record<string, AgentProfileMcpServer>, extra: Record<string, AgentProfileMcpServer> | undefined): Record<string, AgentProfileMcpServer>;
|
|
1504
520
|
/** Attach a specified reasoning effort level to an agent profile for a given harness */
|
|
1505
|
-
declare function attachReasoningEffort(profile: AgentProfile, harness: Harness, effort: 'auto' | ReasoningEffort | undefined): AgentProfile;
|
|
521
|
+
export declare function attachReasoningEffort(profile: AgentProfile, harness: Harness, effort: 'auto' | ReasoningEffort | undefined): AgentProfile;
|
|
1506
522
|
/** Define options for configuring and controlling a streaming sandbox prompt session */
|
|
1507
|
-
interface StreamSandboxPromptOptions {
|
|
523
|
+
export interface StreamSandboxPromptOptions {
|
|
1508
524
|
sessionId?: string;
|
|
1509
525
|
executionId?: string;
|
|
1510
526
|
/** Stable idempotency key for one logical dispatch. Reuse it with the same
|
|
@@ -1543,7 +559,7 @@ interface StreamSandboxPromptOptions {
|
|
|
1543
559
|
* adapter deliberately copies only the fields the gateway understands so
|
|
1544
560
|
* consumers do not each have to maintain a provider-to-gateway cast.
|
|
1545
561
|
*/
|
|
1546
|
-
interface SandboxStreamEvent {
|
|
562
|
+
export interface SandboxStreamEvent {
|
|
1547
563
|
type?: string;
|
|
1548
564
|
data?: {
|
|
1549
565
|
part?: {
|
|
@@ -1558,9 +574,9 @@ interface SandboxStreamEvent {
|
|
|
1558
574
|
};
|
|
1559
575
|
}
|
|
1560
576
|
/** Normalize raw sandbox events for shared agent-gateway consumers. */
|
|
1561
|
-
declare function adaptSandboxStream(events: AsyncIterable<unknown>): AsyncGenerator<SandboxStreamEvent>;
|
|
577
|
+
export declare function adaptSandboxStream(events: AsyncIterable<unknown>): AsyncGenerator<SandboxStreamEvent>;
|
|
1562
578
|
/** Resolve and stream AI-generated responses from a sandboxed environment based on input messages and options */
|
|
1563
|
-
declare function streamSandboxPrompt(shell: SandboxRuntimeConfig, box: SandboxInstance, message: string | PromptInputPart[], options?: StreamSandboxPromptOptions): AsyncGenerator<unknown>;
|
|
579
|
+
export declare function streamSandboxPrompt(shell: SandboxRuntimeConfig, box: SandboxInstance, message: string | PromptInputPart[], options?: StreamSandboxPromptOptions): AsyncGenerator<unknown>;
|
|
1564
580
|
/**
|
|
1565
581
|
* Aggregate a sandbox prompt event stream down to the turn's one final answer.
|
|
1566
582
|
*
|
|
@@ -1591,7 +607,7 @@ declare function streamSandboxPrompt(shell: SandboxRuntimeConfig, box: SandboxIn
|
|
|
1591
607
|
* @param history folded into the dispatched prompt by `streamSandboxPrompt`;
|
|
1592
608
|
* pass whatever was passed there, since the echo replays the FOLDED text
|
|
1593
609
|
*/
|
|
1594
|
-
declare function collectSandboxPromptText(events: AsyncIterable<unknown>, message: string | PromptInputPart[], history?: StreamSandboxPromptOptions['history']): Promise<string>;
|
|
610
|
+
export declare function collectSandboxPromptText(events: AsyncIterable<unknown>, message: string | PromptInputPart[], history?: StreamSandboxPromptOptions['history']): Promise<string>;
|
|
1595
611
|
/**
|
|
1596
612
|
* Resolve a sandbox prompt by streaming it and aggregating the turn down to one
|
|
1597
613
|
* final string. The shell's profile / model / MCP resolution and severed-stream
|
|
@@ -1599,19 +615,19 @@ declare function collectSandboxPromptText(events: AsyncIterable<unknown>, messag
|
|
|
1599
615
|
* `collectSandboxPromptText`, which products driving their own generator should
|
|
1600
616
|
* import directly.
|
|
1601
617
|
*/
|
|
1602
|
-
declare function runSandboxPrompt(shell: SandboxRuntimeConfig, box: SandboxInstance, message: string | PromptInputPart[], options?: StreamSandboxPromptOptions): Promise<string>;
|
|
618
|
+
export declare function runSandboxPrompt(shell: SandboxRuntimeConfig, box: SandboxInstance, message: string | PromptInputPart[], options?: StreamSandboxPromptOptions): Promise<string>;
|
|
1603
619
|
/** Define permission levels for sandbox access and control */
|
|
1604
|
-
type SandboxPermissionLevel = 'owner' | 'admin' | 'developer' | 'viewer';
|
|
620
|
+
export type SandboxPermissionLevel = 'owner' | 'admin' | 'developer' | 'viewer';
|
|
1605
621
|
/** Map workspace roles to corresponding sandbox permission levels */
|
|
1606
|
-
interface MemberSyncSeam {
|
|
622
|
+
export interface MemberSyncSeam {
|
|
1607
623
|
roleToSandboxRole: (workspaceRole: string) => SandboxPermissionLevel;
|
|
1608
624
|
}
|
|
1609
625
|
/** Resolve adding a user with a specific role to a sandbox and return the operation outcome */
|
|
1610
|
-
declare function syncSandboxMemberAdd(box: SandboxInstance, seam: MemberSyncSeam, userId: string, role: string): Promise<Outcome<void>>;
|
|
626
|
+
export declare function syncSandboxMemberAdd(box: SandboxInstance, seam: MemberSyncSeam, userId: string, role: string): Promise<Outcome<void>>;
|
|
1611
627
|
/** Remove a member from the sandbox while preserving their home directory and handle the outcome */
|
|
1612
|
-
declare function syncSandboxMemberRemove(box: SandboxInstance, userId: string): Promise<Outcome<void>>;
|
|
628
|
+
export declare function syncSandboxMemberRemove(box: SandboxInstance, userId: string): Promise<Outcome<void>>;
|
|
1613
629
|
/** Synchronize a sandbox member's role by updating permissions based on the provided role mapping */
|
|
1614
|
-
declare function syncSandboxMemberRole(box: SandboxInstance, seam: MemberSyncSeam, userId: string, role: string): Promise<Outcome<void>>;
|
|
630
|
+
export declare function syncSandboxMemberRole(box: SandboxInstance, seam: MemberSyncSeam, userId: string, role: string): Promise<Outcome<void>>;
|
|
1615
631
|
/**
|
|
1616
632
|
* Write-only secret port: create, replace, and delete a secret by name.
|
|
1617
633
|
*
|
|
@@ -1620,19 +636,19 @@ declare function syncSandboxMemberRole(box: SandboxInstance, seam: MemberSyncSea
|
|
|
1620
636
|
* the sandbox as an environment variable. A `get` here could only ever return
|
|
1621
637
|
* a value this process already held, so the port does not offer one.
|
|
1622
638
|
*/
|
|
1623
|
-
interface SecretStore {
|
|
639
|
+
export interface SecretStore {
|
|
1624
640
|
create: (name: string, value: string) => Promise<void>;
|
|
1625
641
|
update: (name: string, value: string) => Promise<void>;
|
|
1626
642
|
delete: (name: string) => Promise<void>;
|
|
1627
643
|
}
|
|
1628
644
|
/** Resolve a SecretStore interface using the provided SandboxRuntimeConfig shell */
|
|
1629
|
-
declare function secretStoreFromClient(shell: SandboxRuntimeConfig): SecretStore;
|
|
645
|
+
export declare function secretStoreFromClient(shell: SandboxRuntimeConfig): SecretStore;
|
|
1630
646
|
/** Resolve storing a secret by creating it, or replacing it when it exists */
|
|
1631
|
-
declare function storeSecret(store: SecretStore, name: string, value: string): Promise<Outcome<void>>;
|
|
647
|
+
export declare function storeSecret(store: SecretStore, name: string, value: string): Promise<Outcome<void>>;
|
|
1632
648
|
/** Delete a secret by name from the given secret store and return the operation outcome */
|
|
1633
|
-
declare function deleteSecret(store: SecretStore, name: string): Promise<Outcome<void>>;
|
|
649
|
+
export declare function deleteSecret(store: SecretStore, name: string): Promise<Outcome<void>>;
|
|
1634
650
|
/** Represent a token with its expiration date and associated scope */
|
|
1635
|
-
interface ScopedTokenResult {
|
|
651
|
+
export interface ScopedTokenResult {
|
|
1636
652
|
token: string;
|
|
1637
653
|
expiresAt: Date;
|
|
1638
654
|
scope: ScopedTokenScope;
|
|
@@ -1642,9 +658,9 @@ interface ScopedTokenResult {
|
|
|
1642
658
|
* proxy a narrowed credential). Uses the SDK's native `box.mintScopedToken`,
|
|
1643
659
|
* which normalizes `expiresAt` to a Date — no hand-rolled wire call.
|
|
1644
660
|
*/
|
|
1645
|
-
declare function mintSandboxScopedToken(box: SandboxInstance, options: MintScopedTokenOptions): Promise<Outcome<ScopedTokenResult>>;
|
|
661
|
+
export declare function mintSandboxScopedToken(box: SandboxInstance, options: MintScopedTokenOptions): Promise<Outcome<ScopedTokenResult>>;
|
|
1646
662
|
/** Define options to manage deterministic session resumption and turn idempotency in sandboxed drive turns */
|
|
1647
|
-
interface DriveSandboxTurnOptions extends StreamSandboxPromptOptions {
|
|
663
|
+
export interface DriveSandboxTurnOptions extends StreamSandboxPromptOptions {
|
|
1648
664
|
/** Deterministic resume key — required. Every tick for the same logical turn
|
|
1649
665
|
* MUST reuse it so a crash + re-drive finds the in-flight session instead of
|
|
1650
666
|
* starting a second agent run. */
|
|
@@ -1655,9 +671,9 @@ interface DriveSandboxTurnOptions extends StreamSandboxPromptOptions {
|
|
|
1655
671
|
wallCapMs?: number;
|
|
1656
672
|
}
|
|
1657
673
|
/** Resolve a sandbox turn by processing a message with given configuration and options */
|
|
1658
|
-
declare function driveSandboxTurn(shell: SandboxRuntimeConfig, box: SandboxInstance, message: string | PromptInputPart[], options: DriveSandboxTurnOptions): Promise<Outcome<TurnDriveResult>>;
|
|
674
|
+
export declare function driveSandboxTurn(shell: SandboxRuntimeConfig, box: SandboxInstance, message: string | PromptInputPart[], options: DriveSandboxTurnOptions): Promise<Outcome<TurnDriveResult>>;
|
|
1659
675
|
/** Define transitions marking the start or finish of a sandbox step with associated details */
|
|
1660
|
-
type SandboxStepTransition = {
|
|
676
|
+
export type SandboxStepTransition = {
|
|
1661
677
|
kind: 'step-start';
|
|
1662
678
|
} | {
|
|
1663
679
|
kind: 'step-finish';
|
|
@@ -1665,10 +681,12 @@ type SandboxStepTransition = {
|
|
|
1665
681
|
severed: boolean;
|
|
1666
682
|
};
|
|
1667
683
|
/** Resolve the severed stream event to a corresponding sandbox step transition or null */
|
|
1668
|
-
declare function classifySeveredStream(event: unknown): SandboxStepTransition | null;
|
|
684
|
+
export declare function classifySeveredStream(event: unknown): SandboxStepTransition | null;
|
|
1669
685
|
/** Determine if an event is a terminal prompt event with type 'result' or 'done */
|
|
1670
|
-
declare function isTerminalPromptEvent(event: unknown): boolean;
|
|
686
|
+
export declare function isTerminalPromptEvent(event: unknown): boolean;
|
|
1671
687
|
/** Resolve the interactive question text from a structured event or return null if none found */
|
|
1672
|
-
declare function detectInteractiveQuestion(event: unknown): string | null;
|
|
1673
|
-
|
|
1674
|
-
export
|
|
688
|
+
export declare function detectInteractiveQuestion(event: unknown): string | null;
|
|
689
|
+
export * from './workspace-sandbox-manager';
|
|
690
|
+
export * from './terminal-connection';
|
|
691
|
+
export * from './prewarm';
|
|
692
|
+
export * from './prewarm-claim-d1';
|