@kortix/sdk 0.13.4 → 0.13.7
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 +63 -6
- package/dist/browser/cache/idb-sync-cache.d.ts +19 -1
- package/dist/browser/cache/idb-sync-cache.d.ts.map +1 -1
- package/dist/browser/cache/idb-sync-cache.js +39 -4
- package/dist/browser/cache/idb-sync-cache.js.map +1 -1
- package/dist/browser/session-sync/server-transcript-mirror.d.ts +82 -0
- package/dist/browser/session-sync/server-transcript-mirror.d.ts.map +1 -0
- package/dist/browser/session-sync/server-transcript-mirror.js +143 -0
- package/dist/browser/session-sync/server-transcript-mirror.js.map +1 -0
- package/dist/browser/session-sync/session-sync-registry.d.ts +11 -1
- package/dist/browser/session-sync/session-sync-registry.d.ts.map +1 -1
- package/dist/browser/session-sync/session-sync-registry.js +117 -9
- package/dist/browser/session-sync/session-sync-registry.js.map +1 -1
- package/dist/browser/session-sync/visibility.d.ts +19 -0
- package/dist/browser/session-sync/visibility.d.ts.map +1 -0
- package/dist/browser/session-sync/visibility.js +16 -0
- package/dist/browser/session-sync/visibility.js.map +1 -0
- package/dist/browser/stores/sandbox-connection-store.d.ts +13 -1
- package/dist/browser/stores/sandbox-connection-store.d.ts.map +1 -1
- package/dist/browser/stores/sandbox-connection-store.js +6 -3
- package/dist/browser/stores/sandbox-connection-store.js.map +1 -1
- package/dist/browser/stores/session-working-store.d.ts +10 -5
- package/dist/browser/stores/session-working-store.d.ts.map +1 -1
- package/dist/browser/stores/session-working-store.js +32 -8
- package/dist/browser/stores/session-working-store.js.map +1 -1
- package/dist/browser/stores/sync-store.d.ts +56 -2
- package/dist/browser/stores/sync-store.d.ts.map +1 -1
- package/dist/browser/stores/sync-store.js +682 -402
- package/dist/browser/stores/sync-store.js.map +1 -1
- package/dist/core/auth/app-viewer.d.ts +57 -0
- package/dist/core/auth/app-viewer.d.ts.map +1 -0
- package/dist/core/auth/app-viewer.js +82 -0
- package/dist/core/auth/app-viewer.js.map +1 -0
- package/dist/core/auth/session.d.ts +45 -0
- package/dist/core/auth/session.d.ts.map +1 -0
- package/dist/core/auth/session.js +113 -0
- package/dist/core/auth/session.js.map +1 -0
- package/dist/core/client/kortix.d.ts +37 -29
- package/dist/core/client/kortix.d.ts.map +1 -1
- package/dist/core/client/kortix.js +61 -8
- package/dist/core/client/kortix.js.map +1 -1
- package/dist/core/http/config.d.ts +4 -2
- package/dist/core/http/config.d.ts.map +1 -1
- package/dist/core/http/config.js.map +1 -1
- package/dist/core/http/opencode-errors.d.ts +17 -0
- package/dist/core/http/opencode-errors.d.ts.map +1 -1
- package/dist/core/http/opencode-errors.js +25 -0
- package/dist/core/http/opencode-errors.js.map +1 -1
- package/dist/core/rest/platform-client/auth.d.ts +120 -0
- package/dist/core/rest/platform-client/auth.d.ts.map +1 -0
- package/dist/core/rest/platform-client/auth.js +98 -0
- package/dist/core/rest/platform-client/auth.js.map +1 -0
- package/dist/core/rest/platform-client/host-boundary.d.ts +5 -0
- package/dist/core/rest/platform-client/host-boundary.d.ts.map +1 -1
- package/dist/core/rest/platform-client/host-boundary.js.map +1 -1
- package/dist/core/rest/projects-client/accounts.d.ts +57 -0
- package/dist/core/rest/projects-client/accounts.d.ts.map +1 -1
- package/dist/core/rest/projects-client/accounts.js +31 -0
- package/dist/core/rest/projects-client/accounts.js.map +1 -1
- package/dist/core/rest/projects-client/apps.d.ts +9 -0
- package/dist/core/rest/projects-client/apps.d.ts.map +1 -1
- package/dist/core/rest/projects-client/apps.js.map +1 -1
- package/dist/core/rest/projects-client/billing.d.ts +2 -0
- package/dist/core/rest/projects-client/billing.d.ts.map +1 -1
- package/dist/core/rest/projects-client/billing.js.map +1 -1
- package/dist/core/rest/projects-client/channels.d.ts +0 -3
- package/dist/core/rest/projects-client/channels.d.ts.map +1 -1
- package/dist/core/rest/projects-client/channels.js +0 -6
- package/dist/core/rest/projects-client/channels.js.map +1 -1
- package/dist/core/rest/projects-client/connectors.d.ts +104 -19
- package/dist/core/rest/projects-client/connectors.d.ts.map +1 -1
- package/dist/core/rest/projects-client/connectors.js +56 -2
- package/dist/core/rest/projects-client/connectors.js.map +1 -1
- package/dist/core/rest/projects-client/index.d.ts +1 -2
- package/dist/core/rest/projects-client/index.d.ts.map +1 -1
- package/dist/core/rest/projects-client/index.js +1 -2
- package/dist/core/rest/projects-client/index.js.map +1 -1
- package/dist/core/rest/projects-client/oauth-clients.d.ts +47 -0
- package/dist/core/rest/projects-client/oauth-clients.d.ts.map +1 -0
- package/dist/core/rest/projects-client/oauth-clients.js +33 -0
- package/dist/core/rest/projects-client/oauth-clients.js.map +1 -0
- package/dist/core/rest/projects-client/projects.d.ts +23 -6
- package/dist/core/rest/projects-client/projects.d.ts.map +1 -1
- package/dist/core/rest/projects-client/projects.js +6 -3
- package/dist/core/rest/projects-client/projects.js.map +1 -1
- package/dist/core/rest/projects-client/session-sandbox.d.ts +52 -0
- package/dist/core/rest/projects-client/session-sandbox.d.ts.map +1 -1
- package/dist/core/rest/projects-client/session-sandbox.js.map +1 -1
- package/dist/core/rest/projects-client/sessions.d.ts +142 -34
- package/dist/core/rest/projects-client/sessions.d.ts.map +1 -1
- package/dist/core/rest/projects-client/sessions.js +48 -19
- package/dist/core/rest/projects-client/sessions.js.map +1 -1
- package/dist/core/runtime/attachment-part.d.ts +26 -0
- package/dist/core/runtime/attachment-part.d.ts.map +1 -0
- package/dist/core/runtime/attachment-part.js +41 -0
- package/dist/core/runtime/attachment-part.js.map +1 -0
- package/dist/core/runtime/client.d.ts +4 -2
- package/dist/core/runtime/client.d.ts.map +1 -1
- package/dist/core/runtime/client.js +3 -2
- package/dist/core/runtime/client.js.map +1 -1
- package/dist/core/runtime/opencode-v2-event-aliases.d.ts +184 -0
- package/dist/core/runtime/opencode-v2-event-aliases.d.ts.map +1 -0
- package/dist/core/runtime/opencode-v2-event-aliases.js +2 -0
- package/dist/core/runtime/opencode-v2-event-aliases.js.map +1 -0
- package/dist/core/runtime/pty.d.ts +11 -1
- package/dist/core/runtime/pty.d.ts.map +1 -1
- package/dist/core/runtime/pty.js +19 -6
- package/dist/core/runtime/pty.js.map +1 -1
- package/dist/core/session/connection.d.ts +64 -0
- package/dist/core/session/connection.d.ts.map +1 -0
- package/dist/core/session/connection.js +36 -0
- package/dist/core/session/connection.js.map +1 -0
- package/dist/core/session/index.d.ts +2 -0
- package/dist/core/session/index.d.ts.map +1 -1
- package/dist/core/session/index.js +2 -0
- package/dist/core/session/index.js.map +1 -1
- package/dist/core/session/open-bundle.d.ts +110 -0
- package/dist/core/session/open-bundle.d.ts.map +1 -0
- package/dist/core/session/open-bundle.js +183 -0
- package/dist/core/session/open-bundle.js.map +1 -0
- package/dist/core/session/poll-owner.d.ts +35 -0
- package/dist/core/session/poll-owner.d.ts.map +1 -0
- package/dist/core/session/poll-owner.js +90 -0
- package/dist/core/session/poll-owner.js.map +1 -0
- package/dist/core/session/preview-auth.d.ts +25 -0
- package/dist/core/session/preview-auth.d.ts.map +1 -1
- package/dist/core/session/preview-auth.js +31 -1
- package/dist/core/session/preview-auth.js.map +1 -1
- package/dist/core/session/preview-config.d.ts +26 -0
- package/dist/core/session/preview-config.d.ts.map +1 -0
- package/dist/core/session/preview-config.js +95 -0
- package/dist/core/session/preview-config.js.map +1 -0
- package/dist/core/session/preview-options.d.ts +25 -0
- package/dist/core/session/preview-options.d.ts.map +1 -0
- package/dist/core/session/preview-options.js +45 -0
- package/dist/core/session/preview-options.js.map +1 -0
- package/dist/core/session/preview.d.ts +8 -3
- package/dist/core/session/preview.d.ts.map +1 -1
- package/dist/core/session/preview.js +11 -4
- package/dist/core/session/preview.js.map +1 -1
- package/dist/core/session/rewind.d.ts +67 -24
- package/dist/core/session/rewind.d.ts.map +1 -1
- package/dist/core/session/rewind.js +74 -26
- package/dist/core/session/rewind.js.map +1 -1
- package/dist/core/session/server-store/active.d.ts +10 -12
- package/dist/core/session/server-store/active.d.ts.map +1 -1
- package/dist/core/session/server-store/active.js +11 -9
- package/dist/core/session/server-store/active.js.map +1 -1
- package/dist/core/session/server-store/url-helpers.d.ts +11 -2
- package/dist/core/session/server-store/url-helpers.d.ts.map +1 -1
- package/dist/core/session/server-store/url-helpers.js +11 -2
- package/dist/core/session/server-store/url-helpers.js.map +1 -1
- package/dist/core/session/static-file-preview.d.ts +50 -0
- package/dist/core/session/static-file-preview.d.ts.map +1 -0
- package/dist/core/session/static-file-preview.js +91 -0
- package/dist/core/session/static-file-preview.js.map +1 -0
- package/dist/core/session/url.d.ts +25 -2
- package/dist/core/session/url.d.ts.map +1 -1
- package/dist/core/session/url.js +87 -11
- package/dist/core/session/url.js.map +1 -1
- package/dist/core/session/wake-escalation.d.ts +188 -0
- package/dist/core/session/wake-escalation.d.ts.map +1 -0
- package/dist/core/session/wake-escalation.js +241 -0
- package/dist/core/session/wake-escalation.js.map +1 -0
- package/dist/core/session/working.d.ts +107 -2
- package/dist/core/session/working.d.ts.map +1 -1
- package/dist/core/session/working.js +206 -7
- package/dist/core/session/working.js.map +1 -1
- package/dist/core/session-sync/durable-log.d.ts +96 -0
- package/dist/core/session-sync/durable-log.d.ts.map +1 -0
- package/dist/core/session-sync/durable-log.js +94 -0
- package/dist/core/session-sync/durable-log.js.map +1 -0
- package/dist/core/session-sync/fragment.d.ts +27 -0
- package/dist/core/session-sync/fragment.d.ts.map +1 -0
- package/dist/core/session-sync/fragment.js +24 -0
- package/dist/core/session-sync/fragment.js.map +1 -0
- package/dist/core/session-sync/session-sync-controller.d.ts +117 -11
- package/dist/core/session-sync/session-sync-controller.d.ts.map +1 -1
- package/dist/core/session-sync/session-sync-controller.js +278 -26
- package/dist/core/session-sync/session-sync-controller.js.map +1 -1
- package/dist/core/stream/keepalive.d.ts +17 -0
- package/dist/core/stream/keepalive.d.ts.map +1 -0
- package/dist/core/stream/keepalive.js +19 -0
- package/dist/core/stream/keepalive.js.map +1 -0
- package/dist/core/turns/grouping.d.ts.map +1 -1
- package/dist/core/turns/grouping.js +73 -23
- package/dist/core/turns/grouping.js.map +1 -1
- package/dist/core/turns/types.d.ts +5 -0
- package/dist/core/turns/types.d.ts.map +1 -1
- package/dist/index.d.ts +16 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -1
- package/dist/kortix.esm.min.js +25 -25
- package/dist/kortix.global.js +25 -25
- package/dist/node/app-viewer.d.ts +41 -0
- package/dist/node/app-viewer.d.ts.map +1 -0
- package/dist/node/app-viewer.js +150 -0
- package/dist/node/app-viewer.js.map +1 -0
- package/dist/node/auth.d.ts +84 -0
- package/dist/node/auth.d.ts.map +1 -0
- package/dist/node/auth.js +414 -0
- package/dist/node/auth.js.map +1 -0
- package/dist/node/server.d.ts +19 -0
- package/dist/node/server.d.ts.map +1 -1
- package/dist/node/server.js +13 -1
- package/dist/node/server.js.map +1 -1
- package/dist/platform/auth-core.d.ts +13 -1
- package/dist/platform/auth-core.d.ts.map +1 -1
- package/dist/platform/auth-core.js +13 -1
- package/dist/platform/auth-core.js.map +1 -1
- package/dist/react/bedrock-invokable.d.ts +58 -0
- package/dist/react/bedrock-invokable.d.ts.map +1 -0
- package/dist/react/bedrock-invokable.js +83 -0
- package/dist/react/bedrock-invokable.js.map +1 -0
- package/dist/react/index.d.ts +3 -0
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +7 -0
- package/dist/react/index.js.map +1 -1
- package/dist/react/model-flatten.d.ts +14 -1
- package/dist/react/model-flatten.d.ts.map +1 -1
- package/dist/react/model-flatten.js +3 -4
- package/dist/react/model-flatten.js.map +1 -1
- package/dist/react/opencode.d.ts +3 -1
- package/dist/react/opencode.d.ts.map +1 -1
- package/dist/react/opencode.js +5 -1
- package/dist/react/opencode.js.map +1 -1
- package/dist/react/provider-selection.d.ts +58 -0
- package/dist/react/provider-selection.d.ts.map +1 -1
- package/dist/react/provider-selection.js +253 -2
- package/dist/react/provider-selection.js.map +1 -1
- package/dist/react/session-start-giveup.d.ts +12 -0
- package/dist/react/session-start-giveup.d.ts.map +1 -0
- package/dist/react/session-start-giveup.js +13 -0
- package/dist/react/session-start-giveup.js.map +1 -0
- package/dist/react/session-title-sync.d.ts.map +1 -1
- package/dist/react/session-title-sync.js +15 -5
- package/dist/react/session-title-sync.js.map +1 -1
- package/dist/react/sign-in-with-kortix.d.ts +346 -0
- package/dist/react/sign-in-with-kortix.d.ts.map +1 -0
- package/dist/react/sign-in-with-kortix.js +65 -0
- package/dist/react/sign-in-with-kortix.js.map +1 -0
- package/dist/react/use-admin-accounts.d.ts +36 -1
- package/dist/react/use-admin-accounts.d.ts.map +1 -1
- package/dist/react/use-admin-accounts.js +19 -0
- package/dist/react/use-admin-accounts.js.map +1 -1
- package/dist/react/use-gateway-routing-policy.d.ts +1 -0
- package/dist/react/use-gateway-routing-policy.d.ts.map +1 -1
- package/dist/react/use-gateway-routing-policy.js +12 -1
- package/dist/react/use-gateway-routing-policy.js.map +1 -1
- package/dist/react/use-kortix-app-viewer.d.ts +13 -0
- package/dist/react/use-kortix-app-viewer.d.ts.map +1 -0
- package/dist/react/use-kortix-app-viewer.js +29 -0
- package/dist/react/use-kortix-app-viewer.js.map +1 -0
- package/dist/react/use-model-defaults.d.ts +7 -0
- package/dist/react/use-model-defaults.d.ts.map +1 -1
- package/dist/react/use-model-defaults.js +7 -1
- package/dist/react/use-model-defaults.js.map +1 -1
- package/dist/react/use-model-enablement.d.ts.map +1 -1
- package/dist/react/use-model-enablement.js +5 -1
- package/dist/react/use-model-enablement.js.map +1 -1
- package/dist/react/use-model-store.d.ts +31 -0
- package/dist/react/use-model-store.d.ts.map +1 -1
- package/dist/react/use-model-store.js +31 -2
- package/dist/react/use-model-store.js.map +1 -1
- package/dist/react/use-opencode-events/handle-event.d.ts.map +1 -1
- package/dist/react/use-opencode-events/handle-event.js +26 -0
- package/dist/react/use-opencode-events/handle-event.js.map +1 -1
- package/dist/react/use-opencode-events/helpers.d.ts +49 -5
- package/dist/react/use-opencode-events/helpers.d.ts.map +1 -1
- package/dist/react/use-opencode-events/helpers.js +54 -6
- package/dist/react/use-opencode-events/helpers.js.map +1 -1
- package/dist/react/use-opencode-events/index.d.ts.map +1 -1
- package/dist/react/use-opencode-events/index.js +80 -8
- package/dist/react/use-opencode-events/index.js.map +1 -1
- package/dist/react/use-opencode-events/rehydrate-targets.d.ts +18 -0
- package/dist/react/use-opencode-events/rehydrate-targets.d.ts.map +1 -0
- package/dist/react/use-opencode-events/rehydrate-targets.js +20 -0
- package/dist/react/use-opencode-events/rehydrate-targets.js.map +1 -0
- package/dist/react/use-opencode-events/stream-revival.d.ts +37 -0
- package/dist/react/use-opencode-events/stream-revival.d.ts.map +1 -0
- package/dist/react/use-opencode-events/stream-revival.js +53 -0
- package/dist/react/use-opencode-events/stream-revival.js.map +1 -0
- package/dist/react/use-opencode-events/use-event-stream-refs.d.ts.map +1 -1
- package/dist/react/use-opencode-events/use-event-stream-refs.js +14 -2
- package/dist/react/use-opencode-events/use-event-stream-refs.js.map +1 -1
- package/dist/react/use-opencode-local.d.ts.map +1 -1
- package/dist/react/use-opencode-local.js +27 -8
- package/dist/react/use-opencode-local.js.map +1 -1
- package/dist/react/use-opencode-pty.d.ts +7 -1
- package/dist/react/use-opencode-pty.d.ts.map +1 -1
- package/dist/react/use-opencode-pty.js +6 -2
- package/dist/react/use-opencode-pty.js.map +1 -1
- package/dist/react/use-opencode-sessions/agents.d.ts.map +1 -1
- package/dist/react/use-opencode-sessions/agents.js +13 -2
- package/dist/react/use-opencode-sessions/agents.js.map +1 -1
- package/dist/react/use-opencode-sessions/commands.d.ts +12 -0
- package/dist/react/use-opencode-sessions/commands.d.ts.map +1 -1
- package/dist/react/use-opencode-sessions/commands.js +15 -3
- package/dist/react/use-opencode-sessions/commands.js.map +1 -1
- package/dist/react/use-opencode-sessions/index.d.ts +1 -0
- package/dist/react/use-opencode-sessions/index.d.ts.map +1 -1
- package/dist/react/use-opencode-sessions/index.js +1 -0
- package/dist/react/use-opencode-sessions/index.js.map +1 -1
- package/dist/react/use-opencode-sessions/keys.d.ts +8 -0
- package/dist/react/use-opencode-sessions/keys.d.ts.map +1 -1
- package/dist/react/use-opencode-sessions/keys.js +8 -0
- package/dist/react/use-opencode-sessions/keys.js.map +1 -1
- package/dist/react/use-opencode-sessions/providers.d.ts.map +1 -1
- package/dist/react/use-opencode-sessions/providers.js +56 -5
- package/dist/react/use-opencode-sessions/providers.js.map +1 -1
- package/dist/react/use-opencode-sessions/shared.d.ts +23 -0
- package/dist/react/use-opencode-sessions/shared.d.ts.map +1 -1
- package/dist/react/use-opencode-sessions/shared.js +31 -0
- package/dist/react/use-opencode-sessions/shared.js.map +1 -1
- package/dist/react/use-opencode-sessions/vcs.d.ts +28 -0
- package/dist/react/use-opencode-sessions/vcs.d.ts.map +1 -0
- package/dist/react/use-opencode-sessions/vcs.js +42 -0
- package/dist/react/use-opencode-sessions/vcs.js.map +1 -0
- package/dist/react/use-poll-owner.d.ts +14 -0
- package/dist/react/use-poll-owner.d.ts.map +1 -0
- package/dist/react/use-poll-owner.js +32 -0
- package/dist/react/use-poll-owner.js.map +1 -0
- package/dist/react/use-project-llm-gateway.d.ts +27 -0
- package/dist/react/use-project-llm-gateway.d.ts.map +1 -0
- package/dist/react/use-project-llm-gateway.js +41 -0
- package/dist/react/use-project-llm-gateway.js.map +1 -0
- package/dist/react/use-project-models.d.ts +9 -0
- package/dist/react/use-project-models.d.ts.map +1 -1
- package/dist/react/use-project-models.js +24 -1
- package/dist/react/use-project-models.js.map +1 -1
- package/dist/react/use-runtime-reconnect.d.ts +11 -0
- package/dist/react/use-runtime-reconnect.d.ts.map +1 -1
- package/dist/react/use-runtime-reconnect.js +34 -3
- package/dist/react/use-runtime-reconnect.js.map +1 -1
- package/dist/react/use-session-prompts.d.ts +53 -3
- package/dist/react/use-session-prompts.d.ts.map +1 -1
- package/dist/react/use-session-prompts.js +133 -21
- package/dist/react/use-session-prompts.js.map +1 -1
- package/dist/react/use-session-send.d.ts +17 -0
- package/dist/react/use-session-send.d.ts.map +1 -1
- package/dist/react/use-session-send.js +54 -5
- package/dist/react/use-session-send.js.map +1 -1
- package/dist/react/use-session-start-give-up.d.ts +20 -0
- package/dist/react/use-session-start-give-up.d.ts.map +1 -0
- package/dist/react/use-session-start-give-up.js +60 -0
- package/dist/react/use-session-start-give-up.js.map +1 -0
- package/dist/react/use-session-sync.d.ts +35 -1
- package/dist/react/use-session-sync.d.ts.map +1 -1
- package/dist/react/use-session-sync.js +135 -53
- package/dist/react/use-session-sync.js.map +1 -1
- package/dist/react/use-session-working.d.ts +55 -0
- package/dist/react/use-session-working.d.ts.map +1 -1
- package/dist/react/use-session-working.js +114 -13
- package/dist/react/use-session-working.js.map +1 -1
- package/dist/react/use-session.d.ts +13 -13
- package/dist/react/use-session.d.ts.map +1 -1
- package/dist/react/use-session.js +74 -53
- package/dist/react/use-session.js.map +1 -1
- package/dist/react/use-static-file-preview.d.ts +12 -0
- package/dist/react/use-static-file-preview.d.ts.map +1 -0
- package/dist/react/use-static-file-preview.js +119 -0
- package/dist/react/use-static-file-preview.js.map +1 -0
- package/dist/react/use-wake-escalation.d.ts +51 -0
- package/dist/react/use-wake-escalation.d.ts.map +1 -0
- package/dist/react/use-wake-escalation.js +62 -0
- package/dist/react/use-wake-escalation.js.map +1 -0
- package/package.json +6 -4
- package/dist/browser/session-sync/session-transcript-cache.d.ts +0 -79
- package/dist/browser/session-sync/session-transcript-cache.d.ts.map +0 -1
- package/dist/browser/session-sync/session-transcript-cache.js +0 -91
- package/dist/browser/session-sync/session-transcript-cache.js.map +0 -1
- package/dist/core/rest/projects-client/public-voice-join.d.ts +0 -59
- package/dist/core/rest/projects-client/public-voice-join.d.ts.map +0 -1
- package/dist/core/rest/projects-client/public-voice-join.js +0 -64
- package/dist/core/rest/projects-client/public-voice-join.js.map +0 -1
- package/dist/core/rest/projects-client/transcription.d.ts +0 -5
- package/dist/core/rest/projects-client/transcription.d.ts.map +0 -1
- package/dist/core/rest/projects-client/transcription.js +0 -14
- package/dist/core/rest/projects-client/transcription.js.map +0 -1
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The wake escalation ladder — what a session view does when bringing a
|
|
3
|
+
* runtime up takes longer than it should.
|
|
4
|
+
*
|
|
5
|
+
* ## The failure this replaces
|
|
6
|
+
*
|
|
7
|
+
* Opening a stopped session starts a wake. The old model gave that wake a FIXED
|
|
8
|
+
* budget: the server's own `RUNTIME_WAKE_LEASE_MS` (240s,
|
|
9
|
+
* `apps/api/src/projects/session-lifecycle/runtime-wake-fence.ts:10`), after
|
|
10
|
+
* which maintenance stamps `stopReason: 'runtime_wake_failed'` and every
|
|
11
|
+
* subsequent `/start` short-circuits to a terminal payload
|
|
12
|
+
* (`apps/api/src/projects/routes/shared.ts:672-694`)
|
|
13
|
+
*
|
|
14
|
+
* "Couldn't start session <id> — The session runtime did not become
|
|
15
|
+
* reachable. Restart the session to try again."
|
|
16
|
+
*
|
|
17
|
+
* Measured on Essentia (2026-08-26, box `inqwpv4a1cc1kynlg46k8`): that card
|
|
18
|
+
* painted while the box was SECONDS from ready — its daemon logged
|
|
19
|
+
* `opencode ready` at 06:10:02, right after the budget expired. The card is a
|
|
20
|
+
* dead end with no auto-recovery, and the human's fix is always the same one
|
|
21
|
+
* click: "clicking restart made it work instantly". Two more recurrences
|
|
22
|
+
* followed, both during a post-deploy image rebuild — i.e. this class recurs on
|
|
23
|
+
* every ops event that slows a provider resume.
|
|
24
|
+
*
|
|
25
|
+
* ## The two rules that fix it
|
|
26
|
+
*
|
|
27
|
+
* 1. **A budget measures SILENCE, not elapsed time.** A wake that is visibly
|
|
28
|
+
* advancing — provider state moving, daemon boot phases changing, health
|
|
29
|
+
* improving — has not failed, however long it takes. Only a bounded window
|
|
30
|
+
* with ZERO observable change is evidence of a wedge. So the clock here is
|
|
31
|
+
* reset by any change to {@link WakeObservation.progress} and the elapsed
|
|
32
|
+
* total is never consulted.
|
|
33
|
+
*
|
|
34
|
+
* 2. **Escalate through the ladder the human uses, and only then give up.**
|
|
35
|
+
* A quiet `/start` retry first (free, and it heals a row that recovered on
|
|
36
|
+
* its own), then the RESTART the user would have clicked — bounded to
|
|
37
|
+
* {@link WAKE_MAX_RESTARTS}. The terminal card is what remains after the
|
|
38
|
+
* ladder is exhausted, and it then has to name what was tried
|
|
39
|
+
* ({@link wakeEscalationAttemptSummary}).
|
|
40
|
+
*
|
|
41
|
+
* A blanket "just restart it by default" was considered and REJECTED: it
|
|
42
|
+
* destroys fast warm resumes (a Platinum CoW resume reaches `running` in ~1.9s)
|
|
43
|
+
* by throwing away a box that was about to answer.
|
|
44
|
+
*
|
|
45
|
+
* ## Why `runtimeReachable` is a separate input from `waking`
|
|
46
|
+
*
|
|
47
|
+
* The session row is NOT proof the runtime is up. Observed on Essentia the same
|
|
48
|
+
* day: `POST …/start` answered 202 and the row stayed `running` for 5+ minutes
|
|
49
|
+
* while the E2B resume had silently failed — the provider reported the sandbox
|
|
50
|
+
* `stopped` and the daemon proxy answered `503 sandbox_not_ready`. A ladder that
|
|
51
|
+
* treated `stage: 'ready'` as the end of the wake would sit there forever. So
|
|
52
|
+
* the wake ends when the RUNTIME ANSWERS (`/kortix/health`), not when the
|
|
53
|
+
* control plane says it should have.
|
|
54
|
+
*
|
|
55
|
+
* That reachability is also a LATCH: once a runtime has answered, this machine
|
|
56
|
+
* is done for the life of the session view. A box that drops mid-session is
|
|
57
|
+
* `useRuntimeReconnect`'s problem, and auto-restarting it would destroy the
|
|
58
|
+
* turn the user is watching.
|
|
59
|
+
*
|
|
60
|
+
* Pure and clock-free: every decision is a function of the passed state plus one
|
|
61
|
+
* observation. The React glue lives in `react/use-wake-escalation.ts`.
|
|
62
|
+
*/
|
|
63
|
+
/**
|
|
64
|
+
* How long a wake may show ZERO observable change before the ladder escalates.
|
|
65
|
+
*
|
|
66
|
+
* Sized against the measured wake profile rather than a guess: a cold resume is
|
|
67
|
+
* 18.9s (Daytona) / 24.5s (Platinum) end to end, and each phase of it produces
|
|
68
|
+
* an observable change, so a healthy wake never accumulates more than a few
|
|
69
|
+
* seconds of silence. 75s is comfortably past the slowest legitimate single
|
|
70
|
+
* phase (the server's own provider-confirmation grace is 90s but it emits
|
|
71
|
+
* `runtime_waking` throughout) while still being three times faster to react
|
|
72
|
+
* than the 240s lease that produced the incident.
|
|
73
|
+
*/
|
|
74
|
+
export const WAKE_NO_PROGRESS_MS = 75_000;
|
|
75
|
+
/**
|
|
76
|
+
* Automatic restarts the ladder may perform. Two, because the human fix that
|
|
77
|
+
* always works is one restart, and a second covers the case where the first
|
|
78
|
+
* landed during the same ops event (an image rebuild) that wedged the wake.
|
|
79
|
+
* Unbounded retries would be a restart loop against a genuinely dead provider.
|
|
80
|
+
*/
|
|
81
|
+
export const WAKE_MAX_RESTARTS = 2;
|
|
82
|
+
/**
|
|
83
|
+
* Minimum gap between two ladder actions.
|
|
84
|
+
*
|
|
85
|
+
* A server-declared wake failure short-circuits the no-progress window (there is
|
|
86
|
+
* nothing left to wait for), so without a floor the ladder would spend its whole
|
|
87
|
+
* budget inside one second. `POST /restart` plus its first `/start` take ~2.6s
|
|
88
|
+
* measured; 20s leaves the new attempt room to produce its first signal.
|
|
89
|
+
*/
|
|
90
|
+
export const WAKE_ESCALATION_COOLDOWN_MS = 20_000;
|
|
91
|
+
export function initialWakeEscalationState() {
|
|
92
|
+
return {
|
|
93
|
+
status: 'idle',
|
|
94
|
+
dispatch: 'none',
|
|
95
|
+
fingerprint: null,
|
|
96
|
+
lastProgressAtMs: null,
|
|
97
|
+
lastDispatchAtMs: null,
|
|
98
|
+
attempts: [],
|
|
99
|
+
msSinceProgress: 0,
|
|
100
|
+
settled: false,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Join the observable wake signals into one comparable value, dropping the ones
|
|
105
|
+
* that are not known yet.
|
|
106
|
+
*
|
|
107
|
+
* `null`/`undefined` are DROPPED rather than stringified so that a signal
|
|
108
|
+
* arriving for the first time (a sandbox row appearing, a health body parsing)
|
|
109
|
+
* reads as the progress it is, while a signal that is simply absent contributes
|
|
110
|
+
* nothing and cannot manufacture a change on its own.
|
|
111
|
+
*/
|
|
112
|
+
export function wakeProgressFingerprint(parts) {
|
|
113
|
+
return parts.filter((part) => part !== null && part !== undefined).join('|');
|
|
114
|
+
}
|
|
115
|
+
/** The next rung, or null when the ladder is spent. */
|
|
116
|
+
function nextStep(attempts, maxRestarts) {
|
|
117
|
+
if (attempts.length === 0)
|
|
118
|
+
return 'retry-start';
|
|
119
|
+
const restarts = attempts.filter((attempt) => attempt.step === 'restart').length;
|
|
120
|
+
return restarts < maxRestarts ? 'restart' : null;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Fold one observation into the ladder's state. Pure — same inputs, same output,
|
|
124
|
+
* no clock and no I/O.
|
|
125
|
+
*/
|
|
126
|
+
export function advanceWakeEscalation(state, observation, limits = {}) {
|
|
127
|
+
const noProgressMs = limits.noProgressMs ?? WAKE_NO_PROGRESS_MS;
|
|
128
|
+
const maxRestarts = limits.maxRestarts ?? WAKE_MAX_RESTARTS;
|
|
129
|
+
const cooldownMs = limits.cooldownMs ?? WAKE_ESCALATION_COOLDOWN_MS;
|
|
130
|
+
// The runtime answered. The wake is over, and nothing about it may leak into
|
|
131
|
+
// the next one. `settled` survives the reset: within one session view, a
|
|
132
|
+
// runtime that has answered is never woken again by this machine.
|
|
133
|
+
if (observation.runtimeReachable) {
|
|
134
|
+
return { ...initialWakeEscalationState(), settled: true };
|
|
135
|
+
}
|
|
136
|
+
// The host cannot classify the wake right now — PAUSE, do not forget.
|
|
137
|
+
//
|
|
138
|
+
// This is not hypothetical tidiness. `useRestartProjectSession` seeds the
|
|
139
|
+
// `/start` cache with `{stage: 'provisioning', sandbox: null}` the instant a
|
|
140
|
+
// restart is dispatched, and a null sandbox is exactly "cannot classify". If
|
|
141
|
+
// that cleared `attempts`, every rung the ladder fired would reset its own
|
|
142
|
+
// budget and `WAKE_MAX_RESTARTS` would bound nothing — a restart loop, which
|
|
143
|
+
// is strictly worse than the dead-end card this replaces.
|
|
144
|
+
//
|
|
145
|
+
// The silence clock IS cleared, so resuming re-baselines rather than
|
|
146
|
+
// escalating on the strength of a window the ladder never actually watched.
|
|
147
|
+
// The dispatch cooldown is deliberately kept: a pause must not become a way
|
|
148
|
+
// to fire two rungs back to back.
|
|
149
|
+
if (!observation.waking) {
|
|
150
|
+
return { ...state, dispatch: 'none', fingerprint: null, lastProgressAtMs: null, msSinceProgress: 0 };
|
|
151
|
+
}
|
|
152
|
+
// A runtime that already answered and later dropped is a mid-session
|
|
153
|
+
// reconnect, not a wake. Restarting it would destroy the live turn.
|
|
154
|
+
if (state.settled)
|
|
155
|
+
return { ...initialWakeEscalationState(), settled: true };
|
|
156
|
+
const previousProgressAtMs = state.lastProgressAtMs;
|
|
157
|
+
const first = previousProgressAtMs === null;
|
|
158
|
+
const changed = observation.progress !== state.fingerprint;
|
|
159
|
+
const lastProgressAtMs = previousProgressAtMs === null || changed ? observation.nowMs : previousProgressAtMs;
|
|
160
|
+
const msSinceProgress = Math.max(0, observation.nowMs - lastProgressAtMs);
|
|
161
|
+
const base = {
|
|
162
|
+
...state,
|
|
163
|
+
dispatch: 'none',
|
|
164
|
+
fingerprint: observation.progress,
|
|
165
|
+
lastProgressAtMs,
|
|
166
|
+
msSinceProgress,
|
|
167
|
+
status: state.attempts.length > 0 ? 'escalating' : 'waking',
|
|
168
|
+
};
|
|
169
|
+
if (state.status === 'exhausted')
|
|
170
|
+
return { ...base, status: 'exhausted' };
|
|
171
|
+
// A server-declared failure needs no window: the wake is over, only the
|
|
172
|
+
// ladder is left. Everything else waits out the silence.
|
|
173
|
+
const stalled = !first && !changed && msSinceProgress >= noProgressMs;
|
|
174
|
+
if (!observation.serverGaveUp && !stalled)
|
|
175
|
+
return base;
|
|
176
|
+
// One action per cooldown, whatever triggered it.
|
|
177
|
+
if (state.lastDispatchAtMs !== null &&
|
|
178
|
+
observation.nowMs - state.lastDispatchAtMs < cooldownMs) {
|
|
179
|
+
return base;
|
|
180
|
+
}
|
|
181
|
+
const step = nextStep(state.attempts, maxRestarts);
|
|
182
|
+
if (!step)
|
|
183
|
+
return { ...base, status: 'exhausted' };
|
|
184
|
+
return {
|
|
185
|
+
...base,
|
|
186
|
+
status: 'escalating',
|
|
187
|
+
dispatch: step,
|
|
188
|
+
attempts: [...state.attempts, { step, atMs: observation.nowMs }],
|
|
189
|
+
lastDispatchAtMs: observation.nowMs,
|
|
190
|
+
// The new attempt gets its own window: it has not been silent yet.
|
|
191
|
+
lastProgressAtMs: observation.nowMs,
|
|
192
|
+
msSinceProgress: 0,
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
const STEP_VERB = {
|
|
196
|
+
'retry-start': 'retrying',
|
|
197
|
+
restart: 'restarting',
|
|
198
|
+
};
|
|
199
|
+
/**
|
|
200
|
+
* The honest one-line status while the ladder is working, in the same voice as
|
|
201
|
+
* the boot-phase pill ("Waking the agent", "Connecting").
|
|
202
|
+
*
|
|
203
|
+
* Null while the first, ordinary wake is running — that wake already has honest
|
|
204
|
+
* copy and does not need a second component talking over it — and null once
|
|
205
|
+
* exhausted, where the terminal card takes over.
|
|
206
|
+
*/
|
|
207
|
+
export function wakeEscalationNote(state) {
|
|
208
|
+
if (state.status !== 'escalating')
|
|
209
|
+
return null;
|
|
210
|
+
const last = state.attempts[state.attempts.length - 1];
|
|
211
|
+
if (!last)
|
|
212
|
+
return null;
|
|
213
|
+
// The original wake is attempt 1, so the Nth ladder action is attempt N+1.
|
|
214
|
+
return `Still waking — ${STEP_VERB[last.step]} the runtime (attempt ${state.attempts.length + 1})`;
|
|
215
|
+
}
|
|
216
|
+
function countWord(count) {
|
|
217
|
+
if (count === 1)
|
|
218
|
+
return 'once';
|
|
219
|
+
if (count === 2)
|
|
220
|
+
return 'twice';
|
|
221
|
+
return `${count} times`;
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* What the ladder tried, for the terminal card. A dead end that cannot say what
|
|
225
|
+
* was already attempted invites the user to repeat it by hand.
|
|
226
|
+
*/
|
|
227
|
+
export function wakeEscalationAttemptSummary(state) {
|
|
228
|
+
if (state.status !== 'exhausted')
|
|
229
|
+
return null;
|
|
230
|
+
const restarts = state.attempts.filter((attempt) => attempt.step === 'restart').length;
|
|
231
|
+
const retried = state.attempts.some((attempt) => attempt.step === 'retry-start');
|
|
232
|
+
if (!retried && restarts === 0)
|
|
233
|
+
return null;
|
|
234
|
+
const parts = [];
|
|
235
|
+
if (retried)
|
|
236
|
+
parts.push('re-issuing the wake');
|
|
237
|
+
if (restarts > 0)
|
|
238
|
+
parts.push(`restarting the session ${countWord(restarts)}`);
|
|
239
|
+
return `Tried: ${parts.join(', then ')}.`;
|
|
240
|
+
}
|
|
241
|
+
//# sourceMappingURL=wake-escalation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wake-escalation.js","sourceRoot":"","sources":["../../../src/core/session/wake-escalation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6DG;AAEH;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,MAAM,CAAC;AAE1C;;;;;GAKG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC;AAEnC;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAG,MAAM,CAAC;AA4ElD,MAAM,UAAU,0BAA0B;IACxC,OAAO;QACL,MAAM,EAAE,MAAM;QACd,QAAQ,EAAE,MAAM;QAChB,WAAW,EAAE,IAAI;QACjB,gBAAgB,EAAE,IAAI;QACtB,gBAAgB,EAAE,IAAI;QACtB,QAAQ,EAAE,EAAE;QACZ,eAAe,EAAE,CAAC;QAClB,OAAO,EAAE,KAAK;KACf,CAAC;AACJ,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,uBAAuB,CACrC,KAAgE;IAEhE,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,SAAS,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/E,CAAC;AAED,uDAAuD;AACvD,SAAS,QAAQ,CACf,QAAgC,EAChC,WAAmB;IAEnB,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,aAAa,CAAC;IAChD,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,MAAM,CAAC;IACjF,OAAO,QAAQ,GAAG,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC;AACnD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CACnC,KAA0B,EAC1B,WAA4B,EAC5B,SAA+B,EAAE;IAEjC,MAAM,YAAY,GAAG,MAAM,CAAC,YAAY,IAAI,mBAAmB,CAAC;IAChE,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,IAAI,iBAAiB,CAAC;IAC5D,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,IAAI,2BAA2B,CAAC;IAEpE,6EAA6E;IAC7E,yEAAyE;IACzE,kEAAkE;IAClE,IAAI,WAAW,CAAC,gBAAgB,EAAE,CAAC;QACjC,OAAO,EAAE,GAAG,0BAA0B,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC5D,CAAC;IACD,sEAAsE;IACtE,EAAE;IACF,0EAA0E;IAC1E,6EAA6E;IAC7E,6EAA6E;IAC7E,2EAA2E;IAC3E,6EAA6E;IAC7E,0DAA0D;IAC1D,EAAE;IACF,qEAAqE;IACrE,4EAA4E;IAC5E,4EAA4E;IAC5E,kCAAkC;IAClC,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC;QACxB,OAAO,EAAE,GAAG,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,gBAAgB,EAAE,IAAI,EAAE,eAAe,EAAE,CAAC,EAAE,CAAC;IACvG,CAAC;IACD,qEAAqE;IACrE,oEAAoE;IACpE,IAAI,KAAK,CAAC,OAAO;QAAE,OAAO,EAAE,GAAG,0BAA0B,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAE7E,MAAM,oBAAoB,GAAG,KAAK,CAAC,gBAAgB,CAAC;IACpD,MAAM,KAAK,GAAG,oBAAoB,KAAK,IAAI,CAAC;IAC5C,MAAM,OAAO,GAAG,WAAW,CAAC,QAAQ,KAAK,KAAK,CAAC,WAAW,CAAC;IAC3D,MAAM,gBAAgB,GACpB,oBAAoB,KAAK,IAAI,IAAI,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,oBAAoB,CAAC;IACtF,MAAM,eAAe,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,WAAW,CAAC,KAAK,GAAG,gBAAgB,CAAC,CAAC;IAC1E,MAAM,IAAI,GAAwB;QAChC,GAAG,KAAK;QACR,QAAQ,EAAE,MAAM;QAChB,WAAW,EAAE,WAAW,CAAC,QAAQ;QACjC,gBAAgB;QAChB,eAAe;QACf,MAAM,EAAE,KAAK,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ;KAC5D,CAAC;IAEF,IAAI,KAAK,CAAC,MAAM,KAAK,WAAW;QAAE,OAAO,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;IAE1E,wEAAwE;IACxE,yDAAyD;IACzD,MAAM,OAAO,GAAG,CAAC,KAAK,IAAI,CAAC,OAAO,IAAI,eAAe,IAAI,YAAY,CAAC;IACtE,IAAI,CAAC,WAAW,CAAC,YAAY,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAEvD,kDAAkD;IAClD,IACE,KAAK,CAAC,gBAAgB,KAAK,IAAI;QAC/B,WAAW,CAAC,KAAK,GAAG,KAAK,CAAC,gBAAgB,GAAG,UAAU,EACvD,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;IACnD,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;IAEnD,OAAO;QACL,GAAG,IAAI;QACP,MAAM,EAAE,YAAY;QACpB,QAAQ,EAAE,IAAI;QACd,QAAQ,EAAE,CAAC,GAAG,KAAK,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,WAAW,CAAC,KAAK,EAAE,CAAC;QAChE,gBAAgB,EAAE,WAAW,CAAC,KAAK;QACnC,mEAAmE;QACnE,gBAAgB,EAAE,WAAW,CAAC,KAAK;QACnC,eAAe,EAAE,CAAC;KACnB,CAAC;AACJ,CAAC;AAED,MAAM,SAAS,GAAuC;IACpD,aAAa,EAAE,UAAU;IACzB,OAAO,EAAE,YAAY;CACtB,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAA0B;IAC3D,IAAI,KAAK,CAAC,MAAM,KAAK,YAAY;QAAE,OAAO,IAAI,CAAC;IAC/C,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACvD,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IACvB,2EAA2E;IAC3E,OAAO,kBAAkB,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,yBAAyB,KAAK,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,GAAG,CAAC;AACrG,CAAC;AAED,SAAS,SAAS,CAAC,KAAa;IAC9B,IAAI,KAAK,KAAK,CAAC;QAAE,OAAO,MAAM,CAAC;IAC/B,IAAI,KAAK,KAAK,CAAC;QAAE,OAAO,OAAO,CAAC;IAChC,OAAO,GAAG,KAAK,QAAQ,CAAC;AAC1B,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,4BAA4B,CAAC,KAA0B;IACrE,IAAI,KAAK,CAAC,MAAM,KAAK,WAAW;QAAE,OAAO,IAAI,CAAC;IAC9C,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,MAAM,CAAC;IACvF,MAAM,OAAO,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,KAAK,aAAa,CAAC,CAAC;IACjF,IAAI,CAAC,OAAO,IAAI,QAAQ,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAC5C,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,OAAO;QAAE,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;IAC/C,IAAI,QAAQ,GAAG,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,0BAA0B,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IAC9E,OAAO,UAAU,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC;AAC5C,CAAC"}
|
|
@@ -92,6 +92,30 @@ export declare const STREAM_OBSERVATION_MAX_MS = 45000;
|
|
|
92
92
|
* Stop with its reply on screen for up to 45s.
|
|
93
93
|
*/
|
|
94
94
|
export declare const INBOX_OBSERVATION_MAX_MS = 10000;
|
|
95
|
+
/**
|
|
96
|
+
* How long a runtime `idle` frame may outrank the control plane's turn row.
|
|
97
|
+
*
|
|
98
|
+
* The ledger is closed by a SEPARATE daemon relay (`POST .../turn-stream`
|
|
99
|
+
* `kind:"end"`), so for a moment after the runtime goes idle the row is still
|
|
100
|
+
* open and a `/turn` read taken in that window honestly reports a turn that has
|
|
101
|
+
* finished. MEASURED 2026-08-21 on a healthy stack: the relay POST itself took
|
|
102
|
+
* 1765ms, while the idle frame reaches the tab immediately and triggers its own
|
|
103
|
+
* refetch that lands ~186ms later — squarely inside the gap. Without this the
|
|
104
|
+
* composer's Stop button and the turn shimmer came back ~200ms after the reply
|
|
105
|
+
* and stayed for the whole poll interval.
|
|
106
|
+
*
|
|
107
|
+
* BOUNDED, and this is the important half. An idle frame is NOT proof the turn
|
|
108
|
+
* ended: `session.error` is relayed as `idle` too ("errors terminate the
|
|
109
|
+
* response"), and OpenCode emits it while it is RETRYING a provider — a 429
|
|
110
|
+
* backoff, a transient upstream 5xx — with the turn still very much live. An
|
|
111
|
+
* unbounded rule therefore un-busied the composer mid-turn on every retry and
|
|
112
|
+
* held it that way until the next `busy` frame, which is a worse flicker than
|
|
113
|
+
* the one it fixes. Past this window the ledger is believed again, so a retry
|
|
114
|
+
* blip self-heals in seconds instead of lasting the stream's whole 45s life.
|
|
115
|
+
*
|
|
116
|
+
* Comfortably above the measured relay, far below a provider backoff.
|
|
117
|
+
*/
|
|
118
|
+
export declare const TURN_END_LEDGER_LAG_MS = 3000;
|
|
95
119
|
/**
|
|
96
120
|
* How long a stop this tab issued may bar a server read from reporting the
|
|
97
121
|
* turn it is ending.
|
|
@@ -105,9 +129,17 @@ export declare const INBOX_OBSERVATION_MAX_MS = 10000;
|
|
|
105
129
|
export declare const OPTIMISTIC_ABORT_MAX_MS = 15000;
|
|
106
130
|
/** This tab's own record that a prompt went out. */
|
|
107
131
|
export interface SendReceipt {
|
|
108
|
-
/** The submission's tab-local name — never sent anywhere.
|
|
109
|
-
* `working` state can say WHICH send it is standing on. */
|
|
132
|
+
/** The submission's tab-local name — never sent anywhere. */
|
|
110
133
|
messageId: string;
|
|
134
|
+
/**
|
|
135
|
+
* The user-message turn that owns the working indicator while this receipt
|
|
136
|
+
* is live. A direct idle send names itself. A send made during an existing
|
|
137
|
+
* response names that existing turn, so its new bubble remains pending.
|
|
138
|
+
*
|
|
139
|
+
* `undefined` preserves the original contract and falls back to
|
|
140
|
+
* `messageId`. `null` explicitly means the caller cannot identify the turn.
|
|
141
|
+
*/
|
|
142
|
+
turnId?: string | null;
|
|
111
143
|
/** ms epoch at which the send left this tab. */
|
|
112
144
|
atMs: number;
|
|
113
145
|
/**
|
|
@@ -157,14 +189,85 @@ export interface WorkingServerInput {
|
|
|
157
189
|
/** One observed runtime status frame, stamped when this tab observed it. */
|
|
158
190
|
export interface WorkingStreamInput {
|
|
159
191
|
type: 'busy' | 'retry' | 'idle';
|
|
192
|
+
/**
|
|
193
|
+
* WHO minted the frame. `'wire'` (or absent — the field is additive) means
|
|
194
|
+
* the runtime's own SSE frame reached this tab. `'local'` means the tab
|
|
195
|
+
* synthesized it: `reconcileMissingBusySessions` reading absence out of a
|
|
196
|
+
* status snapshot, `markSessionAbortedLocally` on `server.instance.disposed`,
|
|
197
|
+
* `clearSession` on a cache-ownership handoff.
|
|
198
|
+
*
|
|
199
|
+
* The distinction exists for exactly one rule: only the runtime's own idle
|
|
200
|
+
* frame may CONTRADICT the lifecycle authority (`endedByRuntime`, and the
|
|
201
|
+
* "fresher frame knows more" ordering over an open row). A local frame is an
|
|
202
|
+
* inference, and the veto it inherited is unbounded on purpose — so one
|
|
203
|
+
* fabricated idle discarded every fresh `/turn` read for the rest of a quiet
|
|
204
|
+
* turn: the busy indicator left, the composer swapped Stop for Send, and
|
|
205
|
+
* both came back only when the reply finally streamed (dev, 2026-08-24). A
|
|
206
|
+
* local frame may still ANSWER when nothing fresher exists — the repair for
|
|
207
|
+
* a missed terminal frame stays a repair — it just cannot overrule a source
|
|
208
|
+
* that can actually know.
|
|
209
|
+
*/
|
|
210
|
+
origin?: 'wire' | 'local';
|
|
211
|
+
atMs: number;
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* The last moment the RUNTIME'S OWN OUTPUT reached this tab for this session —
|
|
215
|
+
* a streamed part, a message. Stamped on observation, like every other input.
|
|
216
|
+
*
|
|
217
|
+
* Every other input here is an OBSERVER of the runtime: a `/turn` poll, a
|
|
218
|
+
* status frame, a health probe, an inbox read. Each can be dropped, throttled
|
|
219
|
+
* or aged out, and when one is, the projection has historically had to guess.
|
|
220
|
+
* This one is not an observer. Content arriving is not a report that the
|
|
221
|
+
* runtime is working — it IS the runtime working, and no report outranks it.
|
|
222
|
+
*
|
|
223
|
+
* Reported with a screen recording (essentia, 2026-08-23): a tool row with a
|
|
224
|
+
* live spinner and text growing on screen, and a composer showing its send
|
|
225
|
+
* arrow. Every observer had gone quiet; the only thing still speaking was the
|
|
226
|
+
* content, and nothing was listening to it.
|
|
227
|
+
*
|
|
228
|
+
* Content reaches the tab two ways, and both stamp this: pushed (a streamed
|
|
229
|
+
* part off the SSE wire) and PULLED (a liveness-poll tail read whose hydrate
|
|
230
|
+
* shows the transcript moved with its tail still open — `sync-store.hydrate`).
|
|
231
|
+
* The pull path is what answers when the wire itself is the thing that died
|
|
232
|
+
* (essentia, 2026-08-26: stream black-holed mid-turn, stale idle frame vetoing
|
|
233
|
+
* the open turn row, transcript minutes behind).
|
|
234
|
+
*/
|
|
235
|
+
export interface WorkingActivityInput {
|
|
160
236
|
atMs: number;
|
|
161
237
|
}
|
|
162
238
|
/** One read of the session's durable prompt inbox: how many rows the server is
|
|
163
239
|
* still going to run, and when that list was read. */
|
|
164
240
|
export interface WorkingInboxInput {
|
|
165
241
|
pending: number;
|
|
242
|
+
/** This tab's clock at ISSUE or RECEIVE time. The AGE stamp: it only ever
|
|
243
|
+
* meets `nowMs` — the same clock — in `INBOX_OBSERVATION_MAX_MS`. */
|
|
166
244
|
atMs: number;
|
|
245
|
+
/**
|
|
246
|
+
* The SERVER's clock at the observation — `observed_at` captured before the
|
|
247
|
+
* read (GET, bundle, stream frame) or after the write (`POST .../prompts`).
|
|
248
|
+
* The ORDERING stamp: it only ever meets another `serverAtMs`. Absent when
|
|
249
|
+
* the server did not supply one.
|
|
250
|
+
*
|
|
251
|
+
* Two stamps because one field served both jobs and the jobs need different
|
|
252
|
+
* clocks. Ranked against a browser stamp, an API clock ±10 minutes off
|
|
253
|
+
* either rejected every later direct read (skew ahead) or aged the
|
|
254
|
+
* observation out on arrival (skew behind) — both reproduced in PR #6957's
|
|
255
|
+
* review as a stale empty snapshot hiding a backend-confirmed queue row.
|
|
256
|
+
*/
|
|
257
|
+
serverAtMs?: number;
|
|
167
258
|
}
|
|
259
|
+
/**
|
|
260
|
+
* May `candidate` replace `current` as the session's inbox observation?
|
|
261
|
+
*
|
|
262
|
+
* ONE clock per comparison. When both observations carry the server's stamp,
|
|
263
|
+
* the server clock decides — it is the only pair drawn from one clock, and it
|
|
264
|
+
* orders a read against a write exactly (a read issued before a POST carries an
|
|
265
|
+
* older `observed_at` than the POST's response, so it can never erase it).
|
|
266
|
+
* Otherwise the browser stamps decide, as before. Ties stand aside for the
|
|
267
|
+
* candidate: two reads of the same instant agree, and the newer arrival may
|
|
268
|
+
* carry a corrected list.
|
|
269
|
+
*/
|
|
270
|
+
export declare function inboxObservationSupersedes(candidate: WorkingInboxInput, current: WorkingInboxInput | null | undefined): boolean;
|
|
168
271
|
export interface WorkingInputs {
|
|
169
272
|
optimistic: SendReceipt | null;
|
|
170
273
|
/** This tab's pending stop. `null`/absent means it is not stopping. */
|
|
@@ -173,6 +276,8 @@ export interface WorkingInputs {
|
|
|
173
276
|
inbox?: WorkingInboxInput | null;
|
|
174
277
|
server: WorkingServerInput | null;
|
|
175
278
|
stream: WorkingStreamInput | null;
|
|
279
|
+
/** The runtime's own output, last seen. See `WorkingActivityInput`. */
|
|
280
|
+
activity?: WorkingActivityInput | null;
|
|
176
281
|
nowMs: number;
|
|
177
282
|
}
|
|
178
283
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"working.d.ts","sourceRoot":"","sources":["../../../src/core/session/working.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,WAAW,EACX,gBAAgB,EACjB,MAAM,kCAAkC,CAAC;AAE1C;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,QAAQ,GAAG,YAAY,CAAC;AAE/D,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,wEAAwE;IACxE,MAAM,EAAE,aAAa,CAAC;IACtB,iEAAiE;IACjE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,yEAAyE;IACzE,KAAK,EAAE,MAAM,CAAC;IACd;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;CACpC;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,yBAAyB,QAAS,CAAC;AAEhD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,yBAAyB,QAAS,CAAC;AAEhD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,yBAAyB,QAAS,CAAC;AAEhD;;;;;;;;GAQG;AACH,eAAO,MAAM,wBAAwB,QAAS,CAAC;AAE/C;;;;;;;;;GASG;AACH,eAAO,MAAM,uBAAuB,QAAS,CAAC;AAE9C,oDAAoD;AACpD,MAAM,WAAW,WAAW;IAC1B;
|
|
1
|
+
{"version":3,"file":"working.d.ts","sourceRoot":"","sources":["../../../src/core/session/working.ts"],"names":[],"mappings":"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"}
|