@kortix/sdk 0.13.3 → 0.13.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/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/session-sync-registry.d.ts +20 -0
- package/dist/browser/session-sync/session-sync-registry.d.ts.map +1 -1
- package/dist/browser/session-sync/session-sync-registry.js +69 -6
- 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.js +1 -1
- package/dist/browser/stores/sandbox-connection-store.js.map +1 -1
- package/dist/browser/stores/sync-store.d.ts +27 -1
- package/dist/browser/stores/sync-store.d.ts.map +1 -1
- package/dist/browser/stores/sync-store.js +198 -41
- package/dist/browser/stores/sync-store.js.map +1 -1
- package/dist/core/client/kortix.d.ts +0 -11
- package/dist/core/client/kortix.d.ts.map +1 -1
- package/dist/core/client/kortix.js +14 -8
- package/dist/core/client/kortix.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/index.d.ts +0 -2
- package/dist/core/rest/projects-client/index.d.ts.map +1 -1
- package/dist/core/rest/projects-client/index.js +0 -2
- 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 +5 -3
- package/dist/core/rest/projects-client/projects.js.map +1 -1
- package/dist/core/rest/projects-client/sessions.d.ts +8 -33
- package/dist/core/rest/projects-client/sessions.d.ts.map +1 -1
- package/dist/core/rest/projects-client/sessions.js +1 -18
- 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 +1 -0
- package/dist/core/session/index.d.ts.map +1 -1
- package/dist/core/session/index.js +1 -0
- package/dist/core/session/index.js.map +1 -1
- 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/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/working.d.ts +44 -0
- package/dist/core/session/working.d.ts.map +1 -1
- package/dist/core/session/working.js +146 -4
- 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 +83 -9
- package/dist/core/session-sync/session-sync-controller.d.ts.map +1 -1
- package/dist/core/session-sync/session-sync-controller.js +183 -17
- package/dist/core/session-sync/session-sync-controller.js.map +1 -1
- package/dist/core/turns/grouping.d.ts.map +1 -1
- package/dist/core/turns/grouping.js +60 -23
- package/dist/core/turns/grouping.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/kortix.esm.min.js +24 -24
- package/dist/kortix.global.js +24 -24
- 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/opencode.d.ts +1 -0
- package/dist/react/opencode.d.ts.map +1 -1
- package/dist/react/opencode.js +3 -0
- package/dist/react/opencode.js.map +1 -1
- package/dist/react/use-admin-accounts.d.ts +35 -0
- package/dist/react/use-admin-accounts.d.ts.map +1 -1
- package/dist/react/use-admin-accounts.js +18 -0
- package/dist/react/use-admin-accounts.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/index.d.ts.map +1 -1
- package/dist/react/use-opencode-events/index.js +59 -6
- 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-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 +12 -2
- 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-session-prompts.d.ts +37 -2
- package/dist/react/use-session-prompts.d.ts.map +1 -1
- package/dist/react/use-session-prompts.js +62 -15
- 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 +40 -4
- package/dist/react/use-session-send.js.map +1 -1
- package/dist/react/use-session-sync.d.ts +13 -1
- package/dist/react/use-session-sync.d.ts.map +1 -1
- package/dist/react/use-session-sync.js +81 -55
- package/dist/react/use-session-sync.js.map +1 -1
- package/dist/react/use-session-working.d.ts +17 -0
- package/dist/react/use-session-working.d.ts.map +1 -1
- package/dist/react/use-session-working.js +33 -3
- package/dist/react/use-session-working.js.map +1 -1
- package/package.json +3 -3
- 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
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
import { 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 { transcriptIsFragment } from '../core/session-sync/fragment.js';
|
|
6
|
+
import { onTabVisible } from '../browser/session-sync/visibility.js';
|
|
6
7
|
import { useSandboxConnectionStore } from '../browser/stores/sandbox-connection-store.js';
|
|
7
8
|
import { useSyncStore } from '../browser/stores/sync-store.js';
|
|
8
9
|
import { useCurrentRuntime } from './use-current-runtime.js';
|
|
@@ -27,7 +28,7 @@ export function sessionSyncBusy(input) {
|
|
|
27
28
|
* projection outranks the stream slot" is a test rather than a convention.
|
|
28
29
|
*/
|
|
29
30
|
export function livenessBusy(input) {
|
|
30
|
-
if (!input.networkEnabled
|
|
31
|
+
if (!input.networkEnabled)
|
|
31
32
|
return false;
|
|
32
33
|
return sessionSyncBusy(input);
|
|
33
34
|
}
|
|
@@ -65,69 +66,94 @@ export function useSessionSync(sessionId, options = {}) {
|
|
|
65
66
|
resetSessionSyncControllersForSession(sessionId, runtimeScope === 'none' ? undefined : runtimeScope);
|
|
66
67
|
useSyncStore.getState().clearSession(sessionId);
|
|
67
68
|
}, [cacheOwnerScope, runtimeScope, sessionId]);
|
|
68
|
-
//
|
|
69
|
-
//
|
|
70
|
-
//
|
|
71
|
-
//
|
|
72
|
-
//
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
69
|
+
// NO DISK PAINT. The transcript renders from the runtime and from this tab's
|
|
70
|
+
// own optimistic writes — nothing else.
|
|
71
|
+
//
|
|
72
|
+
// There used to be an IndexedDB mirror here, hydrated before `runtimeHealthy`
|
|
73
|
+
// so a hibernated session showed its history instead of a blank screen for
|
|
74
|
+
// the length of a VM boot. It was removed because it could not tell a
|
|
75
|
+
// FINISHED turn from a running one. Its write gate was structural (message
|
|
76
|
+
// count, total part count, tail id), and the two changes that end a turn move
|
|
77
|
+
// none of those: `time.completed` stamped on the tail message, and the `error`
|
|
78
|
+
// an abort stamps. A normal turn escaped by accident, because OpenCode
|
|
79
|
+
// appends a `step-finish` part and that moves the part count — but a STOP
|
|
80
|
+
// appends no part at all. So the disk copy of a stopped thread held an
|
|
81
|
+
// assistant message with neither `time.completed` nor `error`, which
|
|
82
|
+
// `open-turn.ts` reads as STILL RUNNING: on the next cold paint the stopped
|
|
83
|
+
// turn shimmered and every message the user sent after it dimmed to "Queued".
|
|
84
|
+
//
|
|
85
|
+
// The cold-open cost is real and known — see `session-sync-registry`'s
|
|
86
|
+
// `reconcile('initial')` below, which is now the only thing that fills the
|
|
87
|
+
// transcript. If the blank wake is worth solving again, it needs a mirror
|
|
88
|
+
// whose freshness test reads the MESSAGE, not its shape.
|
|
89
|
+
// ASK AS SOON AS WE KNOW WHICH SANDBOX — not when a probe agrees.
|
|
90
|
+
//
|
|
91
|
+
// This read used to wait for `runtimeHealthy === true`, and that one
|
|
92
|
+
// condition is what hung the session page. `resolveSessionContentState` keeps
|
|
93
|
+
// the web app on its "Waking the agent" loader while there are no messages,
|
|
94
|
+
// and this read is the only thing that produces messages. So the page's ONLY
|
|
95
|
+
// exit was a health probe — the least reliable signal in the system — and a
|
|
96
|
+
// box that was up while failing its probe showed a spinner over a session
|
|
97
|
+
// that could have been read the whole time. The sidebar, reading the session
|
|
98
|
+
// list instead, showed the same session as live: one page, two answers.
|
|
99
|
+
//
|
|
100
|
+
// The read IS the liveness check. If the runtime is not up the request fails
|
|
101
|
+
// and the controller retries with backoff until it lands, so readiness
|
|
102
|
+
// becomes a byproduct of asking for what we wanted anyway.
|
|
96
103
|
useEffect(() => {
|
|
97
|
-
if (!networkEnabled ||
|
|
98
|
-
!canQueryOpenCodeSession(sessionId) ||
|
|
99
|
-
!runtimeHealthy ||
|
|
100
|
-
runtimeScope === 'none')
|
|
104
|
+
if (!networkEnabled || !canQueryOpenCodeSession(sessionId) || runtimeScope === 'none')
|
|
101
105
|
return;
|
|
102
106
|
resetSessionSyncControllersForSession(sessionId, runtimeScope);
|
|
103
107
|
const release = retainSessionSyncController(sessionId, runtimeScope);
|
|
104
|
-
//
|
|
105
|
-
//
|
|
108
|
+
// The ONLY thing that fills the transcript. One bounded tail, so events
|
|
109
|
+
// produced while this route was inactive are not skipped.
|
|
106
110
|
void controller.reconcile('initial');
|
|
107
111
|
return release;
|
|
108
|
-
}, [controller, networkEnabled,
|
|
109
|
-
//
|
|
110
|
-
//
|
|
111
|
-
//
|
|
112
|
-
//
|
|
112
|
+
}, [controller, networkEnabled, runtimeScope, sessionId]);
|
|
113
|
+
// A transcript the live stream rebuilt after an eviction starts
|
|
114
|
+
// mid-conversation, and nothing else will correct it: the mount already ran,
|
|
115
|
+
// so no `initial` read is coming, and the liveness poll only turns on while
|
|
116
|
+
// the session is working. Removing the IndexedDB mirror (5a7a43517f) named
|
|
117
|
+
// this exact hole and left it open — "no reconcile is keyed on eviction …
|
|
118
|
+
// can sit on a partial transcript until a reload".
|
|
119
|
+
//
|
|
120
|
+
// Subscribed rather than checked once, because the refill happens while this
|
|
121
|
+
// component is already mounted. `hydrate` clears the mark, so the successful
|
|
122
|
+
// read is what disarms this.
|
|
113
123
|
useEffect(() => {
|
|
114
|
-
if (!canQueryOpenCodeSession(sessionId))
|
|
124
|
+
if (!networkEnabled || !canQueryOpenCodeSession(sessionId))
|
|
115
125
|
return;
|
|
116
|
-
let
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
// The store is shared by every session and also carries status/todos, so
|
|
120
|
-
// most notifications are irrelevant here. Compare the two slices this
|
|
121
|
-
// cache actually mirrors before rebuilding anything.
|
|
122
|
-
if (state.messages[sessionId] === lastMessages && state.parts === lastParts)
|
|
126
|
+
let repairing = false;
|
|
127
|
+
const check = (state) => {
|
|
128
|
+
if (repairing)
|
|
123
129
|
return;
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
130
|
+
if (!transcriptIsFragment({
|
|
131
|
+
hasMessages: (state.messages[sessionId]?.length ?? 0) > 0,
|
|
132
|
+
wasEvicted: state.wasTranscriptEvicted(sessionId),
|
|
133
|
+
})) {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
repairing = true;
|
|
137
|
+
void controller.reconcile('eviction').finally(() => {
|
|
138
|
+
repairing = false;
|
|
139
|
+
});
|
|
127
140
|
};
|
|
128
|
-
|
|
129
|
-
return useSyncStore.subscribe(
|
|
130
|
-
}, [
|
|
141
|
+
check(useSyncStore.getState());
|
|
142
|
+
return useSyncStore.subscribe((state) => check(state));
|
|
143
|
+
}, [controller, networkEnabled, sessionId]);
|
|
144
|
+
// Coming back to the tab is a moment of MAXIMUM uncertainty, so it is a
|
|
145
|
+
// moment to re-read. A backgrounded tab has its timers clamped (Chrome: about
|
|
146
|
+
// one tick a minute), so the 10s liveness poll effectively stops, and the SSE
|
|
147
|
+
// connection can be dropped with no visible error. Whatever the transcript
|
|
148
|
+
// shows on return was assembled from a stream nobody was watching. One
|
|
149
|
+
// bounded tail read settles it.
|
|
150
|
+
useEffect(() => {
|
|
151
|
+
if (!networkEnabled || !canQueryOpenCodeSession(sessionId))
|
|
152
|
+
return;
|
|
153
|
+
return onTabVisible(() => {
|
|
154
|
+
void controller.reconcile('visible');
|
|
155
|
+
});
|
|
156
|
+
}, [controller, networkEnabled, sessionId]);
|
|
131
157
|
const messages = useSyncStore((state) => state.buildSessionMessages(readableSessionId, state.messages[readableSessionId], state.parts));
|
|
132
158
|
// The runtime's own status, unmodified.
|
|
133
159
|
//
|
|
@@ -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;AACxD,OAAO,EACL,0BAA0B,EAC1B,wBAAwB,EACxB,6BAA6B,EAC7B,+BAA+B,GAChC,MAAM,iDAAiD,CAAC;AACzD,OAAO,EACL,wBAAwB,EACxB,wBAAwB,EACxB,6BAA6B,EAC7B,qCAAqC,EACrC,2BAA2B,GAC5B,MAAM,+CAA+C,CAAC;AACvD,OAAO,
|
|
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,9 @@ export declare function buildWorkingInputs(input: {
|
|
|
36
50
|
inbox: WorkingInboxInput | undefined;
|
|
37
51
|
status: SessionStatus | undefined;
|
|
38
52
|
statusAtMs: number;
|
|
53
|
+
/** When the runtime's own output last reached this tab for this session
|
|
54
|
+
* (`useSyncStore.sessionActivityAt`). 0/undefined when it never has. */
|
|
55
|
+
activityAtMs?: number;
|
|
39
56
|
optimistic: SendReceipt | null;
|
|
40
57
|
abort?: AbortReceipt | null;
|
|
41
58
|
nowMs: number;
|
|
@@ -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;AAGjC;;;;;;;;;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;;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,UAAU,EAAE,WAAW,GAAG,IAAI,CAAC;IAC/B,KAAK,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC;IAC5B,KAAK,EAAE,MAAM,CAAC;CACf,GAAG,aAAa,
|
|
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;AAGjC;;;;;;;;;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;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,CA2BhB;AAED,MAAM,WAAW,wBAAwB;IACvC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;;;;;OAQG;IACH,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAMD,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,wBAA6B,GACrC,iBAAiB,CAkJnB"}
|
|
@@ -27,6 +27,24 @@ export const WORKING_POLL_ACTIVE_MS = 5_000;
|
|
|
27
27
|
export function workingPollMs(projection) {
|
|
28
28
|
return projection.state === 'working' ? WORKING_POLL_ACTIVE_MS : WORKING_POLL_IDLE_MS;
|
|
29
29
|
}
|
|
30
|
+
/**
|
|
31
|
+
* Which side of a turn boundary a status frame is on.
|
|
32
|
+
*
|
|
33
|
+
* The runtime does NOT emit one frame per turn. Measured mid-turn on the local
|
|
34
|
+
* stack, it alternated `busy` → `retry` → `busy` about every 140ms, and an
|
|
35
|
+
* effect keyed on the observation INSTANT therefore re-invalidated `/turn` and
|
|
36
|
+
* `/prompts` at that rate, once per mount. A `busy`→`retry` flip is not news
|
|
37
|
+
* about whether a turn is open; only crossing between `idle` and not-idle is.
|
|
38
|
+
*
|
|
39
|
+
* `'none'` is deliberately distinct from `'idle'`: silence is not an
|
|
40
|
+
* observation, and collapsing them would stop the FIRST frame of a turn from
|
|
41
|
+
* reading as a change.
|
|
42
|
+
*/
|
|
43
|
+
export function streamTurnPhase(status) {
|
|
44
|
+
if (!status)
|
|
45
|
+
return 'none';
|
|
46
|
+
return status.type === 'idle' ? 'idle' : 'active';
|
|
47
|
+
}
|
|
30
48
|
/** Fold the two live sources plus the local receipt into the projection's
|
|
31
49
|
* inputs. Pure, so "a failed read contributes nothing" is a test, not a
|
|
32
50
|
* convention. */
|
|
@@ -39,6 +57,11 @@ export function buildWorkingInputs(input) {
|
|
|
39
57
|
server: input.turn
|
|
40
58
|
? { turns: input.turn.turns, lastEnded: input.turn.last_ended, atMs: input.turn.atMs }
|
|
41
59
|
: null,
|
|
60
|
+
// The runtime's own output, which is not an observation OF the runtime but
|
|
61
|
+
// the runtime itself — see `WorkingActivityInput`. It is what answers when
|
|
62
|
+
// every observer has gone quiet: a dropped status frame, a poll throttled
|
|
63
|
+
// by a backgrounded tab.
|
|
64
|
+
activity: input.activityAtMs ? { atMs: input.activityAtMs } : null,
|
|
42
65
|
// Silence is not an observation. A session with no status frame yet feeds
|
|
43
66
|
// NOTHING here — the old code read "no status" as idle, which unmasked
|
|
44
67
|
// live turns whenever a frame was dropped.
|
|
@@ -98,12 +121,16 @@ export function useSessionWorking(projectId, sessionId, options = {}) {
|
|
|
98
121
|
setObserved({ key: streamKey, status, atMs: Date.now() });
|
|
99
122
|
}, [status, streamKey]);
|
|
100
123
|
const stream = observed && observed.key === streamKey ? observed : null;
|
|
124
|
+
// The runtime's own output for THIS session's wire id. Quantized to a second
|
|
125
|
+
// in the store, so subscribing here cannot re-render at the stream's rate.
|
|
126
|
+
const activityAtMs = useSyncStore((s) => streamKey ? s.sessionActivityAt[streamKey] : undefined);
|
|
101
127
|
const canRead = enabled && !!projectId && !!sessionId;
|
|
102
128
|
const inputsFor = (turn, nowMs) => buildWorkingInputs({
|
|
103
129
|
turn,
|
|
104
130
|
inbox,
|
|
105
131
|
status: stream?.status,
|
|
106
132
|
statusAtMs: stream?.atMs ?? 0,
|
|
133
|
+
activityAtMs,
|
|
107
134
|
optimistic,
|
|
108
135
|
abort,
|
|
109
136
|
nowMs,
|
|
@@ -138,9 +165,12 @@ export function useSessionWorking(projectId, sessionId, options = {}) {
|
|
|
138
165
|
// input with a life shorter than its own poll interval, and the turn ending
|
|
139
166
|
// is exactly when a `waiting` row becomes a running one.
|
|
140
167
|
const queryClient = useQueryClient();
|
|
141
|
-
|
|
168
|
+
// Keyed on the PHASE, not on the observation instant. The instant changes on
|
|
169
|
+
// every frame, and the runtime emits many per turn — see `streamTurnPhase`
|
|
170
|
+
// for the measured `busy`/`retry` oscillation this stops re-fetching on.
|
|
171
|
+
const streamPhase = streamTurnPhase(stream?.status);
|
|
142
172
|
useEffect(() => {
|
|
143
|
-
if (!canRead ||
|
|
173
|
+
if (!canRead || streamPhase === 'none')
|
|
144
174
|
return;
|
|
145
175
|
void queryClient.invalidateQueries({
|
|
146
176
|
queryKey: qk.project.sessionTurn(projectId, sessionId),
|
|
@@ -148,7 +178,7 @@ export function useSessionWorking(projectId, sessionId, options = {}) {
|
|
|
148
178
|
void queryClient.invalidateQueries({
|
|
149
179
|
queryKey: qk.project.sessionPrompts(projectId, sessionId),
|
|
150
180
|
});
|
|
151
|
-
}, [canRead, projectId, sessionId,
|
|
181
|
+
}, [canRead, projectId, sessionId, streamPhase, queryClient]);
|
|
152
182
|
// Re-evaluated on every render because `nowMs` moves — the projection is
|
|
153
183
|
// pure, so this costs one object and cannot drift from the poll's own view.
|
|
154
184
|
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;AAElC;;;;;;;;;GASG;AAEH;;;yBAGyB;AACzB,MAAM,CAAC,MAAM,oBAAoB,GAAG,MAAM,CAAC;AAC3C;8EAC8E;AAC9E,MAAM,CAAC,MAAM,sBAAsB,GAAG,KAAK,CAAC;AAE5C,MAAM,UAAU,aAAa,CAAC,UAA6B;IACzD,OAAO,UAAU,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,oBAAoB,CAAC;AACxF,CAAC;AAWD;;kBAEkB;AAClB,MAAM,UAAU,kBAAkB,CAAC,
|
|
1
|
+
{"version":3,"file":"use-session-working.js","sourceRoot":"","sources":["../../src/react/use-session-working.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kortix/sdk",
|
|
3
|
-
"version": "0.13.
|
|
3
|
+
"version": "0.13.5",
|
|
4
4
|
"description": "Official Kortix frontend TypeScript SDK — one typed client for the Kortix agent platform. Unifies project/session lifecycle and live agent streaming behind a single ergonomic Session handle, so web, mobile, and white-label apps never touch the raw HTTP API or OpenCode semantics.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Elastic-2.0",
|
|
@@ -20,8 +20,8 @@
|
|
|
20
20
|
],
|
|
21
21
|
"sideEffects": false,
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@kortix/llm-catalog": "0.13.
|
|
24
|
-
"@opencode-ai/sdk": "1.
|
|
23
|
+
"@kortix/llm-catalog": "0.13.5",
|
|
24
|
+
"@opencode-ai/sdk": "1.18.19",
|
|
25
25
|
"zustand": "^5.0.3"
|
|
26
26
|
},
|
|
27
27
|
"peerDependencies": {
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Local transcript cache — the reason a session can paint before its sandbox
|
|
3
|
-
* is awake.
|
|
4
|
-
*
|
|
5
|
-
* Reading a transcript used to be gated on booting a VM: the messages live on
|
|
6
|
-
* the opencode runtime *inside* the session's sandbox, reachable only through
|
|
7
|
-
* `/p/{externalId}/…`, so opening a hibernated session meant waiting out the
|
|
8
|
-
* whole `/start` wake before a single word appeared. The transcript is already
|
|
9
|
-
* settled history; it does not need a running machine to be shown.
|
|
10
|
-
*
|
|
11
|
-
* So: mirror the tail into IndexedDB as it arrives, and hydrate straight back
|
|
12
|
-
* out of it on open. The live runtime still reconciles behind it — this only
|
|
13
|
-
* changes WHEN the user sees what is already theirs, never what is true.
|
|
14
|
-
*/
|
|
15
|
-
import type { Message, Part } from '@opencode-ai/sdk/v2/client';
|
|
16
|
-
export interface CachedTranscript {
|
|
17
|
-
messages: Message[];
|
|
18
|
-
parts: Record<string, Part[]>;
|
|
19
|
-
}
|
|
20
|
-
interface TranscriptStoreSlice {
|
|
21
|
-
messages: Record<string, Message[]>;
|
|
22
|
-
parts: Record<string, Part[]>;
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* Pull one session's messages, plus only the parts belonging to them, out of
|
|
26
|
-
* the (globally part-keyed) sync store. Returns null when there is nothing
|
|
27
|
-
* worth persisting — an absent session and an empty one are the same to a
|
|
28
|
-
* cache whose entire job is having something to show.
|
|
29
|
-
*/
|
|
30
|
-
export declare function selectSessionTranscript(state: TranscriptStoreSlice, sessionId: string,
|
|
31
|
-
/**
|
|
32
|
-
* Messages to leave OUT of the entry — this tab's optimistic stubs. The
|
|
33
|
-
* cache mirrors the runtime's transcript, and a stub is not in it: persisted,
|
|
34
|
-
* it came back after a reload as a plain message the runtime had never
|
|
35
|
-
* heard of, beside the real one, for ever.
|
|
36
|
-
*/
|
|
37
|
-
exclude?: (messageId: string) => boolean): CachedTranscript | null;
|
|
38
|
-
/** Reshape a cached transcript into the `{ info, parts }` rows `hydrate` takes. */
|
|
39
|
-
export declare function toHydrateEntries(transcript: CachedTranscript): Array<{
|
|
40
|
-
info: Message;
|
|
41
|
-
parts: Part[];
|
|
42
|
-
}>;
|
|
43
|
-
/**
|
|
44
|
-
* The cache is a first-paint accelerator, never a source of truth. Once the
|
|
45
|
-
* store holds anything for this session — from SSE, an optimistic send, or a
|
|
46
|
-
* completed reconcile — it outranks whatever is on disk, so hydrating again
|
|
47
|
-
* could only ever move the transcript backwards.
|
|
48
|
-
*
|
|
49
|
-
* With exactly one exception, and it is not hypothetical: a session whose agent
|
|
50
|
-
* is still running when the store evicts it. Eviction deletes the key; the
|
|
51
|
-
* agent's next SSE frame puts it straight back, holding only what streamed
|
|
52
|
-
* after the eviction. The store "has" the session, but what it has is strictly
|
|
53
|
-
* less than the disk copy, so standing down leaves the user with a fragment and
|
|
54
|
-
* a `loadOlder` for their own history. `hydrate` merges rather than replaces —
|
|
55
|
-
* it never drops a message the store has that the incoming set lacks, and for
|
|
56
|
-
* text parts it keeps whichever side has more — so painting the disk copy under
|
|
57
|
-
* a live fragment restores the history without touching the live tail.
|
|
58
|
-
*/
|
|
59
|
-
export declare function shouldHydrateFromCache(input: {
|
|
60
|
-
storeHasSession: boolean;
|
|
61
|
-
cachedMessageCount: number;
|
|
62
|
-
/**
|
|
63
|
-
* The store's entry for this session is a post-eviction fragment. From
|
|
64
|
-
* `useSyncStore.wasTranscriptEvicted`, which also reports false the moment a
|
|
65
|
-
* send goes in flight — repainting under one would retire the message the
|
|
66
|
-
* user just typed.
|
|
67
|
-
*/
|
|
68
|
-
storeSessionWasEvicted?: boolean;
|
|
69
|
-
}): boolean;
|
|
70
|
-
/**
|
|
71
|
-
* Read this session's cached transcript. Resolves to null when there is no
|
|
72
|
-
* usable entry — the caller then simply waits for the runtime, exactly as
|
|
73
|
-
* before this cache existed.
|
|
74
|
-
*/
|
|
75
|
-
export declare function readCachedTranscript(sessionId: string, kortixSessionScope?: string): Promise<CachedTranscript | null>;
|
|
76
|
-
/** Mirror the session's current tail to disk. Debounced inside the IDB layer. */
|
|
77
|
-
export declare function writeCachedTranscript(state: TranscriptStoreSlice, sessionId: string, kortixSessionScope?: string, exclude?: (messageId: string) => boolean): Promise<void>;
|
|
78
|
-
export {};
|
|
79
|
-
//# sourceMappingURL=session-transcript-cache.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"session-transcript-cache.d.ts","sourceRoot":"","sources":["../../../src/browser/session-sync/session-transcript-cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,4BAA4B,CAAC;AAIhE,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;CAC/B;AAED,UAAU,oBAAoB;IAC5B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;IACpC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;CAC/B;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,oBAAoB,EAC3B,SAAS,EAAE,MAAM;AACjB;;;;;GAKG;AACH,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,GACvC,gBAAgB,GAAG,IAAI,CAWzB;AACD,mFAAmF;AACnF,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,gBAAgB,GAC3B,KAAK,CAAC;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,IAAI,EAAE,CAAA;CAAE,CAAC,CAIzC;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE;IAC5C,eAAe,EAAE,OAAO,CAAC;IACzB,kBAAkB,EAAE,MAAM,CAAC;IAC3B;;;;;OAKG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;CAClC,GAAG,OAAO,CAIV;AAED;;;;GAIG;AACH,wBAAsB,oBAAoB,CACxC,SAAS,EAAE,MAAM,EACjB,kBAAkB,CAAC,EAAE,MAAM,GAC1B,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAIlC;AAED,iFAAiF;AACjF,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,oBAAoB,EAC3B,SAAS,EAAE,MAAM,EACjB,kBAAkB,CAAC,EAAE,MAAM,EAC3B,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,GACvC,OAAO,CAAC,IAAI,CAAC,CAIf"}
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Local transcript cache — the reason a session can paint before its sandbox
|
|
3
|
-
* is awake.
|
|
4
|
-
*
|
|
5
|
-
* Reading a transcript used to be gated on booting a VM: the messages live on
|
|
6
|
-
* the opencode runtime *inside* the session's sandbox, reachable only through
|
|
7
|
-
* `/p/{externalId}/…`, so opening a hibernated session meant waiting out the
|
|
8
|
-
* whole `/start` wake before a single word appeared. The transcript is already
|
|
9
|
-
* settled history; it does not need a running machine to be shown.
|
|
10
|
-
*
|
|
11
|
-
* So: mirror the tail into IndexedDB as it arrives, and hydrate straight back
|
|
12
|
-
* out of it on open. The live runtime still reconciles behind it — this only
|
|
13
|
-
* changes WHEN the user sees what is already theirs, never what is true.
|
|
14
|
-
*/
|
|
15
|
-
import { loadSessionFromIDB, saveSessionToIDB } from '../cache/idb-sync-cache.js';
|
|
16
|
-
/**
|
|
17
|
-
* Pull one session's messages, plus only the parts belonging to them, out of
|
|
18
|
-
* the (globally part-keyed) sync store. Returns null when there is nothing
|
|
19
|
-
* worth persisting — an absent session and an empty one are the same to a
|
|
20
|
-
* cache whose entire job is having something to show.
|
|
21
|
-
*/
|
|
22
|
-
export function selectSessionTranscript(state, sessionId,
|
|
23
|
-
/**
|
|
24
|
-
* Messages to leave OUT of the entry — this tab's optimistic stubs. The
|
|
25
|
-
* cache mirrors the runtime's transcript, and a stub is not in it: persisted,
|
|
26
|
-
* it came back after a reload as a plain message the runtime had never
|
|
27
|
-
* heard of, beside the real one, for ever.
|
|
28
|
-
*/
|
|
29
|
-
exclude) {
|
|
30
|
-
const all = state.messages[sessionId];
|
|
31
|
-
if (!all || all.length === 0)
|
|
32
|
-
return null;
|
|
33
|
-
const messages = exclude ? all.filter((message) => !message?.id || !exclude(message.id)) : all;
|
|
34
|
-
if (messages.length === 0)
|
|
35
|
-
return null;
|
|
36
|
-
const parts = {};
|
|
37
|
-
for (const message of messages) {
|
|
38
|
-
if (!message?.id)
|
|
39
|
-
continue;
|
|
40
|
-
parts[message.id] = state.parts[message.id] ?? [];
|
|
41
|
-
}
|
|
42
|
-
return { messages, parts };
|
|
43
|
-
}
|
|
44
|
-
/** Reshape a cached transcript into the `{ info, parts }` rows `hydrate` takes. */
|
|
45
|
-
export function toHydrateEntries(transcript) {
|
|
46
|
-
return (transcript.messages ?? [])
|
|
47
|
-
.filter((message) => !!message?.id)
|
|
48
|
-
.map((message) => ({ info: message, parts: transcript.parts?.[message.id] ?? [] }));
|
|
49
|
-
}
|
|
50
|
-
/**
|
|
51
|
-
* The cache is a first-paint accelerator, never a source of truth. Once the
|
|
52
|
-
* store holds anything for this session — from SSE, an optimistic send, or a
|
|
53
|
-
* completed reconcile — it outranks whatever is on disk, so hydrating again
|
|
54
|
-
* could only ever move the transcript backwards.
|
|
55
|
-
*
|
|
56
|
-
* With exactly one exception, and it is not hypothetical: a session whose agent
|
|
57
|
-
* is still running when the store evicts it. Eviction deletes the key; the
|
|
58
|
-
* agent's next SSE frame puts it straight back, holding only what streamed
|
|
59
|
-
* after the eviction. The store "has" the session, but what it has is strictly
|
|
60
|
-
* less than the disk copy, so standing down leaves the user with a fragment and
|
|
61
|
-
* a `loadOlder` for their own history. `hydrate` merges rather than replaces —
|
|
62
|
-
* it never drops a message the store has that the incoming set lacks, and for
|
|
63
|
-
* text parts it keeps whichever side has more — so painting the disk copy under
|
|
64
|
-
* a live fragment restores the history without touching the live tail.
|
|
65
|
-
*/
|
|
66
|
-
export function shouldHydrateFromCache(input) {
|
|
67
|
-
if (input.cachedMessageCount <= 0)
|
|
68
|
-
return false;
|
|
69
|
-
if (!input.storeHasSession)
|
|
70
|
-
return true;
|
|
71
|
-
return input.storeSessionWasEvicted === true;
|
|
72
|
-
}
|
|
73
|
-
/**
|
|
74
|
-
* Read this session's cached transcript. Resolves to null when there is no
|
|
75
|
-
* usable entry — the caller then simply waits for the runtime, exactly as
|
|
76
|
-
* before this cache existed.
|
|
77
|
-
*/
|
|
78
|
-
export async function readCachedTranscript(sessionId, kortixSessionScope) {
|
|
79
|
-
const cached = await loadSessionFromIDB(sessionId, kortixSessionScope);
|
|
80
|
-
if (!cached || !Array.isArray(cached.messages) || cached.messages.length === 0)
|
|
81
|
-
return null;
|
|
82
|
-
return { messages: cached.messages, parts: cached.parts ?? {} };
|
|
83
|
-
}
|
|
84
|
-
/** Mirror the session's current tail to disk. Debounced inside the IDB layer. */
|
|
85
|
-
export function writeCachedTranscript(state, sessionId, kortixSessionScope, exclude) {
|
|
86
|
-
const transcript = selectSessionTranscript(state, sessionId, exclude);
|
|
87
|
-
if (!transcript)
|
|
88
|
-
return Promise.resolve();
|
|
89
|
-
return saveSessionToIDB(sessionId, transcript.messages, transcript.parts, kortixSessionScope);
|
|
90
|
-
}
|
|
91
|
-
//# sourceMappingURL=session-transcript-cache.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"session-transcript-cache.js","sourceRoot":"","sources":["../../../src/browser/session-sync/session-transcript-cache.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
export declare class PublicVoiceJoinError extends Error {
|
|
2
|
-
readonly status: number;
|
|
3
|
-
constructor(message: string, status: number);
|
|
4
|
-
}
|
|
5
|
-
export interface PublicVoiceJoinInfo {
|
|
6
|
-
call_id: string;
|
|
7
|
-
/** The LiveKit server's `ws(s)://` URL — never assume it shares an origin
|
|
8
|
-
* with either the API or the frontend that served this page. */
|
|
9
|
-
url: string;
|
|
10
|
-
/** A freshly-minted, room-scoped LiveKit access token — not the join
|
|
11
|
-
* link's own token. */
|
|
12
|
-
token: string;
|
|
13
|
-
}
|
|
14
|
-
/** Resolves a short `voice_spawn` join-link token into a live LiveKit
|
|
15
|
-
* session's server URL + a fresh access token. Throws `PublicVoiceJoinError`
|
|
16
|
-
* (404 unknown, 410 expired/revoked) on anything but 200. */
|
|
17
|
-
export declare function getPublicVoiceJoin(token: string): Promise<PublicVoiceJoinInfo>;
|
|
18
|
-
/**
|
|
19
|
-
* One line of a call's durable record (`kortix.voice_call_turns`).
|
|
20
|
-
*
|
|
21
|
-
* `role` + `speaker` together say who — and they must be read together,
|
|
22
|
-
* because `agent` covers two different things:
|
|
23
|
-
* - `user` — a human in the room. `speaker` is a display name if one is known.
|
|
24
|
-
* - `agent` + `speaker === 'kortix'` — what the KORTIX agent put into the
|
|
25
|
-
* call (`send_prompt`, a finished turn's result, an error).
|
|
26
|
-
* - `agent` + anything else — what the voice itself actually said, labelled
|
|
27
|
-
* with the bot's display name.
|
|
28
|
-
* - `tool` — an MCP call the voice made; `speaker` is the tool name
|
|
29
|
-
* (`ask_kortix`, `run_command`) and `text` is the call and its outcome.
|
|
30
|
-
* Nobody spoke this line.
|
|
31
|
-
*/
|
|
32
|
-
export interface PublicVoiceTranscriptTurn {
|
|
33
|
-
/** Monotonic per-call sequence number — pass the page's last one back as `cursor`. */
|
|
34
|
-
cursor: number;
|
|
35
|
-
role: 'user' | 'agent' | 'tool' | (string & {});
|
|
36
|
-
speaker: string | null;
|
|
37
|
-
text: string;
|
|
38
|
-
/** ISO-8601. */
|
|
39
|
-
at: string;
|
|
40
|
-
}
|
|
41
|
-
export interface PublicVoiceTranscriptPage {
|
|
42
|
-
call_id: string;
|
|
43
|
-
/** The cursor to poll with next — unchanged when nothing new arrived. */
|
|
44
|
-
cursor: number;
|
|
45
|
-
turns: PublicVoiceTranscriptTurn[];
|
|
46
|
-
}
|
|
47
|
-
/**
|
|
48
|
-
* Reads the durable transcript of the ONE call a join-link token was minted
|
|
49
|
-
* for — every spoken turn on both sides, everything the Kortix agent said into
|
|
50
|
-
* the call, and every tool call the voice made.
|
|
51
|
-
*
|
|
52
|
-
* This is not the same stream as LiveKit's client-side transcription, which
|
|
53
|
-
* only ever carries the two voices. Authorized by the join link alone (same
|
|
54
|
-
* capability, same revocation as `getPublicVoiceJoin`), so it works on the
|
|
55
|
-
* logged-out `/voice/[token]` page. Throws `PublicVoiceJoinError` (404
|
|
56
|
-
* unknown, 410 expired or the call ended).
|
|
57
|
-
*/
|
|
58
|
-
export declare function getPublicVoiceTranscript(token: string, cursor?: number): Promise<PublicVoiceTranscriptPage>;
|
|
59
|
-
//# sourceMappingURL=public-voice-join.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"public-voice-join.d.ts","sourceRoot":"","sources":["../../../../src/core/rest/projects-client/public-voice-join.ts"],"names":[],"mappings":"AAeA,qBAAa,oBAAqB,SAAQ,KAAK;aAG3B,MAAM,EAAE,MAAM;gBAD9B,OAAO,EAAE,MAAM,EACC,MAAM,EAAE,MAAM;CAKjC;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB;qEACiE;IACjE,GAAG,EAAE,MAAM,CAAC;IACZ;4BACwB;IACxB,KAAK,EAAE,MAAM,CAAC;CACf;AAyBD;;8DAE8D;AAC9D,wBAAsB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAEpF;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,yBAAyB;IACxC,sFAAsF;IACtF,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;IAChD,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,gBAAgB;IAChB,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,MAAM,CAAC;IAChB,yEAAyE;IACzE,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,yBAAyB,EAAE,CAAC;CACpC;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,wBAAwB,CAC5C,KAAK,EAAE,MAAM,EACb,MAAM,SAAI,GACT,OAAO,CAAC,yBAAyB,CAAC,CAGpC"}
|