@opengeni/react 7.6.1-canary.37073905159001 → 7.6.1
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 +2 -19
- package/dist/{browser-viewer-63TXMINB.js → browser-viewer-5X47I6T2.js} +5 -6
- package/dist/{chunk-TKB4SB44.js → chunk-45GE35O7.js} +2 -10
- package/dist/chunk-45GE35O7.js.map +1 -0
- package/dist/{chunk-DOJWJQ3F.js → chunk-5EXGU7UF.js} +3 -3
- package/dist/{chunk-YN7I3STW.js → chunk-6NEZPF53.js} +32 -153
- package/dist/chunk-6NEZPF53.js.map +1 -0
- package/dist/{chunk-I7IWRQLN.js → chunk-BI57CQUV.js} +2 -2
- package/dist/{chunk-6ZSWSH4I.js → chunk-CHPKSLPN.js} +1 -3
- package/dist/chunk-CHPKSLPN.js.map +1 -0
- package/dist/{chunk-Q5QBEZIQ.js → chunk-DV2DBNPQ.js} +29 -48
- package/dist/chunk-DV2DBNPQ.js.map +1 -0
- package/dist/{chunk-RDKBXMWX.js → chunk-FGBCYQOT.js} +74 -120
- package/dist/chunk-FGBCYQOT.js.map +1 -0
- package/dist/{chunk-AAG4R3QN.js → chunk-KGENSZKS.js} +3 -4
- package/dist/chunk-KGENSZKS.js.map +1 -0
- package/dist/{chunk-YQEAA6LT.js → chunk-KZ73RL76.js} +3 -7
- package/dist/chunk-KZ73RL76.js.map +1 -0
- package/dist/{chunk-LFXYGZWK.js → chunk-LZ3KHA55.js} +60 -169
- package/dist/chunk-LZ3KHA55.js.map +1 -0
- package/dist/{chunk-2QUSQVF2.js → chunk-UINDK6C3.js} +3 -3
- package/dist/{chunk-UTRTG6LH.js → chunk-UJRYEWZI.js} +8 -48
- package/dist/chunk-UJRYEWZI.js.map +1 -0
- package/dist/{chunk-XOAMRDDK.js → chunk-VGIKFIO2.js} +3 -6
- package/dist/chunk-VGIKFIO2.js.map +1 -0
- package/dist/{chunk-ELCE5SXV.js → chunk-WZ55DVGK.js} +4 -8
- package/dist/chunk-WZ55DVGK.js.map +1 -0
- package/dist/{chunk-IQUCRAT7.js → chunk-XA6R7DJQ.js} +3 -3
- package/dist/{chunk-TOAH2BKA.js → chunk-YCGBREUV.js} +2 -6
- package/dist/{chunk-TOAH2BKA.js.map → chunk-YCGBREUV.js.map} +1 -1
- package/dist/{chunk-HNFCAQ5R.js → chunk-YRYF2GLG.js} +31 -39
- package/dist/chunk-YRYF2GLG.js.map +1 -0
- package/dist/{chunk-GISEVGS6.js → chunk-YSMMDOOE.js} +2 -10
- package/dist/chunk-YSMMDOOE.js.map +1 -0
- package/dist/{chunk-CWWKTNKK.js → chunk-Z3DISEQN.js} +18 -35
- package/dist/chunk-Z3DISEQN.js.map +1 -0
- package/dist/client.d.ts +1 -4
- package/dist/commands/types.d.ts +0 -2
- package/dist/components/approval-surface.d.ts +0 -15
- package/dist/composer.js +7 -8
- package/dist/{computer-viewer-X2MBRZY4.js → computer-viewer-7GF35SNY.js} +4 -5
- package/dist/connect.js +3 -3
- package/dist/hooks/use-browser-session.d.ts +0 -4
- package/dist/hooks/use-composer.d.ts +0 -2
- package/dist/hooks/use-computer-session.d.ts +0 -2
- package/dist/hooks/use-file-attachments.d.ts +0 -2
- package/dist/hooks/use-session-events.d.ts +1 -1
- package/dist/hooks/use-workspace-sessions.d.ts +5 -15
- package/dist/index.d.ts +2 -2
- package/dist/index.js +21 -28
- package/dist/index.js.map +1 -1
- package/dist/interaction.d.ts +1 -1
- package/dist/interaction.js +5 -6
- package/dist/interaction.js.map +1 -1
- package/dist/{latest-question-CNEZ5KAN.js → latest-question-3BJGKQQ6.js} +3 -3
- package/dist/lib/format.d.ts +3 -27
- package/dist/lib/interaction-errors.d.ts +0 -3
- package/dist/machines.js +4 -5
- package/dist/{model-policy-picker-menu-JSA64TNN.js → model-policy-picker-menu-PUTA5JOB.js} +4 -4
- package/dist/model-policy.js +1 -1
- package/dist/provider.d.ts +1 -5
- package/dist/{queue-surface-implementation-HENWYFWA.js → queue-surface-implementation-2CAQAIHM.js} +2 -3
- package/dist/{queue-surface-implementation-HENWYFWA.js.map → queue-surface-implementation-2CAQAIHM.js.map} +1 -1
- package/dist/realtime.js +2 -2
- package/dist/{sandbox-files-BBC47SLD.js → sandbox-files-AEJTWGT4.js} +3 -4
- package/dist/session-ui.d.ts +1 -1
- package/dist/session-ui.js +12 -13
- package/dist/session-ui.js.map +1 -1
- package/dist/session.js +6 -7
- package/dist/usage.js +1 -2
- package/dist/usage.js.map +1 -1
- package/package.json +3 -3
- package/src/client.ts +1 -5
- package/src/commands/registry.ts +15 -18
- package/src/commands/types.ts +0 -2
- package/src/components/approval-surface.tsx +42 -166
- package/src/components/browser-viewer.tsx +9 -38
- package/src/components/composer.tsx +2 -9
- package/src/components/computer-viewer.tsx +30 -160
- package/src/components/generated-video-player.tsx +2 -4
- package/src/components/human-input-form.tsx +5 -18
- package/src/components/message-timeline.tsx +2 -4
- package/src/components/open-geni-chat.tsx +4 -11
- package/src/components/queue-surface-state.tsx +1 -3
- package/src/components/session-chrome.tsx +2 -5
- package/src/components/session-commands-panel.tsx +1 -3
- package/src/components/session-conversation.tsx +2 -4
- package/src/components/session-list.tsx +5 -7
- package/src/components/session-mcp-capability-card.tsx +1 -11
- package/src/hooks/internal.ts +2 -3
- package/src/hooks/use-browser-session.ts +79 -115
- package/src/hooks/use-composer.ts +31 -70
- package/src/hooks/use-computer-session.ts +6 -57
- package/src/hooks/use-file-attachments.ts +3 -16
- package/src/hooks/use-goal.ts +1 -2
- package/src/hooks/use-session-capabilities.ts +2 -3
- package/src/hooks/use-session-events.ts +8 -15
- package/src/hooks/use-slash-commands.ts +11 -6
- package/src/hooks/use-turn-queue.ts +1 -2
- package/src/hooks/use-workspace-sessions.ts +7 -40
- package/src/index.ts +2 -7
- package/src/interaction.ts +0 -1
- package/src/lib/format.ts +9 -73
- package/src/lib/interaction-errors.ts +0 -15
- package/src/model-policy.ts +0 -5
- package/src/provider.tsx +4 -12
- package/src/session-ui.ts +1 -1
- package/src/timeline/projection.ts +1 -12
- package/styles/compiled.css +0 -14
- package/dist/chunk-6ZSWSH4I.js.map +0 -1
- package/dist/chunk-AAG4R3QN.js.map +0 -1
- package/dist/chunk-CWWKTNKK.js.map +0 -1
- package/dist/chunk-ELCE5SXV.js.map +0 -1
- package/dist/chunk-GISEVGS6.js.map +0 -1
- package/dist/chunk-HNFCAQ5R.js.map +0 -1
- package/dist/chunk-LFXYGZWK.js.map +0 -1
- package/dist/chunk-Q5QBEZIQ.js.map +0 -1
- package/dist/chunk-RDKBXMWX.js.map +0 -1
- package/dist/chunk-TKB4SB44.js.map +0 -1
- package/dist/chunk-UGLEYEMP.js +0 -33
- package/dist/chunk-UGLEYEMP.js.map +0 -1
- package/dist/chunk-UTRTG6LH.js.map +0 -1
- package/dist/chunk-XOAMRDDK.js.map +0 -1
- package/dist/chunk-YN7I3STW.js.map +0 -1
- package/dist/chunk-YQEAA6LT.js.map +0 -1
- package/dist/lib/error-message.d.ts +0 -7
- package/src/lib/error-message.ts +0 -37
- /package/dist/{browser-viewer-63TXMINB.js.map → browser-viewer-5X47I6T2.js.map} +0 -0
- /package/dist/{chunk-DOJWJQ3F.js.map → chunk-5EXGU7UF.js.map} +0 -0
- /package/dist/{chunk-I7IWRQLN.js.map → chunk-BI57CQUV.js.map} +0 -0
- /package/dist/{chunk-2QUSQVF2.js.map → chunk-UINDK6C3.js.map} +0 -0
- /package/dist/{chunk-IQUCRAT7.js.map → chunk-XA6R7DJQ.js.map} +0 -0
- /package/dist/{computer-viewer-X2MBRZY4.js.map → computer-viewer-7GF35SNY.js.map} +0 -0
- /package/dist/{latest-question-CNEZ5KAN.js.map → latest-question-3BJGKQQ6.js.map} +0 -0
- /package/dist/{model-policy-picker-menu-JSA64TNN.js.map → model-policy-picker-menu-PUTA5JOB.js.map} +0 -0
- /package/dist/{sandbox-files-BBC47SLD.js.map → sandbox-files-AEJTWGT4.js.map} +0 -0
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
type EffectiveControlResumeOption,
|
|
6
6
|
type EffectiveSessionControl,
|
|
7
7
|
type LatencyMode,
|
|
8
|
-
OpenGeniApiError,
|
|
8
|
+
type OpenGeniApiError,
|
|
9
9
|
type ReasoningEffort,
|
|
10
10
|
type ResourceRef,
|
|
11
11
|
type SaveComposerDraftRequest,
|
|
@@ -15,15 +15,7 @@ import {
|
|
|
15
15
|
} from "@opengeni/sdk";
|
|
16
16
|
import { useCallback, useEffect, useLayoutEffect, useRef, useState } from "react";
|
|
17
17
|
import { useEmbeddedSession, type EmbeddedSessionClientOverride } from "../session-context";
|
|
18
|
-
import {
|
|
19
|
-
COMPOSER_MODEL_UNAVAILABLE_MESSAGE,
|
|
20
|
-
ComposerReconciliationRequiredError,
|
|
21
|
-
ComposerStateError,
|
|
22
|
-
ComposerWorkspaceControlUnavailableError,
|
|
23
|
-
composerSubmissionCanRetry,
|
|
24
|
-
composerSubmissionErrorMessage,
|
|
25
|
-
} from "../lib/format";
|
|
26
|
-
import { normalizeError, useErrorMessage } from "../lib/error-message";
|
|
18
|
+
import { composerSubmissionCanRetry, composerSubmissionErrorMessage } from "../lib/format";
|
|
27
19
|
import { useSessionEventTrigger, type SessionEventFeedOptions } from "./internal";
|
|
28
20
|
|
|
29
21
|
export type ComposerPolicy = {
|
|
@@ -106,8 +98,6 @@ export type ComposerOptimisticMessage = {
|
|
|
106
98
|
triggerEventId?: string | null | undefined;
|
|
107
99
|
appliedQueueVersion?: number | null | undefined;
|
|
108
100
|
error?: string | undefined;
|
|
109
|
-
/** Bounded support reference retained independently of display copy across remounts. */
|
|
110
|
-
correlationId?: string | undefined;
|
|
111
101
|
/** False for a definitive refusal that requires changing payment or allowance settings. */
|
|
112
102
|
retryable?: boolean | undefined;
|
|
113
103
|
outcomeUnknown?: boolean | undefined;
|
|
@@ -195,19 +185,12 @@ function restoreOptimisticSendOperations(key: string | null): OptimisticSendOper
|
|
|
195
185
|
operation.state === "sending" || operation.state === "queued"
|
|
196
186
|
? true
|
|
197
187
|
: operation.outcomeUnknown,
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
? "Delivery was interrupted; retry to reconcile this message."
|
|
205
|
-
: operation.outcomeUnknown
|
|
206
|
-
? "The request could not be confirmed. Check its status before retrying."
|
|
207
|
-
: operation.error
|
|
208
|
-
? composerSubmissionErrorMessage(new Error(operation.error))
|
|
209
|
-
: undefined,
|
|
210
|
-
),
|
|
188
|
+
error:
|
|
189
|
+
operation.state === "sending"
|
|
190
|
+
? "Delivery was interrupted; retry to reconcile this message."
|
|
191
|
+
: operation.error
|
|
192
|
+
? composerSubmissionErrorMessage(new Error(operation.error))
|
|
193
|
+
: undefined,
|
|
211
194
|
retryable:
|
|
212
195
|
operation.state === "sending" || operation.outcomeUnknown
|
|
213
196
|
? true
|
|
@@ -218,20 +201,6 @@ function restoreOptimisticSendOperations(key: string | null): OptimisticSendOper
|
|
|
218
201
|
}));
|
|
219
202
|
}
|
|
220
203
|
|
|
221
|
-
function restoredCorrelationId(value: unknown): string | undefined {
|
|
222
|
-
return typeof value === "string" && /^[\w.:-]{1,128}$/u.test(value) ? value : undefined;
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
function restoredErrorReference(
|
|
226
|
-
reference: unknown,
|
|
227
|
-
message: string | undefined,
|
|
228
|
-
): string | undefined {
|
|
229
|
-
const correlationId = restoredCorrelationId(reference);
|
|
230
|
-
return message && correlationId && message !== COMPOSER_MODEL_UNAVAILABLE_MESSAGE
|
|
231
|
-
? `${message} Reference: ${correlationId}.`
|
|
232
|
-
: message;
|
|
233
|
-
}
|
|
234
|
-
|
|
235
204
|
function rememberOptimisticSendOperations(
|
|
236
205
|
key: string | null,
|
|
237
206
|
operations: OptimisticSendOperation[],
|
|
@@ -682,7 +651,6 @@ export function useComposer(
|
|
|
682
651
|
options: UseComposerOptions = {},
|
|
683
652
|
): ComposerControllerState {
|
|
684
653
|
const { client, workspaceId, registerSessionReconciler } = useEmbeddedSession(options);
|
|
685
|
-
const formatError = useErrorMessage();
|
|
686
654
|
const durableDrafts = options.draftPersistence !== "disabled";
|
|
687
655
|
if (!durableDrafts && !options.initialPolicy) {
|
|
688
656
|
throw new Error("useComposer requires initialPolicy when draft persistence is disabled");
|
|
@@ -1103,9 +1071,7 @@ export function useComposer(
|
|
|
1103
1071
|
const problem = asError(cause);
|
|
1104
1072
|
const timedOut = problem.name === "TimeoutError";
|
|
1105
1073
|
setDraftReadError(
|
|
1106
|
-
timedOut
|
|
1107
|
-
? new ComposerStateError("Draft sync timed out. Retrying…", { cause })
|
|
1108
|
-
: problem,
|
|
1074
|
+
timedOut ? new Error("Draft sync timed out. Retrying…", { cause }) : problem,
|
|
1109
1075
|
);
|
|
1110
1076
|
if (
|
|
1111
1077
|
timedOut ||
|
|
@@ -1412,34 +1378,22 @@ export function useComposer(
|
|
|
1412
1378
|
optimisticProcessorBusyRef.current = true;
|
|
1413
1379
|
void (async () => {
|
|
1414
1380
|
let mutationFailureObserved = false;
|
|
1415
|
-
const markFailed = (
|
|
1381
|
+
const markFailed = (problem: Error, outcomeUnknown: boolean): void => {
|
|
1416
1382
|
if (
|
|
1417
1383
|
targetKeyRef.current !== ownedTargetKey ||
|
|
1418
1384
|
targetGeneration.current !== ownedGeneration
|
|
1419
1385
|
) {
|
|
1420
1386
|
return;
|
|
1421
1387
|
}
|
|
1422
|
-
const problem = asError(cause);
|
|
1423
1388
|
replaceOptimisticSends((current) =>
|
|
1424
1389
|
current.map((candidate) =>
|
|
1425
1390
|
candidate.clientEventId === operation.clientEventId
|
|
1426
1391
|
? {
|
|
1427
1392
|
...candidate,
|
|
1428
1393
|
state: "failed",
|
|
1429
|
-
error:
|
|
1430
|
-
cause,
|
|
1431
|
-
outcomeUnknown &&
|
|
1432
|
-
!isOutcomeUnknownError(problem) &&
|
|
1433
|
-
!(problem instanceof ComposerReconciliationRequiredError)
|
|
1434
|
-
? `The request could not be confirmed. Check its status before retrying.${problem instanceof OpenGeniApiError && problem.correlationId ? ` Reference: ${problem.correlationId}.` : ""}`
|
|
1435
|
-
: composerSubmissionErrorMessage(problem),
|
|
1436
|
-
),
|
|
1394
|
+
error: outcomeUnknown ? problem.message : composerSubmissionErrorMessage(problem),
|
|
1437
1395
|
retryable: outcomeUnknown || composerSubmissionCanRetry(problem),
|
|
1438
1396
|
outcomeUnknown,
|
|
1439
|
-
correlationId:
|
|
1440
|
-
problem instanceof OpenGeniApiError
|
|
1441
|
-
? problem.correlationId
|
|
1442
|
-
: candidate.correlationId,
|
|
1443
1397
|
}
|
|
1444
1398
|
: candidate,
|
|
1445
1399
|
),
|
|
@@ -1466,7 +1420,7 @@ export function useComposer(
|
|
|
1466
1420
|
// This read cannot settle the prior mutation in either direction.
|
|
1467
1421
|
// Preserve its exact key and uncertain status until reconciliation
|
|
1468
1422
|
// succeeds or that same mutation is actually replayed.
|
|
1469
|
-
markFailed(cause, true);
|
|
1423
|
+
markFailed(asError(cause), true);
|
|
1470
1424
|
return;
|
|
1471
1425
|
}
|
|
1472
1426
|
const reconciled = reconcileOptimisticSendFromEvents(operation, events);
|
|
@@ -1490,13 +1444,15 @@ export function useComposer(
|
|
|
1490
1444
|
return;
|
|
1491
1445
|
}
|
|
1492
1446
|
if (!operation.canRetry) {
|
|
1493
|
-
throw new
|
|
1447
|
+
throw new Error(
|
|
1448
|
+
"Opengeni cannot safely retry this uncertain request after remount; reconcile the session before sending again.",
|
|
1449
|
+
);
|
|
1494
1450
|
}
|
|
1495
1451
|
}
|
|
1496
1452
|
let expectedDraftRevision: number | undefined;
|
|
1497
1453
|
if (durableDrafts && operation.draftPayload) {
|
|
1498
1454
|
if (!(await persistPayload(operation.draftPayload))) {
|
|
1499
|
-
throw new
|
|
1455
|
+
throw new Error("The message draft could not be saved before delivery.");
|
|
1500
1456
|
}
|
|
1501
1457
|
expectedDraftRevision = draftRef.current?.revision;
|
|
1502
1458
|
}
|
|
@@ -1514,7 +1470,7 @@ export function useComposer(
|
|
|
1514
1470
|
let acceptedEvent: SessionEvent | null = null;
|
|
1515
1471
|
if (durableDrafts) {
|
|
1516
1472
|
if (!operation.draftPayload || expectedDraftRevision === undefined) {
|
|
1517
|
-
throw new
|
|
1473
|
+
throw new Error("The durable composer draft is not ready for delivery.");
|
|
1518
1474
|
}
|
|
1519
1475
|
const result = await client
|
|
1520
1476
|
.submitComposerDraft(workspaceId, sessionId, {
|
|
@@ -1612,7 +1568,7 @@ export function useComposer(
|
|
|
1612
1568
|
operation.outcomeUnknown && !mutationFailureObserved
|
|
1613
1569
|
? true
|
|
1614
1570
|
: isOutcomeUnknownError(cause);
|
|
1615
|
-
markFailed(
|
|
1571
|
+
markFailed(problem, outcomeUnknown);
|
|
1616
1572
|
} finally {
|
|
1617
1573
|
optimisticProcessorBusyRef.current = false;
|
|
1618
1574
|
if (targetKeyRef.current === ownedTargetKey) {
|
|
@@ -1624,7 +1580,6 @@ export function useComposer(
|
|
|
1624
1580
|
adoptDraftBase,
|
|
1625
1581
|
client,
|
|
1626
1582
|
durableDrafts,
|
|
1627
|
-
formatError,
|
|
1628
1583
|
markOptimisticAccepted,
|
|
1629
1584
|
loadDraft,
|
|
1630
1585
|
onSent,
|
|
@@ -1793,7 +1748,7 @@ export function useComposer(
|
|
|
1793
1748
|
input.reasoningEffort === undefined ||
|
|
1794
1749
|
input.latencyMode === undefined
|
|
1795
1750
|
) {
|
|
1796
|
-
throw new
|
|
1751
|
+
throw new Error("The durable composer draft is not ready for delivery.");
|
|
1797
1752
|
}
|
|
1798
1753
|
const result = await client.submitComposerDraft(workspaceId, sessionId, {
|
|
1799
1754
|
text: input.text,
|
|
@@ -1898,7 +1853,11 @@ export function useComposer(
|
|
|
1898
1853
|
return true;
|
|
1899
1854
|
}
|
|
1900
1855
|
if (!pending.canRetry) {
|
|
1901
|
-
setError(
|
|
1856
|
+
setError(
|
|
1857
|
+
new Error(
|
|
1858
|
+
"Opengeni cannot safely retry this uncertain request after remount; reconcile the session before sending again.",
|
|
1859
|
+
),
|
|
1860
|
+
);
|
|
1902
1861
|
return false;
|
|
1903
1862
|
}
|
|
1904
1863
|
try {
|
|
@@ -2293,7 +2252,7 @@ export function useComposer(
|
|
|
2293
2252
|
targetKeyRef.current === ownedTargetKey &&
|
|
2294
2253
|
targetGeneration.current === ownedGeneration
|
|
2295
2254
|
) {
|
|
2296
|
-
setError(
|
|
2255
|
+
setError(cause instanceof Error ? cause : new Error(String(cause)));
|
|
2297
2256
|
}
|
|
2298
2257
|
} finally {
|
|
2299
2258
|
if (
|
|
@@ -2337,7 +2296,7 @@ export function useComposer(
|
|
|
2337
2296
|
targetKeyRef.current === ownedTargetKey &&
|
|
2338
2297
|
targetGeneration.current === ownedGeneration
|
|
2339
2298
|
) {
|
|
2340
|
-
setError(
|
|
2299
|
+
setError(cause instanceof Error ? cause : new Error(String(cause)));
|
|
2341
2300
|
}
|
|
2342
2301
|
} finally {
|
|
2343
2302
|
if (
|
|
@@ -2364,7 +2323,9 @@ export function useComposer(
|
|
|
2364
2323
|
(blocker) => blocker.kind === "workspace",
|
|
2365
2324
|
);
|
|
2366
2325
|
if (!client.setWorkspaceInferenceState) {
|
|
2367
|
-
throw new
|
|
2326
|
+
throw new Error(
|
|
2327
|
+
"@opengeni/react: workspace-scoped resume requires setWorkspaceInferenceState.",
|
|
2328
|
+
);
|
|
2368
2329
|
}
|
|
2369
2330
|
const clientEventId = generateClientEventId();
|
|
2370
2331
|
await replayOutcomeUnknown(() =>
|
|
@@ -2494,7 +2455,7 @@ export function useComposer(
|
|
|
2494
2455
|
const addAnnotation = useCallback(
|
|
2495
2456
|
(annotation: DraftTimelineAnnotation) => {
|
|
2496
2457
|
if (annotationsRef.current.length >= 12) {
|
|
2497
|
-
setError(new
|
|
2458
|
+
setError(new Error("A message can include at most 12 timeline annotations."));
|
|
2498
2459
|
return;
|
|
2499
2460
|
}
|
|
2500
2461
|
const next = [...annotationsRef.current, annotation];
|
|
@@ -2891,7 +2852,7 @@ async function replayOutcomeUnknown<T>(command: () => Promise<T>): Promise<T> {
|
|
|
2891
2852
|
}
|
|
2892
2853
|
|
|
2893
2854
|
function asError(cause: unknown): Error {
|
|
2894
|
-
return
|
|
2855
|
+
return cause instanceof Error ? cause : new Error(String(cause));
|
|
2895
2856
|
}
|
|
2896
2857
|
|
|
2897
2858
|
function promptRoutingFromAcceptedEvent(
|
|
@@ -8,10 +8,7 @@ import type {
|
|
|
8
8
|
ComputerTarget,
|
|
9
9
|
} from "@opengeni/sdk/interaction";
|
|
10
10
|
import { useCallback, useEffect, useRef, useState } from "react";
|
|
11
|
-
import {
|
|
12
|
-
isInteractionControlUnavailable,
|
|
13
|
-
isNonRetryableInteractionError,
|
|
14
|
-
} from "../lib/interaction-errors";
|
|
11
|
+
import { isNonRetryableInteractionError } from "../lib/interaction-errors";
|
|
15
12
|
import {
|
|
16
13
|
type EmbeddedComputerInteractionClientOverride,
|
|
17
14
|
useEmbeddedComputerInteraction,
|
|
@@ -32,8 +29,6 @@ export type UseComputerSessionResult = {
|
|
|
32
29
|
loading: boolean;
|
|
33
30
|
mutating: boolean;
|
|
34
31
|
error: Error | null;
|
|
35
|
-
/** Control service loss, independent of target accessibility inspection and media. */
|
|
36
|
-
controlError: Error | null;
|
|
37
32
|
refresh: () => Promise<void>;
|
|
38
33
|
readClipboard: () => Promise<ComputerClipboard>;
|
|
39
34
|
/** Changes only this viewer's target cursor; it never takes ownership or
|
|
@@ -110,7 +105,6 @@ export function useComputerSession(options: UseComputerSessionOptions): UseCompu
|
|
|
110
105
|
requestRef.current.controller?.abort();
|
|
111
106
|
const controller = new AbortController();
|
|
112
107
|
requestRef.current = { id, controller };
|
|
113
|
-
let discoveryCompleted = false;
|
|
114
108
|
try {
|
|
115
109
|
const [session, targetResponse] = await Promise.all([
|
|
116
110
|
client.getComputerSession(workspaceId, computerSessionId, {
|
|
@@ -120,7 +114,6 @@ export function useComputerSession(options: UseComputerSessionOptions): UseCompu
|
|
|
120
114
|
signal: controller.signal,
|
|
121
115
|
}),
|
|
122
116
|
]);
|
|
123
|
-
discoveryCompleted = true;
|
|
124
117
|
if (!mountedRef.current || requestRef.current.id !== id) return;
|
|
125
118
|
const targets = sortComputerTargets(targetResponse.targets);
|
|
126
119
|
const selected = chooseTarget(targets, selectedTargetIdRef.current, session.platform);
|
|
@@ -148,7 +141,6 @@ export function useComputerSession(options: UseComputerSessionOptions): UseCompu
|
|
|
148
141
|
observation: retainedObservation,
|
|
149
142
|
loading: false,
|
|
150
143
|
error: null,
|
|
151
|
-
controlError: null,
|
|
152
144
|
}
|
|
153
145
|
: current,
|
|
154
146
|
);
|
|
@@ -176,19 +168,12 @@ export function useComputerSession(options: UseComputerSessionOptions): UseCompu
|
|
|
176
168
|
);
|
|
177
169
|
} catch (cause) {
|
|
178
170
|
if (controller.signal.aborted || !mountedRef.current || requestRef.current.id !== id) return;
|
|
179
|
-
const error = cause instanceof Error ? cause : new Error(String(cause));
|
|
180
171
|
setState((current) =>
|
|
181
172
|
current.computerSessionId === computerSessionId
|
|
182
173
|
? {
|
|
183
174
|
...current,
|
|
184
175
|
loading: false,
|
|
185
|
-
error,
|
|
186
|
-
controlError: isInteractionControlUnavailable(
|
|
187
|
-
error,
|
|
188
|
-
discoveryCompleted ? "observation" : "control",
|
|
189
|
-
)
|
|
190
|
-
? error
|
|
191
|
-
: current.controlError,
|
|
176
|
+
error: cause instanceof Error ? cause : new Error(String(cause)),
|
|
192
177
|
}
|
|
193
178
|
: current,
|
|
194
179
|
);
|
|
@@ -254,23 +239,11 @@ export function useComputerSession(options: UseComputerSessionOptions): UseCompu
|
|
|
254
239
|
: current,
|
|
255
240
|
);
|
|
256
241
|
try {
|
|
257
|
-
|
|
258
|
-
setState((current) =>
|
|
259
|
-
current.computerSessionId === scopeComputerSessionId
|
|
260
|
-
? { ...current, controlError: null }
|
|
261
|
-
: current,
|
|
262
|
-
);
|
|
263
|
-
return result;
|
|
242
|
+
return await operation();
|
|
264
243
|
} catch (cause) {
|
|
265
244
|
const error = cause instanceof Error ? cause : new Error(String(cause));
|
|
266
245
|
setState((current) =>
|
|
267
|
-
current.computerSessionId === scopeComputerSessionId
|
|
268
|
-
? {
|
|
269
|
-
...current,
|
|
270
|
-
error,
|
|
271
|
-
controlError: isInteractionControlUnavailable(error) ? error : current.controlError,
|
|
272
|
-
}
|
|
273
|
-
: current,
|
|
246
|
+
current.computerSessionId === scopeComputerSessionId ? { ...current, error } : current,
|
|
274
247
|
);
|
|
275
248
|
throw error;
|
|
276
249
|
} finally {
|
|
@@ -325,14 +298,7 @@ export function useComputerSession(options: UseComputerSessionOptions): UseCompu
|
|
|
325
298
|
const error = cause instanceof Error ? cause : new Error(String(cause));
|
|
326
299
|
setState((current) =>
|
|
327
300
|
current.computerSessionId === computerSessionId && current.selectedTargetId === target.id
|
|
328
|
-
? {
|
|
329
|
-
...current,
|
|
330
|
-
loading: false,
|
|
331
|
-
error,
|
|
332
|
-
controlError: isInteractionControlUnavailable(error, "observation")
|
|
333
|
-
? error
|
|
334
|
-
: current.controlError,
|
|
335
|
-
}
|
|
301
|
+
? { ...current, loading: false, error }
|
|
336
302
|
: current,
|
|
337
303
|
);
|
|
338
304
|
throw error;
|
|
@@ -439,21 +405,7 @@ export function useComputerSession(options: UseComputerSessionOptions): UseCompu
|
|
|
439
405
|
|
|
440
406
|
const readClipboard = useCallback(async (): Promise<ComputerClipboard> => {
|
|
441
407
|
if (!computerSessionId) throw new Error("No desktop is selected.");
|
|
442
|
-
|
|
443
|
-
return await client.readComputerClipboard(workspaceId, computerSessionId);
|
|
444
|
-
} catch (cause) {
|
|
445
|
-
const error = cause instanceof Error ? cause : new Error(String(cause));
|
|
446
|
-
setState((current) =>
|
|
447
|
-
current.computerSessionId === computerSessionId
|
|
448
|
-
? {
|
|
449
|
-
...current,
|
|
450
|
-
error,
|
|
451
|
-
controlError: isInteractionControlUnavailable(error) ? error : current.controlError,
|
|
452
|
-
}
|
|
453
|
-
: current,
|
|
454
|
-
);
|
|
455
|
-
throw error;
|
|
456
|
-
}
|
|
408
|
+
return await client.readComputerClipboard(workspaceId, computerSessionId);
|
|
457
409
|
}, [client, computerSessionId, workspaceId]);
|
|
458
410
|
|
|
459
411
|
return {
|
|
@@ -465,7 +417,6 @@ export function useComputerSession(options: UseComputerSessionOptions): UseCompu
|
|
|
465
417
|
loading: visible.loading,
|
|
466
418
|
mutating: visible.mutating,
|
|
467
419
|
error: visible.error,
|
|
468
|
-
controlError: visible.controlError,
|
|
469
420
|
refresh,
|
|
470
421
|
readClipboard,
|
|
471
422
|
selectTarget,
|
|
@@ -483,7 +434,6 @@ type ComputerControlState = {
|
|
|
483
434
|
loading: boolean;
|
|
484
435
|
mutating: boolean;
|
|
485
436
|
error: Error | null;
|
|
486
|
-
controlError: Error | null;
|
|
487
437
|
};
|
|
488
438
|
|
|
489
439
|
function emptyState(computerSessionId: string | null, loading: boolean): ComputerControlState {
|
|
@@ -496,7 +446,6 @@ function emptyState(computerSessionId: string | null, loading: boolean): Compute
|
|
|
496
446
|
loading,
|
|
497
447
|
mutating: false,
|
|
498
448
|
error: null,
|
|
499
|
-
controlError: null,
|
|
500
449
|
};
|
|
501
450
|
}
|
|
502
451
|
|
|
@@ -4,7 +4,6 @@ import {
|
|
|
4
4
|
useEmbeddedFileAttachments,
|
|
5
5
|
type EmbeddedFileAttachmentClientOverride,
|
|
6
6
|
} from "../session-context";
|
|
7
|
-
import { useErrorMessage } from "../lib/error-message";
|
|
8
7
|
|
|
9
8
|
export type UseFileAttachmentsOptions = EmbeddedFileAttachmentClientOverride & {
|
|
10
9
|
/**
|
|
@@ -32,8 +31,6 @@ export type FileAttachment = {
|
|
|
32
31
|
/** Stable SDK failure code for UI behavior that must not parse error copy. */
|
|
33
32
|
errorCode?: "secure_context_required" | undefined;
|
|
34
33
|
error?: string | undefined;
|
|
35
|
-
/** Original diagnostic failure; presentation copy is kept separately in `error`. */
|
|
36
|
-
errorCause?: unknown;
|
|
37
34
|
};
|
|
38
35
|
|
|
39
36
|
export type UseFileAttachmentsResult = {
|
|
@@ -123,7 +120,6 @@ export function useFileAttachments(
|
|
|
123
120
|
options: UseFileAttachmentsOptions = {},
|
|
124
121
|
): UseFileAttachmentsResult {
|
|
125
122
|
const { client, workspaceId } = useEmbeddedFileAttachments(options);
|
|
126
|
-
const formatError = useErrorMessage();
|
|
127
123
|
const pasteFilter = options.pasteFilter ?? isImage;
|
|
128
124
|
const [attachments, setAttachments] = useState<FileAttachment[]>([]);
|
|
129
125
|
const attachmentsRef = useRef(attachments);
|
|
@@ -238,7 +234,6 @@ export function useFileAttachments(
|
|
|
238
234
|
sizeBytes: asset.sizeBytes,
|
|
239
235
|
errorCode: undefined,
|
|
240
236
|
error: undefined,
|
|
241
|
-
errorCause: undefined,
|
|
242
237
|
}
|
|
243
238
|
: attachment,
|
|
244
239
|
),
|
|
@@ -253,15 +248,14 @@ export function useFileAttachments(
|
|
|
253
248
|
...attachment,
|
|
254
249
|
status: "failed",
|
|
255
250
|
errorCode: secureContextRequiredErrorCode(error),
|
|
256
|
-
error:
|
|
257
|
-
errorCause: error,
|
|
251
|
+
error: error instanceof Error ? error.message : String(error),
|
|
258
252
|
}
|
|
259
253
|
: attachment,
|
|
260
254
|
),
|
|
261
255
|
);
|
|
262
256
|
});
|
|
263
257
|
},
|
|
264
|
-
[client, workspaceId, options.scope
|
|
258
|
+
[client, workspaceId, options.scope],
|
|
265
259
|
);
|
|
266
260
|
|
|
267
261
|
const addFiles = useCallback(
|
|
@@ -297,13 +291,7 @@ export function useFileAttachments(
|
|
|
297
291
|
setAttachments((current) =>
|
|
298
292
|
current.map((attachment) =>
|
|
299
293
|
attachment.id === id
|
|
300
|
-
? {
|
|
301
|
-
...attachment,
|
|
302
|
-
status: "uploading",
|
|
303
|
-
errorCode: undefined,
|
|
304
|
-
error: undefined,
|
|
305
|
-
errorCause: undefined,
|
|
306
|
-
}
|
|
294
|
+
? { ...attachment, status: "uploading", errorCode: undefined, error: undefined }
|
|
307
295
|
: attachment,
|
|
308
296
|
),
|
|
309
297
|
);
|
|
@@ -355,7 +343,6 @@ export function useFileAttachments(
|
|
|
355
343
|
file,
|
|
356
344
|
errorCode: undefined,
|
|
357
345
|
error: undefined,
|
|
358
|
-
errorCause: undefined,
|
|
359
346
|
}
|
|
360
347
|
: {
|
|
361
348
|
id: `restored:${file.id}`,
|
package/src/hooks/use-goal.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { OpenGeniApiError, type SessionEvent, type SessionGoal } from "@opengeni/sdk";
|
|
2
2
|
import { useCallback, useEffect, useRef, useState } from "react";
|
|
3
3
|
import { useEmbeddedGoal, type EmbeddedGoalClientOverride } from "../session-context";
|
|
4
|
-
import { normalizeError } from "../lib/error-message";
|
|
5
4
|
import {
|
|
6
5
|
useDebouncedCallback,
|
|
7
6
|
useMutationRunner,
|
|
@@ -118,7 +117,7 @@ export function useGoal(
|
|
|
118
117
|
setGoal(null);
|
|
119
118
|
setError(null);
|
|
120
119
|
} else {
|
|
121
|
-
setError(
|
|
120
|
+
setError(cause instanceof Error ? cause : new Error(String(cause)));
|
|
122
121
|
}
|
|
123
122
|
setLoading(false);
|
|
124
123
|
} finally {
|
|
@@ -9,7 +9,6 @@ import { useCallback, useEffect, useRef, useState } from "react";
|
|
|
9
9
|
import { useOpenGeni, type ClientOverride } from "../provider";
|
|
10
10
|
import { sandboxAcceptsLiveIo } from "../lib/sandbox-liveness";
|
|
11
11
|
import { terminalCanAcquirePty } from "../lib/terminal-capability";
|
|
12
|
-
import { normalizeError } from "../lib/error-message";
|
|
13
12
|
import { usePageLiveActivity } from "./internal";
|
|
14
13
|
|
|
15
14
|
// "on-demand" is the boxless-benign resting state: the lease is not currently
|
|
@@ -290,7 +289,7 @@ export function useSessionCapabilities(
|
|
|
290
289
|
return;
|
|
291
290
|
}
|
|
292
291
|
setState("error");
|
|
293
|
-
setError(
|
|
292
|
+
setError(cause instanceof Error ? cause : new Error(String(cause)));
|
|
294
293
|
}
|
|
295
294
|
});
|
|
296
295
|
}, warmingPollMs);
|
|
@@ -470,7 +469,7 @@ export function useSessionCapabilities(
|
|
|
470
469
|
return;
|
|
471
470
|
}
|
|
472
471
|
setState("error");
|
|
473
|
-
setError(
|
|
472
|
+
setError(cause instanceof Error ? cause : new Error(String(cause)));
|
|
474
473
|
}
|
|
475
474
|
})();
|
|
476
475
|
|
|
@@ -10,7 +10,6 @@ import { createOlderHistoryLoadReceipt, type OlderHistoryLoadReceipt } from "../
|
|
|
10
10
|
import { buildTimeline, groupTimeline, sessionStatusFromEvents } from "../timeline/projection";
|
|
11
11
|
import type { TimelineItem } from "../timeline/types";
|
|
12
12
|
import type { EmbeddedSessionClientLike } from "../client";
|
|
13
|
-
import { normalizeError } from "../lib/error-message";
|
|
14
13
|
import { usePageLiveActivity } from "./internal";
|
|
15
14
|
import type { LatestQuestionOptions } from "./latest-question";
|
|
16
15
|
|
|
@@ -115,11 +114,8 @@ const FOREGROUND_COMPACT_CATCHUP_MAX_GROUPS = 16;
|
|
|
115
114
|
const FOREGROUND_COMPACT_CATCHUP_MAX_BYTES = 512 * 1024;
|
|
116
115
|
const EMPTY_EVENTS: SessionEvent[] = [];
|
|
117
116
|
const encoder = new TextEncoder();
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
// serialized payloads also expand into objects and timeline projections.
|
|
121
|
-
export const SESSION_EVENT_BROWSER_MAX_BYTES = 16 * 1024 * 1024;
|
|
122
|
-
export const SESSION_EVENT_BROWSER_MAX_COUNT = 20_000;
|
|
117
|
+
export const SESSION_EVENT_BROWSER_MAX_BYTES = 160 * 1024 * 1024;
|
|
118
|
+
export const SESSION_EVENT_BROWSER_MAX_COUNT = 200_000;
|
|
123
119
|
export const SESSION_EVENT_BROWSER_PENDING_MAX_BYTES = 1024 * 1024;
|
|
124
120
|
export const SESSION_EVENT_BROWSER_PENDING_MAX_COUNT = 256;
|
|
125
121
|
|
|
@@ -499,7 +495,7 @@ export function useSessionEvents(
|
|
|
499
495
|
.then(() => reconcileSession(sessionId))
|
|
500
496
|
.catch((cause) => {
|
|
501
497
|
if (isCurrent()) {
|
|
502
|
-
setError(
|
|
498
|
+
setError(cause instanceof Error ? cause : new Error(String(cause)));
|
|
503
499
|
}
|
|
504
500
|
});
|
|
505
501
|
},
|
|
@@ -540,7 +536,7 @@ export function useSessionEvents(
|
|
|
540
536
|
} catch (cause) {
|
|
541
537
|
if (isCurrent()) {
|
|
542
538
|
flush();
|
|
543
|
-
setError(
|
|
539
|
+
setError(cause instanceof Error ? cause : new Error(String(cause)));
|
|
544
540
|
setConnectionState("error");
|
|
545
541
|
// A failed first compact-tail request has no later success path in
|
|
546
542
|
// this effect instance. End the loading gate so hosts can render the
|
|
@@ -882,7 +878,7 @@ export function useSessionEvents(
|
|
|
882
878
|
if (!isCurrent()) {
|
|
883
879
|
return false;
|
|
884
880
|
}
|
|
885
|
-
setNewerError(
|
|
881
|
+
setNewerError(reason instanceof Error ? reason : new Error(String(reason)));
|
|
886
882
|
// Keep authorization and integrity failures actionable for callers;
|
|
887
883
|
// timeline-owned invocations attach their own explicit recovery UI.
|
|
888
884
|
throw reason;
|
|
@@ -1082,13 +1078,10 @@ export function useSessionEvents(
|
|
|
1082
1078
|
visibleEvents.some((event) => event.sequence === questionEvidence.anchor)
|
|
1083
1079
|
? questionEvidence.events
|
|
1084
1080
|
: EMPTY_EVENTS;
|
|
1085
|
-
const timelineOptions = { partialStart: hasOlder || eventWindow.truncated || after > 0 };
|
|
1086
|
-
if (witness.length === 0) return buildTimeline(visibleEvents, timelineOptions);
|
|
1087
1081
|
const ids = new Set(visibleEvents.map((event) => event.id));
|
|
1088
|
-
return buildTimeline(
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
);
|
|
1082
|
+
return buildTimeline([...visibleEvents, ...witness.filter((event) => !ids.has(event.id))], {
|
|
1083
|
+
partialStart: hasOlder || eventWindow.truncated || after > 0,
|
|
1084
|
+
});
|
|
1092
1085
|
}, [visibleEvents, hasOlder, eventWindow.truncated, after, questionEvidence, client, streamKey]);
|
|
1093
1086
|
|
|
1094
1087
|
return {
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { KeyboardEvent } from "react";
|
|
2
2
|
import { useCallback, useMemo, useRef, useState } from "react";
|
|
3
|
-
import { useErrorMessage } from "../lib/error-message";
|
|
4
3
|
import {
|
|
5
4
|
argHint,
|
|
6
5
|
filterCommands,
|
|
@@ -82,7 +81,6 @@ export type UseSlashCommandsResult = {
|
|
|
82
81
|
};
|
|
83
82
|
|
|
84
83
|
export function useSlashCommands(options: UseSlashCommandsOptions): UseSlashCommandsResult {
|
|
85
|
-
const formatError = useErrorMessage();
|
|
86
84
|
const { commands, context, handlers, value, setValue } = options;
|
|
87
85
|
const [highlight, setHighlight] = useState(0);
|
|
88
86
|
// Escape closes the palette but keeps the draft. We remember the dismissed
|
|
@@ -155,9 +153,9 @@ export function useSlashCommands(options: UseSlashCommandsOptions): UseSlashComm
|
|
|
155
153
|
if (!context) {
|
|
156
154
|
return null;
|
|
157
155
|
}
|
|
158
|
-
return { ...context, ...handlers,
|
|
156
|
+
return { ...context, ...handlers, confirm: () => handlers.confirm(command) };
|
|
159
157
|
},
|
|
160
|
-
[context, handlers
|
|
158
|
+
[context, handlers],
|
|
161
159
|
);
|
|
162
160
|
|
|
163
161
|
const execute = useCallback(
|
|
@@ -175,10 +173,10 @@ export function useSlashCommands(options: UseSlashCommandsOptions): UseSlashComm
|
|
|
175
173
|
setValue("");
|
|
176
174
|
}
|
|
177
175
|
} catch (cause) {
|
|
178
|
-
ctx.notice({ tone: "error", message:
|
|
176
|
+
ctx.notice({ tone: "error", message: errorMessage(cause) });
|
|
179
177
|
}
|
|
180
178
|
},
|
|
181
|
-
[buildContext, setValue
|
|
179
|
+
[buildContext, setValue],
|
|
182
180
|
);
|
|
183
181
|
|
|
184
182
|
const autocomplete = useCallback(
|
|
@@ -361,3 +359,10 @@ export function useSlashCommands(options: UseSlashCommandsOptions): UseSlashComm
|
|
|
361
359
|
autocompleteHighlighted,
|
|
362
360
|
};
|
|
363
361
|
}
|
|
362
|
+
|
|
363
|
+
function errorMessage(cause: unknown): string {
|
|
364
|
+
if (cause instanceof Error) {
|
|
365
|
+
return cause.message;
|
|
366
|
+
}
|
|
367
|
+
return String(cause);
|
|
368
|
+
}
|
|
@@ -10,7 +10,6 @@ import type {
|
|
|
10
10
|
} from "@opengeni/sdk";
|
|
11
11
|
import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
12
12
|
import { useEmbeddedSession, type EmbeddedSessionClientOverride } from "../session-context";
|
|
13
|
-
import { normalizeError } from "../lib/error-message";
|
|
14
13
|
import {
|
|
15
14
|
useDebouncedCallback,
|
|
16
15
|
usePageLiveActivity,
|
|
@@ -464,7 +463,7 @@ function operationKey(): string {
|
|
|
464
463
|
}
|
|
465
464
|
|
|
466
465
|
function asError(cause: unknown): Error {
|
|
467
|
-
return
|
|
466
|
+
return cause instanceof Error ? cause : new Error(String(cause));
|
|
468
467
|
}
|
|
469
468
|
|
|
470
469
|
function isOutcomeUnknownError(cause: unknown): boolean {
|