@kortix/sdk 0.12.7 → 0.13.0
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 +13 -6
- package/dist/browser/session-sync/session-sync-registry.d.ts +7 -2
- package/dist/browser/session-sync/session-sync-registry.d.ts.map +1 -1
- package/dist/browser/session-sync/session-sync-registry.js +33 -44
- package/dist/browser/session-sync/session-sync-registry.js.map +1 -1
- package/dist/browser/stores/opencode-compaction-store.d.ts +9 -3
- package/dist/browser/stores/opencode-compaction-store.d.ts.map +1 -1
- package/dist/browser/stores/opencode-compaction-store.js +5 -12
- package/dist/browser/stores/opencode-compaction-store.js.map +1 -1
- package/dist/browser/stores/sandbox-connection-store.d.ts +28 -17
- package/dist/browser/stores/sandbox-connection-store.d.ts.map +1 -1
- package/dist/browser/stores/sandbox-connection-store.js +32 -84
- package/dist/browser/stores/sandbox-connection-store.js.map +1 -1
- package/dist/browser/stores/session-working-store.d.ts +73 -0
- package/dist/browser/stores/session-working-store.d.ts.map +1 -0
- package/dist/browser/stores/session-working-store.js +86 -0
- package/dist/browser/stores/session-working-store.js.map +1 -0
- package/dist/browser/stores/sync-store/types.d.ts +14 -4
- package/dist/browser/stores/sync-store/types.d.ts.map +1 -1
- package/dist/browser/stores/sync-store.d.ts +140 -3
- package/dist/browser/stores/sync-store.d.ts.map +1 -1
- package/dist/browser/stores/sync-store.js +425 -36
- package/dist/browser/stores/sync-store.js.map +1 -1
- package/dist/core/client/kortix.d.ts +102 -1
- package/dist/core/client/kortix.d.ts.map +1 -1
- package/dist/core/client/kortix.js +78 -0
- package/dist/core/client/kortix.js.map +1 -1
- package/dist/core/files/client.d.ts +50 -2
- package/dist/core/files/client.d.ts.map +1 -1
- package/dist/core/files/client.js +253 -44
- package/dist/core/files/client.js.map +1 -1
- package/dist/core/files/types.d.ts +11 -0
- package/dist/core/files/types.d.ts.map +1 -1
- package/dist/core/http/abort-error.d.ts +89 -0
- package/dist/core/http/abort-error.d.ts.map +1 -0
- package/dist/core/http/abort-error.js +190 -0
- package/dist/core/http/abort-error.js.map +1 -0
- package/dist/core/http/api-client.d.ts.map +1 -1
- package/dist/core/http/api-client.js +28 -4
- package/dist/core/http/api-client.js.map +1 -1
- package/dist/core/http/impersonation.d.ts +58 -0
- package/dist/core/http/impersonation.d.ts.map +1 -0
- package/dist/core/http/impersonation.js +174 -0
- package/dist/core/http/impersonation.js.map +1 -0
- package/dist/core/rest/platform-client/github-app.d.ts +13 -0
- package/dist/core/rest/platform-client/github-app.d.ts.map +1 -1
- package/dist/core/rest/platform-client/github-app.js +2 -0
- package/dist/core/rest/platform-client/github-app.js.map +1 -1
- package/dist/core/rest/platform-client/members.d.ts +10 -64
- package/dist/core/rest/platform-client/members.d.ts.map +1 -1
- package/dist/core/rest/platform-client/members.js +10 -28
- package/dist/core/rest/platform-client/members.js.map +1 -1
- package/dist/core/rest/projects-client/accounts.d.ts +30 -1
- package/dist/core/rest/projects-client/accounts.d.ts.map +1 -1
- package/dist/core/rest/projects-client/accounts.js +1 -1
- package/dist/core/rest/projects-client/accounts.js.map +1 -1
- package/dist/core/rest/projects-client/agent-config.d.ts +21 -0
- package/dist/core/rest/projects-client/agent-config.d.ts.map +1 -1
- package/dist/core/rest/projects-client/agent-config.js +14 -0
- package/dist/core/rest/projects-client/agent-config.js.map +1 -1
- package/dist/core/rest/projects-client/apps.d.ts +13 -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/assignments.d.ts +114 -0
- package/dist/core/rest/projects-client/assignments.d.ts.map +1 -0
- package/dist/core/rest/projects-client/assignments.js +91 -0
- package/dist/core/rest/projects-client/assignments.js.map +1 -0
- package/dist/core/rest/projects-client/billing.d.ts +80 -1
- package/dist/core/rest/projects-client/billing.d.ts.map +1 -1
- package/dist/core/rest/projects-client/billing.js +61 -2
- package/dist/core/rest/projects-client/billing.js.map +1 -1
- package/dist/core/rest/projects-client/connectors.d.ts +2 -0
- package/dist/core/rest/projects-client/connectors.d.ts.map +1 -1
- package/dist/core/rest/projects-client/connectors.js.map +1 -1
- package/dist/core/rest/projects-client/files.js +2 -2
- package/dist/core/rest/projects-client/files.js.map +1 -1
- package/dist/core/rest/projects-client/gateway.d.ts +51 -0
- package/dist/core/rest/projects-client/gateway.d.ts.map +1 -1
- package/dist/core/rest/projects-client/gateway.js.map +1 -1
- package/dist/core/rest/projects-client/iam.d.ts +51 -3
- package/dist/core/rest/projects-client/iam.d.ts.map +1 -1
- package/dist/core/rest/projects-client/iam.js +18 -1
- package/dist/core/rest/projects-client/iam.js.map +1 -1
- package/dist/core/rest/projects-client/index.d.ts +1 -0
- package/dist/core/rest/projects-client/index.d.ts.map +1 -1
- package/dist/core/rest/projects-client/index.js +1 -0
- package/dist/core/rest/projects-client/index.js.map +1 -1
- package/dist/core/rest/projects-client/projects.d.ts +1 -1
- package/dist/core/rest/projects-client/projects.d.ts.map +1 -1
- package/dist/core/rest/projects-client/projects.js +3 -0
- package/dist/core/rest/projects-client/projects.js.map +1 -1
- package/dist/core/rest/projects-client/secrets.d.ts +11 -0
- package/dist/core/rest/projects-client/secrets.d.ts.map +1 -1
- package/dist/core/rest/projects-client/secrets.js +1 -1
- package/dist/core/rest/projects-client/secrets.js.map +1 -1
- package/dist/core/rest/projects-client/session-costs.d.ts +33 -0
- package/dist/core/rest/projects-client/session-costs.d.ts.map +1 -1
- package/dist/core/rest/projects-client/session-costs.js.map +1 -1
- package/dist/core/rest/projects-client/sessions.d.ts +253 -4
- package/dist/core/rest/projects-client/sessions.d.ts.map +1 -1
- package/dist/core/rest/projects-client/sessions.js +101 -4
- package/dist/core/rest/projects-client/sessions.js.map +1 -1
- package/dist/core/rest/projects-client/shared.d.ts +10 -1
- package/dist/core/rest/projects-client/shared.d.ts.map +1 -1
- package/dist/core/rest/projects-client/shared.js.map +1 -1
- package/dist/core/rest/projects-client/tokens.d.ts +13 -1
- package/dist/core/rest/projects-client/tokens.d.ts.map +1 -1
- package/dist/core/rest/projects-client/tokens.js +7 -2
- package/dist/core/rest/projects-client/tokens.js.map +1 -1
- package/dist/core/rest/projects-client/triggers.d.ts +69 -2
- package/dist/core/rest/projects-client/triggers.d.ts.map +1 -1
- package/dist/core/rest/projects-client/triggers.js +1 -1
- package/dist/core/rest/projects-client/triggers.js.map +1 -1
- package/dist/core/session/compaction.d.ts +98 -0
- package/dist/core/session/compaction.d.ts.map +1 -0
- package/dist/core/session/compaction.js +108 -0
- package/dist/core/session/compaction.js.map +1 -0
- package/dist/core/session/health.d.ts +22 -0
- package/dist/core/session/health.d.ts.map +1 -1
- package/dist/core/session/health.js +31 -5
- package/dist/core/session/health.js.map +1 -1
- 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/message-queue.d.ts +79 -15
- package/dist/core/session/message-queue.d.ts.map +1 -1
- package/dist/core/session/message-queue.js +73 -27
- package/dist/core/session/message-queue.js.map +1 -1
- package/dist/core/session/rewind.d.ts +76 -10
- package/dist/core/session/rewind.d.ts.map +1 -1
- package/dist/core/session/rewind.js +68 -11
- package/dist/core/session/rewind.js.map +1 -1
- package/dist/core/session/working.d.ts +241 -0
- package/dist/core/session/working.d.ts.map +1 -0
- package/dist/core/session/working.js +261 -0
- package/dist/core/session/working.js.map +1 -0
- package/dist/core/session-sync/session-sync-controller.d.ts +35 -20
- package/dist/core/session-sync/session-sync-controller.d.ts.map +1 -1
- package/dist/core/session-sync/session-sync-controller.js +48 -115
- package/dist/core/session-sync/session-sync-controller.js.map +1 -1
- package/dist/core/stream/event-stream.d.ts +22 -0
- package/dist/core/stream/event-stream.d.ts.map +1 -1
- package/dist/core/stream/event-stream.js +132 -36
- package/dist/core/stream/event-stream.js.map +1 -1
- package/dist/core/turns/classify.d.ts +5 -2
- package/dist/core/turns/classify.d.ts.map +1 -1
- package/dist/core/turns/classify.js +1 -0
- package/dist/core/turns/classify.js.map +1 -1
- package/dist/core/turns/errors.d.ts +11 -0
- package/dist/core/turns/errors.d.ts.map +1 -1
- package/dist/core/turns/errors.js +49 -2
- package/dist/core/turns/errors.js.map +1 -1
- package/dist/core/turns/grouping.d.ts +32 -2
- package/dist/core/turns/grouping.d.ts.map +1 -1
- package/dist/core/turns/grouping.js +31 -2
- package/dist/core/turns/grouping.js.map +1 -1
- package/dist/core/turns/index.d.ts +1 -0
- package/dist/core/turns/index.d.ts.map +1 -1
- package/dist/core/turns/index.js +1 -0
- package/dist/core/turns/index.js.map +1 -1
- package/dist/core/turns/open-turn.d.ts +81 -0
- package/dist/core/turns/open-turn.d.ts.map +1 -0
- package/dist/core/turns/open-turn.js +77 -0
- package/dist/core/turns/open-turn.js.map +1 -0
- package/dist/core/turns/state.d.ts +1 -1
- package/dist/core/turns/state.d.ts.map +1 -1
- package/dist/core/turns/state.js +29 -27
- package/dist/core/turns/state.js.map +1 -1
- package/dist/core/turns/types.d.ts +8 -0
- package/dist/core/turns/types.d.ts.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- 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/server.d.ts.map +1 -1
- package/dist/node/server.js +14 -2
- package/dist/node/server.js.map +1 -1
- package/dist/react/index.d.ts +3 -1
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +8 -1
- package/dist/react/index.js.map +1 -1
- package/dist/react/initial-session-pin.d.ts +17 -0
- package/dist/react/initial-session-pin.d.ts.map +1 -1
- package/dist/react/initial-session-pin.js +58 -0
- package/dist/react/initial-session-pin.js.map +1 -1
- package/dist/react/opencode.d.ts +6 -2
- 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/prefetch-session-start.d.ts +10 -4
- package/dist/react/prefetch-session-start.d.ts.map +1 -1
- package/dist/react/prefetch-session-start.js +10 -4
- package/dist/react/prefetch-session-start.js.map +1 -1
- package/dist/react/query-keys.d.ts +8 -2
- package/dist/react/query-keys.d.ts.map +1 -1
- package/dist/react/query-keys.js +8 -2
- package/dist/react/query-keys.js.map +1 -1
- package/dist/react/session-start-stash.d.ts +25 -0
- package/dist/react/session-start-stash.d.ts.map +1 -1
- package/dist/react/session-start-stash.js +34 -3
- package/dist/react/session-start-stash.js.map +1 -1
- package/dist/react/session-title-sync.d.ts +5 -1
- package/dist/react/session-title-sync.d.ts.map +1 -1
- package/dist/react/session-title-sync.js +16 -4
- package/dist/react/session-title-sync.js.map +1 -1
- package/dist/react/use-admin-accounts.d.ts +121 -0
- package/dist/react/use-admin-accounts.d.ts.map +1 -1
- package/dist/react/use-admin-accounts.js +92 -0
- package/dist/react/use-admin-accounts.js.map +1 -1
- package/dist/react/use-can.d.ts +105 -0
- package/dist/react/use-can.d.ts.map +1 -0
- package/dist/react/use-can.js +190 -0
- package/dist/react/use-can.js.map +1 -0
- package/dist/react/use-canonical-opencode-session.d.ts +6 -1
- package/dist/react/use-canonical-opencode-session.d.ts.map +1 -1
- package/dist/react/use-canonical-opencode-session.js +46 -3
- package/dist/react/use-canonical-opencode-session.js.map +1 -1
- package/dist/react/use-impersonation.d.ts +54 -0
- package/dist/react/use-impersonation.d.ts.map +1 -0
- package/dist/react/use-impersonation.js +91 -0
- package/dist/react/use-impersonation.js.map +1 -0
- package/dist/react/use-opencode-events/handle-event.d.ts +10 -0
- package/dist/react/use-opencode-events/handle-event.d.ts.map +1 -1
- package/dist/react/use-opencode-events/handle-event.js +76 -7
- package/dist/react/use-opencode-events/handle-event.js.map +1 -1
- package/dist/react/use-opencode-events/helpers.d.ts +21 -8
- package/dist/react/use-opencode-events/helpers.d.ts.map +1 -1
- package/dist/react/use-opencode-events/helpers.js +25 -26
- 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 +43 -26
- package/dist/react/use-opencode-events/index.js.map +1 -1
- 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 +66 -3
- package/dist/react/use-opencode-events/use-event-stream-refs.js.map +1 -1
- package/dist/react/use-opencode-local.d.ts +17 -0
- package/dist/react/use-opencode-local.d.ts.map +1 -1
- package/dist/react/use-opencode-local.js +41 -7
- package/dist/react/use-opencode-local.js.map +1 -1
- package/dist/react/use-opencode-sessions/messages.d.ts +101 -1
- package/dist/react/use-opencode-sessions/messages.d.ts.map +1 -1
- package/dist/react/use-opencode-sessions/messages.js +481 -63
- package/dist/react/use-opencode-sessions/messages.js.map +1 -1
- package/dist/react/use-project-apps.d.ts +24 -1
- package/dist/react/use-project-apps.d.ts.map +1 -1
- package/dist/react/use-project-apps.js +5 -3
- package/dist/react/use-project-apps.js.map +1 -1
- package/dist/react/use-runtime-boot-stalled.d.ts +32 -0
- package/dist/react/use-runtime-boot-stalled.d.ts.map +1 -0
- package/dist/react/use-runtime-boot-stalled.js +48 -0
- package/dist/react/use-runtime-boot-stalled.js.map +1 -0
- package/dist/react/use-runtime-reconnect.d.ts +67 -1
- package/dist/react/use-runtime-reconnect.d.ts.map +1 -1
- package/dist/react/use-runtime-reconnect.js +116 -18
- package/dist/react/use-runtime-reconnect.js.map +1 -1
- package/dist/react/use-session-prompts.d.ts +113 -0
- package/dist/react/use-session-prompts.d.ts.map +1 -0
- package/dist/react/use-session-prompts.js +242 -0
- package/dist/react/use-session-prompts.js.map +1 -0
- package/dist/react/use-session-send.d.ts +169 -20
- package/dist/react/use-session-send.d.ts.map +1 -1
- package/dist/react/use-session-send.js +178 -29
- package/dist/react/use-session-send.js.map +1 -1
- package/dist/react/use-session-sync.d.ts +35 -2
- package/dist/react/use-session-sync.d.ts.map +1 -1
- package/dist/react/use-session-sync.js +46 -9
- package/dist/react/use-session-sync.js.map +1 -1
- package/dist/react/use-session-working.d.ts +57 -0
- package/dist/react/use-session-working.d.ts.map +1 -0
- package/dist/react/use-session-working.js +178 -0
- package/dist/react/use-session-working.js.map +1 -0
- package/dist/react/use-session.d.ts +122 -5
- package/dist/react/use-session.d.ts.map +1 -1
- package/dist/react/use-session.js +343 -69
- package/dist/react/use-session.js.map +1 -1
- package/package.json +2 -2
- package/dist/browser/stores/tab-store.d.ts +0 -91
- package/dist/browser/stores/tab-store.d.ts.map +0 -1
- package/dist/browser/stores/tab-store.js +0 -369
- package/dist/browser/stores/tab-store.js.map +0 -1
- package/dist/core/session/send-queue.d.ts +0 -70
- package/dist/core/session/send-queue.d.ts.map +0 -1
- package/dist/core/session/send-queue.js +0 -116
- package/dist/core/session/send-queue.js.map +0 -1
package/README.md
CHANGED
|
@@ -127,11 +127,8 @@ await kortix.project(pid).secrets.upsert({
|
|
|
127
127
|
const visibleSessions = await kortix.project(pid).sessions.list();
|
|
128
128
|
const projectInventory = await kortix
|
|
129
129
|
.project(pid)
|
|
130
|
-
.sessions.list({ scope: "project" }); // manager only
|
|
131
|
-
const warm = await kortix.project(pid).sessions.ensureWarm();
|
|
132
|
-
await kortix
|
|
133
|
-
.project(pid)
|
|
134
|
-
.sessions.claimWarm({ session_id: warm.session.session_id });
|
|
130
|
+
.sessions.list({ scope: "project" }); // manager only; inaccessible rows omitted
|
|
131
|
+
const warm = await kortix.project(pid).sessions.ensureWarm(); // ordinary session, pre-created
|
|
135
132
|
|
|
136
133
|
// Sessions (id-bound handle)
|
|
137
134
|
const s = kortix.session(pid, sid);
|
|
@@ -472,6 +469,16 @@ Idempotent reads (`GET`/`HEAD`) also absorb transient gateway blips: `502`,
|
|
|
472
469
|
`503`, and `504` retry up to two times with 250ms → 500ms backoff before an
|
|
473
470
|
`ApiError` is surfaced. Mutations and HTTP `500` responses are never retried.
|
|
474
471
|
|
|
472
|
+
LLM session retries can carry the gateway's structured failure chain. Use
|
|
473
|
+
`getRetryInfo(status)`. Its optional `details` field contains the final
|
|
474
|
+
`provider`, gateway `code`, `requestId`, and ordered `attemptFailures`. Each
|
|
475
|
+
failure identifies the provider, route model, resolved model, stage, upstream
|
|
476
|
+
status when available, concrete code, and bounded message. Plain legacy retry
|
|
477
|
+
messages remain supported and return `details: undefined`. When OpenCode keeps
|
|
478
|
+
only the HTTP error message, `getRetryMessage(status)` still returns the full
|
|
479
|
+
gateway composite. That message includes the request ID and each candidate's
|
|
480
|
+
provider, resolved model, HTTP status, code, and bounded message.
|
|
481
|
+
|
|
475
482
|
## Subpath modules
|
|
476
483
|
|
|
477
484
|
Stable, tree-shakeable surfaces (also reachable via the facade). Not exhaustive
|
|
@@ -487,7 +494,7 @@ Stable, tree-shakeable surfaces (also reachable via the facade). Not exhaustive
|
|
|
487
494
|
| `@kortix/sdk/server` | **Node/Bun only** — `runWithKortix`, `createScopedKortix`, `getScopedConfig` (per-request config isolation; see "Kortix as a Backend") |
|
|
488
495
|
| `@kortix/sdk/react` | every `useOpenCode*` hook + providers (reactive data), `useSession`, `useChatTurns`/`renderParts`, domain hooks (`useProjectSecrets`/`useProjectTriggers`/`useChangeRequests`) |
|
|
489
496
|
| `@kortix/sdk/turns` | framework-free part/turn classification (`classifyPart`, `classifyTurn`, `toolInfo`, turn grouping/cost helpers) |
|
|
490
|
-
| `@kortix/sdk/files` | workspace file ops (daemon `/file` + `/find`): `listFiles`, `readFile`, `readBlob`, `getFileStatus`, `findFiles`, `findText`, `uploadFile`, `deleteFile`, `mkdir`, `renameFile`, …
|
|
497
|
+
| `@kortix/sdk/files` | workspace file ops (daemon `/file` + `/find`): `listFiles`, `readFile`, `readBlob`, `getFileStatus`, `findFiles`, `findText`, `uploadFile`, `writeFile` (the only op that OVERWRITES — `uploadFile` never does), `deleteFile`, `mkdir`, `renameFile`, … |
|
|
491
498
|
| `@kortix/sdk/session` | a session's runtime surface — `getSessionHealth`/`isRuntimeReady` + proxy/preview URL builders (`rewriteLocalhostUrl`, `proxyLocalhostUrl`, `detectLocalhostUrls`, …) + preview-auth helpers. **No "sandbox" in the public surface** — a session owns its runtime |
|
|
492
499
|
| `@kortix/sdk/opencode-client` | `getClient`, `getClientForUrl` + the **full opencode v2 type surface** (`Event`, `Part`, `Message`, `Session`, `Pty`, `Config`, …) |
|
|
493
500
|
| `@kortix/sdk/projects-client` | the raw REST functions (the facade wraps these) |
|
|
@@ -30,8 +30,13 @@ export declare function prefetchSessionSyncOnce(sessionId: string, source: Sessi
|
|
|
30
30
|
export declare function clearActiveSessionPrefetches(): void;
|
|
31
31
|
export declare function retainSessionSyncController(sessionId: string, runtimeScope?: string): () => void;
|
|
32
32
|
export declare function reconcileSessionTail(sessionId: string, reason: SessionSyncReason, runtimeScope?: string): Promise<void>;
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
/**
|
|
34
|
+
* One authoritative read of a session's runtime status. `null` when the
|
|
35
|
+
* runtime exposes no status endpoint — the caller decides what silence means.
|
|
36
|
+
* A session absent from the snapshot is authoritatively idle: the runtime
|
|
37
|
+
* enumerates every session it is working on.
|
|
38
|
+
*/
|
|
39
|
+
export declare function loadSessionRuntimeStatus(sessionId: string, client?: SessionMessageClient): Promise<SessionStatus | null>;
|
|
35
40
|
export declare function loadSessionTranscriptMessages(sessionId: string): Promise<SessionSyncPage['messages']>;
|
|
36
41
|
export declare function noteSessionSyncEvent(event: {
|
|
37
42
|
type?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-sync-registry.d.ts","sourceRoot":"","sources":["../../../src/browser/session-sync/session-sync-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAE/E,OAAO,EACL,qBAAqB,EACrB,KAAK,eAAe,EACpB,KAAK,iBAAiB,EAGvB,MAAM,iDAAiD,CAAC;AAIzD,UAAU,gBAAgB;IACxB,IAAI,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,OAAO,CAAC;QAAC,KAAK,EAAE,IAAI,EAAE,CAAA;KAAE,CAAC,CAAC;IAC/C,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB;AAED,UAAU,oBAAoB;IAC5B,OAAO,EAAE;QACP,QAAQ,EAAE,CAAC,OAAO,EAAE;YAClB,SAAS,EAAE,MAAM,CAAC;YAClB,KAAK,EAAE,MAAM,CAAC;YACd,MAAM,CAAC,EAAE,MAAM,CAAC;SACjB,KAAK,OAAO,CAAC,gBAAgB,CAAC,CAAC;QAChC,MAAM,CAAC,EAAE,MAAM,OAAO,CAAC;YAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAA;SAAE,CAAC,CAAC;KAClE,CAAC;CACH;AAED,eAAO,MAAM,8BAA8B,eAAoC,CAAC;AAChF,KAAK,qBAAqB,GAAG,MAAM,GAAG,OAAO,8BAA8B,CAAC;AA4C5E,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,oBAAoB,EAC5B,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAC1C,OAAO,CAAC,eAAe,CAAC,CAU1B;
|
|
1
|
+
{"version":3,"file":"session-sync-registry.d.ts","sourceRoot":"","sources":["../../../src/browser/session-sync/session-sync-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAE/E,OAAO,EACL,qBAAqB,EACrB,KAAK,eAAe,EACpB,KAAK,iBAAiB,EAGvB,MAAM,iDAAiD,CAAC;AAIzD,UAAU,gBAAgB;IACxB,IAAI,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,OAAO,CAAC;QAAC,KAAK,EAAE,IAAI,EAAE,CAAA;KAAE,CAAC,CAAC;IAC/C,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB;AAED,UAAU,oBAAoB;IAC5B,OAAO,EAAE;QACP,QAAQ,EAAE,CAAC,OAAO,EAAE;YAClB,SAAS,EAAE,MAAM,CAAC;YAClB,KAAK,EAAE,MAAM,CAAC;YACd,MAAM,CAAC,EAAE,MAAM,CAAC;SACjB,KAAK,OAAO,CAAC,gBAAgB,CAAC,CAAC;QAChC,MAAM,CAAC,EAAE,MAAM,OAAO,CAAC;YAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAA;SAAE,CAAC,CAAC;KAClE,CAAC;CACH;AAED,eAAO,MAAM,8BAA8B,eAAoC,CAAC;AAChF,KAAK,qBAAqB,GAAG,MAAM,GAAG,OAAO,8BAA8B,CAAC;AA4C5E,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,oBAAoB,EAC5B,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAC1C,OAAO,CAAC,eAAe,CAAC,CAU1B;AAoED,wBAAgB,wBAAwB,CACtC,SAAS,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,oBAAoB,EAC7B,YAAY,CAAC,EAAE,MAAM,GACpB,qBAAqB,CAKvB;AAED,wBAAsB,uBAAuB,CAC3C,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,qBAAqB,EAC7B,MAAM,CAAC,EAAE,oBAAoB,GAC5B,OAAO,CAAC,OAAO,CAAC,CAiBlB;AAED,wBAAgB,4BAA4B,IAAI,IAAI,CAMnD;AAED,wBAAgB,2BAA2B,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,IAAI,CAoBhG;AAED,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,iBAAiB,EACzB,YAAY,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC,IAAI,CAAC,CAEf;AAED;;;;;GAKG;AACH,wBAAsB,wBAAwB,CAC5C,SAAS,EAAE,MAAM,EACjB,MAAM,GAAE,oBAAkC,GACzC,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAkB/B;AAED,wBAAgB,6BAA6B,CAC3C,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC,CAItC;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE;IAC1C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,GAAG,IAAI,CAgBP;AAED,wBAAgB,2BAA2B,IAAI,IAAI,CAGlD;AAED,8EAA8E;AAC9E,wBAAgB,qCAAqC,CACnD,SAAS,EAAE,MAAM,EACjB,gBAAgB,CAAC,EAAE,MAAM,GACxB,IAAI,CAMN"}
|
|
@@ -52,13 +52,12 @@ function createController(sessionId, key) {
|
|
|
52
52
|
return new SessionSyncController({
|
|
53
53
|
sessionId,
|
|
54
54
|
loadPage: (request) => readSessionMessagePage(resolveClient(key), sessionId, request),
|
|
55
|
-
loadStatus
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
},
|
|
55
|
+
// No `loadStatus` / `setStatus`. The liveness poll reconciles the
|
|
56
|
+
// transcript tail and claims nothing about whether the session is working:
|
|
57
|
+
// `GET .../turn` answers that, and `setBusy` is already driven from that
|
|
58
|
+
// projection (`livenessBusy`). `loadSessionRuntimeStatus` stays — it is a
|
|
59
|
+
// published export of `@kortix/sdk/react` — but this controller no longer
|
|
60
|
+
// calls it.
|
|
62
61
|
hydrate: (messages) => {
|
|
63
62
|
useSyncStore.getState().hydrate(sessionId, messages);
|
|
64
63
|
},
|
|
@@ -67,10 +66,6 @@ function createController(sessionId, key) {
|
|
|
67
66
|
if (!(sessionId in state.messages))
|
|
68
67
|
state.hydrate(sessionId, []);
|
|
69
68
|
},
|
|
70
|
-
setStatus: (status) => {
|
|
71
|
-
controllers.get(key)?.controller.observePromptStatus(status);
|
|
72
|
-
useSyncStore.getState().setStatus(sessionId, status);
|
|
73
|
-
},
|
|
74
69
|
onTelemetry: (event) => reportTelemetry(sessionId, event),
|
|
75
70
|
});
|
|
76
71
|
}
|
|
@@ -161,19 +156,28 @@ export function retainSessionSyncController(sessionId, runtimeScope) {
|
|
|
161
156
|
export function reconcileSessionTail(sessionId, reason, runtimeScope) {
|
|
162
157
|
return getSessionSyncController(sessionId, undefined, runtimeScope).reconcile(reason);
|
|
163
158
|
}
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
159
|
+
/**
|
|
160
|
+
* One authoritative read of a session's runtime status. `null` when the
|
|
161
|
+
* runtime exposes no status endpoint — the caller decides what silence means.
|
|
162
|
+
* A session absent from the snapshot is authoritatively idle: the runtime
|
|
163
|
+
* enumerates every session it is working on.
|
|
164
|
+
*/
|
|
165
|
+
export async function loadSessionRuntimeStatus(sessionId, client = getClient()) {
|
|
166
|
+
// Invoke BOUND — `client.session.status()` — never detached into a local.
|
|
167
|
+
// The real SDK's SessionClient.status() dereferences `this.client`, so a
|
|
168
|
+
// detached call throws a TypeError before any request goes out. That exact
|
|
169
|
+
// detachment silently disabled status reconciliation against real clients
|
|
170
|
+
// while every plain-object test fake kept passing.
|
|
171
|
+
if (!client.session.status)
|
|
172
|
+
return null;
|
|
173
|
+
const result = (await client.session.status());
|
|
174
|
+
// The generated client RESOLVES with { error } on HTTP failure. Mapping
|
|
175
|
+
// that to "idle" told callers a failing runtime was authoritatively done —
|
|
176
|
+
// and starved every retry budget built on thrown errors. Fail loudly.
|
|
177
|
+
if (result.error !== undefined || result.data === undefined) {
|
|
178
|
+
throw new Error(`session status read failed: ${JSON.stringify(result.error ?? 'no data')}`);
|
|
169
179
|
}
|
|
170
|
-
|
|
171
|
-
if (runtimeScopeKey(runtimeScope) === 'none' && hasAmbiguousOwner)
|
|
172
|
-
return;
|
|
173
|
-
getSessionSyncController(sessionId, undefined, runtimeScope).beginPromptObservation();
|
|
174
|
-
}
|
|
175
|
-
export function endSessionPromptObservation(sessionId, runtimeScope) {
|
|
176
|
-
findExistingSessionEntry(sessionId, runtimeScope)?.controller.endPromptObservation();
|
|
180
|
+
return result.data[sessionId] ?? { type: 'idle' };
|
|
177
181
|
}
|
|
178
182
|
export function loadSessionTranscriptMessages(sessionId) {
|
|
179
183
|
return loadCompleteSessionHistory((request) => readSessionMessagePage(getClient(), sessionId, request));
|
|
@@ -189,27 +193,12 @@ export function noteSessionSyncEvent(event) {
|
|
|
189
193
|
part?.sessionID;
|
|
190
194
|
if (!sessionId)
|
|
191
195
|
return;
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
if (status)
|
|
199
|
-
controller.observePromptStatus(status);
|
|
200
|
-
return;
|
|
201
|
-
}
|
|
202
|
-
if (event.type === 'session.idle') {
|
|
203
|
-
controller.observePromptStatus({ type: 'idle' });
|
|
204
|
-
return;
|
|
205
|
-
}
|
|
206
|
-
if (event.type === 'session.error') {
|
|
207
|
-
controller.endPromptObservation();
|
|
208
|
-
return;
|
|
209
|
-
}
|
|
210
|
-
if (event.type === 'message.updated' && info?.role === 'assistant') {
|
|
211
|
-
controller.observePromptActivity();
|
|
212
|
-
}
|
|
196
|
+
// Every frame for this session is proof its transcript moved, and that is
|
|
197
|
+
// all this hook does now: it renews freshness. The frames themselves are
|
|
198
|
+
// applied by the event handler, and "is this session working?" is answered
|
|
199
|
+
// by `projectWorking` over the server's turn authority — not by inferring a
|
|
200
|
+
// phase from which frame arrived when.
|
|
201
|
+
findExistingSessionEntry(sessionId)?.controller.noteActivity();
|
|
213
202
|
}
|
|
214
203
|
export function resetSessionSyncControllers() {
|
|
215
204
|
for (const entry of controllers.values())
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-sync-registry.js","sourceRoot":"","sources":["../../../src/browser/session-sync/session-sync-registry.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,EACL,qBAAqB,EAIrB,0BAA0B,GAC3B,MAAM,iDAAiD,CAAC;AACzD,OAAO,EAAE,0BAA0B,EAAE,MAAM,oCAAoC,CAAC;AAChF,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAkBpD,MAAM,CAAC,MAAM,8BAA8B,GAAG,MAAM,CAAC,yBAAyB,CAAC,CAAC;AAahF,MAAM,eAAe,GAAG,EAAE,CAAC;AAC3B,MAAM,WAAW,GAAG,IAAI,GAAG,EAAyB,CAAC;AAErD,SAAS,eAAe,CAAC,YAAqB;IAC5C,OAAO,YAAY,IAAI,0BAA0B,EAAE,IAAI,MAAM,CAAC;AAChE,CAAC;AAED,SAAS,aAAa,CAAC,SAAiB,EAAE,YAAqB;IAC7D,OAAO,GAAG,eAAe,CAAC,YAAY,CAAC,KAAK,SAAS,EAAE,CAAC;AAC1D,CAAC;AAED,SAAS,wBAAwB,CAC/B,SAAiB,EACjB,YAAqB;IAErB,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,aAAa,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC,CAAC;IACtE,IAAI,KAAK;QAAE,OAAO,KAAK,CAAC;IAExB,8EAA8E;IAC9E,2EAA2E;IAC3E,2EAA2E;IAC3E,yEAAyE;IACzE,IAAI,eAAe,CAAC,YAAY,CAAC,KAAK,MAAM;QAAE,OAAO,SAAS,CAAC;IAC/D,IAAI,KAAgC,CAAC;IACrC,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,MAAM,EAAE,EAAE,CAAC;QACzC,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS;YAAE,SAAS;QAC5C,IAAI,KAAK;YAAE,OAAO,SAAS,CAAC;QAC5B,KAAK,GAAG,KAAK,CAAC;IAChB,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,MAA4B,EAC5B,SAAiB,EACjB,OAA2C;IAE3C,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC;QAC3C,SAAS,EAAE,SAAS;QACpB,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACtD,CAAC,CAAC;IACH,OAAO;QACL,QAAQ,EAAE,MAAM,CAAC,IAAI,IAAI,EAAE;QAC3B,UAAU,EAAE,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,IAAI,SAAS;KACvE,CAAC;AACJ,CAAC;AAED,SAAS,eAAe,CAAC,SAAiB,EAAE,KAAgC;IAC1E,OAAO,CAAC,KAAK,CAAC,gBAAgB,EAAE,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC;AAC3D,CAAC;AAED,SAAS,aAAa,CAAC,GAAW;IAChC,OAAO,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,MAAM,IAAI,SAAS,EAAE,CAAC;AACrD,CAAC;AAED,SAAS,gBAAgB,CAAC,SAAiB,EAAE,GAAW;IACtD,OAAO,IAAI,qBAAqB,CAAC;QAC/B,SAAS;QACT,QAAQ,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,sBAAsB,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC;QACrF,
|
|
1
|
+
{"version":3,"file":"session-sync-registry.js","sourceRoot":"","sources":["../../../src/browser/session-sync/session-sync-registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
interface OpenCodeCompactionState {
|
|
2
|
-
|
|
2
|
+
/**
|
|
3
|
+
* ms epoch at which THIS tab issued `/compact` for a session.
|
|
4
|
+
*
|
|
5
|
+
* A stamp rather than a boolean, because the flag it replaced was cleared
|
|
6
|
+
* only by the `session.compacted` SSE frame — miss that frame and the
|
|
7
|
+
* composer was pinned for the lifetime of the tab. `projectCompacting`
|
|
8
|
+
* (`core/session/compaction.ts`) bounds the stamp; nothing here is authority.
|
|
9
|
+
*/
|
|
10
|
+
compactingBySession: Record<string, number>;
|
|
3
11
|
startCompaction: (sessionId: string) => void;
|
|
4
12
|
stopCompaction: (sessionId: string) => void;
|
|
5
|
-
clear: () => void;
|
|
6
|
-
clearCompaction: () => void;
|
|
7
13
|
}
|
|
8
14
|
export declare const useOpenCodeCompactionStore: import("zustand").UseBoundStore<import("zustand").StoreApi<OpenCodeCompactionState>>;
|
|
9
15
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"opencode-compaction-store.d.ts","sourceRoot":"","sources":["../../../src/browser/stores/opencode-compaction-store.ts"],"names":[],"mappings":"AAIA,UAAU,uBAAuB;IAC/B,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"opencode-compaction-store.d.ts","sourceRoot":"","sources":["../../../src/browser/stores/opencode-compaction-store.ts"],"names":[],"mappings":"AAIA,UAAU,uBAAuB;IAC/B;;;;;;;OAOG;IACH,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5C,eAAe,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7C,cAAc,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7C;AAED,eAAO,MAAM,0BAA0B,sFAqBpC,CAAC"}
|
|
@@ -3,12 +3,15 @@ import { create } from 'zustand';
|
|
|
3
3
|
export const useOpenCodeCompactionStore = create()((set) => ({
|
|
4
4
|
compactingBySession: {},
|
|
5
5
|
startCompaction: (sessionId) => set((state) => {
|
|
6
|
-
|
|
6
|
+
// Keep the FIRST stamp: re-stamping would extend the cap every time a
|
|
7
|
+
// second `/compact` fired, which is the latch in slow motion. `in`, not
|
|
8
|
+
// truthiness — an epoch is a number, and a re-issue must not restart it.
|
|
9
|
+
if (sessionId in state.compactingBySession)
|
|
7
10
|
return state;
|
|
8
11
|
return {
|
|
9
12
|
compactingBySession: {
|
|
10
13
|
...state.compactingBySession,
|
|
11
|
-
[sessionId]:
|
|
14
|
+
[sessionId]: Date.now(),
|
|
12
15
|
},
|
|
13
16
|
};
|
|
14
17
|
}),
|
|
@@ -18,15 +21,5 @@ export const useOpenCodeCompactionStore = create()((set) => ({
|
|
|
18
21
|
const { [sessionId]: _, ...rest } = state.compactingBySession;
|
|
19
22
|
return { compactingBySession: rest };
|
|
20
23
|
}),
|
|
21
|
-
clear: () => set((state) => {
|
|
22
|
-
if (Object.keys(state.compactingBySession).length === 0)
|
|
23
|
-
return state;
|
|
24
|
-
return { compactingBySession: {} };
|
|
25
|
-
}),
|
|
26
|
-
clearCompaction: () => set((state) => {
|
|
27
|
-
if (Object.keys(state.compactingBySession).length === 0)
|
|
28
|
-
return state;
|
|
29
|
-
return { compactingBySession: {} };
|
|
30
|
-
}),
|
|
31
24
|
}));
|
|
32
25
|
//# sourceMappingURL=opencode-compaction-store.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"opencode-compaction-store.js","sourceRoot":"","sources":["../../../src/browser/stores/opencode-compaction-store.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"opencode-compaction-store.js","sourceRoot":"","sources":["../../../src/browser/stores/opencode-compaction-store.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAgBjC,MAAM,CAAC,MAAM,0BAA0B,GAAG,MAAM,EAA2B,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IACpF,mBAAmB,EAAE,EAAE;IACvB,eAAe,EAAE,CAAC,SAAS,EAAE,EAAE,CAC7B,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QACZ,sEAAsE;QACtE,wEAAwE;QACxE,yEAAyE;QACzE,IAAI,SAAS,IAAI,KAAK,CAAC,mBAAmB;YAAE,OAAO,KAAK,CAAC;QACzD,OAAO;YACL,mBAAmB,EAAE;gBACnB,GAAG,KAAK,CAAC,mBAAmB;gBAC5B,CAAC,SAAS,CAAC,EAAE,IAAI,CAAC,GAAG,EAAE;aACxB;SACF,CAAC;IACJ,CAAC,CAAC;IACJ,cAAc,EAAE,CAAC,SAAS,EAAE,EAAE,CAC5B,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QACZ,IAAI,CAAC,CAAC,SAAS,IAAI,KAAK,CAAC,mBAAmB,CAAC;YAAE,OAAO,KAAK,CAAC;QAC5D,MAAM,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,GAAG,KAAK,CAAC,mBAAmB,CAAC;QAC9D,OAAO,EAAE,mBAAmB,EAAE,IAAI,EAAE,CAAC;IACvC,CAAC,CAAC;CACL,CAAC,CAAC,CAAC"}
|
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
export type SandboxConnectionStatus = "connecting" | "connected" | "unreachable";
|
|
2
|
-
export type SandboxRecoveryPhase = "idle" | "restarting_workload" | "restarting_runtime" | "restarting_host";
|
|
3
2
|
interface SandboxConnectionStore {
|
|
4
3
|
status: SandboxConnectionStatus;
|
|
5
4
|
/** How many consecutive health-check failures */
|
|
6
5
|
failCount: number;
|
|
7
|
-
/** When the connection was last confirmed */
|
|
8
|
-
lastConnectedAt: number | null;
|
|
9
6
|
/** True once at least one health check has completed (success or fail) */
|
|
10
7
|
initialCheckDone: boolean;
|
|
11
8
|
/** True if we were connected at some point and then lost connection */
|
|
@@ -14,17 +11,34 @@ interface SandboxConnectionStore {
|
|
|
14
11
|
reconnectAttempts: number;
|
|
15
12
|
/** Timestamp when status changed to unreachable/connecting (for "down since") */
|
|
16
13
|
disconnectedAt: number | null;
|
|
17
|
-
/** Current sandbox version from /kortix/health (e.g. "0.5.1") */
|
|
18
|
-
sandboxVersion: string | null;
|
|
19
14
|
/** OpenCode server version from /global/health (e.g. "1.2.10") */
|
|
20
15
|
openCodeVersion: string | null;
|
|
21
16
|
/** Whether the OpenCode server reports healthy */
|
|
22
17
|
healthy: boolean | null;
|
|
23
18
|
/** Last runtime boot/readiness error reported by /kortix/health */
|
|
24
19
|
runtimeError: string | null;
|
|
25
|
-
recoveryPhase: SandboxRecoveryPhase;
|
|
26
|
-
restartRequestedAt: number | null;
|
|
27
20
|
manualRetryNonce: number;
|
|
21
|
+
/**
|
|
22
|
+
* When the last live SSE event from the active runtime arrived. Proof of
|
|
23
|
+
* reachability that outranks a failed health probe: an event that just came
|
|
24
|
+
* over the wire cannot be stale, while a probe on a loaded box can time out
|
|
25
|
+
* even though the runtime is mid-turn and serving traffic. See
|
|
26
|
+
* `shouldIgnoreProbeFailure` in `react/use-runtime-reconnect`.
|
|
27
|
+
*/
|
|
28
|
+
lastRuntimeEvidenceAt: number | null;
|
|
29
|
+
/**
|
|
30
|
+
* When the runtime last started waiting to become healthy — set the moment
|
|
31
|
+
* `healthy` isn't `true` and cleared the moment it is. Unlike
|
|
32
|
+
* `disconnectedAt` (which tracks `status`, and is CLEARED the instant a
|
|
33
|
+
* "booting" 503 classification calls `setSandboxStatus('connected')`), this
|
|
34
|
+
* survives an indefinite `connected`-but-not-`healthy` stretch — the case a
|
|
35
|
+
* wedged OpenCode boot produces: every probe gets a 503, which resets the
|
|
36
|
+
* failure counter each time, so `status` never crosses the unreachable
|
|
37
|
+
* threshold and `disconnectedAt` never even gets set. Without a clock that
|
|
38
|
+
* survives that shape, that case has no time bound at all. See
|
|
39
|
+
* `react/use-runtime-boot-stalled`.
|
|
40
|
+
*/
|
|
41
|
+
bootingSinceAt: number | null;
|
|
28
42
|
}
|
|
29
43
|
export declare const useSandboxConnectionStore: import("zustand").UseBoundStore<import("zustand").StoreApi<SandboxConnectionStore>>;
|
|
30
44
|
export declare function requestRuntimeReconnect(): void;
|
|
@@ -38,19 +52,17 @@ export declare function resetSandboxFail(): void;
|
|
|
38
52
|
* instance starts fresh. Without this, `wasConnected` from a previous instance
|
|
39
53
|
* leaks into the new one, causing wrong thresholds and stale UI.
|
|
40
54
|
*
|
|
41
|
-
* Exception: if
|
|
42
|
-
*
|
|
43
|
-
*
|
|
55
|
+
* Exception: if POST /start already proved the runtime ready
|
|
56
|
+
* (`markRuntimeReadyVerified`), we start connected+healthy so the chat
|
|
57
|
+
* subscribes at the switch instead of after one more client health RTT.
|
|
44
58
|
*/
|
|
45
59
|
export declare function resetForServerSwitch(): void;
|
|
46
|
-
export declare function markRecoveryRequested(phase: Exclude<SandboxRecoveryPhase, 'idle'>): void;
|
|
47
|
-
export declare function markHostRestartRequested(): void;
|
|
48
60
|
/**
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
61
|
+
* Record that a live SSE event from the active runtime just arrived. Cheap and
|
|
62
|
+
* called per event, so it only writes when the timestamp actually moves the
|
|
63
|
+
* freshness window (>= 1s granularity keeps store notifications rare).
|
|
52
64
|
*/
|
|
53
|
-
export declare function
|
|
65
|
+
export declare function noteRuntimeEvidence(at?: number): void;
|
|
54
66
|
/**
|
|
55
67
|
* Called right before switching to a sandbox whose POST /start already returned
|
|
56
68
|
* stage='ready' (runtime proven healthy server-side). The next server-switch
|
|
@@ -58,7 +70,6 @@ export declare function markProvisioningVerified(): void;
|
|
|
58
70
|
* extra client health RTT. Implies provisioning-verified.
|
|
59
71
|
*/
|
|
60
72
|
export declare function markRuntimeReadyVerified(): void;
|
|
61
|
-
export declare function setSandboxVersion(version: string | null): void;
|
|
62
73
|
export declare function setOpenCodeHealth(healthy: boolean, version?: string, runtimeError?: string | null): void;
|
|
63
74
|
export {};
|
|
64
75
|
//# sourceMappingURL=sandbox-connection-store.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sandbox-connection-store.d.ts","sourceRoot":"","sources":["../../../src/browser/stores/sandbox-connection-store.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,uBAAuB,GAChC,YAAY,GACZ,WAAW,GACX,aAAa,CAAC;AAEjB,
|
|
1
|
+
{"version":3,"file":"sandbox-connection-store.d.ts","sourceRoot":"","sources":["../../../src/browser/stores/sandbox-connection-store.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,uBAAuB,GAChC,YAAY,GACZ,WAAW,GACX,aAAa,CAAC;AAEjB,UAAU,sBAAsB;IAC/B,MAAM,EAAE,uBAAuB,CAAC;IAChC,iDAAiD;IACjD,SAAS,EAAE,MAAM,CAAC;IAClB,0EAA0E;IAC1E,gBAAgB,EAAE,OAAO,CAAC;IAC1B,uEAAuE;IACvE,YAAY,EAAE,OAAO,CAAC;IACtB,gEAAgE;IAChE,iBAAiB,EAAE,MAAM,CAAC;IAC1B,iFAAiF;IACjF,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,kEAAkE;IAClE,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,kDAAkD;IAClD,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IACxB,mEAAmE;IACnE,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,gBAAgB,EAAE,MAAM,CAAC;IACzB;;;;;;OAMG;IACH,qBAAqB,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC;;;;;;;;;;;OAWG;IACH,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAkDD,eAAO,MAAM,yBAAyB,qFAanC,CAAC;AAEJ,wBAAgB,uBAAuB,SAQtC;AAID,kDAAkD;AAClD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,uBAAuB,QAoC7D;AAED,wBAAgB,oBAAoB,SAGnC;AAED,wBAAgB,oBAAoB,SAUnC;AAED,wBAAgB,gBAAgB,SAI/B;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,SAmDnC;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,EAAE,GAAE,MAAmB,QAI1D;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,SAMvC;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,QAwBjG"}
|
|
@@ -5,7 +5,6 @@ import { logger } from "../../core/http/logger.js";
|
|
|
5
5
|
// blocking overlay. By persisting it, users who were previously connected
|
|
6
6
|
// see the lightweight reconnect pill instead, making reconnection feel instant.
|
|
7
7
|
const STORAGE_KEY = "kortix-runtime-was-connected";
|
|
8
|
-
const PROVISION_VERIFIED_KEY = "kortix-runtime-provision-verified";
|
|
9
8
|
// Stronger than PROVISION_VERIFIED: POST /start already resolved stage='ready',
|
|
10
9
|
// which the backend only returns once it reached the daemon's /session (runtime
|
|
11
10
|
// proven healthy server-side). When this flag is set, the new instance starts
|
|
@@ -33,22 +32,6 @@ function saveWasConnected(value) {
|
|
|
33
32
|
/* SSR or storage unavailable */
|
|
34
33
|
}
|
|
35
34
|
}
|
|
36
|
-
function loadProvisionVerified() {
|
|
37
|
-
try {
|
|
38
|
-
return sessionStorage.getItem(PROVISION_VERIFIED_KEY) === "1";
|
|
39
|
-
}
|
|
40
|
-
catch {
|
|
41
|
-
return false;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
function clearProvisionVerified() {
|
|
45
|
-
try {
|
|
46
|
-
sessionStorage.removeItem(PROVISION_VERIFIED_KEY);
|
|
47
|
-
}
|
|
48
|
-
catch {
|
|
49
|
-
/* SSR or storage unavailable */
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
35
|
function loadRuntimeReadyVerified() {
|
|
53
36
|
try {
|
|
54
37
|
return sessionStorage.getItem(RUNTIME_READY_VERIFIED_KEY) === "1";
|
|
@@ -68,23 +51,24 @@ function clearRuntimeReadyVerified() {
|
|
|
68
51
|
export const useSandboxConnectionStore = create(() => ({
|
|
69
52
|
status: "connecting",
|
|
70
53
|
failCount: 0,
|
|
71
|
-
lastConnectedAt: null,
|
|
72
54
|
initialCheckDone: false,
|
|
73
55
|
wasConnected: loadWasConnected(),
|
|
74
56
|
reconnectAttempts: 0,
|
|
75
57
|
disconnectedAt: null,
|
|
76
|
-
sandboxVersion: null,
|
|
77
58
|
openCodeVersion: null,
|
|
78
59
|
healthy: null,
|
|
79
60
|
runtimeError: null,
|
|
80
|
-
recoveryPhase: "idle",
|
|
81
|
-
restartRequestedAt: null,
|
|
82
61
|
manualRetryNonce: 0,
|
|
62
|
+
lastRuntimeEvidenceAt: null,
|
|
63
|
+
bootingSinceAt: null,
|
|
83
64
|
}));
|
|
84
65
|
export function requestRuntimeReconnect() {
|
|
85
66
|
useSandboxConnectionStore.setState((state) => ({
|
|
86
67
|
status: "connecting", healthy: null, failCount: 0, runtimeError: null,
|
|
87
68
|
disconnectedAt: state.disconnectedAt ?? Date.now(), manualRetryNonce: state.manualRetryNonce + 1,
|
|
69
|
+
// A manual retry is the user's own reset — give the stall clock a fresh
|
|
70
|
+
// start too, instead of it re-firing on the very next tick.
|
|
71
|
+
bootingSinceAt: Date.now(),
|
|
88
72
|
}));
|
|
89
73
|
}
|
|
90
74
|
// ── Static actions (stable references, no re-render loops) ──
|
|
@@ -95,13 +79,10 @@ export function setSandboxStatus(next) {
|
|
|
95
79
|
return;
|
|
96
80
|
const updates = { status: next };
|
|
97
81
|
if (next === "connected") {
|
|
98
|
-
updates.lastConnectedAt = Date.now();
|
|
99
82
|
updates.failCount = 0;
|
|
100
83
|
updates.wasConnected = true;
|
|
101
84
|
updates.reconnectAttempts = 0;
|
|
102
85
|
updates.disconnectedAt = null;
|
|
103
|
-
updates.recoveryPhase = "idle";
|
|
104
|
-
updates.restartRequestedAt = null;
|
|
105
86
|
saveWasConnected(true);
|
|
106
87
|
if (state.status === "unreachable") {
|
|
107
88
|
logger.info("Sandbox connection restored", {
|
|
@@ -155,15 +136,13 @@ export function resetSandboxFail() {
|
|
|
155
136
|
* instance starts fresh. Without this, `wasConnected` from a previous instance
|
|
156
137
|
* leaks into the new one, causing wrong thresholds and stale UI.
|
|
157
138
|
*
|
|
158
|
-
* Exception: if
|
|
159
|
-
*
|
|
160
|
-
*
|
|
139
|
+
* Exception: if POST /start already proved the runtime ready
|
|
140
|
+
* (`markRuntimeReadyVerified`), we start connected+healthy so the chat
|
|
141
|
+
* subscribes at the switch instead of after one more client health RTT.
|
|
161
142
|
*/
|
|
162
143
|
export function resetForServerSwitch() {
|
|
163
144
|
const runtimeReady = loadRuntimeReadyVerified();
|
|
164
|
-
const fromProvisioning = loadProvisionVerified();
|
|
165
145
|
clearRuntimeReadyVerified();
|
|
166
|
-
clearProvisionVerified();
|
|
167
146
|
if (runtimeReady) {
|
|
168
147
|
// /start already resolved stage==='ready' (markRuntimeReadyVerified is set
|
|
169
148
|
// ONLY then — page.tsx), which the backend returns only after it reached the
|
|
@@ -185,34 +164,12 @@ export function resetForServerSwitch() {
|
|
|
185
164
|
wasConnected: true,
|
|
186
165
|
reconnectAttempts: 0,
|
|
187
166
|
disconnectedAt: null,
|
|
188
|
-
sandboxVersion: null,
|
|
189
167
|
openCodeVersion: null,
|
|
190
168
|
healthy: true,
|
|
191
169
|
runtimeError: null,
|
|
192
|
-
recoveryPhase: "idle",
|
|
193
|
-
restartRequestedAt: null,
|
|
194
|
-
manualRetryNonce: 0,
|
|
195
|
-
});
|
|
196
|
-
saveWasConnected(true);
|
|
197
|
-
return;
|
|
198
|
-
}
|
|
199
|
-
if (fromProvisioning) {
|
|
200
|
-
// Provisioning already verified health — skip the blocking overlay.
|
|
201
|
-
// The health poller will still run and correct the status if needed.
|
|
202
|
-
useSandboxConnectionStore.setState({
|
|
203
|
-
status: "connecting",
|
|
204
|
-
failCount: 0,
|
|
205
|
-
initialCheckDone: false,
|
|
206
|
-
wasConnected: true, // lightweight reconnect pill instead of blocking overlay
|
|
207
|
-
reconnectAttempts: 0,
|
|
208
|
-
disconnectedAt: null,
|
|
209
|
-
sandboxVersion: null,
|
|
210
|
-
openCodeVersion: null,
|
|
211
|
-
healthy: null,
|
|
212
|
-
runtimeError: null,
|
|
213
|
-
recoveryPhase: "idle",
|
|
214
|
-
restartRequestedAt: null,
|
|
215
170
|
manualRetryNonce: 0,
|
|
171
|
+
lastRuntimeEvidenceAt: null,
|
|
172
|
+
bootingSinceAt: null,
|
|
216
173
|
});
|
|
217
174
|
saveWasConnected(true);
|
|
218
175
|
return;
|
|
@@ -224,40 +181,25 @@ export function resetForServerSwitch() {
|
|
|
224
181
|
wasConnected: false,
|
|
225
182
|
reconnectAttempts: 0,
|
|
226
183
|
disconnectedAt: null,
|
|
227
|
-
sandboxVersion: null,
|
|
228
184
|
openCodeVersion: null,
|
|
229
185
|
healthy: null,
|
|
230
186
|
runtimeError: null,
|
|
231
|
-
recoveryPhase: "idle",
|
|
232
|
-
restartRequestedAt: null,
|
|
233
187
|
manualRetryNonce: 0,
|
|
188
|
+
lastRuntimeEvidenceAt: null,
|
|
189
|
+
bootingSinceAt: Date.now(),
|
|
234
190
|
});
|
|
235
191
|
saveWasConnected(false);
|
|
236
192
|
}
|
|
237
|
-
export function markRecoveryRequested(phase) {
|
|
238
|
-
const now = Date.now();
|
|
239
|
-
useSandboxConnectionStore.setState((state) => ({
|
|
240
|
-
recoveryPhase: phase,
|
|
241
|
-
restartRequestedAt: now,
|
|
242
|
-
status: state.status === "connected" ? "connecting" : state.status,
|
|
243
|
-
disconnectedAt: state.disconnectedAt ?? now,
|
|
244
|
-
}));
|
|
245
|
-
}
|
|
246
|
-
export function markHostRestartRequested() {
|
|
247
|
-
markRecoveryRequested("restarting_host");
|
|
248
|
-
}
|
|
249
193
|
/**
|
|
250
|
-
*
|
|
251
|
-
*
|
|
252
|
-
*
|
|
194
|
+
* Record that a live SSE event from the active runtime just arrived. Cheap and
|
|
195
|
+
* called per event, so it only writes when the timestamp actually moves the
|
|
196
|
+
* freshness window (>= 1s granularity keeps store notifications rare).
|
|
253
197
|
*/
|
|
254
|
-
export function
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
/* SSR or storage unavailable */
|
|
260
|
-
}
|
|
198
|
+
export function noteRuntimeEvidence(at = Date.now()) {
|
|
199
|
+
const previous = useSandboxConnectionStore.getState().lastRuntimeEvidenceAt;
|
|
200
|
+
if (previous !== null && at - previous < 1_000)
|
|
201
|
+
return;
|
|
202
|
+
useSandboxConnectionStore.setState({ lastRuntimeEvidenceAt: at });
|
|
261
203
|
}
|
|
262
204
|
/**
|
|
263
205
|
* Called right before switching to a sandbox whose POST /start already returned
|
|
@@ -273,12 +215,6 @@ export function markRuntimeReadyVerified() {
|
|
|
273
215
|
/* SSR or storage unavailable */
|
|
274
216
|
}
|
|
275
217
|
}
|
|
276
|
-
export function setSandboxVersion(version) {
|
|
277
|
-
const current = useSandboxConnectionStore.getState().sandboxVersion;
|
|
278
|
-
if (current === version)
|
|
279
|
-
return;
|
|
280
|
-
useSandboxConnectionStore.setState({ sandboxVersion: version });
|
|
281
|
-
}
|
|
282
218
|
export function setOpenCodeHealth(healthy, version, runtimeError) {
|
|
283
219
|
const state = useSandboxConnectionStore.getState();
|
|
284
220
|
const updates = {};
|
|
@@ -293,6 +229,18 @@ export function setOpenCodeHealth(healthy, version, runtimeError) {
|
|
|
293
229
|
else if (healthy && state.runtimeError !== null) {
|
|
294
230
|
updates.runtimeError = null;
|
|
295
231
|
}
|
|
232
|
+
// Start (or keep) the stall clock while not healthy; clear it the instant
|
|
233
|
+
// we are. A "booting" 503 classification resets `failCount` on every tick
|
|
234
|
+
// (see `use-runtime-reconnect`'s `classifyProbeResult`), so it can repeat
|
|
235
|
+
// forever without ever crossing the unreachable threshold — this clock is
|
|
236
|
+
// the only thing that still bounds that case. See `bootingSinceAt`.
|
|
237
|
+
if (healthy) {
|
|
238
|
+
if (state.bootingSinceAt !== null)
|
|
239
|
+
updates.bootingSinceAt = null;
|
|
240
|
+
}
|
|
241
|
+
else if (state.bootingSinceAt === null) {
|
|
242
|
+
updates.bootingSinceAt = Date.now();
|
|
243
|
+
}
|
|
296
244
|
if (Object.keys(updates).length > 0) {
|
|
297
245
|
useSandboxConnectionStore.setState(updates);
|
|
298
246
|
}
|