@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
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { useEffect, useSyncExternalStore } from 'react';
|
|
2
|
+
import { useCallback, useEffect, useSyncExternalStore } from 'react';
|
|
3
3
|
import { claimSessionCacheOwnership, getSessionCacheOwnership, resolveSessionCacheOwnerScope, sessionCacheOwnerScopesConflict, } from '../browser/session-sync/session-cache-ownership.js';
|
|
4
4
|
import { getSessionSyncController, loadSessionRuntimeStatus, loadSessionTranscriptMessages, resetSessionSyncControllersForSession, retainSessionSyncController, } from '../browser/session-sync/session-sync-registry.js';
|
|
5
|
-
import {
|
|
5
|
+
import { loadSessionTranscriptMirror, mirrorMessagesForHydrate, shouldHydrateFromMirror, } from '../browser/session-sync/server-transcript-mirror.js';
|
|
6
|
+
import { transcriptIsFragment } from '../core/session-sync/fragment.js';
|
|
7
|
+
import { onTabVisible } from '../browser/session-sync/visibility.js';
|
|
6
8
|
import { useSandboxConnectionStore } from '../browser/stores/sandbox-connection-store.js';
|
|
7
9
|
import { useSyncStore } from '../browser/stores/sync-store.js';
|
|
8
10
|
import { useCurrentRuntime } from './use-current-runtime.js';
|
|
@@ -27,12 +29,12 @@ export function sessionSyncBusy(input) {
|
|
|
27
29
|
* projection outranks the stream slot" is a test rather than a convention.
|
|
28
30
|
*/
|
|
29
31
|
export function livenessBusy(input) {
|
|
30
|
-
if (!input.networkEnabled
|
|
32
|
+
if (!input.networkEnabled)
|
|
31
33
|
return false;
|
|
32
|
-
return sessionSyncBusy(input);
|
|
34
|
+
return sessionSyncBusy(input) || input.serverHoldsTurn === true;
|
|
33
35
|
}
|
|
34
36
|
export function useSessionSync(sessionId, options = {}) {
|
|
35
|
-
const { kortixSessionScope, networkEnabled = true, working } = options;
|
|
37
|
+
const { kortixSessionScope, networkEnabled = true, working, serverHoldsTurn } = options;
|
|
36
38
|
const runtimeHealthy = useSandboxConnectionStore((state) => state.healthy === true);
|
|
37
39
|
const runtimeScope = useCurrentRuntime((state) => state.sandboxId) ?? 'none';
|
|
38
40
|
const cacheOwnerScope = resolveSessionCacheOwnerScope(runtimeScope, kortixSessionScope);
|
|
@@ -65,69 +67,141 @@ export function useSessionSync(sessionId, options = {}) {
|
|
|
65
67
|
resetSessionSyncControllersForSession(sessionId, runtimeScope === 'none' ? undefined : runtimeScope);
|
|
66
68
|
useSyncStore.getState().clearSession(sessionId);
|
|
67
69
|
}, [cacheOwnerScope, runtimeScope, sessionId]);
|
|
68
|
-
//
|
|
69
|
-
//
|
|
70
|
-
//
|
|
71
|
-
//
|
|
72
|
-
//
|
|
70
|
+
// FIRST PAINT FROM THE SERVER'S MIRROR — deliberately NOT gated on
|
|
71
|
+
// `networkEnabled`, `runtimeHealthy`, or `runtimeScope`.
|
|
72
|
+
//
|
|
73
|
+
// That is the whole point. Every other read in this hook waits for the box;
|
|
74
|
+
// opening a hibernated session therefore showed a full-screen loader with no
|
|
75
|
+
// transcript for the length of the wake (measured 5-240 s) although every
|
|
76
|
+
// message existed. This read asks the CONTROL PLANE, which is up, for the
|
|
77
|
+
// copy it wrote at the last turn end.
|
|
78
|
+
//
|
|
79
|
+
// It is not the disk mirror returning. That one was deleted because its
|
|
80
|
+
// freshness test read the transcript's SHAPE and a Stop moves none of it, so
|
|
81
|
+
// a stopped thread painted as still running. This payload carries OpenCode's
|
|
82
|
+
// `info` VERBATIM — `time.completed` and `error` included — and the server
|
|
83
|
+
// writes it BECAUSE a turn ended, so there is no client-side freshness test
|
|
84
|
+
// left to get wrong. `shouldHydrateFromMirror` additionally refuses a mirror
|
|
85
|
+
// captured from a different OpenCode root, which the scope-keyed disk cache
|
|
86
|
+
// could not check.
|
|
87
|
+
//
|
|
88
|
+
// Painted with `source: 'cache'`, so the store's existing settle rule owns
|
|
89
|
+
// reconciliation: the first runtime read confirms every id it contains and
|
|
90
|
+
// drops any it covers but lacks. Nothing here needs the settle rule changed.
|
|
73
91
|
useEffect(() => {
|
|
74
|
-
if (!canQueryOpenCodeSession(sessionId))
|
|
92
|
+
if (!canQueryOpenCodeSession(sessionId) || !kortixSessionScope)
|
|
93
|
+
return;
|
|
94
|
+
// Already have the thread (a warm remount, or the runtime beat us): the
|
|
95
|
+
// live read outranks a snapshot and must never be overwritten by one.
|
|
96
|
+
if ((useSyncStore.getState().messages[sessionId]?.length ?? 0) > 0)
|
|
75
97
|
return;
|
|
76
|
-
|
|
77
|
-
void (
|
|
78
|
-
|
|
79
|
-
|
|
98
|
+
const abort = new AbortController();
|
|
99
|
+
void loadSessionTranscriptMirror({
|
|
100
|
+
kortixSessionScope,
|
|
101
|
+
signal: abort.signal,
|
|
102
|
+
}).then((envelope) => {
|
|
103
|
+
if (abort.signal.aborted || !envelope)
|
|
80
104
|
return;
|
|
81
|
-
const
|
|
82
|
-
if (!
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
105
|
+
const state = useSyncStore.getState();
|
|
106
|
+
if (!shouldHydrateFromMirror({
|
|
107
|
+
envelope,
|
|
108
|
+
runtimeSessionId: sessionId,
|
|
109
|
+
hasMessages: (state.messages[sessionId]?.length ?? 0) > 0,
|
|
86
110
|
})) {
|
|
87
111
|
return;
|
|
88
112
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
return () => {
|
|
93
|
-
cancelled = true;
|
|
94
|
-
};
|
|
113
|
+
state.hydrate(sessionId, mirrorMessagesForHydrate(envelope), { source: 'cache' });
|
|
114
|
+
});
|
|
115
|
+
return () => abort.abort();
|
|
95
116
|
}, [kortixSessionScope, sessionId]);
|
|
117
|
+
// NO DISK PAINT. The transcript renders from the runtime and from this tab's
|
|
118
|
+
// own optimistic writes — nothing else.
|
|
119
|
+
//
|
|
120
|
+
// There used to be an IndexedDB mirror here, hydrated before `runtimeHealthy`
|
|
121
|
+
// so a hibernated session showed its history instead of a blank screen for
|
|
122
|
+
// the length of a VM boot. It was removed because it could not tell a
|
|
123
|
+
// FINISHED turn from a running one. Its write gate was structural (message
|
|
124
|
+
// count, total part count, tail id), and the two changes that end a turn move
|
|
125
|
+
// none of those: `time.completed` stamped on the tail message, and the `error`
|
|
126
|
+
// an abort stamps. A normal turn escaped by accident, because OpenCode
|
|
127
|
+
// appends a `step-finish` part and that moves the part count — but a STOP
|
|
128
|
+
// appends no part at all. So the disk copy of a stopped thread held an
|
|
129
|
+
// assistant message with neither `time.completed` nor `error`, which
|
|
130
|
+
// `open-turn.ts` reads as STILL RUNNING: on the next cold paint the stopped
|
|
131
|
+
// turn shimmered and every message the user sent after it dimmed to "Queued".
|
|
132
|
+
//
|
|
133
|
+
// The cold-open cost is real and known — see `session-sync-registry`'s
|
|
134
|
+
// `reconcile('initial')` below, which is now the only thing that fills the
|
|
135
|
+
// transcript. If the blank wake is worth solving again, it needs a mirror
|
|
136
|
+
// whose freshness test reads the MESSAGE, not its shape.
|
|
137
|
+
// ASK AS SOON AS WE KNOW WHICH SANDBOX — not when a probe agrees.
|
|
138
|
+
//
|
|
139
|
+
// This read used to wait for `runtimeHealthy === true`, and that one
|
|
140
|
+
// condition is what hung the session page. `resolveSessionContentState` keeps
|
|
141
|
+
// the web app on its "Waking the agent" loader while there are no messages,
|
|
142
|
+
// and this read is the only thing that produces messages. So the page's ONLY
|
|
143
|
+
// exit was a health probe — the least reliable signal in the system — and a
|
|
144
|
+
// box that was up while failing its probe showed a spinner over a session
|
|
145
|
+
// that could have been read the whole time. The sidebar, reading the session
|
|
146
|
+
// list instead, showed the same session as live: one page, two answers.
|
|
147
|
+
//
|
|
148
|
+
// The read IS the liveness check. If the runtime is not up the request fails
|
|
149
|
+
// and the controller retries with backoff until it lands, so readiness
|
|
150
|
+
// becomes a byproduct of asking for what we wanted anyway.
|
|
96
151
|
useEffect(() => {
|
|
97
|
-
if (!networkEnabled ||
|
|
98
|
-
!canQueryOpenCodeSession(sessionId) ||
|
|
99
|
-
!runtimeHealthy ||
|
|
100
|
-
runtimeScope === 'none')
|
|
152
|
+
if (!networkEnabled || !canQueryOpenCodeSession(sessionId) || runtimeScope === 'none')
|
|
101
153
|
return;
|
|
102
154
|
resetSessionSyncControllersForSession(sessionId, runtimeScope);
|
|
103
155
|
const release = retainSessionSyncController(sessionId, runtimeScope);
|
|
104
|
-
//
|
|
105
|
-
//
|
|
156
|
+
// The ONLY thing that fills the transcript. One bounded tail, so events
|
|
157
|
+
// produced while this route was inactive are not skipped.
|
|
106
158
|
void controller.reconcile('initial');
|
|
107
159
|
return release;
|
|
108
|
-
}, [controller, networkEnabled,
|
|
109
|
-
//
|
|
110
|
-
//
|
|
111
|
-
//
|
|
112
|
-
//
|
|
160
|
+
}, [controller, networkEnabled, runtimeScope, sessionId]);
|
|
161
|
+
// A transcript the live stream rebuilt after an eviction starts
|
|
162
|
+
// mid-conversation, and nothing else will correct it: the mount already ran,
|
|
163
|
+
// so no `initial` read is coming, and the liveness poll only turns on while
|
|
164
|
+
// the session is working. Removing the IndexedDB mirror (5a7a43517f) named
|
|
165
|
+
// this exact hole and left it open — "no reconcile is keyed on eviction …
|
|
166
|
+
// can sit on a partial transcript until a reload".
|
|
167
|
+
//
|
|
168
|
+
// Subscribed rather than checked once, because the refill happens while this
|
|
169
|
+
// component is already mounted. `hydrate` clears the mark, so the successful
|
|
170
|
+
// read is what disarms this.
|
|
113
171
|
useEffect(() => {
|
|
114
|
-
if (!canQueryOpenCodeSession(sessionId))
|
|
172
|
+
if (!networkEnabled || !canQueryOpenCodeSession(sessionId))
|
|
115
173
|
return;
|
|
116
|
-
let
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
174
|
+
let repairing = false;
|
|
175
|
+
const check = (state) => {
|
|
176
|
+
if (repairing)
|
|
177
|
+
return;
|
|
178
|
+
if (!transcriptIsFragment({
|
|
179
|
+
hasMessages: (state.messages[sessionId]?.length ?? 0) > 0,
|
|
180
|
+
wasEvicted: state.wasTranscriptEvicted(sessionId),
|
|
181
|
+
})) {
|
|
123
182
|
return;
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
void
|
|
183
|
+
}
|
|
184
|
+
repairing = true;
|
|
185
|
+
void controller.reconcile('eviction').finally(() => {
|
|
186
|
+
repairing = false;
|
|
187
|
+
});
|
|
127
188
|
};
|
|
128
|
-
|
|
129
|
-
return useSyncStore.subscribe(
|
|
130
|
-
}, [
|
|
189
|
+
check(useSyncStore.getState());
|
|
190
|
+
return useSyncStore.subscribe((state) => check(state));
|
|
191
|
+
}, [controller, networkEnabled, sessionId]);
|
|
192
|
+
// Coming back to the tab is a moment of MAXIMUM uncertainty, so it is a
|
|
193
|
+
// moment to re-read. A backgrounded tab has its timers clamped (Chrome: about
|
|
194
|
+
// one tick a minute), so the 10s liveness poll effectively stops, and the SSE
|
|
195
|
+
// connection can be dropped with no visible error. Whatever the transcript
|
|
196
|
+
// shows on return was assembled from a stream nobody was watching. One
|
|
197
|
+
// bounded tail read settles it.
|
|
198
|
+
useEffect(() => {
|
|
199
|
+
if (!networkEnabled || !canQueryOpenCodeSession(sessionId))
|
|
200
|
+
return;
|
|
201
|
+
return onTabVisible(() => {
|
|
202
|
+
void controller.reconcile('visible');
|
|
203
|
+
});
|
|
204
|
+
}, [controller, networkEnabled, sessionId]);
|
|
131
205
|
const messages = useSyncStore((state) => state.buildSessionMessages(readableSessionId, state.messages[readableSessionId], state.parts));
|
|
132
206
|
// The runtime's own status, unmodified.
|
|
133
207
|
//
|
|
@@ -154,12 +228,20 @@ export function useSessionSync(sessionId, options = {}) {
|
|
|
154
228
|
const isBusy = sessionSyncBusy({ working, streamBusy });
|
|
155
229
|
const isLoading = !useSyncStore((state) => readableSessionId in state.messages);
|
|
156
230
|
useEffect(() => {
|
|
157
|
-
controller.setBusy(livenessBusy({ networkEnabled, runtimeHealthy, working, streamBusy }));
|
|
158
|
-
}, [controller, streamBusy, networkEnabled, runtimeHealthy, working]);
|
|
231
|
+
controller.setBusy(livenessBusy({ networkEnabled, runtimeHealthy, working, streamBusy, serverHoldsTurn }));
|
|
232
|
+
}, [controller, streamBusy, networkEnabled, runtimeHealthy, working, serverHoldsTurn]);
|
|
233
|
+
// Re-read the tail on demand. The transcript body renders this behind its
|
|
234
|
+
// "couldn't load" state so `freshness === 'error'` is recoverable without a
|
|
235
|
+
// page reload or a full sandbox restart — it just asks the controller to
|
|
236
|
+
// reconcile again, which is the same read the mount and the poll do.
|
|
237
|
+
const retryTranscript = useCallback(() => {
|
|
238
|
+
void controller.reconcile('manual');
|
|
239
|
+
}, [controller]);
|
|
159
240
|
return {
|
|
160
241
|
messages,
|
|
161
242
|
status,
|
|
162
243
|
freshness: sync.freshness,
|
|
244
|
+
retryTranscript,
|
|
163
245
|
isBusy,
|
|
164
246
|
isLoading,
|
|
165
247
|
hasOlder: sync.hasOlder,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-session-sync.js","sourceRoot":"","sources":["../../src/react/use-session-sync.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAGb,OAAO,EAAE,SAAS,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"use-session-sync.js","sourceRoot":"","sources":["../../src/react/use-session-sync.ts"],"names":[],"mappings":"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"}
|
|
@@ -20,6 +20,20 @@ export declare const WORKING_POLL_IDLE_MS = 15000;
|
|
|
20
20
|
* unanswered receipt: the end of the turn is the news worth having early. */
|
|
21
21
|
export declare const WORKING_POLL_ACTIVE_MS = 5000;
|
|
22
22
|
export declare function workingPollMs(projection: WorkingProjection): number;
|
|
23
|
+
/**
|
|
24
|
+
* Which side of a turn boundary a status frame is on.
|
|
25
|
+
*
|
|
26
|
+
* The runtime does NOT emit one frame per turn. Measured mid-turn on the local
|
|
27
|
+
* stack, it alternated `busy` → `retry` → `busy` about every 140ms, and an
|
|
28
|
+
* effect keyed on the observation INSTANT therefore re-invalidated `/turn` and
|
|
29
|
+
* `/prompts` at that rate, once per mount. A `busy`→`retry` flip is not news
|
|
30
|
+
* about whether a turn is open; only crossing between `idle` and not-idle is.
|
|
31
|
+
*
|
|
32
|
+
* `'none'` is deliberately distinct from `'idle'`: silence is not an
|
|
33
|
+
* observation, and collapsing them would stop the FIRST frame of a turn from
|
|
34
|
+
* reading as a change.
|
|
35
|
+
*/
|
|
36
|
+
export declare function streamTurnPhase(status: SessionStatus | undefined): 'idle' | 'active' | 'none';
|
|
23
37
|
/** One `GET .../turn` answer plus the instant the read was ISSUED. Stamping at
|
|
24
38
|
* issue rather than arrival is what lets the projection tell "this read is
|
|
25
39
|
* older than the send" from "this read answers the send". */
|
|
@@ -36,6 +50,16 @@ export declare function buildWorkingInputs(input: {
|
|
|
36
50
|
inbox: WorkingInboxInput | undefined;
|
|
37
51
|
status: SessionStatus | undefined;
|
|
38
52
|
statusAtMs: number;
|
|
53
|
+
/**
|
|
54
|
+
* Who minted the status frame (`useSyncStore.sessionStatusOrigin`). `'local'`
|
|
55
|
+
* marks a tab fabrication — the missing-busy sweep, a synthetic abort, a
|
|
56
|
+
* cache handoff — which may answer for a silent session but may never veto
|
|
57
|
+
* the server's open turn. Absent means `'wire'`.
|
|
58
|
+
*/
|
|
59
|
+
statusOrigin?: 'wire' | 'local';
|
|
60
|
+
/** When the runtime's own output last reached this tab for this session
|
|
61
|
+
* (`useSyncStore.sessionActivityAt`). 0/undefined when it never has. */
|
|
62
|
+
activityAtMs?: number;
|
|
39
63
|
optimistic: SendReceipt | null;
|
|
40
64
|
abort?: AbortReceipt | null;
|
|
41
65
|
nowMs: number;
|
|
@@ -53,5 +77,36 @@ export interface UseSessionWorkingOptions {
|
|
|
53
77
|
*/
|
|
54
78
|
runtimeSessionId?: string | null;
|
|
55
79
|
}
|
|
80
|
+
/**
|
|
81
|
+
* The instant a status frame counts from: the store's own arrival stamp
|
|
82
|
+
* (`sessionStatusAt`, written by `setStatus` when the frame landed), falling
|
|
83
|
+
* back to the observer's clock only for a slot that predates the stamp slice.
|
|
84
|
+
*
|
|
85
|
+
* Stamping at OBSERVATION was the old rule, and it had a resurrection hole: a
|
|
86
|
+
* remount resets the observation state, the effect re-stamps whatever the
|
|
87
|
+
* store still holds, and a dead stream's last idle frame came back looking
|
|
88
|
+
* brand new — fresh enough to veto the open `/turn` row for another full
|
|
89
|
+
* `STREAM_OBSERVATION_MAX_MS` window. The frame's age is a fact about the
|
|
90
|
+
* frame, so it lives with the frame.
|
|
91
|
+
*/
|
|
92
|
+
export declare function streamObservationStamp(storeStampMs: number | undefined, nowMs: number): number;
|
|
93
|
+
/**
|
|
94
|
+
* ONE reading of "which turns are open", for the `/turn` query.
|
|
95
|
+
*
|
|
96
|
+
* It claims the SESSION-OPEN BUNDLE first. Three hooks mount this query on a
|
|
97
|
+
* session route (`useSession`, the composer, the session panel) and the open
|
|
98
|
+
* path reads it before anything else can, which measured as up to 6 `/turn`
|
|
99
|
+
* requests inside a single open. A claim only succeeds while an open bundle is
|
|
100
|
+
* in flight or seconds old, so the burst collapses to one server answer and
|
|
101
|
+
* every poll after it still goes to the endpoint.
|
|
102
|
+
*
|
|
103
|
+
* A claim that answers `null` — no bundle, a failed bundle, or a bundle whose
|
|
104
|
+
* turn leg was `known: false` — falls through to `GET .../turn`. UNKNOWN is not
|
|
105
|
+
* idle: the fallback must ASK, never assume.
|
|
106
|
+
*
|
|
107
|
+
* Exported because this package has no hook-render harness: the reads and pure
|
|
108
|
+
* predicates ARE the test surface for effect-gated logic.
|
|
109
|
+
*/
|
|
110
|
+
export declare function readSessionTurnObservation(projectId: string, sessionId: string): Promise<SessionTurnObservation>;
|
|
56
111
|
export declare function useSessionWorking(projectId: string, sessionId: string, options?: UseSessionWorkingOptions): WorkingProjection;
|
|
57
112
|
//# sourceMappingURL=use-session-working.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-session-working.d.ts","sourceRoot":"","sources":["../../src/react/use-session-working.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAKhE,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,gBAAgB,EAEtB,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACtB,KAAK,aAAa,EAClB,KAAK,iBAAiB,EAGvB,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"use-session-working.d.ts","sourceRoot":"","sources":["../../src/react/use-session-working.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAKhE,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,gBAAgB,EAEtB,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACtB,KAAK,aAAa,EAClB,KAAK,iBAAiB,EAGvB,MAAM,yBAAyB,CAAC;AAKjC;;;;;;;;;GASG;AAEH;;;yBAGyB;AACzB,eAAO,MAAM,oBAAoB,QAAS,CAAC;AAC3C;8EAC8E;AAC9E,eAAO,MAAM,sBAAsB,OAAQ,CAAC;AAE5C,wBAAgB,aAAa,CAAC,UAAU,EAAE,iBAAiB,GAAG,MAAM,CAEnE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,aAAa,GAAG,SAAS,GAAG,MAAM,GAAG,QAAQ,GAAG,MAAM,CAG7F;AAED;;8DAE8D;AAC9D,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;kBAEkB;AAClB,wBAAgB,kBAAkB,CAAC,KAAK,EAAE;IACxC,IAAI,EAAE,sBAAsB,GAAG,SAAS,CAAC;IACzC,KAAK,EAAE,iBAAiB,GAAG,SAAS,CAAC;IACrC,MAAM,EAAE,aAAa,GAAG,SAAS,CAAC;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB;;;;;OAKG;IACH,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAChC;6EACyE;IACzE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,WAAW,GAAG,IAAI,CAAC;IAC/B,KAAK,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC;IAC5B,KAAK,EAAE,MAAM,CAAC;CACf,GAAG,aAAa,CA4BhB;AAED,MAAM,WAAW,wBAAwB;IACvC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;;;;;OAQG;IACH,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAMD;;;;;;;;;;;GAWG;AACH,wBAAgB,sBAAsB,CACpC,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,KAAK,EAAE,MAAM,GACZ,MAAM,CAER;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,0BAA0B,CAC9C,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,sBAAsB,CAAC,CAejC;AAED,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,wBAA6B,GACrC,iBAAiB,CA4KnB"}
|
|
@@ -5,7 +5,9 @@ import { useSessionWorkingStore } from '../browser/stores/session-working-store.
|
|
|
5
5
|
import { useSyncStore } from '../browser/stores/sync-store.js';
|
|
6
6
|
import { getSessionTurn, } from '../core/rest/projects-client/sessions.js';
|
|
7
7
|
import { projectWorking, workingExpiryAtMs, } from '../core/session/working.js';
|
|
8
|
+
import { claimOpenBundle, openBundleTurn } from '../core/session/open-bundle.js';
|
|
8
9
|
import { qk } from './query-keys.js';
|
|
10
|
+
import { usePollOwner } from './use-poll-owner.js';
|
|
9
11
|
/**
|
|
10
12
|
* The ONE answer to "is this session working?", and where the answer came from.
|
|
11
13
|
*
|
|
@@ -27,6 +29,24 @@ export const WORKING_POLL_ACTIVE_MS = 5_000;
|
|
|
27
29
|
export function workingPollMs(projection) {
|
|
28
30
|
return projection.state === 'working' ? WORKING_POLL_ACTIVE_MS : WORKING_POLL_IDLE_MS;
|
|
29
31
|
}
|
|
32
|
+
/**
|
|
33
|
+
* Which side of a turn boundary a status frame is on.
|
|
34
|
+
*
|
|
35
|
+
* The runtime does NOT emit one frame per turn. Measured mid-turn on the local
|
|
36
|
+
* stack, it alternated `busy` → `retry` → `busy` about every 140ms, and an
|
|
37
|
+
* effect keyed on the observation INSTANT therefore re-invalidated `/turn` and
|
|
38
|
+
* `/prompts` at that rate, once per mount. A `busy`→`retry` flip is not news
|
|
39
|
+
* about whether a turn is open; only crossing between `idle` and not-idle is.
|
|
40
|
+
*
|
|
41
|
+
* `'none'` is deliberately distinct from `'idle'`: silence is not an
|
|
42
|
+
* observation, and collapsing them would stop the FIRST frame of a turn from
|
|
43
|
+
* reading as a change.
|
|
44
|
+
*/
|
|
45
|
+
export function streamTurnPhase(status) {
|
|
46
|
+
if (!status)
|
|
47
|
+
return 'none';
|
|
48
|
+
return status.type === 'idle' ? 'idle' : 'active';
|
|
49
|
+
}
|
|
30
50
|
/** Fold the two live sources plus the local receipt into the projection's
|
|
31
51
|
* inputs. Pure, so "a failed read contributes nothing" is a test, not a
|
|
32
52
|
* convention. */
|
|
@@ -39,6 +59,11 @@ export function buildWorkingInputs(input) {
|
|
|
39
59
|
server: input.turn
|
|
40
60
|
? { turns: input.turn.turns, lastEnded: input.turn.last_ended, atMs: input.turn.atMs }
|
|
41
61
|
: null,
|
|
62
|
+
// The runtime's own output, which is not an observation OF the runtime but
|
|
63
|
+
// the runtime itself — see `WorkingActivityInput`. It is what answers when
|
|
64
|
+
// every observer has gone quiet: a dropped status frame, a poll throttled
|
|
65
|
+
// by a backgrounded tab.
|
|
66
|
+
activity: input.activityAtMs ? { atMs: input.activityAtMs } : null,
|
|
42
67
|
// Silence is not an observation. A session with no status frame yet feeds
|
|
43
68
|
// NOTHING here — the old code read "no status" as idle, which unmasked
|
|
44
69
|
// live turns whenever a frame was dropped.
|
|
@@ -47,6 +72,7 @@ export function buildWorkingInputs(input) {
|
|
|
47
72
|
type: input.status.type === 'busy' || input.status.type === 'retry'
|
|
48
73
|
? input.status.type
|
|
49
74
|
: 'idle',
|
|
75
|
+
origin: input.statusOrigin ?? 'wire',
|
|
50
76
|
atMs: input.statusAtMs,
|
|
51
77
|
}
|
|
52
78
|
: null,
|
|
@@ -55,10 +81,65 @@ export function buildWorkingInputs(input) {
|
|
|
55
81
|
/** How many live `useSessionWorking` mounts observe each session — the guard
|
|
56
82
|
* that makes the unmount pruning below safe under multiple observers. */
|
|
57
83
|
const workingObserverCounts = new Map();
|
|
84
|
+
/**
|
|
85
|
+
* The instant a status frame counts from: the store's own arrival stamp
|
|
86
|
+
* (`sessionStatusAt`, written by `setStatus` when the frame landed), falling
|
|
87
|
+
* back to the observer's clock only for a slot that predates the stamp slice.
|
|
88
|
+
*
|
|
89
|
+
* Stamping at OBSERVATION was the old rule, and it had a resurrection hole: a
|
|
90
|
+
* remount resets the observation state, the effect re-stamps whatever the
|
|
91
|
+
* store still holds, and a dead stream's last idle frame came back looking
|
|
92
|
+
* brand new — fresh enough to veto the open `/turn` row for another full
|
|
93
|
+
* `STREAM_OBSERVATION_MAX_MS` window. The frame's age is a fact about the
|
|
94
|
+
* frame, so it lives with the frame.
|
|
95
|
+
*/
|
|
96
|
+
export function streamObservationStamp(storeStampMs, nowMs) {
|
|
97
|
+
return storeStampMs ?? nowMs;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* ONE reading of "which turns are open", for the `/turn` query.
|
|
101
|
+
*
|
|
102
|
+
* It claims the SESSION-OPEN BUNDLE first. Three hooks mount this query on a
|
|
103
|
+
* session route (`useSession`, the composer, the session panel) and the open
|
|
104
|
+
* path reads it before anything else can, which measured as up to 6 `/turn`
|
|
105
|
+
* requests inside a single open. A claim only succeeds while an open bundle is
|
|
106
|
+
* in flight or seconds old, so the burst collapses to one server answer and
|
|
107
|
+
* every poll after it still goes to the endpoint.
|
|
108
|
+
*
|
|
109
|
+
* A claim that answers `null` — no bundle, a failed bundle, or a bundle whose
|
|
110
|
+
* turn leg was `known: false` — falls through to `GET .../turn`. UNKNOWN is not
|
|
111
|
+
* idle: the fallback must ASK, never assume.
|
|
112
|
+
*
|
|
113
|
+
* Exported because this package has no hook-render harness: the reads and pure
|
|
114
|
+
* predicates ARE the test surface for effect-gated logic.
|
|
115
|
+
*/
|
|
116
|
+
export async function readSessionTurnObservation(projectId, sessionId) {
|
|
117
|
+
const claimed = claimOpenBundle(projectId, sessionId);
|
|
118
|
+
if (claimed) {
|
|
119
|
+
const bundle = await claimed;
|
|
120
|
+
const turn = bundle ? openBundleTurn(bundle) : null;
|
|
121
|
+
// The stamp is the bundle's `observed_at` — the instant the SERVER took the
|
|
122
|
+
// reading — never arrival, for the same reason the direct read below stamps
|
|
123
|
+
// before the request and not after it.
|
|
124
|
+
if (turn)
|
|
125
|
+
return { turns: turn.turns, last_ended: turn.last_ended, atMs: turn.atMs };
|
|
126
|
+
}
|
|
127
|
+
// Stamped BEFORE the request. An answer is only as fresh as the moment
|
|
128
|
+
// it was asked, and a slow proxy hop must not make a stale read look new.
|
|
129
|
+
const atMs = Date.now();
|
|
130
|
+
const status = await getSessionTurn(projectId, sessionId);
|
|
131
|
+
return { turns: status.turns ?? [], last_ended: status.last_ended, atMs };
|
|
132
|
+
}
|
|
58
133
|
export function useSessionWorking(projectId, sessionId, options = {}) {
|
|
59
134
|
const { enabled = true, runtimeSessionId = null } = options;
|
|
60
135
|
const streamKey = runtimeSessionId ?? '';
|
|
61
136
|
const status = useSyncStore((state) => streamKey ? state.sessionStatus[streamKey] : undefined);
|
|
137
|
+
// Who minted that frame — `'local'` for a tab fabrication, which the
|
|
138
|
+
// projection lets answer but never lets contradict the server's open turn.
|
|
139
|
+
const statusOrigin = useSyncStore((state) => streamKey ? state.sessionStatusOrigin[streamKey] : undefined);
|
|
140
|
+
// When the frame LANDED in the store — the stamp `observed` below counts
|
|
141
|
+
// from, so a remount cannot resurrect a dead stream's frame as fresh.
|
|
142
|
+
const statusAtMs = useSyncStore((state) => streamKey ? state.sessionStatusAt[streamKey] : undefined);
|
|
62
143
|
// Both LOCAL inputs come from one per-session store rather than from props.
|
|
63
144
|
// More than one place mounts this hook for the same session and they share
|
|
64
145
|
// one `/turn` cache entry; when each held its own receipt, the observer
|
|
@@ -95,31 +176,48 @@ export function useSessionWorking(projectId, sessionId, options = {}) {
|
|
|
95
176
|
setObserved((previous) => (previous && previous.key === streamKey ? previous : null));
|
|
96
177
|
return;
|
|
97
178
|
}
|
|
98
|
-
|
|
99
|
-
|
|
179
|
+
// An origin flip over an unchanged value re-stamps too: the store kept the
|
|
180
|
+
// object's identity on purpose (`setStatus`), but a wire frame landing
|
|
181
|
+
// over a fabricated one — or the reverse — is a new observation. The stamp
|
|
182
|
+
// itself is the store's arrival time (`streamObservationStamp`), so a
|
|
183
|
+
// remount observing an OLD frame does not mint it a new age.
|
|
184
|
+
setObserved({
|
|
185
|
+
key: streamKey,
|
|
186
|
+
status,
|
|
187
|
+
origin: statusOrigin ?? 'wire',
|
|
188
|
+
atMs: streamObservationStamp(statusAtMs, Date.now()),
|
|
189
|
+
});
|
|
190
|
+
}, [status, statusOrigin, statusAtMs, streamKey]);
|
|
100
191
|
const stream = observed && observed.key === streamKey ? observed : null;
|
|
192
|
+
// The runtime's own output for THIS session's wire id. Quantized to a second
|
|
193
|
+
// in the store, so subscribing here cannot re-render at the stream's rate.
|
|
194
|
+
const activityAtMs = useSyncStore((s) => streamKey ? s.sessionActivityAt[streamKey] : undefined);
|
|
101
195
|
const canRead = enabled && !!projectId && !!sessionId;
|
|
102
196
|
const inputsFor = (turn, nowMs) => buildWorkingInputs({
|
|
103
197
|
turn,
|
|
104
198
|
inbox,
|
|
105
199
|
status: stream?.status,
|
|
106
200
|
statusAtMs: stream?.atMs ?? 0,
|
|
201
|
+
statusOrigin: stream?.origin,
|
|
202
|
+
activityAtMs,
|
|
107
203
|
optimistic,
|
|
108
204
|
abort,
|
|
109
205
|
nowMs,
|
|
110
206
|
});
|
|
111
207
|
const project = (turn, nowMs) => projectWorking(inputsFor(turn, nowMs));
|
|
208
|
+
const pollOwner = usePollOwner(`turn:${projectId}/${sessionId}`, canRead);
|
|
112
209
|
const query = useQuery({
|
|
113
210
|
queryKey: qk.project.sessionTurn(projectId, sessionId),
|
|
114
211
|
enabled: canRead,
|
|
115
|
-
queryFn:
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
212
|
+
queryFn: () => readSessionTurnObservation(projectId, sessionId),
|
|
213
|
+
// ONE timer per session, however many components mount this hook.
|
|
214
|
+
// `refetchInterval` is scheduled per OBSERVER: three mount points on a
|
|
215
|
+
// session route (this hook is called by `useSession`, the composer and the
|
|
216
|
+
// session panel) ran three timers against one cache entry and polled the
|
|
217
|
+
// session at three times its declared cadence — measured as 6 `/turn`
|
|
218
|
+
// reads inside one 25 s open. Non-owners read the same entry the owner
|
|
219
|
+
// refreshes, so nobody sees a staler answer; only the scheduling moved.
|
|
220
|
+
refetchInterval: (query) => pollOwner ? workingPollMs(project(query.state.data, Date.now())) : false,
|
|
123
221
|
// Coming back to a tab is the moment a turn that started (or ended) while
|
|
124
222
|
// it was hidden has to be on screen.
|
|
125
223
|
refetchOnWindowFocus: true,
|
|
@@ -138,9 +236,12 @@ export function useSessionWorking(projectId, sessionId, options = {}) {
|
|
|
138
236
|
// input with a life shorter than its own poll interval, and the turn ending
|
|
139
237
|
// is exactly when a `waiting` row becomes a running one.
|
|
140
238
|
const queryClient = useQueryClient();
|
|
141
|
-
|
|
239
|
+
// Keyed on the PHASE, not on the observation instant. The instant changes on
|
|
240
|
+
// every frame, and the runtime emits many per turn — see `streamTurnPhase`
|
|
241
|
+
// for the measured `busy`/`retry` oscillation this stops re-fetching on.
|
|
242
|
+
const streamPhase = streamTurnPhase(stream?.status);
|
|
142
243
|
useEffect(() => {
|
|
143
|
-
if (!canRead ||
|
|
244
|
+
if (!canRead || streamPhase === 'none')
|
|
144
245
|
return;
|
|
145
246
|
void queryClient.invalidateQueries({
|
|
146
247
|
queryKey: qk.project.sessionTurn(projectId, sessionId),
|
|
@@ -148,7 +249,7 @@ export function useSessionWorking(projectId, sessionId, options = {}) {
|
|
|
148
249
|
void queryClient.invalidateQueries({
|
|
149
250
|
queryKey: qk.project.sessionPrompts(projectId, sessionId),
|
|
150
251
|
});
|
|
151
|
-
}, [canRead, projectId, sessionId,
|
|
252
|
+
}, [canRead, projectId, sessionId, streamPhase, queryClient]);
|
|
152
253
|
// Re-evaluated on every render because `nowMs` moves — the projection is
|
|
153
254
|
// pure, so this costs one object and cannot drift from the poll's own view.
|
|
154
255
|
const inputs = inputsFor(canRead ? query.data : undefined, Date.now());
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-session-working.js","sourceRoot":"","sources":["../../src/react/use-session-working.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAGb,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACjE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACrD,OAAO,EAAE,sBAAsB,EAAE,MAAM,yCAAyC,CAAC;AACjF,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EAGL,cAAc,GACf,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EAML,cAAc,EACd,iBAAiB,GAClB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"use-session-working.js","sourceRoot":"","sources":["../../src/react/use-session-working.ts"],"names":[],"mappings":"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"}
|