@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
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
|
3
|
+
import { useCallback } from 'react';
|
|
4
|
+
import { createSessionPrompt, deleteSessionPrompt, holdSessionPrompts, listSessionPrompts, retrySessionPrompt, } from '../core/rest/projects-client/sessions.js';
|
|
5
|
+
import { useSessionWorkingStore } from '../browser/stores/session-working-store.js';
|
|
6
|
+
import { countLiveInboxPrompts } from '../core/session/working.js';
|
|
7
|
+
import { qk } from './query-keys.js';
|
|
8
|
+
import { mintSessionWireMessageId } from './use-opencode-sessions/messages.js';
|
|
9
|
+
/**
|
|
10
|
+
* The session's SERVER-SIDE prompt inbox.
|
|
11
|
+
*
|
|
12
|
+
* The queue used to be a browser store: closing the tab, switching device, or
|
|
13
|
+
* a crash lost every pending message silently, and two tabs on one session each
|
|
14
|
+
* believed their own list. This hook reads the durable rows instead, so what
|
|
15
|
+
* the composer renders is what the server will actually deliver.
|
|
16
|
+
*
|
|
17
|
+
* Polling has TWO cadences, and the slow one is not an optimization.
|
|
18
|
+
*
|
|
19
|
+
* While prompts exist the list is the only thing that can report a state change
|
|
20
|
+
* (`waiting` → `queued` → `delivering`), so it polls fast. An empty list is the
|
|
21
|
+
* common state and does not need that — but it cannot stop either, because a
|
|
22
|
+
* prompt can ENTER the inbox with this tab doing nothing at all: the reaper
|
|
23
|
+
* redelivers one whose turn never ran, and parking a box requeues its in-flight
|
|
24
|
+
* prompt as `held`. A held row is deliberately not due; the user releases it by
|
|
25
|
+
* sending something or pressing "send now" on it, which they can only do if
|
|
26
|
+
* they can SEE it. Not polling an empty list meant only a full page load ever
|
|
27
|
+
* showed those rows — and the same gap hid a prompt queued from a second tab.
|
|
28
|
+
*/
|
|
29
|
+
export const SESSION_PROMPTS_POLL_MS = 1_000;
|
|
30
|
+
/** The floor for an EMPTY list. Slow enough to be free, fast enough that a
|
|
31
|
+
* prompt handed back by the server appears while the user is still looking. */
|
|
32
|
+
export const SESSION_PROMPTS_IDLE_POLL_MS = 15_000;
|
|
33
|
+
/** The cadence for a list of `count` prompts. Pure, so the floor is testable. */
|
|
34
|
+
export function sessionPromptsPollMs(count, pollMs) {
|
|
35
|
+
return count > 0 ? (pollMs ?? SESSION_PROMPTS_POLL_MS) : SESSION_PROMPTS_IDLE_POLL_MS;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Feed one reading of the list into the working projection.
|
|
39
|
+
*
|
|
40
|
+
* The inbox is not only something to render. A prompt is DURABLE long before it
|
|
41
|
+
* is a turn: the lifecycle row has to be drained, and the box may have to resume
|
|
42
|
+
* first (18.9s Daytona / 24.5s Platinum, measured). `GET .../turn` truthfully
|
|
43
|
+
* answers "no turns" for that whole window, and the composer used to believe it
|
|
44
|
+
* — swapping Stop back to Send while the user's prompt was still queued. The
|
|
45
|
+
* stamp is the instant the read was ISSUED, for the same reason `/turn`'s is.
|
|
46
|
+
*/
|
|
47
|
+
export function noteInboxObservation(sessionId, prompts, atMs) {
|
|
48
|
+
useSessionWorkingStore.getState().noteInboxPending(sessionId, countLiveInboxPrompts(prompts), atMs);
|
|
49
|
+
}
|
|
50
|
+
// ============================================================================
|
|
51
|
+
// Optimistic queue rows — Enter paints the row in the SAME frame
|
|
52
|
+
// ============================================================================
|
|
53
|
+
export const OPTIMISTIC_PROMPT_PREFIX = 'optimistic:';
|
|
54
|
+
/** Is this row the tab's own echo, not yet confirmed by the server? */
|
|
55
|
+
export function isOptimisticSessionPrompt(prompt) {
|
|
56
|
+
return prompt.prompt_id.startsWith(OPTIMISTIC_PROMPT_PREFIX);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* The strip-shaped row for a submission that has left this tab but not yet
|
|
60
|
+
* come back from `POST .../prompts`. The queue is server-side; this is the
|
|
61
|
+
* one client-side thing a server queue cannot do — paint on the keypress.
|
|
62
|
+
* Replaced by the server's row on the response (`settleOptimisticPrompt`),
|
|
63
|
+
* or by the poll landing first (`reconcileOptimisticPrompts`), and removed
|
|
64
|
+
* on failure so a refused send never lingers.
|
|
65
|
+
*/
|
|
66
|
+
export function optimisticSessionPrompt(input, nowMs) {
|
|
67
|
+
const text = input.parts
|
|
68
|
+
.filter((part) => part.type === 'text' && typeof part.text === 'string')
|
|
69
|
+
.map((part) => part.text)
|
|
70
|
+
.join('\n')
|
|
71
|
+
.trim();
|
|
72
|
+
const at = new Date(nowMs).toISOString();
|
|
73
|
+
return {
|
|
74
|
+
prompt_id: `${OPTIMISTIC_PROMPT_PREFIX}${input.clientMessageId}`,
|
|
75
|
+
client_message_id: input.clientMessageId,
|
|
76
|
+
message_id: input.messageId,
|
|
77
|
+
state: 'queued',
|
|
78
|
+
reason: null,
|
|
79
|
+
text,
|
|
80
|
+
attempts: 0,
|
|
81
|
+
last_error: null,
|
|
82
|
+
created_at: at,
|
|
83
|
+
available_at: at,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
export function applyOptimisticPrompt(prompts, input, nowMs) {
|
|
87
|
+
if (prompts.some((p) => p.client_message_id === input.clientMessageId))
|
|
88
|
+
return [...prompts];
|
|
89
|
+
return [...prompts, optimisticSessionPrompt(input, nowMs)];
|
|
90
|
+
}
|
|
91
|
+
export function settleOptimisticPrompt(prompts, clientMessageId, result) {
|
|
92
|
+
return prompts.map((p) => p.client_message_id === clientMessageId && isOptimisticSessionPrompt(p)
|
|
93
|
+
? { ...p, prompt_id: result.prompt_id, state: result.state, message_id: result.message_id }
|
|
94
|
+
: p);
|
|
95
|
+
}
|
|
96
|
+
export function removeOptimisticPrompt(prompts, clientMessageId) {
|
|
97
|
+
return prompts.filter((p) => !(p.client_message_id === clientMessageId && isOptimisticSessionPrompt(p)));
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Merge a fresh server list over the cached one: the server's rows are the
|
|
101
|
+
* truth, and an optimistic row survives only while the server has not listed
|
|
102
|
+
* its submission yet (the POST is still in flight).
|
|
103
|
+
*/
|
|
104
|
+
export function reconcileOptimisticPrompts(cached, server) {
|
|
105
|
+
const listed = new Set(server.map((p) => p.client_message_id).filter(Boolean));
|
|
106
|
+
const pending = (cached ?? []).filter((p) => isOptimisticSessionPrompt(p) && !listed.has(p.client_message_id));
|
|
107
|
+
return pending.length ? [...server, ...pending] : [...server];
|
|
108
|
+
}
|
|
109
|
+
export function useSessionPrompts(projectId, sessionId, options) {
|
|
110
|
+
const queryClient = useQueryClient();
|
|
111
|
+
const enabled = options?.enabled !== false && !!projectId && !!sessionId;
|
|
112
|
+
const key = qk.project.sessionPrompts(projectId ?? '', sessionId ?? '');
|
|
113
|
+
const query = useQuery({
|
|
114
|
+
queryKey: key,
|
|
115
|
+
enabled,
|
|
116
|
+
queryFn: async () => {
|
|
117
|
+
// Stamped BEFORE the request, like `/turn`'s: an answer is only as fresh
|
|
118
|
+
// as the moment it was asked.
|
|
119
|
+
const atMs = Date.now();
|
|
120
|
+
const { prompts } = await listSessionPrompts(projectId, sessionId);
|
|
121
|
+
noteInboxObservation(sessionId, prompts, atMs);
|
|
122
|
+
// Keep this tab's not-yet-confirmed rows on screen across a poll that
|
|
123
|
+
// landed before their POST returned.
|
|
124
|
+
return reconcileOptimisticPrompts(queryClient.getQueryData(key), prompts);
|
|
125
|
+
},
|
|
126
|
+
// Two cadences, never `false` — see the note above.
|
|
127
|
+
refetchInterval: (q) => sessionPromptsPollMs(q.state.data?.length ?? 0, options?.pollMs),
|
|
128
|
+
// Per-query, because the host disables focus refetching globally. Coming
|
|
129
|
+
// back to a tab is the moment a prompt the server handed back while it was
|
|
130
|
+
// hidden has to be on screen.
|
|
131
|
+
refetchOnWindowFocus: true,
|
|
132
|
+
});
|
|
133
|
+
const invalidate = useCallback(() => queryClient.invalidateQueries({ queryKey: key }),
|
|
134
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
135
|
+
[queryClient, projectId, sessionId]);
|
|
136
|
+
const enqueueMutation = useMutation({
|
|
137
|
+
// Enter paints the row NOW. The queue is server-side; the only client-side
|
|
138
|
+
// job left is to not make the user wait a round-trip to see their own
|
|
139
|
+
// keypress. The optimistic row is swapped for the server's on the
|
|
140
|
+
// response, removed on failure, and never outlives a poll that lists its
|
|
141
|
+
// submission (`reconcileOptimisticPrompts`). The write is SYNCHRONOUS and
|
|
142
|
+
// comes before anything awaited, so the row is on screen in the same frame
|
|
143
|
+
// as the keypress.
|
|
144
|
+
onMutate: async (input) => {
|
|
145
|
+
queryClient.setQueryData(key, (prev) => applyOptimisticPrompt(prev ?? [], input, Date.now()));
|
|
146
|
+
// The receipt-side floor: a `/turn` poll landing before the POST returns
|
|
147
|
+
// must not swap Stop back to Send with the row already on screen.
|
|
148
|
+
useSessionWorkingStore.getState().notePromptAccepted(sessionId, Date.now());
|
|
149
|
+
await queryClient.cancelQueries({ queryKey: key });
|
|
150
|
+
},
|
|
151
|
+
mutationFn: async (input) => {
|
|
152
|
+
const result = await createSessionPrompt(projectId, sessionId, input);
|
|
153
|
+
if (result.state !== 'failed') {
|
|
154
|
+
useSessionWorkingStore.getState().notePromptAccepted(sessionId, Date.now());
|
|
155
|
+
}
|
|
156
|
+
return result;
|
|
157
|
+
},
|
|
158
|
+
onSuccess: (result, input) => {
|
|
159
|
+
queryClient.setQueryData(key, (prev) => result.state === 'failed'
|
|
160
|
+
? removeOptimisticPrompt(prev ?? [], input.clientMessageId)
|
|
161
|
+
: settleOptimisticPrompt(prev ?? [], input.clientMessageId, result));
|
|
162
|
+
},
|
|
163
|
+
onError: (_error, input) => {
|
|
164
|
+
queryClient.setQueryData(key, (prev) => removeOptimisticPrompt(prev ?? [], input.clientMessageId));
|
|
165
|
+
},
|
|
166
|
+
onSettled: invalidate,
|
|
167
|
+
});
|
|
168
|
+
const removeMutation = useMutation({
|
|
169
|
+
mutationFn: (promptId) => deleteSessionPrompt(projectId, sessionId, promptId),
|
|
170
|
+
onSettled: invalidate,
|
|
171
|
+
});
|
|
172
|
+
const retryMutation = useMutation({
|
|
173
|
+
mutationFn: (promptId) => retrySessionPrompt(projectId, sessionId, promptId),
|
|
174
|
+
onSettled: invalidate,
|
|
175
|
+
});
|
|
176
|
+
const holdMutation = useMutation({
|
|
177
|
+
mutationFn: (held) => holdSessionPrompts(projectId, sessionId, held),
|
|
178
|
+
onSettled: invalidate,
|
|
179
|
+
});
|
|
180
|
+
return {
|
|
181
|
+
prompts: query.data ?? [],
|
|
182
|
+
isLoading: query.isLoading,
|
|
183
|
+
enqueue: enqueueMutation.mutateAsync,
|
|
184
|
+
remove: removeMutation.mutateAsync,
|
|
185
|
+
retry: retryMutation.mutateAsync,
|
|
186
|
+
hold: holdMutation.mutateAsync,
|
|
187
|
+
refetch: query.refetch,
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* POST the first prompt of a session straight to the durable inbox.
|
|
192
|
+
*
|
|
193
|
+
* A plain async function, not a hook — two of its producers are plain click
|
|
194
|
+
* handlers on pages that never mount a session. The admission gate holds the
|
|
195
|
+
* row until the box answers; `session-composer-readiness.ts` states the
|
|
196
|
+
* contract: "A submit against a sleeping box is POSTed to `.../prompts` and
|
|
197
|
+
* becomes a durable row."
|
|
198
|
+
*
|
|
199
|
+
* This replaces the sessionStorage start-stash as the delivery channel (the
|
|
200
|
+
* stash still hands off the model/agent PICKS): the stash needed a mounted
|
|
201
|
+
* workbench to replay it 19-25s later (measured boot), and a closed tab in
|
|
202
|
+
* that window lost the message silently. The wire id is minted here but
|
|
203
|
+
* flagged `remintOnDelivery` — this producer runs before any transcript
|
|
204
|
+
* exists to place an id against, which is the exact criterion that flag
|
|
205
|
+
* documents.
|
|
206
|
+
*
|
|
207
|
+
* Files the same receipts `handleSend` does, so the composer's working
|
|
208
|
+
* projection covers the send from the click, and drops them on every path
|
|
209
|
+
* where nothing is coming — including a `failed` verdict, which arrives as a
|
|
210
|
+
* 200 (a dead-lettered dedupe) and is thrown here as the refusal it is.
|
|
211
|
+
*/
|
|
212
|
+
export async function startSessionWithPrompt(projectId, sessionId, input, adapters) {
|
|
213
|
+
const create = adapters?.create ?? createSessionPrompt;
|
|
214
|
+
const now = adapters?.nowMs ?? Date.now;
|
|
215
|
+
const clientMessageId = typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function'
|
|
216
|
+
? `start_${crypto.randomUUID()}`
|
|
217
|
+
: `start_${now()}_${Math.random().toString(36).slice(2, 10)}`;
|
|
218
|
+
const store = useSessionWorkingStore.getState();
|
|
219
|
+
store.noteSendReceipt(sessionId, { messageId: clientMessageId, atMs: now() });
|
|
220
|
+
try {
|
|
221
|
+
const result = await create(projectId, sessionId, {
|
|
222
|
+
clientMessageId,
|
|
223
|
+
messageId: mintSessionWireMessageId(sessionId, clientMessageId),
|
|
224
|
+
parts: input.parts,
|
|
225
|
+
...(input.overrides ? { overrides: input.overrides } : {}),
|
|
226
|
+
remintOnDelivery: true,
|
|
227
|
+
});
|
|
228
|
+
if (result.state === 'failed') {
|
|
229
|
+
throw new Error('This prompt was refused — its earlier delivery already failed.');
|
|
230
|
+
}
|
|
231
|
+
const acceptedAt = now();
|
|
232
|
+
useSessionWorkingStore.getState().acceptSendReceipt(sessionId, clientMessageId, acceptedAt);
|
|
233
|
+
useSessionWorkingStore.getState().notePromptAccepted(sessionId, acceptedAt);
|
|
234
|
+
return result;
|
|
235
|
+
}
|
|
236
|
+
catch (error) {
|
|
237
|
+
// Named, so a slow refusal cannot drop a receipt a later send now owns.
|
|
238
|
+
useSessionWorkingStore.getState().clearSendReceipt(sessionId, clientMessageId);
|
|
239
|
+
throw error;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
//# sourceMappingURL=use-session-prompts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-session-prompts.js","sourceRoot":"","sources":["../../src/react/use-session-prompts.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
import { type KortixSendError } from './use-session.js';
|
|
2
|
-
import { type PromptPart, type SendMessageOptions } from './use-opencode-sessions/index.js';
|
|
2
|
+
import { type AbortSettlement, type PromptPart, type SendMessageOptions } from './use-opencode-sessions/index.js';
|
|
3
3
|
import { type StartStash } from './session-start-stash.js';
|
|
4
4
|
/**
|
|
5
|
-
* Add a user message to the sync store optimistically
|
|
6
|
-
* accepted it
|
|
7
|
-
*
|
|
8
|
-
* used to
|
|
5
|
+
* Add a user message to the sync store optimistically — before the server has
|
|
6
|
+
* accepted it — and nothing else.
|
|
7
|
+
*
|
|
8
|
+
* It used to also write `{type:'busy'}` into `sessionStatus`, the slot the
|
|
9
|
+
* runtime's own SSE frames land in. A fabricated frame there is
|
|
10
|
+
* indistinguishable from one the daemon sent, and it outranked a real
|
|
11
|
+
* `GET .../turn` read stamped after it. "Is this session working?" is answered
|
|
12
|
+
* once, by `projectWorking`, and this tab's own claim on it is the
|
|
13
|
+
* `SendReceipt` (`session-working-store.ts`) — not a status write. This
|
|
14
|
+
* function paints the bubble; the receipt owns the working state.
|
|
9
15
|
*/
|
|
10
16
|
export declare function beginOptimisticSend(sessionId: string, messageId: string, text: string, partIds?: string[]): void;
|
|
11
17
|
/**
|
|
@@ -29,12 +35,29 @@ export declare function beginOptimisticSend(sessionId: string, messageId: string
|
|
|
29
35
|
* pairing them would delete text the user typed.
|
|
30
36
|
*/
|
|
31
37
|
export declare function markOptimisticSendDispatched(sessionId: string, messageId: string): void;
|
|
38
|
+
/**
|
|
39
|
+
* The prompt is going to the durable inbox (`POST .../prompts`): from here the
|
|
40
|
+
* host's own send path owns the bubble's life — the POST's failure path
|
|
41
|
+
* removes it explicitly, the runtime's echo confirms it in place (same id) or
|
|
42
|
+
* supersedes it (re-minted id, aliased by the store) — and the local idle
|
|
43
|
+
* sweep must leave it alone. Call it next to `markOptimisticSendDispatched`,
|
|
44
|
+
* BEFORE the POST: the enqueue promise settles after its cache work, and a
|
|
45
|
+
* session that goes idle or aborts in that window (a Stop, an asleep box) is
|
|
46
|
+
* not evidence the prompt was lost. Only for a host that painted the bubble
|
|
47
|
+
* with the WIRE id it hands the inbox.
|
|
48
|
+
*/
|
|
49
|
+
export declare function markOptimisticSendInboxBacked(sessionId: string, messageId: string): void;
|
|
32
50
|
/**
|
|
33
51
|
* A send that never reached the network at all (e.g. building the outgoing
|
|
34
52
|
* parts — file uploads — threw before `promptOpenCodeMessage` was even
|
|
35
53
|
* called). There is nothing to rehydrate from the server since it never saw
|
|
36
|
-
* this message, so
|
|
37
|
-
*
|
|
54
|
+
* this message, so drop the optimistic message outright — unlike
|
|
55
|
+
* `recoverFromSendFailure`, which keeps it pending a rehydrate.
|
|
56
|
+
*
|
|
57
|
+
* It releases the send RECEIPT, not the session status. "Nothing is coming for
|
|
58
|
+
* this send" is what this path knows; "the session is idle" is not, and writing
|
|
59
|
+
* it into the status slot unmasked live turns (a trigger, a second device).
|
|
60
|
+
* NAMED, so a slow abandon cannot drop a later send's receipt.
|
|
38
61
|
*/
|
|
39
62
|
export declare function abandonOptimisticSend(sessionId: string, messageId: string): void;
|
|
40
63
|
/** The minimal slice of `OpencodeClient` the recovery rehydrate needs. */
|
|
@@ -61,12 +84,19 @@ export interface SendRecoveryOptions {
|
|
|
61
84
|
}
|
|
62
85
|
/**
|
|
63
86
|
* A send reached the network and failed (or the network dispatch itself
|
|
64
|
-
* threw). Classify the error,
|
|
65
|
-
* from the server (keeping the optimistic message
|
|
66
|
-
* error paths never emit a `session.error` SSE
|
|
67
|
-
* message if the server has no record of it. The
|
|
68
|
-
* (matches the original inline `.then()/.catch()`
|
|
69
|
-
* so this function itself resolves synchronously
|
|
87
|
+
* threw). Classify the error, release this send's receipt, and either
|
|
88
|
+
* rehydrate real messages from the server (keeping the optimistic message
|
|
89
|
+
* visible until then — some error paths never emit a `session.error` SSE
|
|
90
|
+
* event) or drop the optimistic message if the server has no record of it. The
|
|
91
|
+
* rehydrate is fire-and-forget (matches the original inline `.then()/.catch()`
|
|
92
|
+
* — callers don't await it), so this function itself resolves synchronously
|
|
93
|
+
* with the classified error.
|
|
94
|
+
*
|
|
95
|
+
* It writes NO status. An HTTP send failure is not evidence that the session is
|
|
96
|
+
* idle: a trigger, a second device, or a POST the control plane already
|
|
97
|
+
* accepted can all be running, and this was the worst of the fabricated writes
|
|
98
|
+
* — it unmasked a live turn by declaring idle into the slot the projection
|
|
99
|
+
* reads as runtime truth.
|
|
70
100
|
*/
|
|
71
101
|
export declare function recoverFromSendFailure(sessionId: string, messageId: string, error: unknown, options?: SendRecoveryOptions): KortixSendError;
|
|
72
102
|
export interface SendAndRecoverArgs {
|
|
@@ -75,6 +105,13 @@ export interface SendAndRecoverArgs {
|
|
|
75
105
|
messageId: string;
|
|
76
106
|
parts: PromptPart[];
|
|
77
107
|
options?: SendMessageOptions;
|
|
108
|
+
/**
|
|
109
|
+
* Stable name for the submission, so re-dispatching a failed send keeps one
|
|
110
|
+
* wire `messageID` and the proxy's duplicate protection still absorbs it.
|
|
111
|
+
* Distinct from `messageId` above, which is the LOCAL optimistic message and
|
|
112
|
+
* never goes on the wire. See `SendOpenCodeMessageArgs.clientMessageId`.
|
|
113
|
+
*/
|
|
114
|
+
clientMessageId?: string;
|
|
78
115
|
getClient?: () => OpenCodeMessagesClient;
|
|
79
116
|
classify?: (error: unknown) => KortixSendError;
|
|
80
117
|
}
|
|
@@ -95,10 +132,18 @@ export type SendAndRecoverResult = {
|
|
|
95
132
|
*/
|
|
96
133
|
export declare function sendAndRecover(args: SendAndRecoverArgs): Promise<SendAndRecoverResult>;
|
|
97
134
|
/**
|
|
98
|
-
*
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
*
|
|
135
|
+
* Patch an "aborted" error onto the last assistant message that doesn't
|
|
136
|
+
* already have one, so an "Interrupted" label can render instantly instead of
|
|
137
|
+
* waiting for the SSE `session.error` round-trip. Call this immediately
|
|
138
|
+
* before issuing the actual abort request.
|
|
139
|
+
*
|
|
140
|
+
* This deliberately writes NO status frame. It used to fabricate an idle
|
|
141
|
+
* frame here, and `projectWorking` cannot tell a fabricated frame from a real
|
|
142
|
+
* one — the fabrication outranked the control plane's own `/turn` answer for
|
|
143
|
+
* the whole abort round-trip. The same intent now travels as an
|
|
144
|
+
* `AbortReceipt` (`noteAbortReceipt`), which carries provenance and a bound
|
|
145
|
+
* (`OPTIMISTIC_ABORT_MAX_MS`). The transcript-side patch below stays: it is a
|
|
146
|
+
* designed optimistic echo about a MESSAGE, not a status.
|
|
102
147
|
*/
|
|
103
148
|
export declare function applyOptimisticAbort(sessionId: string): void;
|
|
104
149
|
/** A timer handle — opaque, only ever round-tripped through the injected timers. */
|
|
@@ -177,9 +222,108 @@ export interface StartStashReplayHandle {
|
|
|
177
222
|
* any other host.
|
|
178
223
|
*/
|
|
179
224
|
export declare function replayStartStash<TReady>(options: StartStashReplayOptions<TReady>): StartStashReplayHandle;
|
|
225
|
+
export interface SendWithReceiptArgs extends SendAndRecoverArgs {
|
|
226
|
+
/**
|
|
227
|
+
* The KORTIX session id, when it differs from `sessionId`.
|
|
228
|
+
*
|
|
229
|
+
* Two ids, deliberately: `sessionId` addresses the OpenCode runtime the
|
|
230
|
+
* prompt is POSTed to, while `useSessionWorking` — and therefore the receipt
|
|
231
|
+
* store — is keyed by the Kortix session `GET .../turn` answers about.
|
|
232
|
+
* Filing under the wrong one is filing under nothing. Defaults to
|
|
233
|
+
* `sessionId` for a host where the two coincide.
|
|
234
|
+
*/
|
|
235
|
+
workingSessionId?: string;
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Send, with this tab's own receipt filed around it.
|
|
239
|
+
*
|
|
240
|
+
* The receipt is what stops a `GET .../turn` read issued while the POST is
|
|
241
|
+
* still on the wire — which honestly answers "no turns", because there is
|
|
242
|
+
* nothing for it to see yet — from flipping the composer back to Send in the
|
|
243
|
+
* middle of the send. It is noted BEFORE the request and accepted only once
|
|
244
|
+
* the server has durably taken the prompt; a refused send releases it (via
|
|
245
|
+
* `recoverFromSendFailure`, by name) so a send that will never run cannot
|
|
246
|
+
* claim `working` for a minute. See `SendReceipt`.
|
|
247
|
+
*/
|
|
248
|
+
export declare function sendWithReceipt(args: SendWithReceiptArgs): Promise<SendAndRecoverResult>;
|
|
249
|
+
/**
|
|
250
|
+
* How long `stopWithReceipt` waits for the server-side prompt-inbox hold
|
|
251
|
+
* (below) before issuing the abort anyway. Mirrors apps/web's
|
|
252
|
+
* `STOP_HOLD_DEADLINE_MS` (`session-chat.tsx`) — kept as the same value for
|
|
253
|
+
* the same reason: the hold call carries no client timeout of its own, and a
|
|
254
|
+
* stalled socket must not delay the abort by more than a bounded amount.
|
|
255
|
+
*/
|
|
256
|
+
export declare const STOP_HOLD_DEADLINE_MS = 1500;
|
|
257
|
+
export interface StopWithReceiptOptions {
|
|
258
|
+
workingSessionId?: string;
|
|
259
|
+
/**
|
|
260
|
+
* Kortix project id. Required to hold the session's server-side prompt
|
|
261
|
+
* inbox before the abort goes out (see below). Omit only for a host with
|
|
262
|
+
* no prompt inbox for this session — the hold is skipped entirely, matching
|
|
263
|
+
* this function's behavior before the inbox existed.
|
|
264
|
+
*/
|
|
265
|
+
projectId?: string;
|
|
266
|
+
/**
|
|
267
|
+
* Kortix session id whose inbox to hold. The inbox is keyed by the same
|
|
268
|
+
* Kortix session `GET .../turn` answers about, so this defaults to
|
|
269
|
+
* `workingSessionId` (or `sessionId`), never to the OpenCode runtime id.
|
|
270
|
+
*/
|
|
271
|
+
inboxSessionId?: string;
|
|
272
|
+
/** Injectable, defaults to `holdSessionPrompts`. Lets a host or a test
|
|
273
|
+
* substitute its own inbox client. */
|
|
274
|
+
holdInboxPrompts?: (projectId: string, sessionId: string, held: boolean) => Promise<unknown>;
|
|
275
|
+
/** Default {@link STOP_HOLD_DEADLINE_MS}. */
|
|
276
|
+
holdDeadlineMs?: number;
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Stop, with this tab's own abort receipt filed around it.
|
|
280
|
+
*
|
|
281
|
+
* The mirror of `sendWithReceipt`, for the mirror-image failure: the cancel
|
|
282
|
+
* needs a round trip through the control plane and the daemon (~1.6s measured)
|
|
283
|
+
* before turn authority is released, so every `/turn` read issued inside that
|
|
284
|
+
* window still reports the doomed turn — including the one the optimistic idle
|
|
285
|
+
* frame itself triggers. Without the receipt the composer swapped Send back to
|
|
286
|
+
* Stop about 120ms after the click and stayed there for the whole abort. See
|
|
287
|
+
* `AbortReceipt`.
|
|
288
|
+
*
|
|
289
|
+
* It also holds the session's server-side prompt inbox BEFORE issuing the
|
|
290
|
+
* abort, the same pairing apps/web's `handleStop` does by hand
|
|
291
|
+
* (`session-chat.tsx`). A prompt sent mid-turn is forwarded into OpenCode's
|
|
292
|
+
* live queue the moment it is admitted, so at stop time the inbox can hold a
|
|
293
|
+
* row OpenCode already has. The abort drops OpenCode's in-memory queue; the
|
|
294
|
+
* reaper then sees that row unanswered and redelivers it — due now — unless
|
|
295
|
+
* the hold already marked it stop-paused. AWAITED (bounded by
|
|
296
|
+
* `holdDeadlineMs`) so the ordering is a fact, not a race: without it, Stop
|
|
297
|
+
* aborts the turn and is followed a beat later by exactly the message the
|
|
298
|
+
* user pressed Stop to get ahead of. A failed hold is caught, never
|
|
299
|
+
* rethrown — it must not cost the user their abort — and skipped entirely
|
|
300
|
+
* when no `projectId` is given.
|
|
301
|
+
*
|
|
302
|
+
* `runAbort` is taken as a callback (normally `() =>
|
|
303
|
+
* abortMutation.mutateAsync(sessionId)`) so the pairing is testable without
|
|
304
|
+
* rendering a hook — the same shape `awaitAbortSettlement` already uses.
|
|
305
|
+
*/
|
|
306
|
+
export declare function stopWithReceipt(sessionId: string, runAbort: () => Promise<void>, options?: StopWithReceiptOptions): Promise<AbortSettlement>;
|
|
180
307
|
export interface UseSessionSendOptions {
|
|
181
308
|
getClient?: () => OpenCodeMessagesClient;
|
|
182
309
|
classify?: (error: unknown) => KortixSendError;
|
|
310
|
+
/**
|
|
311
|
+
* The KORTIX session id, when it differs from the hook's `sessionId`.
|
|
312
|
+
*
|
|
313
|
+
* `sessionId` addresses the OpenCode runtime this hook POSTs to; the send and
|
|
314
|
+
* abort receipts belong to the Kortix session `useSessionWorking` reads. Pass
|
|
315
|
+
* it whenever the two ids differ, or the receipts are filed under a key
|
|
316
|
+
* nothing reads. See `SendWithReceiptArgs.workingSessionId`.
|
|
317
|
+
*/
|
|
318
|
+
workingSessionId?: string;
|
|
319
|
+
/**
|
|
320
|
+
* Kortix project id. Passed straight through to `stopWithReceipt` so
|
|
321
|
+
* `stop()` holds the session's server-side prompt inbox before aborting —
|
|
322
|
+
* see `StopWithReceiptOptions.projectId`. Omit for a host with no prompt
|
|
323
|
+
* inbox for this session; `stop()` then aborts with no hold, exactly as it
|
|
324
|
+
* did before the inbox existed.
|
|
325
|
+
*/
|
|
326
|
+
projectId?: string;
|
|
183
327
|
}
|
|
184
328
|
export interface SendCallOptions {
|
|
185
329
|
/** Optimistic message id. Auto-generated (via the sync store's ascending
|
|
@@ -195,9 +339,14 @@ export interface SendCallOptions {
|
|
|
195
339
|
export interface UseSessionSendResult {
|
|
196
340
|
send: (parts: PromptPart[], options?: SendMessageOptions, callOptions?: SendCallOptions) => Promise<SendAndRecoverResult>;
|
|
197
341
|
/** Abort the run and optimistically patch the last assistant message +
|
|
198
|
-
* session status (see `applyOptimisticAbort`)
|
|
199
|
-
*
|
|
200
|
-
|
|
342
|
+
* session status (see `applyOptimisticAbort`), and stop any delivery still
|
|
343
|
+
* retrying its own boot/wake backoff (T9 — `abortInFlightDeliveries`)
|
|
344
|
+
* so a prompt in flight when Stop is hit can never land afterward. No-ops
|
|
345
|
+
* (resolves `{ status: 'skipped' }`) while a previous abort is still in
|
|
346
|
+
* flight, or when there is no session. Returns a promise that settles once
|
|
347
|
+
* the abort is acknowledged — see `AbortSettlement`; a caller that never
|
|
348
|
+
* awaits it sees exactly the same synchronous effects as before. */
|
|
349
|
+
stop: () => Promise<AbortSettlement>;
|
|
201
350
|
isSending: boolean;
|
|
202
351
|
isStopping: boolean;
|
|
203
352
|
/** Last `send` failure, or null. Reset on every new `send` call. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-session-send.d.ts","sourceRoot":"","sources":["../../src/react/use-session-send.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"use-session-send.d.ts","sourceRoot":"","sources":["../../src/react/use-session-send.ts"],"names":[],"mappings":"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"}
|