@opengeni/react 1.4.4 → 1.4.5-canary.37485542607001
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 +17 -6
- package/dist/artifacts.d.ts +1 -0
- package/dist/artifacts.js +22 -15
- package/dist/artifacts.js.map +1 -1
- package/dist/{browser-viewer-5EEAS3IU.js → browser-viewer-CV23VIHB.js} +8 -6
- package/dist/{chunk-XS67YG5R.js → chunk-4O7OE7ON.js} +45 -4
- package/dist/chunk-4O7OE7ON.js.map +1 -0
- package/dist/{chunk-JHTIMBOL.js → chunk-5JSUNNQN.js} +26 -4
- package/dist/{chunk-JHTIMBOL.js.map → chunk-5JSUNNQN.js.map} +1 -1
- package/dist/{chunk-QMMCJGFI.js → chunk-6BAMPGBV.js} +6 -3
- package/dist/chunk-6BAMPGBV.js.map +1 -0
- package/dist/{chunk-I6OY3MWC.js → chunk-6FOTSVWU.js} +2 -2
- package/dist/{chunk-LVS3MH5T.js → chunk-ATIRUHBZ.js} +128 -10
- package/dist/chunk-ATIRUHBZ.js.map +1 -0
- package/dist/chunk-BOFEQC6K.js +162 -0
- package/dist/chunk-BOFEQC6K.js.map +1 -0
- package/dist/{chunk-2OQA3CPB.js → chunk-CESBPQP5.js} +19 -5
- package/dist/chunk-CESBPQP5.js.map +1 -0
- package/dist/{chunk-YVFRBXST.js → chunk-GMNGUPMX.js} +2 -2
- package/dist/{chunk-PHBFJCEU.js → chunk-I5EGRXXG.js} +110 -7
- package/dist/chunk-I5EGRXXG.js.map +1 -0
- package/dist/{chunk-PBCZL4JP.js → chunk-INIZSNXT.js} +2 -2
- package/dist/chunk-IZV5FTJC.js +55 -0
- package/dist/chunk-IZV5FTJC.js.map +1 -0
- package/dist/chunk-JDJJMBB3.js +1883 -0
- package/dist/chunk-JDJJMBB3.js.map +1 -0
- package/dist/chunk-LHF6BVM4.js +83 -0
- package/dist/chunk-LHF6BVM4.js.map +1 -0
- package/dist/{chunk-C5BF4L26.js → chunk-LSMWZSCJ.js} +7 -7
- package/dist/chunk-LTKGTXUQ.js +174 -0
- package/dist/chunk-LTKGTXUQ.js.map +1 -0
- package/dist/chunk-N7S72EXK.js +25 -0
- package/dist/chunk-N7S72EXK.js.map +1 -0
- package/dist/{chunk-CVYCLFMH.js → chunk-PEHTX3V7.js} +19 -1
- package/dist/chunk-PEHTX3V7.js.map +1 -0
- package/dist/chunk-R5R5RQQD.js +51 -0
- package/dist/chunk-R5R5RQQD.js.map +1 -0
- package/dist/{chunk-IYQCWGU5.js → chunk-RGTZ2VDR.js} +35 -62
- package/dist/chunk-RGTZ2VDR.js.map +1 -0
- package/dist/chunk-RI42H5IU.js +326 -0
- package/dist/chunk-RI42H5IU.js.map +1 -0
- package/dist/{chunk-EAOSEIXB.js → chunk-RRRS5D5T.js} +727 -1983
- package/dist/chunk-RRRS5D5T.js.map +1 -0
- package/dist/{chunk-JH7V627O.js → chunk-SHLZMAJN.js} +2 -11
- package/dist/chunk-SHLZMAJN.js.map +1 -0
- package/dist/{chunk-IUHHPMAX.js → chunk-SZOCY5VG.js} +18 -87
- package/dist/chunk-SZOCY5VG.js.map +1 -0
- package/dist/{chunk-L2J3PU7A.js → chunk-VYIPNDUZ.js} +29 -100
- package/dist/chunk-VYIPNDUZ.js.map +1 -0
- package/dist/{chunk-G6YRCIYJ.js → chunk-YK6QMGVL.js} +55 -60
- package/dist/chunk-YK6QMGVL.js.map +1 -0
- package/dist/chunk-ZIB4H5LN.js +101 -0
- package/dist/chunk-ZIB4H5LN.js.map +1 -0
- package/dist/client.d.ts +9 -3
- package/dist/clipboard.js +1 -1
- package/dist/components/browser-viewer.d.ts +6 -0
- package/dist/components/composer.d.ts +3 -69
- package/dist/components/human-input-form.d.ts +3 -32
- package/dist/components/markdown.d.ts +8 -0
- package/dist/components/model-policy-picker.d.ts +4 -37
- package/dist/components/opper-mark.d.ts +7 -0
- package/dist/components/provider-recovery-notice.d.ts +15 -0
- package/dist/components/remark-soft-line-breaks.d.ts +38 -0
- package/dist/components/sandbox-workspace.d.ts +13 -0
- package/dist/components/session-chrome.d.ts +5 -3
- package/dist/components/session-conversation.d.ts +15 -3
- package/dist/composer-messages.d.ts +74 -0
- package/dist/composer-messages.js +9 -0
- package/dist/composer.js +15 -10
- package/dist/{computer-viewer-ELNLZGHI.js → computer-viewer-K4CKYRX6.js} +4 -4
- package/dist/connect-setup.d.ts +2 -0
- package/dist/connect.d.ts +1 -1
- package/dist/connect.js +21 -6
- package/dist/connect.js.map +1 -1
- package/dist/{embedded-voice-NIL4RDX3.js → embedded-voice-K7SOZVVZ.js} +6 -4
- package/dist/{embedded-voice-NIL4RDX3.js.map → embedded-voice-K7SOZVVZ.js.map} +1 -1
- package/dist/hooks/shared-machines-list.d.ts +4 -0
- package/dist/hooks/use-client-config-flags.d.ts +6 -0
- package/dist/hooks/use-goal.d.ts +2 -1
- package/dist/hooks/use-new-session-draft.d.ts +74 -0
- package/dist/human-input-model.d.ts +40 -0
- package/dist/index.d.ts +4 -1
- package/dist/index.js +116 -73
- package/dist/index.js.map +1 -1
- package/dist/interaction.js +5 -5
- package/dist/{latest-question-2POFPYNB.js → latest-question-27HGRPVF.js} +3 -3
- package/dist/lib/clipboard.d.ts +7 -0
- package/dist/lib/provider-recovery.d.ts +49 -0
- package/dist/lib/transient-retry.d.ts +25 -0
- package/dist/machines.js +2 -2
- package/dist/model-mark-paths.d.ts +34 -0
- package/dist/model-mark-paths.js +16 -0
- package/dist/model-picker-model.d.ts +111 -0
- package/dist/model-picker-model.js +25 -0
- package/dist/model-picker-model.js.map +1 -0
- package/dist/{model-policy-picker-menu-WRNSRFQC.js → model-policy-picker-menu-I5KPC3D6.js} +6 -4
- package/dist/model-policy-picker-menu-I5KPC3D6.js.map +1 -0
- package/dist/model-policy.d.ts +10 -0
- package/dist/model-policy.js +5 -1
- package/dist/new-session-draft.d.ts +7 -0
- package/dist/new-session-draft.js +639 -0
- package/dist/new-session-draft.js.map +1 -0
- package/dist/organization-model.d.ts +32 -0
- package/dist/organization-model.js +65 -0
- package/dist/organization-model.js.map +1 -0
- package/dist/{platform-activity-row-PJJVATTZ.js → platform-activity-row-NJ47YBXW.js} +7 -84
- package/dist/platform-activity-row-NJ47YBXW.js.map +1 -0
- package/dist/queue-presentation-model.d.ts +72 -0
- package/dist/queue-presentation-model.js +38 -0
- package/dist/queue-presentation-model.js.map +1 -0
- package/dist/{queue-surface-implementation-67FS7FUI.js → queue-surface-implementation-YPJFQ3O6.js} +24 -252
- package/dist/queue-surface-implementation-YPJFQ3O6.js.map +1 -0
- package/dist/realtime.js +5 -3
- package/dist/{sandbox-files-34CJJNOY.js → sandbox-files-2DGDO6NI.js} +5 -5
- package/dist/sandbox-files-2DGDO6NI.js.map +1 -0
- package/dist/sandbox-label-model.d.ts +23 -0
- package/dist/sandbox-label-model.js +28 -0
- package/dist/sandbox-label-model.js.map +1 -0
- package/dist/session-agents-model.d.ts +10 -0
- package/dist/session-agents-model.js +25 -0
- package/dist/session-agents-model.js.map +1 -0
- package/dist/session-attention-model.d.ts +8 -0
- package/dist/session-attention-model.js +46 -0
- package/dist/session-attention-model.js.map +1 -0
- package/dist/session-feedback-model.d.ts +20 -0
- package/dist/session-feedback-model.js +56 -0
- package/dist/session-feedback-model.js.map +1 -0
- package/dist/session-list-model.d.ts +119 -0
- package/dist/session-list-model.js +244 -0
- package/dist/session-list-model.js.map +1 -0
- package/dist/session-status-model.d.ts +19 -0
- package/dist/session-ui.js +26 -17
- package/dist/session-ui.js.map +1 -1
- package/dist/session.js +8 -6
- package/dist/testing/session-scenarios.d.ts +10 -0
- package/dist/testing/session-scenarios.js +303 -0
- package/dist/testing/session-scenarios.js.map +1 -0
- package/dist/timeline/genie-copy.d.ts +3 -0
- package/dist/timeline/genie-loading.d.ts +11 -0
- package/dist/timeline/index.d.ts +1 -1
- package/dist/timeline/notice-presentation.d.ts +7 -0
- package/dist/timeline/patch-apply-command.d.ts +18 -0
- package/dist/timeline/platform-activity-presentation.d.ts +7 -0
- package/dist/timeline/presented-image.d.ts +6 -1
- package/dist/timeline/question-nav-model.d.ts +23 -0
- package/dist/timeline/registry.d.ts +10 -1
- package/dist/timeline/retained-loaders.d.ts +1 -1
- package/dist/timeline/tool-presentation.d.ts +172 -0
- package/dist/timeline/turn-summary-model.d.ts +90 -0
- package/dist/timeline/turn-summary.d.ts +4 -74
- package/dist/timeline/work-presentation.d.ts +42 -0
- package/dist/timeline-model.d.ts +24 -0
- package/dist/timeline-model.js +152 -0
- package/dist/timeline-model.js.map +1 -0
- package/package.json +55 -3
- package/src/artifacts.ts +1 -0
- package/src/client.ts +9 -3
- package/src/components/browser-viewer.tsx +23 -2
- package/src/components/claude-mark.tsx +2 -1
- package/src/components/composer.tsx +8 -146
- package/src/components/grok-mark.tsx +2 -1
- package/src/components/human-input-form.tsx +13 -124
- package/src/components/markdown.tsx +19 -1
- package/src/components/message-timeline.tsx +45 -99
- package/src/components/model-mark.tsx +2 -1
- package/src/components/model-policy-picker-menu.tsx +30 -85
- package/src/components/model-policy-picker.tsx +20 -150
- package/src/components/opper-mark.tsx +18 -0
- package/src/components/provider-recovery-notice.tsx +41 -0
- package/src/components/queue-surface-implementation.tsx +20 -349
- package/src/components/remark-soft-line-breaks.ts +166 -0
- package/src/components/sandbox-workspace.tsx +17 -1
- package/src/components/session-chrome.tsx +114 -99
- package/src/components/session-conversation.tsx +55 -6
- package/src/components/session-status.tsx +17 -16
- package/src/composer-messages.ts +150 -0
- package/src/connect-setup.tsx +45 -11
- package/src/connect.ts +1 -1
- package/src/hooks/shared-machines-list.ts +34 -1
- package/src/hooks/use-client-config-flags.ts +8 -0
- package/src/hooks/use-goal.ts +66 -10
- package/src/hooks/use-new-session-draft.ts +813 -0
- package/src/human-input-model.ts +147 -0
- package/src/index.ts +16 -0
- package/src/lib/clipboard.ts +29 -0
- package/src/lib/format.ts +7 -0
- package/src/lib/provider-recovery.ts +202 -0
- package/src/lib/transient-retry.ts +99 -0
- package/src/model-mark-paths.ts +53 -0
- package/src/model-picker-model.ts +330 -0
- package/src/model-policy.ts +75 -5
- package/src/new-session-draft.ts +22 -0
- package/src/organization-model.ts +118 -0
- package/src/queue-presentation-model.ts +464 -0
- package/src/sandbox-label-model.ts +41 -0
- package/src/session-agents-model.ts +33 -0
- package/src/session-attention-model.ts +59 -0
- package/src/session-feedback-model.ts +95 -0
- package/src/session-list-model.ts +377 -0
- package/src/session-status-model.ts +62 -0
- package/src/testing/session-scenarios.ts +326 -0
- package/src/timeline/activity-rail.tsx +54 -24
- package/src/timeline/genie-copy.ts +19 -0
- package/src/timeline/genie-loading.tsx +15 -19
- package/src/timeline/index.ts +1 -0
- package/src/timeline/notice-presentation.ts +22 -0
- package/src/timeline/patch-apply-command.tsx +135 -0
- package/src/timeline/platform-activity-presentation.ts +122 -0
- package/src/timeline/platform-activity-row.tsx +6 -96
- package/src/timeline/presented-image.ts +16 -2
- package/src/timeline/projection.ts +12 -1
- package/src/timeline/question-nav-model.ts +28 -0
- package/src/timeline/registry.ts +11 -1
- package/src/timeline/retained-loaders.ts +9 -4
- package/src/timeline/rolling-activity.tsx +7 -19
- package/src/timeline/tool-presentation.ts +1316 -0
- package/src/timeline/tool-renderers.tsx +254 -1024
- package/src/timeline/turn-summary-model.ts +338 -0
- package/src/timeline/turn-summary.tsx +21 -326
- package/src/timeline/work-presentation.ts +139 -0
- package/src/timeline-model.ts +108 -0
- package/styles/compiled.css +17 -4
- package/styles/connect.css +4 -0
- package/styles/responsive.css +11 -2
- package/dist/chunk-2OQA3CPB.js.map +0 -1
- package/dist/chunk-CVYCLFMH.js.map +0 -1
- package/dist/chunk-EAOSEIXB.js.map +0 -1
- package/dist/chunk-G6YRCIYJ.js.map +0 -1
- package/dist/chunk-HXYOSSQO.js +0 -117
- package/dist/chunk-HXYOSSQO.js.map +0 -1
- package/dist/chunk-IUHHPMAX.js.map +0 -1
- package/dist/chunk-IYQCWGU5.js.map +0 -1
- package/dist/chunk-JH7V627O.js.map +0 -1
- package/dist/chunk-L2J3PU7A.js.map +0 -1
- package/dist/chunk-LVS3MH5T.js.map +0 -1
- package/dist/chunk-PHBFJCEU.js.map +0 -1
- package/dist/chunk-QMMCJGFI.js.map +0 -1
- package/dist/chunk-XS67YG5R.js.map +0 -1
- package/dist/platform-activity-row-PJJVATTZ.js.map +0 -1
- package/dist/queue-surface-implementation-67FS7FUI.js.map +0 -1
- /package/dist/{browser-viewer-5EEAS3IU.js.map → browser-viewer-CV23VIHB.js.map} +0 -0
- /package/dist/{chunk-I6OY3MWC.js.map → chunk-6FOTSVWU.js.map} +0 -0
- /package/dist/{chunk-YVFRBXST.js.map → chunk-GMNGUPMX.js.map} +0 -0
- /package/dist/{chunk-PBCZL4JP.js.map → chunk-INIZSNXT.js.map} +0 -0
- /package/dist/{chunk-C5BF4L26.js.map → chunk-LSMWZSCJ.js.map} +0 -0
- /package/dist/{computer-viewer-ELNLZGHI.js.map → composer-messages.js.map} +0 -0
- /package/dist/{model-policy-picker-menu-WRNSRFQC.js.map → computer-viewer-K4CKYRX6.js.map} +0 -0
- /package/dist/{latest-question-2POFPYNB.js.map → latest-question-27HGRPVF.js.map} +0 -0
- /package/dist/{sandbox-files-34CJJNOY.js.map → model-mark-paths.js.map} +0 -0
package/dist/{queue-surface-implementation-67FS7FUI.js → queue-surface-implementation-YPJFQ3O6.js}
RENAMED
|
@@ -1,14 +1,24 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import {
|
|
3
|
-
QUEUE_ITEM_CONTENT_UNAVAILABLE,
|
|
4
3
|
QueueErrorAlert,
|
|
5
4
|
QueueStoppingStatus,
|
|
6
5
|
TimelineAnnotationsChip,
|
|
7
|
-
queueItemContent,
|
|
8
6
|
requestQueueDraftEdit
|
|
9
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-SHLZMAJN.js";
|
|
10
8
|
import "./chunk-2HVLQ26H.js";
|
|
11
9
|
import "./chunk-LJUMYUBO.js";
|
|
10
|
+
import {
|
|
11
|
+
QUEUE_COLLAPSED_PREVIEW_CHARACTERS,
|
|
12
|
+
QUEUE_ITEM_CONTENT_UNAVAILABLE,
|
|
13
|
+
QUEUE_REPLACE_DRAFT_COPY,
|
|
14
|
+
QUEUE_ROW_PREVIEW_CHARACTERS,
|
|
15
|
+
projectPendingQueueMove,
|
|
16
|
+
queueContentPreview,
|
|
17
|
+
queueItemContent,
|
|
18
|
+
queueMovePlan,
|
|
19
|
+
queuePromptPreview,
|
|
20
|
+
queueTurnPreview
|
|
21
|
+
} from "./chunk-RI42H5IU.js";
|
|
12
22
|
import "./chunk-S2QH6EZ5.js";
|
|
13
23
|
import {
|
|
14
24
|
MENU_ITEM_CLASS,
|
|
@@ -100,29 +110,18 @@ function QueueSurface({
|
|
|
100
110
|
if (oldIndex < 0) return queue.queue;
|
|
101
111
|
return arrayMove(queue.queue, oldIndex, keyboardDrag.projectedIndex);
|
|
102
112
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
}
|
|
106
|
-
const byId = new Map(queue.queue.map((turn) => [turn.id, turn]));
|
|
107
|
-
const projected = pendingMove.turnIds.map((turnId) => byId.get(turnId));
|
|
108
|
-
if (projected.some((turn) => !turn) || projected.length !== queue.queue.length) {
|
|
109
|
-
return queue.queue;
|
|
110
|
-
}
|
|
111
|
-
return projected;
|
|
112
|
-
}, [keyboardDrag, pendingMove, queue.queue, queue.snapshot?.version]);
|
|
113
|
+
return projectPendingQueueMove(queue.queue, pendingMove, queue.snapshot);
|
|
114
|
+
}, [keyboardDrag, pendingMove, queue.queue, queue.snapshot]);
|
|
113
115
|
const ids = useMemo(() => displayedQueue.map((turn) => turn.id), [displayedQueue]);
|
|
114
116
|
const moveToIndex = useCallback(
|
|
115
117
|
async (turnId, nextIndex) => {
|
|
116
118
|
if (queue.mutating || pendingMove) return;
|
|
117
|
-
const
|
|
118
|
-
if (
|
|
119
|
-
const
|
|
120
|
-
if (oldIndex === boundedIndex) return;
|
|
121
|
-
const ordered = arrayMove(queue.queue, oldIndex, boundedIndex);
|
|
122
|
-
const beforeTurnId = ordered[boundedIndex + 1]?.id ?? null;
|
|
119
|
+
const plan = queueMovePlan(queue.queue, turnId, nextIndex);
|
|
120
|
+
if (!plan) return;
|
|
121
|
+
const { beforeTurnId, index: boundedIndex } = plan;
|
|
123
122
|
setPendingMove({
|
|
124
123
|
baseVersion: queue.snapshot?.version ?? null,
|
|
125
|
-
turnIds:
|
|
124
|
+
turnIds: plan.turnIds
|
|
126
125
|
});
|
|
127
126
|
setAnnouncement(`Saving queued prompt at position ${boundedIndex + 1}.`);
|
|
128
127
|
try {
|
|
@@ -428,233 +427,6 @@ function PendingMachineInputs({
|
|
|
428
427
|
)) })
|
|
429
428
|
] });
|
|
430
429
|
}
|
|
431
|
-
var QUEUE_ROW_PREVIEW_CHARACTERS = 360;
|
|
432
|
-
var QUEUE_COLLAPSED_PREVIEW_CHARACTERS = 180;
|
|
433
|
-
var QUEUE_PREVIEW_GRAPHEME_CONTEXT_CHARACTERS = 32;
|
|
434
|
-
var QUEUE_PREVIEW_REFERENCE_SAMPLE_CHARACTERS = 32;
|
|
435
|
-
var QUEUE_VISIBLE_END_IDENTITY_CHARACTERS = 18;
|
|
436
|
-
var QUEUE_PREVIEW_SEPARATOR = " \u2026 ";
|
|
437
|
-
var queuePreviewSegmenter = new Intl.Segmenter(void 0, { granularity: "grapheme" });
|
|
438
|
-
var queuePromptNonRenderingCodePoint = /[\p{White_Space}\p{Control}\p{Default_Ignorable_Code_Point}]/u;
|
|
439
|
-
function labelQueuePreview(summary) {
|
|
440
|
-
return {
|
|
441
|
-
summary,
|
|
442
|
-
collapsedVisual: summary,
|
|
443
|
-
visibleStart: summary,
|
|
444
|
-
visibleIdentity: null,
|
|
445
|
-
visibleIdentityLabel: null,
|
|
446
|
-
isFallback: false
|
|
447
|
-
};
|
|
448
|
-
}
|
|
449
|
-
function queueTurnPreview(turn, maxCharacters) {
|
|
450
|
-
if (!turn) return queuePromptPreview("", maxCharacters);
|
|
451
|
-
return queueContentPreview(turn.prompt, turn.annotations?.length ?? 0, maxCharacters);
|
|
452
|
-
}
|
|
453
|
-
function queueContentPreview(prompt, annotationCount, maxCharacters) {
|
|
454
|
-
switch (queueItemContent(prompt, annotationCount)) {
|
|
455
|
-
case "text":
|
|
456
|
-
return queuePromptPreview(prompt, maxCharacters);
|
|
457
|
-
case "annotations":
|
|
458
|
-
return labelQueuePreview(
|
|
459
|
-
`${annotationCount} timeline ${annotationCount === 1 ? "annotation" : "annotations"}`
|
|
460
|
-
);
|
|
461
|
-
case "unavailable":
|
|
462
|
-
return labelQueuePreview(QUEUE_ITEM_CONTENT_UNAVAILABLE);
|
|
463
|
-
}
|
|
464
|
-
}
|
|
465
|
-
function queuePromptPreview(prompt, maxCharacters) {
|
|
466
|
-
const wholePromptProbe = samplePromptStart(prompt, maxCharacters + 1);
|
|
467
|
-
if (!wholePromptProbe.truncated && wholePromptProbe.characters <= maxCharacters) {
|
|
468
|
-
const summary2 = replaceLoneSurrogates(wholePromptProbe.value);
|
|
469
|
-
return hasVisiblePromptContent(summary2) ? {
|
|
470
|
-
summary: summary2,
|
|
471
|
-
collapsedVisual: summary2,
|
|
472
|
-
visibleStart: summary2,
|
|
473
|
-
visibleIdentity: null,
|
|
474
|
-
visibleIdentityLabel: null,
|
|
475
|
-
isFallback: false
|
|
476
|
-
} : fallbackPromptPreview(prompt.length, wholePromptProbe.value, wholePromptProbe.value);
|
|
477
|
-
}
|
|
478
|
-
const suffixCharacters = Math.min(Math.floor(maxCharacters / 3), 120);
|
|
479
|
-
const prefixCharacters = maxCharacters - codePointLength(QUEUE_PREVIEW_SEPARATOR) - suffixCharacters;
|
|
480
|
-
const prefixSample = samplePromptStart(
|
|
481
|
-
prompt,
|
|
482
|
-
prefixCharacters + QUEUE_PREVIEW_GRAPHEME_CONTEXT_CHARACTERS
|
|
483
|
-
);
|
|
484
|
-
const suffixSample = samplePromptEnd(
|
|
485
|
-
prompt,
|
|
486
|
-
suffixCharacters + QUEUE_PREVIEW_GRAPHEME_CONTEXT_CHARACTERS
|
|
487
|
-
);
|
|
488
|
-
const prefixSegments = segmentPromptSample(prefixSample.value);
|
|
489
|
-
const suffixSegments = segmentPromptSample(suffixSample.value);
|
|
490
|
-
if (prefixSample.truncated) prefixSegments.pop();
|
|
491
|
-
if (suffixSample.truncated) {
|
|
492
|
-
let ambiguousSegment = suffixSegments.shift();
|
|
493
|
-
while (ambiguousSegment?.endsWith("\u200D") && suffixSegments.length > 0) {
|
|
494
|
-
ambiguousSegment = suffixSegments.shift();
|
|
495
|
-
}
|
|
496
|
-
while (suffixSegments[0] && startsWithRegionalIndicator(suffixSegments[0])) {
|
|
497
|
-
suffixSegments.shift();
|
|
498
|
-
}
|
|
499
|
-
}
|
|
500
|
-
const prefix = takeWholeGraphemesFromStart(prefixSegments, prefixCharacters);
|
|
501
|
-
const suffix = takeWholeGraphemesFromEnd(suffixSegments, suffixCharacters);
|
|
502
|
-
const reference = boundedPromptSampleReference(
|
|
503
|
-
prompt.length,
|
|
504
|
-
prefixSample.value,
|
|
505
|
-
suffixSample.value
|
|
506
|
-
);
|
|
507
|
-
if (!hasVisiblePromptContent(prefix) && !hasVisiblePromptContent(suffix)) {
|
|
508
|
-
return fallbackPromptPreview(prompt.length, prefixSample.value, suffixSample.value);
|
|
509
|
-
}
|
|
510
|
-
const safeSuffix = hasVisiblePromptContent(suffix) ? suffix : promptPreviewFallbackLabel(reference);
|
|
511
|
-
const summary = `${prefix}${QUEUE_PREVIEW_SEPARATOR}${safeSuffix}`;
|
|
512
|
-
if (!hasVisiblePromptContent(prefix)) {
|
|
513
|
-
return {
|
|
514
|
-
summary,
|
|
515
|
-
collapsedVisual: summary,
|
|
516
|
-
visibleStart: safeSuffix,
|
|
517
|
-
visibleIdentity: null,
|
|
518
|
-
visibleIdentityLabel: null,
|
|
519
|
-
isFallback: false
|
|
520
|
-
};
|
|
521
|
-
}
|
|
522
|
-
const endIdentity = takeWholeGraphemesFromEnd(
|
|
523
|
-
suffixSegments,
|
|
524
|
-
QUEUE_VISIBLE_END_IDENTITY_CHARACTERS
|
|
525
|
-
);
|
|
526
|
-
return {
|
|
527
|
-
summary,
|
|
528
|
-
collapsedVisual: summary,
|
|
529
|
-
visibleStart: prefix,
|
|
530
|
-
visibleIdentity: hasVisiblePromptContent(endIdentity) ? endIdentity : `ref ${reference}`,
|
|
531
|
-
visibleIdentityLabel: hasVisiblePromptContent(endIdentity) ? "End" : "Safe boundary",
|
|
532
|
-
isFallback: false
|
|
533
|
-
};
|
|
534
|
-
}
|
|
535
|
-
function fallbackPromptPreview(promptLength, startSample, endSample) {
|
|
536
|
-
const reference = boundedPromptSampleReference(promptLength, startSample, endSample);
|
|
537
|
-
const summary = promptPreviewFallbackLabel(reference);
|
|
538
|
-
return {
|
|
539
|
-
summary,
|
|
540
|
-
collapsedVisual: `Omitted \xB7 ${reference}`,
|
|
541
|
-
// The complete fallback remains the canonical accessible summary. Narrow
|
|
542
|
-
// collapsed/row layouts paint the bounded reference in a compact truthful
|
|
543
|
-
// form so ellipsis cannot hide the only identifying portion.
|
|
544
|
-
visibleStart: `Omitted \xB7 ${reference}`,
|
|
545
|
-
visibleIdentity: null,
|
|
546
|
-
visibleIdentityLabel: null,
|
|
547
|
-
isFallback: true
|
|
548
|
-
};
|
|
549
|
-
}
|
|
550
|
-
function promptPreviewFallbackLabel(reference) {
|
|
551
|
-
return `Content omitted at safe boundary \xB7 ref ${reference}`;
|
|
552
|
-
}
|
|
553
|
-
function boundedPromptSampleReference(promptLength, startSample, endSample) {
|
|
554
|
-
const head = samplePromptStart(startSample, QUEUE_PREVIEW_REFERENCE_SAMPLE_CHARACTERS).value;
|
|
555
|
-
const tail = samplePromptEnd(endSample, QUEUE_PREVIEW_REFERENCE_SAMPLE_CHARACTERS).value;
|
|
556
|
-
let hash = 2166136261;
|
|
557
|
-
for (const value of [String(promptLength), head, tail]) {
|
|
558
|
-
for (let index = 0; index < value.length; index += 1) {
|
|
559
|
-
hash ^= value.charCodeAt(index);
|
|
560
|
-
hash = Math.imul(hash, 16777619);
|
|
561
|
-
}
|
|
562
|
-
hash ^= 65535;
|
|
563
|
-
hash = Math.imul(hash, 16777619);
|
|
564
|
-
}
|
|
565
|
-
return (hash >>> 0).toString(16).padStart(8, "0").toUpperCase();
|
|
566
|
-
}
|
|
567
|
-
function hasVisiblePromptContent(value) {
|
|
568
|
-
for (const character of value) {
|
|
569
|
-
if (!queuePromptNonRenderingCodePoint.test(character)) return true;
|
|
570
|
-
}
|
|
571
|
-
return false;
|
|
572
|
-
}
|
|
573
|
-
function samplePromptStart(prompt, maxCharacters) {
|
|
574
|
-
let end = 0;
|
|
575
|
-
let characters = 0;
|
|
576
|
-
while (end < prompt.length && characters < maxCharacters) {
|
|
577
|
-
const first = prompt.charCodeAt(end);
|
|
578
|
-
end += isHighSurrogate(first) && end + 1 < prompt.length && isLowSurrogate(prompt.charCodeAt(end + 1)) ? 2 : 1;
|
|
579
|
-
characters += 1;
|
|
580
|
-
}
|
|
581
|
-
return { value: prompt.slice(0, end), characters, truncated: end < prompt.length };
|
|
582
|
-
}
|
|
583
|
-
function samplePromptEnd(prompt, maxCharacters) {
|
|
584
|
-
let start = prompt.length;
|
|
585
|
-
let characters = 0;
|
|
586
|
-
while (start > 0 && characters < maxCharacters) {
|
|
587
|
-
start -= 1;
|
|
588
|
-
if (isLowSurrogate(prompt.charCodeAt(start)) && start > 0 && isHighSurrogate(prompt.charCodeAt(start - 1))) {
|
|
589
|
-
start -= 1;
|
|
590
|
-
}
|
|
591
|
-
characters += 1;
|
|
592
|
-
}
|
|
593
|
-
return { value: prompt.slice(start), characters, truncated: start > 0 };
|
|
594
|
-
}
|
|
595
|
-
function segmentPromptSample(sample) {
|
|
596
|
-
return Array.from(
|
|
597
|
-
queuePreviewSegmenter.segment(replaceLoneSurrogates(sample)),
|
|
598
|
-
({ segment }) => segment
|
|
599
|
-
);
|
|
600
|
-
}
|
|
601
|
-
function replaceLoneSurrogates(value) {
|
|
602
|
-
let sanitized = "";
|
|
603
|
-
for (let index = 0; index < value.length; index += 1) {
|
|
604
|
-
const current = value.charCodeAt(index);
|
|
605
|
-
if (isHighSurrogate(current) && index + 1 < value.length && isLowSurrogate(value.charCodeAt(index + 1))) {
|
|
606
|
-
sanitized += value.slice(index, index + 2);
|
|
607
|
-
index += 1;
|
|
608
|
-
} else if (isHighSurrogate(current) || isLowSurrogate(current)) {
|
|
609
|
-
sanitized += "\uFFFD";
|
|
610
|
-
} else {
|
|
611
|
-
sanitized += value[index];
|
|
612
|
-
}
|
|
613
|
-
}
|
|
614
|
-
return sanitized;
|
|
615
|
-
}
|
|
616
|
-
function takeWholeGraphemesFromStart(segments, maxCharacters) {
|
|
617
|
-
const selected = [];
|
|
618
|
-
let characters = 0;
|
|
619
|
-
for (const segment of segments) {
|
|
620
|
-
const segmentCharacters = codePointLength(segment);
|
|
621
|
-
if (characters + segmentCharacters > maxCharacters) break;
|
|
622
|
-
selected.push(segment);
|
|
623
|
-
characters += segmentCharacters;
|
|
624
|
-
}
|
|
625
|
-
while (selected.at(-1)?.trim().length === 0) selected.pop();
|
|
626
|
-
return selected.join("");
|
|
627
|
-
}
|
|
628
|
-
function takeWholeGraphemesFromEnd(segments, maxCharacters) {
|
|
629
|
-
const selected = [];
|
|
630
|
-
let characters = 0;
|
|
631
|
-
for (let index = segments.length - 1; index >= 0; index -= 1) {
|
|
632
|
-
const segment = segments[index];
|
|
633
|
-
if (!segment) continue;
|
|
634
|
-
const segmentCharacters = codePointLength(segment);
|
|
635
|
-
if (characters + segmentCharacters > maxCharacters) break;
|
|
636
|
-
selected.unshift(segment);
|
|
637
|
-
characters += segmentCharacters;
|
|
638
|
-
}
|
|
639
|
-
while (selected[0]?.trim().length === 0) selected.shift();
|
|
640
|
-
while (selected.at(-1)?.trim().length === 0) selected.pop();
|
|
641
|
-
return selected.join("");
|
|
642
|
-
}
|
|
643
|
-
function codePointLength(value) {
|
|
644
|
-
let characters = 0;
|
|
645
|
-
for (const _character of value) characters += 1;
|
|
646
|
-
return characters;
|
|
647
|
-
}
|
|
648
|
-
function startsWithRegionalIndicator(value) {
|
|
649
|
-
const codePoint = value.codePointAt(0);
|
|
650
|
-
return codePoint !== void 0 && codePoint >= 127462 && codePoint <= 127487;
|
|
651
|
-
}
|
|
652
|
-
function isHighSurrogate(codeUnit) {
|
|
653
|
-
return codeUnit >= 55296 && codeUnit <= 56319;
|
|
654
|
-
}
|
|
655
|
-
function isLowSurrogate(codeUnit) {
|
|
656
|
-
return codeUnit >= 56320 && codeUnit <= 57343;
|
|
657
|
-
}
|
|
658
430
|
function QueuePrompt({
|
|
659
431
|
prompt,
|
|
660
432
|
annotations,
|
|
@@ -1011,8 +783,8 @@ function SortableQueueRow({
|
|
|
1011
783
|
] })
|
|
1012
784
|
] }),
|
|
1013
785
|
confirmingReplace ? /* @__PURE__ */ jsxs("div", { className: "mx-3 mb-2 rounded-md border border-status-waiting/30 bg-status-waiting/10 p-2 text-og-control text-fg", children: [
|
|
1014
|
-
/* @__PURE__ */ jsx("p", { children:
|
|
1015
|
-
/* @__PURE__ */ jsx("p", { className: "mt-0.5 text-fg-muted", children:
|
|
786
|
+
/* @__PURE__ */ jsx("p", { children: QUEUE_REPLACE_DRAFT_COPY.title }),
|
|
787
|
+
/* @__PURE__ */ jsx("p", { className: "mt-0.5 text-fg-muted", children: QUEUE_REPLACE_DRAFT_COPY.detail }),
|
|
1016
788
|
/* @__PURE__ */ jsxs("div", { className: "mt-2 flex justify-end gap-1.5", children: [
|
|
1017
789
|
/* @__PURE__ */ jsx(
|
|
1018
790
|
"button",
|
|
@@ -1020,7 +792,7 @@ function SortableQueueRow({
|
|
|
1020
792
|
type: "button",
|
|
1021
793
|
className: "rounded-md px-2 py-1 font-medium hover:bg-surface-2 focus-visible:ring-2 focus-visible:ring-ring/40",
|
|
1022
794
|
onClick: onCancelReplace,
|
|
1023
|
-
children:
|
|
795
|
+
children: QUEUE_REPLACE_DRAFT_COPY.keep
|
|
1024
796
|
}
|
|
1025
797
|
),
|
|
1026
798
|
/* @__PURE__ */ jsx(
|
|
@@ -1029,7 +801,7 @@ function SortableQueueRow({
|
|
|
1029
801
|
type: "button",
|
|
1030
802
|
className: "rounded-md border border-og-primary-border bg-og-primary text-og-primary-fg px-2 py-1 font-medium hover:bg-og-primary-hover focus-visible:ring-2 focus-visible:ring-ring/40",
|
|
1031
803
|
onClick: onConfirmReplace,
|
|
1032
|
-
children:
|
|
804
|
+
children: QUEUE_REPLACE_DRAFT_COPY.replace
|
|
1033
805
|
}
|
|
1034
806
|
)
|
|
1035
807
|
] })
|
|
@@ -1075,4 +847,4 @@ export {
|
|
|
1075
847
|
QueueSurface,
|
|
1076
848
|
queueComposerCheckoutEnabled
|
|
1077
849
|
};
|
|
1078
|
-
//# sourceMappingURL=queue-surface-implementation-
|
|
850
|
+
//# sourceMappingURL=queue-surface-implementation-YPJFQ3O6.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/queue-surface-implementation.tsx"],"sourcesContent":["import {\n DndContext,\n DragOverlay,\n PointerSensor,\n closestCenter,\n useSensor,\n useSensors,\n type DragEndEvent,\n type DragStartEvent,\n type Modifier,\n} from \"@dnd-kit/core\";\nimport {\n SortableContext,\n arrayMove,\n useSortable,\n verticalListSortingStrategy,\n} from \"@dnd-kit/sortable\";\nimport { CSS } from \"@dnd-kit/utilities\";\nimport type { SessionPendingInputPreview, SessionTurn, TimelineAnnotation } from \"@opengeni/sdk\";\nimport { modelDisplayName } from \"@opengeni/sdk/model-display\";\nimport {\n ArrowDownToLineIcon,\n ArrowUpToLineIcon,\n ChevronDownIcon,\n EllipsisIcon,\n GripVerticalIcon,\n Loader2Icon,\n PencilIcon,\n Trash2Icon,\n ZapIcon,\n} from \"lucide-react\";\nimport {\n useCallback,\n useId,\n useMemo,\n useState,\n type KeyboardEvent as ReactKeyboardEvent,\n} from \"react\";\n\nimport { DropdownMenu } from \"radix-ui\";\nimport { MENU_ITEM_CLASS, MENU_SEPARATOR_CLASS, MENU_SURFACE_CLASS } from \"../lib/menu-styles\";\nimport type { ComposerState } from \"../hooks/use-composer\";\nimport type { QueueMutationKind, UseTurnQueueResult } from \"../hooks/use-turn-queue\";\nimport {\n type PortalTokenStyle,\n usePortalTokenSource,\n usePortalTokenStyle,\n} from \"../lib/use-portal-token-style\";\nimport { requestQueueDraftEdit } from \"./queue-draft-policy\";\nimport {\n projectPendingQueueMove,\n QUEUE_COLLAPSED_PREVIEW_CHARACTERS,\n QUEUE_REPLACE_DRAFT_COPY,\n QUEUE_ROW_PREVIEW_CHARACTERS,\n queueContentPreview,\n queueMovePlan,\n queuePromptPreview,\n queueTurnPreview,\n} from \"../queue-presentation-model\";\nimport { QUEUE_ITEM_CONTENT_UNAVAILABLE, queueItemContent } from \"./queue-item-content\";\nimport { QueueErrorAlert, QueueStoppingStatus } from \"./queue-surface-state\";\nimport { TimelineAnnotationsChip } from \"./timeline-annotations\";\n\n// Queued prompts can be long; menu rows wrap instead of truncating.\nconst QUEUE_MENU_ITEM_CLASS = `${MENU_ITEM_CLASS} whitespace-normal break-words`;\n\n/** The sole pending-input surface: compact above Goal, Agents, and composer. */\ntype QueueSurfaceCommonProps = {\n /** Focus the composer owned by this queue after checkout/removal. */\n onRequestComposerFocus?: (() => void) | undefined;\n};\n\nexport type QueueSurfaceProps =\n | (QueueSurfaceCommonProps & {\n queue: UseTurnQueueResult;\n composer: ComposerState;\n readOnly?: false | undefined;\n })\n | (QueueSurfaceCommonProps & {\n queue: UseTurnQueueResult;\n composer?: undefined;\n readOnly: true;\n });\n\n/** @internal Pure policy seam for queue/composer embedding tests. */\nexport function queueComposerCheckoutEnabled(\n composer: ComposerState | undefined,\n readOnly: boolean,\n): boolean {\n return !readOnly && composer !== undefined && composer.draftPersistence !== \"disabled\";\n}\n\nexport function QueueSurface({\n queue,\n composer,\n readOnly = false,\n onRequestComposerFocus,\n}: QueueSurfaceProps) {\n const [open, setOpen] = useState(false);\n const [replaceDraftFor, setReplaceDraftFor] = useState<string | null>(null);\n const [announcement, setAnnouncement] = useState(\"\");\n const [draggedTurnId, setDraggedTurnId] = useState<string | null>(null);\n const [pendingMove, setPendingMove] = useState<{\n baseVersion: number | null;\n turnIds: string[];\n } | null>(null);\n const surface = usePortalTokenSource<HTMLDivElement>();\n const surfaceRef = surface.currentRef;\n const portalTokenStyle = usePortalTokenStyle(surface.source);\n const [keyboardDrag, setKeyboardDrag] = useState<{\n turnId: string;\n projectedIndex: number;\n } | null>(null);\n const count = queue.queue.length;\n const pendingInputCount = queue.pendingInputs.length;\n const totalCount = count + pendingInputCount;\n const attachedInputIds = queue.pendingInputAttachment?.inputIds ?? [];\n const attachedInputs = queue.pendingInputs.filter((input) => attachedInputIds.includes(input.id));\n const standaloneInputs = queue.pendingInputs.filter(\n (input) => !attachedInputIds.includes(input.id),\n );\n const canEditInComposer = queueComposerCheckoutEnabled(composer, readOnly);\n const collapsedPreview = useMemo(() => {\n const firstTurn = queue.queue[0];\n return firstTurn\n ? queueTurnPreview(firstTurn, QUEUE_COLLAPSED_PREVIEW_CHARACTERS)\n : queuePromptPreview(\n queue.pendingInputs[0]?.summary ?? \"\",\n QUEUE_COLLAPSED_PREVIEW_CHARACTERS,\n );\n }, [queue.pendingInputs, queue.queue]);\n const sensors = useSensors(useSensor(PointerSensor, { activationConstraint: { distance: 6 } }));\n\n const displayedQueue = useMemo(() => {\n if (keyboardDrag) {\n const oldIndex = queue.queue.findIndex((turn) => turn.id === keyboardDrag.turnId);\n if (oldIndex < 0) return queue.queue;\n return arrayMove(queue.queue, oldIndex, keyboardDrag.projectedIndex);\n }\n // Never let an optimistic ordering projection omit or invent a row. Any\n // concurrent authoritative membership change wins immediately.\n return projectPendingQueueMove(queue.queue, pendingMove, queue.snapshot);\n }, [keyboardDrag, pendingMove, queue.queue, queue.snapshot]);\n\n const ids = useMemo(() => displayedQueue.map((turn) => turn.id), [displayedQueue]);\n const moveToIndex = useCallback(\n async (turnId: string, nextIndex: number): Promise<void> => {\n if (queue.mutating || pendingMove) return;\n const plan = queueMovePlan(queue.queue, turnId, nextIndex);\n if (!plan) return;\n const { beforeTurnId, index: boundedIndex } = plan;\n setPendingMove({\n baseVersion: queue.snapshot?.version ?? null,\n turnIds: plan.turnIds,\n });\n setAnnouncement(`Saving queued prompt at position ${boundedIndex + 1}.`);\n try {\n const moved = await queue.moveTurn(turnId, beforeTurnId);\n setAnnouncement(\n moved\n ? `Queued prompt moved to position ${boundedIndex + 1}.`\n : \"The queue changed before that prompt could be moved. Refreshed server order.\",\n );\n if (moved) focusQueueTurn(surfaceRef.current, turnId);\n } finally {\n setPendingMove(null);\n }\n },\n [pendingMove, queue, surfaceRef],\n );\n\n const onDragEnd = useCallback(\n (event: DragEndEvent) => {\n setDraggedTurnId(null);\n const activeId = String(event.active.id);\n const overId = event.over ? String(event.over.id) : null;\n if (!overId || activeId === overId) {\n setAnnouncement(\"Queued prompt returned to its original position.\");\n return;\n }\n const nextIndex = queue.queue.findIndex((turn) => turn.id === overId);\n if (nextIndex >= 0) void moveToIndex(activeId, nextIndex);\n },\n [moveToIndex, queue.queue],\n );\n\n const onDragStart = useCallback(\n (event: DragStartEvent) => {\n setKeyboardDrag(null);\n const turnId = String(event.active.id);\n const position = queue.queue.findIndex((turn) => turn.id === turnId) + 1;\n setDraggedTurnId(turnId);\n setAnnouncement(`Dragging queued prompt ${position} of ${queue.queue.length}.`);\n },\n [queue.queue],\n );\n\n const onHandleKeyDown = useCallback(\n (event: ReactKeyboardEvent<HTMLButtonElement>, turnId: string) => {\n const canonicalIndex = queue.queue.findIndex((turn) => turn.id === turnId);\n if (canonicalIndex < 0) return;\n\n if (!keyboardDrag) {\n if (event.key !== \" \") return;\n event.preventDefault();\n setKeyboardDrag({ turnId, projectedIndex: canonicalIndex });\n setAnnouncement(\n `Lifted queued prompt ${canonicalIndex + 1} of ${count}. Use arrow keys to move it, then press Space to drop.`,\n );\n return;\n }\n if (keyboardDrag.turnId !== turnId) return;\n\n if (event.key === \"Escape\") {\n event.preventDefault();\n setKeyboardDrag(null);\n setAnnouncement(\"Queue reorder cancelled.\");\n return;\n }\n if (event.key === \" \") {\n event.preventDefault();\n const targetIndex = keyboardDrag.projectedIndex;\n setAnnouncement(`Moving queued prompt to position ${targetIndex + 1}.`);\n void moveToIndex(turnId, targetIndex).finally(() => setKeyboardDrag(null));\n return;\n }\n\n const direction = event.key === \"ArrowUp\" ? -1 : event.key === \"ArrowDown\" ? 1 : 0;\n const edge = event.key === \"Home\" ? 0 : event.key === \"End\" ? count - 1 : null;\n if (direction === 0 && edge === null) return;\n event.preventDefault();\n const projectedIndex = Math.max(\n 0,\n Math.min(edge ?? keyboardDrag.projectedIndex + direction, count - 1),\n );\n setKeyboardDrag({ turnId, projectedIndex });\n setAnnouncement(`Queued prompt projected to position ${projectedIndex + 1} of ${count}.`);\n },\n [count, keyboardDrag, moveToIndex, queue.queue],\n );\n\n const edit = useCallback(\n async (turn: SessionTurn, replaceDraft: boolean) => {\n if (!composer || !canEditInComposer) return;\n setAnnouncement(\"Moving queued prompt to the composer…\");\n const restored = await queue.editTurn(turn.id, {\n expectedDraftRevision: composer.draftRevision,\n replaceDraft,\n });\n if (!restored) {\n setAnnouncement(\"That prompt changed before it could be moved to the composer.\");\n return;\n }\n composer.applyDraft(restored);\n setReplaceDraftFor(null);\n setAnnouncement(\"Queued prompt moved back to the composer for editing.\");\n window.requestAnimationFrame(() => {\n if (onRequestComposerFocus) {\n onRequestComposerFocus();\n return;\n }\n const input = document.querySelector<HTMLTextAreaElement>(\n 'textarea[aria-label=\"Message the agent\"]',\n );\n input?.scrollIntoView({ block: \"nearest\", behavior: \"smooth\" });\n input?.focus();\n });\n },\n [canEditInComposer, composer, onRequestComposerFocus, queue],\n );\n\n const requestEdit = useCallback(\n (turn: SessionTurn) => {\n if (!composer || !canEditInComposer) return;\n requestQueueDraftEdit(\n composer,\n () => setReplaceDraftFor(turn.id),\n () => void edit(turn, false),\n );\n },\n [canEditInComposer, composer, edit],\n );\n\n if (totalCount === 0 && !queue.stoppingPreviousAttempt && !queue.error && !queue.mutationError)\n return null;\n\n return (\n <div\n ref={surface.ref}\n className=\"og-root mx-auto mb-2 w-full max-w-3xl shrink-0 px-4 sm:px-6\"\n data-testid=\"queue-surface\"\n >\n <div className=\"overflow-hidden rounded-lg border border-border bg-surface/80 shadow-sm\">\n {queue.stoppingPreviousAttempt ? <QueueStoppingStatus queue={queue} dividerAfter /> : null}\n <button\n type=\"button\"\n className=\"flex w-full min-w-0 flex-wrap items-center gap-2 px-3 py-2 text-left outline-hidden transition-colors hover:bg-surface-2/60 focus-visible:bg-surface-2/60 focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring/40 pointer-coarse:min-h-[44px]\"\n onClick={() => setOpen((value) => !value)}\n aria-description={!open && totalCount > 0 ? collapsedPreview.summary : undefined}\n aria-expanded={open}\n aria-label={`${count} queued prompt${count === 1 ? \"\" : \"s\"}${\n pendingInputCount > 0\n ? ` and ${pendingInputCount} pending machine input${pendingInputCount === 1 ? \"\" : \"s\"}`\n : \"\"\n }${readOnly ? \" Read-only\" : \"\"}`}\n >\n <ChevronDownIcon\n aria-hidden=\"true\"\n className={`size-3.5 shrink-0 text-fg-subtle transition-transform ${open ? \"rotate-180\" : \"\"}`}\n />\n <span className=\"text-og-control font-medium text-fg\">\n {count > 0 ? `${count} queued prompt${count === 1 ? \"\" : \"s\"}` : null}\n {count > 0 && pendingInputCount > 0 ? \" · \" : null}\n {pendingInputCount > 0\n ? `${pendingInputCount} incoming update${pendingInputCount === 1 ? \"\" : \"s\"}`\n : null}\n </span>\n {readOnly ? (\n <span className=\"shrink-0 rounded border border-border px-1.5 py-0.5 text-og-xs text-fg-subtle\">\n Read-only\n </span>\n ) : null}\n {!open && totalCount > 0 ? (\n <span\n aria-hidden=\"true\"\n className={`max-w-full truncate text-fg-muted ${\n collapsedPreview.collapsedVisual === collapsedPreview.summary\n ? \"min-w-0 flex-1 text-og-control\"\n : \"shrink-0 text-[10px]\"\n }`}\n data-testid=\"queue-collapsed-preview\"\n dir=\"auto\"\n >\n {collapsedPreview.collapsedVisual}\n </span>\n ) : null}\n {queue.loading ? <Loader2Icon className=\"ml-auto size-3.5 animate-spin\" /> : null}\n </button>\n\n {open && standaloneInputs.length > 0 ? (\n <PendingMachineInputs inputs={standaloneInputs} />\n ) : null}\n\n {open && count > 0 && readOnly ? (\n <ol\n className=\"max-h-[min(30rem,60dvh)] divide-y divide-border overflow-y-auto overscroll-contain border-t border-border\"\n aria-label=\"Queued prompts\"\n data-testid=\"queue-list\"\n >\n {queue.queue.map((turn, index) => (\n <ReadOnlyQueueRow\n key={turn.id}\n turn={turn}\n index={index}\n attachedInputs={\n turn.id === queue.pendingInputAttachment?.turnId ? attachedInputs : []\n }\n onDisclosureChange={(expanded) =>\n setAnnouncement(\n `Full content for queued prompt ${index + 1} ${expanded ? \"shown\" : \"hidden\"}.`,\n )\n }\n />\n ))}\n </ol>\n ) : null}\n\n {open && count > 0 && !readOnly ? (\n <DndContext\n sensors={sensors}\n collisionDetection={closestCenter}\n modifiers={[verticalOnly]}\n onDragStart={onDragStart}\n onDragCancel={() => {\n setDraggedTurnId(null);\n setAnnouncement(\"Queue reorder cancelled.\");\n }}\n onDragEnd={onDragEnd}\n >\n <SortableContext items={ids} strategy={verticalListSortingStrategy}>\n <ol\n className=\"max-h-[min(30rem,60dvh)] divide-y divide-border overflow-y-auto overscroll-contain border-t border-border\"\n aria-label=\"Queued prompts\"\n data-testid=\"queue-list\"\n >\n {displayedQueue.map((turn, index) => (\n <SortableQueueRow\n key={turn.id}\n turn={turn}\n index={index}\n count={count}\n attachedInputs={\n turn.id === queue.pendingInputAttachment?.turnId ? attachedInputs : []\n }\n pending={queue.mutationFor(turn.id)}\n reorderDisabled={queue.mutating || pendingMove !== null}\n confirmingReplace={replaceDraftFor === turn.id}\n keyboardDragging={keyboardDrag?.turnId === turn.id}\n portalTokenStyle={portalTokenStyle}\n onHandleKeyDown={(event) => onHandleKeyDown(event, turn.id)}\n onMove={(nextIndex) => void moveToIndex(turn.id, nextIndex)}\n onEdit={canEditInComposer ? () => requestEdit(turn) : undefined}\n onConfirmReplace={() => void edit(turn, true)}\n onCancelReplace={() => setReplaceDraftFor(null)}\n onSteer={() => {\n setAnnouncement(\"Requesting this queued prompt as the next direction…\");\n void queue.steerTurn(turn.id).then((steered) => {\n setAnnouncement(\n steered\n ? \"Queued prompt is now the next direction.\"\n : \"That prompt changed before it could be steered.\",\n );\n if (steered) {\n focusAfterQueueRemoval(surfaceRef.current, index, onRequestComposerFocus);\n }\n });\n }}\n onDelete={() => {\n setAnnouncement(\"Deleting queued prompt…\");\n void queue.removeTurn(turn.id).then((removed) => {\n setAnnouncement(\n removed\n ? \"Queued prompt deleted.\"\n : \"That prompt changed before it could be deleted.\",\n );\n if (removed) {\n focusAfterQueueRemoval(surfaceRef.current, index, onRequestComposerFocus);\n }\n });\n }}\n onDisclosureChange={(expanded) =>\n setAnnouncement(\n `Full content for queued prompt ${index + 1} ${expanded ? \"shown\" : \"hidden\"}.`,\n )\n }\n />\n ))}\n </ol>\n </SortableContext>\n <DragOverlay modifiers={[verticalOnly]}>\n {draggedTurnId ? (\n <div\n className=\"max-h-20 w-[min(36rem,calc(100vw-2rem))] max-w-[calc(100vw-2rem)] overflow-hidden rounded-md border border-brand/40 bg-surface px-3 py-2 text-og-control text-fg shadow-lg\"\n data-testid=\"queue-drag-overlay\"\n >\n <p\n aria-hidden=\"true\"\n className=\"line-clamp-3 break-all whitespace-pre-wrap [unicode-bidi:plaintext]\"\n dir=\"auto\"\n >\n {\n queueTurnPreview(\n queue.queue.find((turn) => turn.id === draggedTurnId),\n QUEUE_ROW_PREVIEW_CHARACTERS,\n ).summary\n }\n </p>\n </div>\n ) : null}\n </DragOverlay>\n </DndContext>\n ) : null}\n\n {queue.error || queue.mutationError ? (\n <QueueErrorAlert queue={queue} dividerBefore />\n ) : null}\n </div>\n <p className=\"sr-only\" aria-live=\"polite\" aria-atomic=\"true\">\n {announcement}\n </p>\n </div>\n );\n}\n\nfunction PendingMachineInputs({\n inputs,\n attached = false,\n}: {\n inputs: SessionPendingInputPreview[];\n attached?: boolean;\n}) {\n return (\n <section className=\"border-t border-border px-3 py-2\">\n <p className=\"text-og-xs font-medium text-fg-subtle\">\n {attached\n ? `${inputs.length} update${inputs.length === 1 ? \"\" : \"s\"} will join this prompt`\n : \"Incoming updates waiting to run\"}\n </p>\n <ol className=\"mt-1 space-y-1\">\n {inputs.map((input) => (\n <li\n key={input.id}\n className=\"line-clamp-3 break-words text-og-control text-fg\"\n dir=\"auto\"\n >\n <strong className=\"capitalize text-fg-muted\">\n {input.kind.replace(\"_terminal\", \"\").replaceAll(\"_\", \" \")}\n </strong>{\" \"}\n · {input.sourceId}\n {input.summary ? ` — ${input.summary}` : \"\"}\n </li>\n ))}\n </ol>\n </section>\n );\n}\n\nfunction QueuePrompt({\n prompt,\n annotations,\n index,\n onDisclosureChange,\n}: {\n prompt: string;\n annotations: readonly TimelineAnnotation[];\n index: number;\n onDisclosureChange: (expanded: boolean) => void;\n}) {\n const [expanded, setExpanded] = useState(false);\n const fullContentId = useId();\n const content = queueItemContent(prompt, annotations.length);\n const preview = useMemo(\n () => queueContentPreview(prompt, annotations.length, QUEUE_ROW_PREVIEW_CHARACTERS),\n [annotations.length, prompt],\n );\n\n return (\n <div className=\"w-full min-w-0 max-w-full\">\n {prompt ? (\n <div\n aria-label={`Queued prompt ${index + 1} summary: ${preview.summary}`}\n className=\"max-w-full overflow-hidden text-og-control leading-5 text-fg\"\n data-testid={`queue-prompt-preview-${index + 1}`}\n dir=\"auto\"\n role=\"note\"\n >\n <span\n aria-hidden=\"true\"\n className=\"flex min-w-0 max-w-full items-baseline gap-2 sm:block\"\n >\n <span\n className={`${preview.isFallback ? \"\" : \"line-clamp-1 sm:line-clamp-2\"} min-w-0 flex-1 whitespace-pre-wrap break-all [unicode-bidi:plaintext]`}\n data-testid={`queue-prompt-start-${index + 1}`}\n dir=\"auto\"\n >\n {preview.visibleStart}\n </span>\n {preview.visibleIdentity && preview.visibleIdentityLabel ? (\n <span\n className=\"flex min-w-0 max-w-[70%] shrink-0 items-center gap-1 text-og-xs leading-4 text-fg-muted sm:mt-0.5 sm:max-w-full\"\n data-testid={`queue-prompt-identity-row-${index + 1}`}\n >\n <span className=\"shrink-0 font-medium text-fg-subtle\">\n {preview.visibleIdentityLabel}\n </span>\n <span\n className=\"min-w-0 overflow-hidden text-ellipsis whitespace-nowrap font-mono [unicode-bidi:plaintext]\"\n data-testid={`queue-prompt-identity-${index + 1}`}\n dir=\"auto\"\n >\n {preview.visibleIdentity}\n </span>\n </span>\n ) : null}\n </span>\n </div>\n ) : null}\n {annotations.length > 0 ? (\n <TimelineAnnotationsChip\n annotations={annotations}\n className={prompt ? \"mt-1\" : undefined}\n />\n ) : null}\n {content === \"unavailable\" ? (\n <p\n className=\"text-og-control leading-5 text-fg-muted italic\"\n data-testid={`queue-prompt-unavailable-${index + 1}`}\n >\n {QUEUE_ITEM_CONTENT_UNAVAILABLE}\n </p>\n ) : null}\n {prompt ? (\n <button\n type=\"button\"\n aria-controls={fullContentId}\n aria-expanded={expanded}\n aria-label={`${expanded ? \"Hide\" : \"Show\"} full content for queued prompt ${index + 1}`}\n className=\"mt-1 inline-flex min-h-7 min-w-0 max-w-full items-center gap-1 whitespace-normal rounded-md text-left text-og-xs font-medium text-fg outline-hidden focus-visible:ring-2 focus-visible:ring-ring/40 pointer-coarse:min-h-[44px]\"\n data-testid={`queue-prompt-disclosure-${index + 1}`}\n onClick={() => {\n const next = !expanded;\n setExpanded(next);\n onDisclosureChange(next);\n }}\n >\n <ChevronDownIcon\n aria-hidden=\"true\"\n className={`size-3 shrink-0 transition-transform ${expanded ? \"rotate-180\" : \"\"}`}\n />\n {expanded ? \"Hide full prompt\" : \"View full prompt\"}\n </button>\n ) : null}\n {expanded && prompt ? (\n <pre\n id={fullContentId}\n role=\"region\"\n aria-label={`Full content for queued prompt ${index + 1}`}\n className=\"mt-1.5 max-h-64 w-full min-w-0 max-w-full overflow-auto overscroll-contain rounded-md border border-border bg-surface-2/60 p-2 whitespace-pre-wrap break-all font-mono text-og-control leading-5 text-fg [unicode-bidi:plaintext]\"\n data-testid={`queue-prompt-full-${index + 1}`}\n dir=\"auto\"\n tabIndex={0}\n >\n {prompt}\n </pre>\n ) : null}\n </div>\n );\n}\n\nfunction ReadOnlyQueueRow({\n turn,\n index,\n attachedInputs,\n onDisclosureChange,\n}: {\n turn: SessionTurn;\n index: number;\n attachedInputs: SessionPendingInputPreview[];\n onDisclosureChange: (expanded: boolean) => void;\n}) {\n return (\n <li className=\"flex min-w-0 items-start gap-2 bg-surface px-3 py-2\">\n <span className=\"mt-1 shrink-0 font-mono text-og-xs text-fg-subtle\">{index + 1}</span>\n <div className=\"min-w-0 flex-1\">\n <QueuePrompt\n prompt={turn.prompt}\n annotations={turn.annotations ?? []}\n index={index}\n onDisclosureChange={onDisclosureChange}\n />\n {attachedInputs.length > 0 ? (\n <PendingMachineInputs inputs={attachedInputs} attached />\n ) : null}\n <div className=\"mt-1 flex min-w-0 items-center gap-2 overflow-hidden whitespace-nowrap text-og-xs text-fg-subtle\">\n {turn.resources.length > 0 ? (\n <span className=\"shrink-0\">\n {turn.resources.length} resource{turn.resources.length === 1 ? \"\" : \"s\"}\n </span>\n ) : null}\n {turn.tools.length > 0 ? (\n <span className=\"shrink-0\">\n {turn.tools.length} tool{turn.tools.length === 1 ? \"\" : \"s\"}\n </span>\n ) : null}\n <span className=\"min-w-0 truncate\">{modelDisplayName(turn.model)}</span>\n <span className=\"shrink-0\">{turn.reasoningEffort}</span>\n </div>\n </div>\n </li>\n );\n}\n\nfunction SortableQueueRow({\n turn,\n index,\n count,\n attachedInputs,\n pending,\n reorderDisabled,\n confirmingReplace,\n keyboardDragging,\n portalTokenStyle,\n onHandleKeyDown,\n onMove,\n onEdit,\n onConfirmReplace,\n onCancelReplace,\n onSteer,\n onDelete,\n onDisclosureChange,\n}: {\n turn: SessionTurn;\n index: number;\n count: number;\n attachedInputs: SessionPendingInputPreview[];\n pending: QueueMutationKind | null;\n reorderDisabled: boolean;\n confirmingReplace: boolean;\n keyboardDragging: boolean;\n portalTokenStyle: PortalTokenStyle;\n onHandleKeyDown: (event: ReactKeyboardEvent<HTMLButtonElement>) => void;\n onMove: (index: number) => void;\n onEdit?: (() => void) | undefined;\n onConfirmReplace: () => void;\n onCancelReplace: () => void;\n onSteer: () => void;\n onDelete: () => void;\n onDisclosureChange: (expanded: boolean) => void;\n}) {\n const sortable = useSortable({\n id: turn.id,\n disabled: reorderDisabled || keyboardDragging,\n });\n return (\n <li\n data-queue-turn-id={turn.id}\n ref={sortable.setNodeRef}\n style={{\n transform: CSS.Transform.toString(sortable.transform),\n transition: sortable.transition,\n }}\n className={`bg-surface ${sortable.isDragging || keyboardDragging ? \"relative z-10 shadow-lg ring-1 ring-brand/40\" : \"\"}`}\n >\n <div className=\"grid min-w-0 grid-cols-[auto_minmax(0,1fr)] items-start gap-x-1.5 px-2 py-1.5 sm:grid-cols-[auto_auto_minmax(0,1fr)_auto] sm:gap-x-2 sm:px-3 sm:py-2\">\n <button\n data-queue-handle\n ref={sortable.setActivatorNodeRef}\n type=\"button\"\n {...sortable.attributes}\n {...sortable.listeners}\n onKeyDown={onHandleKeyDown}\n disabled={reorderDisabled}\n className=\"col-start-1 row-start-1 mt-0.5 inline-flex size-7 shrink-0 touch-none items-center justify-center rounded-md text-fg-subtle hover:bg-surface-2 hover:text-fg focus-visible:ring-2 focus-visible:ring-ring/40 pointer-coarse:size-[44px]\"\n aria-label={`Reorder queued prompt ${index + 1}`}\n title=\"Drag to reorder. Press Space, arrows, then Space to drop.\"\n >\n <GripVerticalIcon className=\"size-3.5\" />\n </button>\n <span className=\"col-start-2 row-start-1 mt-1 shrink-0 font-mono text-og-xs text-fg-subtle\">\n {index + 1}\n </span>\n <div className=\"col-span-full row-start-2 min-w-0 sm:col-span-1 sm:col-start-3 sm:row-start-1\">\n <QueuePrompt\n prompt={turn.prompt}\n annotations={turn.annotations ?? []}\n index={index}\n onDisclosureChange={onDisclosureChange}\n />\n {attachedInputs.length > 0 ? (\n <PendingMachineInputs inputs={attachedInputs} attached />\n ) : null}\n <div className=\"mt-1 flex min-w-0 items-center gap-2 overflow-hidden whitespace-nowrap text-og-xs text-fg-subtle\">\n {turn.resources.length > 0 ? (\n <span className=\"shrink-0\">\n {turn.resources.length} resource{turn.resources.length === 1 ? \"\" : \"s\"}\n </span>\n ) : null}\n {turn.tools.length > 0 ? (\n <span className=\"shrink-0\">\n {turn.tools.length} tool{turn.tools.length === 1 ? \"\" : \"s\"}\n </span>\n ) : null}\n <span className=\"min-w-0 truncate\">{modelDisplayName(turn.model)}</span>\n <span className=\"shrink-0\">{turn.reasoningEffort}</span>\n </div>\n {pending ? (\n <div\n role=\"status\"\n aria-live=\"polite\"\n className=\"mt-1 flex items-center gap-1.5 text-og-xs font-medium text-status-waiting\"\n data-testid={`queue-mutation-${pending}`}\n >\n <Loader2Icon\n aria-hidden=\"true\"\n className=\"size-3 shrink-0 animate-spin motion-reduce:animate-none\"\n />\n {queueMutationPendingLabel(pending)}\n </div>\n ) : null}\n </div>\n <div className=\"col-span-full row-start-3 flex min-w-0 items-start justify-end gap-1.5 sm:col-span-1 sm:col-start-4 sm:row-start-1 sm:gap-2\">\n <button\n type=\"button\"\n disabled={pending !== null}\n onClick={onSteer}\n aria-label={`Steer queued prompt ${index + 1}`}\n data-analytics-action=\"steer\"\n title=\"Steer — interrupt the current turn and send this message now\"\n className=\"inline-flex h-7 shrink-0 items-center justify-center gap-1 rounded-md px-2 text-og-control font-medium text-fg outline-hidden transition-[background-color] hover:bg-surface-2 focus-visible:ring-2 focus-visible:ring-ring/40 disabled:pointer-events-none disabled:opacity-50 pointer-coarse:min-h-[44px] pointer-coarse:min-w-[44px]\"\n >\n {pending === \"steer\" ? (\n <Loader2Icon className=\"size-3.5 animate-spin\" />\n ) : (\n <ZapIcon className=\"size-3.5\" />\n )}\n <span className=\"hidden sm:inline\">Steer</span>\n </button>\n <button\n type=\"button\"\n disabled={pending !== null}\n onClick={onDelete}\n aria-label={`Delete queued prompt ${index + 1}`}\n title=\"Delete this queued prompt\"\n className=\"inline-flex size-7 shrink-0 items-center justify-center rounded-md outline-hidden transition-colors hover:bg-surface-2 hover:text-status-failed focus-visible:ring-2 focus-visible:ring-ring/40 disabled:pointer-events-none disabled:opacity-50 pointer-coarse:size-[44px]\"\n >\n {pending === \"delete\" ? (\n <Loader2Icon className=\"size-3.5 animate-spin\" />\n ) : (\n <Trash2Icon className=\"size-3.5\" />\n )}\n </button>\n <DropdownMenu.Root>\n <DropdownMenu.Trigger asChild>\n <button\n type=\"button\"\n disabled={pending !== null}\n aria-label={`More actions for queued prompt ${index + 1}`}\n className=\"inline-flex size-7 shrink-0 items-center justify-center rounded-md outline-hidden transition-colors hover:bg-surface-2 focus-visible:ring-2 focus-visible:ring-ring/40 disabled:pointer-events-none disabled:opacity-50 pointer-coarse:size-[44px]\"\n >\n {pending && pending !== \"steer\" && pending !== \"delete\" ? (\n <Loader2Icon className=\"size-3.5 animate-spin\" />\n ) : (\n <EllipsisIcon className=\"size-3.5\" />\n )}\n </button>\n </DropdownMenu.Trigger>\n <DropdownMenu.Portal>\n <DropdownMenu.Content\n align=\"end\"\n sideOffset={4}\n collisionPadding={8}\n className={`${MENU_SURFACE_CLASS} og-root z-50 max-h-(--radix-dropdown-menu-content-available-height) w-52 max-w-[calc(100vw-16px)] overflow-x-hidden overflow-y-auto`}\n style={portalTokenStyle}\n data-testid={`queue-actions-menu-${index + 1}`}\n >\n {onEdit ? (\n <>\n <DropdownMenu.Item className={QUEUE_MENU_ITEM_CLASS} onSelect={onEdit}>\n <PencilIcon /> Edit in composer\n </DropdownMenu.Item>\n <DropdownMenu.Separator className={MENU_SEPARATOR_CLASS} />\n </>\n ) : null}\n <DropdownMenu.Item\n className={QUEUE_MENU_ITEM_CLASS}\n disabled={index === 0}\n onSelect={() => onMove(0)}\n >\n <ArrowUpToLineIcon /> Move to top\n </DropdownMenu.Item>\n <DropdownMenu.Item\n className={QUEUE_MENU_ITEM_CLASS}\n disabled={index === 0}\n onSelect={() => onMove(index - 1)}\n >\n Move up\n </DropdownMenu.Item>\n <DropdownMenu.Item\n className={QUEUE_MENU_ITEM_CLASS}\n disabled={index === count - 1}\n onSelect={() => onMove(index + 1)}\n >\n Move down\n </DropdownMenu.Item>\n <DropdownMenu.Item\n className={QUEUE_MENU_ITEM_CLASS}\n disabled={index === count - 1}\n onSelect={() => onMove(count - 1)}\n >\n <ArrowDownToLineIcon /> Move to bottom\n </DropdownMenu.Item>\n </DropdownMenu.Content>\n </DropdownMenu.Portal>\n </DropdownMenu.Root>\n </div>\n </div>\n {confirmingReplace ? (\n <div className=\"mx-3 mb-2 rounded-md border border-status-waiting/30 bg-status-waiting/10 p-2 text-og-control text-fg\">\n <p>{QUEUE_REPLACE_DRAFT_COPY.title}</p>\n <p className=\"mt-0.5 text-fg-muted\">{QUEUE_REPLACE_DRAFT_COPY.detail}</p>\n <div className=\"mt-2 flex justify-end gap-1.5\">\n <button\n type=\"button\"\n className=\"rounded-md px-2 py-1 font-medium hover:bg-surface-2 focus-visible:ring-2 focus-visible:ring-ring/40\"\n onClick={onCancelReplace}\n >\n {QUEUE_REPLACE_DRAFT_COPY.keep}\n </button>\n <button\n type=\"button\"\n className=\"rounded-md border border-og-primary-border bg-og-primary text-og-primary-fg px-2 py-1 font-medium hover:bg-og-primary-hover focus-visible:ring-2 focus-visible:ring-ring/40\"\n onClick={onConfirmReplace}\n >\n {QUEUE_REPLACE_DRAFT_COPY.replace}\n </button>\n </div>\n </div>\n ) : null}\n </li>\n );\n}\n\nfunction queueMutationPendingLabel(kind: QueueMutationKind): string {\n switch (kind) {\n case \"move\":\n return \"Saving new position…\";\n case \"edit\":\n return \"Moving to composer…\";\n case \"steer\":\n return \"Changing direction…\";\n case \"delete\":\n return \"Deleting…\";\n }\n}\n\nconst verticalOnly: Modifier = ({ transform }) => ({ ...transform, x: 0 });\n\nfunction focusQueueTurn(surface: HTMLElement | null, turnId: string): void {\n window.requestAnimationFrame(() => {\n surface\n ?.querySelector<HTMLElement>(`[data-queue-turn-id=\"${turnId}\"] [data-queue-handle]`)\n ?.focus();\n });\n}\n\nfunction focusAfterQueueRemoval(\n surface: HTMLElement | null,\n previousIndex: number,\n onRequestComposerFocus?: (() => void) | undefined,\n): void {\n window.requestAnimationFrame(() => {\n const handles = surface?.querySelectorAll<HTMLElement>(\"[data-queue-handle]\") ?? [];\n const nearest = handles[Math.min(previousIndex, Math.max(0, handles.length - 1))];\n if (nearest) {\n nearest.focus();\n return;\n }\n if (onRequestComposerFocus) {\n onRequestComposerFocus();\n return;\n }\n document\n .querySelector<HTMLTextAreaElement>('textarea[aria-label=\"Message the agent\"]')\n ?.focus();\n });\n}\n"],"mappings":"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","names":[]}
|
package/dist/realtime.js
CHANGED
|
@@ -13,12 +13,14 @@ import {
|
|
|
13
13
|
useSessionCodexRealtime,
|
|
14
14
|
useSessionRealtime,
|
|
15
15
|
useWorkspaceRealtimeModelSelection
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-GMNGUPMX.js";
|
|
17
17
|
import "./chunk-NX4ADH73.js";
|
|
18
|
-
import "./chunk-
|
|
18
|
+
import "./chunk-VYIPNDUZ.js";
|
|
19
19
|
import "./chunk-PMV53IMM.js";
|
|
20
|
-
import "./chunk-
|
|
20
|
+
import "./chunk-N7S72EXK.js";
|
|
21
|
+
import "./chunk-LTKGTXUQ.js";
|
|
21
22
|
import "./chunk-XEA5BCMA.js";
|
|
23
|
+
import "./chunk-4O7OE7ON.js";
|
|
22
24
|
import "./chunk-XTD7TZHW.js";
|
|
23
25
|
import "./chunk-TXS65BB2.js";
|
|
24
26
|
export {
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import {
|
|
3
3
|
SandboxFiles
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-LSMWZSCJ.js";
|
|
5
|
+
import "./chunk-LSW2OJVV.js";
|
|
5
6
|
import "./chunk-B27E3V37.js";
|
|
7
|
+
import "./chunk-YSRBFJMQ.js";
|
|
6
8
|
import "./chunk-PKCAYHDC.js";
|
|
7
9
|
import "./chunk-OYQQJL3J.js";
|
|
8
|
-
import "./chunk-YSRBFJMQ.js";
|
|
9
10
|
import "./chunk-PMV53IMM.js";
|
|
10
11
|
import "./chunk-XEA5BCMA.js";
|
|
11
12
|
import "./chunk-QV3DJVRZ.js";
|
|
13
|
+
import "./chunk-5I4VRWBB.js";
|
|
12
14
|
import "./chunk-QHUE7E4N.js";
|
|
13
15
|
import "./chunk-CM7LVUKC.js";
|
|
14
16
|
import "./chunk-XTD7TZHW.js";
|
|
15
|
-
import "./chunk-LSW2OJVV.js";
|
|
16
|
-
import "./chunk-5I4VRWBB.js";
|
|
17
17
|
import "./chunk-TXS65BB2.js";
|
|
18
18
|
export {
|
|
19
19
|
SandboxFiles
|
|
20
20
|
};
|
|
21
|
-
//# sourceMappingURL=sandbox-files-
|
|
21
|
+
//# sourceMappingURL=sandbox-files-2DGDO6NI.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* User-facing names for where a session's commands run, shared by the web
|
|
3
|
+
* sandbox switcher and every timeline that labels command rows ("on Cloud
|
|
4
|
+
* sandbox · …"). No DOM, no React.
|
|
5
|
+
*/
|
|
6
|
+
import type { SandboxBackend } from "@opengeni/sdk";
|
|
7
|
+
import type { MachineView } from "./types/machines.js";
|
|
8
|
+
export declare const CLOUD_SANDBOX_LABEL = "Cloud sandbox";
|
|
9
|
+
export declare const NO_SANDBOX_LABEL = "No sandbox";
|
|
10
|
+
export declare const LOCAL_SANDBOX_LABEL = "Local sandbox";
|
|
11
|
+
/**
|
|
12
|
+
* User-facing name for a session's own managed box. Hosting vendors (Modal,
|
|
13
|
+
* Daytona, ...) are deployment detail, not something a user chose, so hosted
|
|
14
|
+
* providers read as the neutral "Cloud sandbox" and the local-dev Docker box as
|
|
15
|
+
* "Local sandbox". The local backend runs directly on the host, so it keeps the
|
|
16
|
+
* honest "this computer" instead of implying isolation. Connected Machines keep
|
|
17
|
+
* their own names.
|
|
18
|
+
*/
|
|
19
|
+
export declare function sessionSandboxLabel(backend: SandboxBackend | string): string;
|
|
20
|
+
/** Display name for a fleet row: the session's own box never shows its vendor. */
|
|
21
|
+
export declare function machineDisplayName(machine: Pick<MachineView, "isSessionGroup" | "kind" | "name">): string;
|
|
22
|
+
/** The compute label a session timeline shows: the active machine, else the cloud box. */
|
|
23
|
+
export declare function sessionComputeLabel(machines: readonly Pick<MachineView, "active" | "isSessionGroup" | "kind" | "name">[]): string;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
// src/sandbox-label-model.ts
|
|
4
|
+
var CLOUD_SANDBOX_LABEL = "Cloud sandbox";
|
|
5
|
+
var NO_SANDBOX_LABEL = "No sandbox";
|
|
6
|
+
var LOCAL_SANDBOX_LABEL = "Local sandbox";
|
|
7
|
+
function sessionSandboxLabel(backend) {
|
|
8
|
+
if (backend === "none") return NO_SANDBOX_LABEL;
|
|
9
|
+
if (backend === "local") return "this computer";
|
|
10
|
+
if (backend === "docker") return LOCAL_SANDBOX_LABEL;
|
|
11
|
+
return CLOUD_SANDBOX_LABEL;
|
|
12
|
+
}
|
|
13
|
+
function machineDisplayName(machine) {
|
|
14
|
+
return machine.isSessionGroup ? sessionSandboxLabel(machine.kind) : machine.name;
|
|
15
|
+
}
|
|
16
|
+
function sessionComputeLabel(machines) {
|
|
17
|
+
const active = machines.find((machine) => machine.active);
|
|
18
|
+
return active ? machineDisplayName(active) : CLOUD_SANDBOX_LABEL;
|
|
19
|
+
}
|
|
20
|
+
export {
|
|
21
|
+
CLOUD_SANDBOX_LABEL,
|
|
22
|
+
LOCAL_SANDBOX_LABEL,
|
|
23
|
+
NO_SANDBOX_LABEL,
|
|
24
|
+
machineDisplayName,
|
|
25
|
+
sessionComputeLabel,
|
|
26
|
+
sessionSandboxLabel
|
|
27
|
+
};
|
|
28
|
+
//# sourceMappingURL=sandbox-label-model.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/sandbox-label-model.ts"],"sourcesContent":["/**\n * User-facing names for where a session's commands run, shared by the web\n * sandbox switcher and every timeline that labels command rows (\"on Cloud\n * sandbox · …\"). No DOM, no React.\n */\nimport type { SandboxBackend } from \"@opengeni/sdk\";\nimport type { MachineView } from \"./types/machines\";\n\nexport const CLOUD_SANDBOX_LABEL = \"Cloud sandbox\";\nexport const NO_SANDBOX_LABEL = \"No sandbox\";\nexport const LOCAL_SANDBOX_LABEL = \"Local sandbox\";\n\n/**\n * User-facing name for a session's own managed box. Hosting vendors (Modal,\n * Daytona, ...) are deployment detail, not something a user chose, so hosted\n * providers read as the neutral \"Cloud sandbox\" and the local-dev Docker box as\n * \"Local sandbox\". The local backend runs directly on the host, so it keeps the\n * honest \"this computer\" instead of implying isolation. Connected Machines keep\n * their own names.\n */\nexport function sessionSandboxLabel(backend: SandboxBackend | string): string {\n if (backend === \"none\") return NO_SANDBOX_LABEL;\n if (backend === \"local\") return \"this computer\";\n if (backend === \"docker\") return LOCAL_SANDBOX_LABEL;\n return CLOUD_SANDBOX_LABEL;\n}\n\n/** Display name for a fleet row: the session's own box never shows its vendor. */\nexport function machineDisplayName(\n machine: Pick<MachineView, \"isSessionGroup\" | \"kind\" | \"name\">,\n): string {\n return machine.isSessionGroup ? sessionSandboxLabel(machine.kind) : machine.name;\n}\n\n/** The compute label a session timeline shows: the active machine, else the cloud box. */\nexport function sessionComputeLabel(\n machines: readonly Pick<MachineView, \"active\" | \"isSessionGroup\" | \"kind\" | \"name\">[],\n): string {\n const active = machines.find((machine) => machine.active);\n return active ? machineDisplayName(active) : CLOUD_SANDBOX_LABEL;\n}\n"],"mappings":";;;AAQO,IAAM,sBAAsB;AAC5B,IAAM,mBAAmB;AACzB,IAAM,sBAAsB;AAU5B,SAAS,oBAAoB,SAA0C;AAC5E,MAAI,YAAY,OAAQ,QAAO;AAC/B,MAAI,YAAY,QAAS,QAAO;AAChC,MAAI,YAAY,SAAU,QAAO;AACjC,SAAO;AACT;AAGO,SAAS,mBACd,SACQ;AACR,SAAO,QAAQ,iBAAiB,oBAAoB,QAAQ,IAAI,IAAI,QAAQ;AAC9E;AAGO,SAAS,oBACd,UACQ;AACR,QAAM,SAAS,SAAS,KAAK,CAAC,YAAY,QAAQ,MAAM;AACxD,SAAO,SAAS,mBAAmB,MAAM,IAAI;AAC/C;","names":[]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { LineageNode, SessionGoal } from "@opengeni/sdk";
|
|
2
|
+
export type SessionAgentsSignal = {
|
|
3
|
+
count: number;
|
|
4
|
+
detail: string;
|
|
5
|
+
tone: "running" | "waiting" | "neutral";
|
|
6
|
+
};
|
|
7
|
+
/** The agents chip for a session's spawned workers, or undefined without any. */
|
|
8
|
+
export declare function sessionAgentsSignal(agents: readonly Pick<LineageNode, "session">[]): SessionAgentsSignal | undefined;
|
|
9
|
+
/** One human word for a goal's state, as the web goal pill reads. */
|
|
10
|
+
export declare function sessionGoalStateLabel(goal: Pick<SessionGoal, "status">): string;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
// src/session-agents-model.ts
|
|
4
|
+
function sessionAgentsSignal(agents) {
|
|
5
|
+
if (agents.length === 0) return void 0;
|
|
6
|
+
const running = agents.filter(
|
|
7
|
+
(node) => node.session.status === "running" && node.session.effectiveControl.state === "active"
|
|
8
|
+
).length;
|
|
9
|
+
const paused = agents.filter((node) => node.session.effectiveControl.state === "paused").length;
|
|
10
|
+
return {
|
|
11
|
+
count: agents.length,
|
|
12
|
+
detail: running > 0 ? `${running} running` : paused > 0 ? `${paused} paused` : "Idle",
|
|
13
|
+
tone: running > 0 ? "running" : paused > 0 ? "waiting" : "neutral"
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
function sessionGoalStateLabel(goal) {
|
|
17
|
+
if (goal.status === "completed") return "Completed";
|
|
18
|
+
if (goal.status === "paused") return "Paused";
|
|
19
|
+
return "Active";
|
|
20
|
+
}
|
|
21
|
+
export {
|
|
22
|
+
sessionAgentsSignal,
|
|
23
|
+
sessionGoalStateLabel
|
|
24
|
+
};
|
|
25
|
+
//# sourceMappingURL=session-agents-model.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/session-agents-model.ts"],"sourcesContent":["import type { LineageNode, SessionGoal } from \"@opengeni/sdk\";\n\n/* Renderer-neutral session chrome signals shared by the web dock and native\n apps: the sub-agents chip and the goal chip. */\n\nexport type SessionAgentsSignal = {\n count: number;\n detail: string;\n tone: \"running\" | \"waiting\" | \"neutral\";\n};\n\n/** The agents chip for a session's spawned workers, or undefined without any. */\nexport function sessionAgentsSignal(\n agents: readonly Pick<LineageNode, \"session\">[],\n): SessionAgentsSignal | undefined {\n if (agents.length === 0) return undefined;\n const running = agents.filter(\n (node) => node.session.status === \"running\" && node.session.effectiveControl.state === \"active\",\n ).length;\n const paused = agents.filter((node) => node.session.effectiveControl.state === \"paused\").length;\n return {\n count: agents.length,\n detail: running > 0 ? `${running} running` : paused > 0 ? `${paused} paused` : \"Idle\",\n tone: running > 0 ? \"running\" : paused > 0 ? \"waiting\" : \"neutral\",\n };\n}\n\n/** One human word for a goal's state, as the web goal pill reads. */\nexport function sessionGoalStateLabel(goal: Pick<SessionGoal, \"status\">): string {\n if (goal.status === \"completed\") return \"Completed\";\n if (goal.status === \"paused\") return \"Paused\";\n return \"Active\";\n}\n"],"mappings":";;;AAYO,SAAS,oBACd,QACiC;AACjC,MAAI,OAAO,WAAW,EAAG,QAAO;AAChC,QAAM,UAAU,OAAO;AAAA,IACrB,CAAC,SAAS,KAAK,QAAQ,WAAW,aAAa,KAAK,QAAQ,iBAAiB,UAAU;AAAA,EACzF,EAAE;AACF,QAAM,SAAS,OAAO,OAAO,CAAC,SAAS,KAAK,QAAQ,iBAAiB,UAAU,QAAQ,EAAE;AACzF,SAAO;AAAA,IACL,OAAO,OAAO;AAAA,IACd,QAAQ,UAAU,IAAI,GAAG,OAAO,aAAa,SAAS,IAAI,GAAG,MAAM,YAAY;AAAA,IAC/E,MAAM,UAAU,IAAI,YAAY,SAAS,IAAI,YAAY;AAAA,EAC3D;AACF;AAGO,SAAS,sBAAsB,MAA2C;AAC/E,MAAI,KAAK,WAAW,YAAa,QAAO;AACxC,MAAI,KAAK,WAAW,SAAU,QAAO;AACrC,SAAO;AACT;","names":[]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { SessionEvent } from "@opengeni/sdk";
|
|
2
|
+
export declare const SESSION_ATTENTION_EVENT_TYPES: ReadonlySet<string>;
|
|
3
|
+
/**
|
|
4
|
+
* The latest delivered attention boundary, independent of raw token activity.
|
|
5
|
+
* A foreground reader acknowledges through this sequence, so streaming flushes
|
|
6
|
+
* never cause a personal-state write and later activity stays unread.
|
|
7
|
+
*/
|
|
8
|
+
export declare function sessionAttentionReadThroughSequence(events: readonly SessionEvent[]): number;
|