@opengeni/react 0.48.0 → 0.52.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 +90 -2
- package/dist/artifacts-document.d.ts +3 -0
- package/dist/artifacts-document.js +17 -0
- package/dist/artifacts-document.js.map +1 -0
- package/dist/artifacts-presentation.d.ts +3 -0
- package/dist/artifacts-presentation.js +17 -0
- package/dist/artifacts-presentation.js.map +1 -0
- package/dist/artifacts-spreadsheet.d.ts +3 -0
- package/dist/artifacts-spreadsheet.js +17 -0
- package/dist/artifacts-spreadsheet.js.map +1 -0
- package/dist/artifacts.d.ts +2 -0
- package/dist/artifacts.js +170 -0
- package/dist/artifacts.js.map +1 -0
- package/dist/chunk-6BBWWOOU.js +82 -0
- package/dist/chunk-6BBWWOOU.js.map +1 -0
- package/dist/{chunk-FWXGSNXT.js → chunk-724BW4TW.js} +585 -34
- package/dist/chunk-724BW4TW.js.map +1 -0
- package/dist/chunk-7I2KB3OK.js +3895 -0
- package/dist/chunk-7I2KB3OK.js.map +1 -0
- package/dist/chunk-7WCLAEFV.js +2828 -0
- package/dist/chunk-7WCLAEFV.js.map +1 -0
- package/dist/{chunk-I4MPFDRP.js → chunk-FWS3KC3Z.js} +3 -3
- package/dist/{chunk-EKZH6IDG.js → chunk-HDBG7XGO.js} +62 -1
- package/dist/chunk-HDBG7XGO.js.map +1 -0
- package/dist/chunk-HUIKIDM5.js +2148 -0
- package/dist/chunk-HUIKIDM5.js.map +1 -0
- package/dist/{chunk-XCNTXWBB.js → chunk-JAGDUCZQ.js} +854 -340
- package/dist/chunk-JAGDUCZQ.js.map +1 -0
- package/dist/{chunk-LHLYWG5R.js → chunk-JR3QFY6B.js} +413 -37
- package/dist/chunk-JR3QFY6B.js.map +1 -0
- package/dist/chunk-JVYQRRC4.js +53 -0
- package/dist/chunk-JVYQRRC4.js.map +1 -0
- package/dist/chunk-KCGXPP5V.js +157 -0
- package/dist/chunk-KCGXPP5V.js.map +1 -0
- package/dist/chunk-PEI6RANI.js +3234 -0
- package/dist/chunk-PEI6RANI.js.map +1 -0
- package/dist/{chunk-NJ7M2B6Z.js → chunk-ROIRTM37.js} +18 -10
- package/dist/{chunk-NJ7M2B6Z.js.map → chunk-ROIRTM37.js.map} +1 -1
- package/dist/{chunk-O4VXOBGF.js → chunk-WSK7G5LE.js} +70 -2
- package/dist/chunk-WSK7G5LE.js.map +1 -0
- package/dist/{chunk-OL6QVXGF.js → chunk-X4S56Y2H.js} +27 -7
- package/dist/{chunk-OL6QVXGF.js.map → chunk-X4S56Y2H.js.map} +1 -1
- package/dist/client.d.ts +7 -1
- package/dist/clipboard.d.ts +1 -0
- package/dist/clipboard.js +7 -0
- package/dist/clipboard.js.map +1 -0
- package/dist/commands/index.d.ts +3 -3
- package/dist/commands/registry.d.ts +1 -1
- package/dist/commands/types.d.ts +1 -1
- package/dist/components/approval-surface.d.ts +2 -2
- package/dist/components/artifacts/artifact-surface.d.ts +18 -0
- package/dist/components/artifacts/document-editor.d.ts +172 -0
- package/dist/components/artifacts/editable-artifact-ui.d.ts +13 -0
- package/dist/components/artifacts/editable-artifact-workbench.d.ts +49 -0
- package/dist/components/artifacts/editable-document.d.ts +24 -0
- package/dist/components/artifacts/editable-presentation.d.ts +24 -0
- package/dist/components/artifacts/editable-spreadsheet.d.ts +32 -0
- package/dist/components/artifacts/index.d.ts +8 -0
- package/dist/components/artifacts/presentation-editor.d.ts +297 -0
- package/dist/components/artifacts/spreadsheet-canvas.d.ts +120 -0
- package/dist/components/artifacts/spreadsheet-grid.d.ts +113 -0
- package/dist/components/browser-viewer.d.ts +29 -0
- package/dist/components/chat-composer.d.ts +8 -8
- package/dist/components/code-editor.d.ts +25 -3
- package/dist/components/command-palette.d.ts +2 -2
- package/dist/components/composer-transcription-control.d.ts +2 -2
- package/dist/components/composer.d.ts +17 -17
- package/dist/components/computer-viewer.d.ts +23 -0
- package/dist/components/copy-button.d.ts +2 -2
- package/dist/components/desktop-viewer.d.ts +25 -21
- package/dist/components/diff-view.d.ts +1 -1
- package/dist/components/enrollment-consent.d.ts +1 -1
- package/dist/components/enrollment-device-flow.d.ts +1 -1
- package/dist/components/file-browser.d.ts +2 -2
- package/dist/components/fleet-tile.d.ts +1 -1
- package/dist/components/generated-video-player.d.ts +10 -0
- package/dist/components/human-input-form.d.ts +1 -1
- package/dist/components/human-input-surface.d.ts +2 -2
- package/dist/components/interactive-workbench-viewers.d.ts +2 -0
- package/dist/components/machine-card.d.ts +2 -2
- package/dist/components/machine-dock-bar.d.ts +3 -3
- package/dist/components/machine-health-pill.d.ts +2 -2
- package/dist/components/machine-input-display.d.ts +1 -1
- package/dist/components/machine-metrics.d.ts +2 -2
- package/dist/components/machine-status-pill.d.ts +4 -4
- package/dist/components/machines/health.d.ts +1 -1
- package/dist/components/machines/machine-detail.d.ts +3 -3
- package/dist/components/machines/metric-history-chart.d.ts +1 -1
- package/dist/components/machines/metric-sparkline.d.ts +2 -2
- package/dist/components/machines/series.d.ts +2 -2
- package/dist/components/machines-dashboard.d.ts +2 -2
- package/dist/components/markdown.d.ts +1 -1
- package/dist/components/message-timeline.d.ts +12 -5
- package/dist/components/model-picker.d.ts +2 -2
- package/dist/components/model-policy-picker.d.ts +7 -7
- package/dist/components/pierre-diff.d.ts +1 -1
- package/dist/components/pierre-file.d.ts +1 -1
- package/dist/components/queue-draft-policy.d.ts +1 -1
- package/dist/components/queue-surface-implementation.d.ts +3 -3
- package/dist/components/queue-surface-state.d.ts +4 -4
- package/dist/components/queue-surface.d.ts +5 -5
- package/dist/components/sandbox-files.d.ts +3 -3
- package/dist/components/sandbox-terminal.d.ts +21 -4
- package/dist/components/sandbox-workspace.d.ts +25 -9
- package/dist/components/session-chrome.d.ts +4 -4
- package/dist/components/session-status.d.ts +2 -2
- package/dist/components/timeline-annotation-selection.d.ts +9 -0
- package/dist/components/timeline-annotations-dialog.d.ts +16 -0
- package/dist/components/timeline-annotations.d.ts +13 -0
- package/dist/components/tooltip.d.ts +4 -4
- package/dist/components/user-message-body.d.ts +2 -2
- package/dist/components/workbench-changes.d.ts +2 -2
- package/dist/components/workspace-dock.d.ts +1 -1
- package/dist/composer.d.ts +11 -11
- package/dist/composer.js +5 -5
- package/dist/hooks/internal.d.ts +1 -1
- package/dist/hooks/use-attached-browsers.d.ts +21 -0
- package/dist/hooks/use-available-models.d.ts +2 -2
- package/dist/hooks/use-billing-usage.d.ts +1 -1
- package/dist/hooks/use-browser-frame-stream.d.ts +28 -0
- package/dist/hooks/use-browser-identities.d.ts +26 -0
- package/dist/hooks/use-browser-session.d.ts +28 -0
- package/dist/hooks/use-browser-sessions.d.ts +32 -0
- package/dist/hooks/use-codex-accounts.d.ts +2 -2
- package/dist/hooks/use-composer.d.ts +36 -9
- package/dist/hooks/use-computer-frame-stream.d.ts +24 -0
- package/dist/hooks/use-computer-session.d.ts +28 -0
- package/dist/hooks/use-computer-sessions.d.ts +28 -0
- package/dist/hooks/use-desktop-stream.d.ts +1 -1
- package/dist/hooks/use-environments.d.ts +1 -1
- package/dist/hooks/use-file-attachments.d.ts +1 -1
- package/dist/hooks/use-goal.d.ts +2 -2
- package/dist/hooks/use-human-input.d.ts +2 -2
- package/dist/hooks/use-last-started-turn-policy.d.ts +2 -2
- package/dist/hooks/use-machine-chip.d.ts +2 -2
- package/dist/hooks/use-machines.d.ts +4 -4
- package/dist/hooks/use-packs.d.ts +7 -2
- package/dist/hooks/use-rigs.d.ts +1 -1
- package/dist/hooks/use-sandbox-files.d.ts +6 -4
- package/dist/hooks/use-sandbox-git.d.ts +6 -5
- package/dist/hooks/use-sandbox-terminal.d.ts +1 -1
- package/dist/hooks/use-scheduled-tasks.d.ts +1 -1
- package/dist/hooks/use-session-capabilities.d.ts +5 -4
- package/dist/hooks/use-session-control.d.ts +1 -1
- package/dist/hooks/use-session-events.d.ts +2 -2
- package/dist/hooks/use-session-lineage.d.ts +1 -1
- package/dist/hooks/use-session-mcp-approval-policy.d.ts +2 -2
- package/dist/hooks/use-session.d.ts +2 -2
- package/dist/hooks/use-slash-commands.d.ts +1 -1
- package/dist/hooks/use-terminal-stream.d.ts +8 -2
- package/dist/hooks/use-turn-queue.d.ts +2 -2
- package/dist/hooks/use-video-artifact-playback.d.ts +9 -0
- package/dist/hooks/use-voice-input.d.ts +1 -1
- package/dist/hooks/use-workspace-capture.d.ts +1 -1
- package/dist/hooks/use-workspace-edit.d.ts +1 -1
- package/dist/hooks/use-workspace-sessions.d.ts +1 -1
- package/dist/hooks/use-workspaces.d.ts +1 -1
- package/dist/index.d.ts +158 -155
- package/dist/index.js +906 -462
- package/dist/index.js.map +1 -1
- package/dist/interaction.d.ts +23 -0
- package/dist/interaction.js +36 -0
- package/dist/interaction.js.map +1 -0
- package/dist/interactive-workbench-viewers-KHNOHWQE.js +13 -0
- package/dist/interactive-workbench-viewers-KHNOHWQE.js.map +1 -0
- package/dist/lib/relay-wire.d.ts +4 -0
- package/dist/lib/sandbox-liveness.d.ts +9 -0
- package/dist/lib/terminal-capability.d.ts +5 -0
- package/dist/lib/xterm-theme.d.ts +1 -1
- package/dist/machines.d.ts +30 -30
- package/dist/machines.js +3 -3
- package/dist/provider.d.ts +4 -4
- package/dist/{queue-surface-implementation-U5JFG7HT.js → queue-surface-implementation-2KVJTYXH.js} +100 -48
- package/dist/queue-surface-implementation-2KVJTYXH.js.map +1 -0
- package/dist/realtime/dropdown-menu.d.ts +8 -8
- package/dist/realtime/realtime-control.d.ts +6 -6
- package/dist/realtime.d.ts +4 -4
- package/dist/realtime.js +3 -3
- package/dist/session-context.d.ts +19 -1
- package/dist/session-ui.d.ts +14 -14
- package/dist/session-ui.js +5 -4
- package/dist/session.d.ts +28 -28
- package/dist/session.js +5 -5
- package/dist/timeline/activity-rail.d.ts +5 -3
- package/dist/timeline/disclosure-context.d.ts +1 -1
- package/dist/timeline/fleet-decision-projection.d.ts +1 -1
- package/dist/timeline/fleet-decision-row.d.ts +3 -3
- package/dist/timeline/index.d.ts +19 -19
- package/dist/timeline/parsers.d.ts +4 -1
- package/dist/timeline/projection.d.ts +3 -3
- package/dist/timeline/registry.d.ts +8 -2
- package/dist/timeline/screenshot-lightbox.d.ts +2 -2
- package/dist/timeline/shared.d.ts +21 -10
- package/dist/timeline/tool-diff.d.ts +2 -2
- package/dist/timeline/tool-renderers.d.ts +1 -1
- package/dist/timeline/turn-summary.d.ts +3 -3
- package/dist/timeline/types.d.ts +39 -3
- package/dist/timeline-annotation-selection-3L7LHGG2.js +187 -0
- package/dist/timeline-annotation-selection-3L7LHGG2.js.map +1 -0
- package/dist/timeline-annotations-dialog-U7EVLR75.js +196 -0
- package/dist/timeline-annotations-dialog-U7EVLR75.js.map +1 -0
- package/package.json +36 -7
- package/src/artifacts-document.ts +31 -0
- package/src/artifacts-presentation.ts +36 -0
- package/src/artifacts-spreadsheet.ts +21 -0
- package/src/artifacts.ts +86 -0
- package/src/client.ts +87 -1
- package/src/clipboard.ts +2 -0
- package/src/components/artifacts/artifact-surface.tsx +93 -0
- package/src/components/artifacts/document-editor.tsx +2255 -0
- package/src/components/artifacts/editable-artifact-ui.tsx +89 -0
- package/src/components/artifacts/editable-artifact-workbench.tsx +203 -0
- package/src/components/artifacts/editable-document.tsx +657 -0
- package/src/components/artifacts/editable-presentation.tsx +1020 -0
- package/src/components/artifacts/editable-spreadsheet.tsx +733 -0
- package/src/components/artifacts/index.ts +99 -0
- package/src/components/artifacts/presentation-editor.tsx +3148 -0
- package/src/components/artifacts/spreadsheet-canvas.ts +799 -0
- package/src/components/artifacts/spreadsheet-grid.tsx +2129 -0
- package/src/components/browser-viewer.tsx +1592 -0
- package/src/components/chat-composer.tsx +13 -0
- package/src/components/code-editor.tsx +89 -30
- package/src/components/composer-transcription-control.tsx +10 -6
- package/src/components/computer-viewer.tsx +1139 -0
- package/src/components/desktop-viewer.tsx +101 -73
- package/src/components/generated-video-player.tsx +89 -0
- package/src/components/interactive-workbench-viewers.ts +2 -0
- package/src/components/machine-input-display.ts +3 -0
- package/src/components/message-timeline.tsx +289 -32
- package/src/components/queue-surface-implementation.tsx +116 -60
- package/src/components/sandbox-files.tsx +2 -2
- package/src/components/sandbox-terminal.tsx +106 -41
- package/src/components/sandbox-workspace.tsx +215 -87
- package/src/components/session-chrome.tsx +53 -13
- package/src/components/timeline-annotation-selection.tsx +221 -0
- package/src/components/timeline-annotations-dialog.tsx +213 -0
- package/src/components/timeline-annotations.tsx +84 -0
- package/src/components/workbench-changes.tsx +188 -31
- package/src/hooks/use-attached-browsers.ts +152 -0
- package/src/hooks/use-browser-frame-stream.ts +316 -0
- package/src/hooks/use-browser-identities.ts +225 -0
- package/src/hooks/use-browser-session.ts +476 -0
- package/src/hooks/use-browser-sessions.ts +281 -0
- package/src/hooks/use-composer.ts +769 -24
- package/src/hooks/use-computer-frame-stream.ts +311 -0
- package/src/hooks/use-computer-session.ts +442 -0
- package/src/hooks/use-computer-sessions.ts +245 -0
- package/src/hooks/use-machine-chip.ts +5 -3
- package/src/hooks/use-machines.ts +33 -3
- package/src/hooks/use-packs.ts +51 -0
- package/src/hooks/use-sandbox-files.ts +98 -55
- package/src/hooks/use-sandbox-git.ts +93 -38
- package/src/hooks/use-sandbox-terminal.ts +3 -2
- package/src/hooks/use-session-capabilities.ts +59 -46
- package/src/hooks/use-terminal-stream.ts +102 -23
- package/src/hooks/use-video-artifact-playback.ts +28 -0
- package/src/hooks/use-workspace-edit.ts +2 -1
- package/src/index.ts +10 -0
- package/src/interaction.ts +71 -0
- package/src/lib/relay-wire.ts +4 -0
- package/src/lib/sandbox-liveness.ts +11 -0
- package/src/lib/terminal-capability.ts +10 -0
- package/src/session-context.ts +90 -0
- package/src/timeline/activity-rail.tsx +19 -3
- package/src/timeline/index.ts +3 -0
- package/src/timeline/parsers.ts +14 -1
- package/src/timeline/projection.ts +211 -14
- package/src/timeline/registry.ts +13 -1
- package/src/timeline/screenshot-lightbox.tsx +19 -9
- package/src/timeline/shared.tsx +56 -8
- package/src/timeline/tool-renderers.tsx +303 -50
- package/src/timeline/types.ts +55 -3
- package/styles/compiled.css +248 -15
- package/styles/index.css +15 -0
- package/styles/responsive.css +13 -1
- package/dist/chunk-EKZH6IDG.js.map +0 -1
- package/dist/chunk-FWXGSNXT.js.map +0 -1
- package/dist/chunk-LHLYWG5R.js.map +0 -1
- package/dist/chunk-O4VXOBGF.js.map +0 -1
- package/dist/chunk-XCNTXWBB.js.map +0 -1
- package/dist/fleet-decision-projection-SLNZMS42.js +0 -241
- package/dist/fleet-decision-projection-SLNZMS42.js.map +0 -1
- package/dist/queue-surface-implementation-U5JFG7HT.js.map +0 -1
- /package/dist/{chunk-I4MPFDRP.js.map → chunk-FWS3KC3Z.js.map} +0 -0
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
verticalListSortingStrategy,
|
|
17
17
|
} from "@dnd-kit/sortable";
|
|
18
18
|
import { CSS } from "@dnd-kit/utilities";
|
|
19
|
-
import type { SessionPendingInputPreview, SessionTurn } from "@opengeni/sdk";
|
|
19
|
+
import type { SessionPendingInputPreview, SessionTurn, TimelineAnnotation } from "@opengeni/sdk";
|
|
20
20
|
import {
|
|
21
21
|
ArrowDownToLineIcon,
|
|
22
22
|
ArrowUpToLineIcon,
|
|
@@ -46,6 +46,7 @@ import {
|
|
|
46
46
|
} from "../lib/use-portal-token-style";
|
|
47
47
|
import { requestQueueDraftEdit } from "./queue-draft-policy";
|
|
48
48
|
import { QueueErrorAlert, QueueStoppingStatus } from "./queue-surface-state";
|
|
49
|
+
import { TimelineAnnotationsChip } from "./timeline-annotations";
|
|
49
50
|
|
|
50
51
|
/** The sole pending-input surface: compact above Goal, Agents, and composer. */
|
|
51
52
|
type QueueSurfaceCommonProps = {
|
|
@@ -99,14 +100,15 @@ export function QueueSurface({
|
|
|
99
100
|
(input) => !attachedInputIds.includes(input.id),
|
|
100
101
|
);
|
|
101
102
|
const canEditInComposer = queueComposerCheckoutEnabled(composer, readOnly);
|
|
102
|
-
const collapsedPreview = useMemo(
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
103
|
+
const collapsedPreview = useMemo(() => {
|
|
104
|
+
const firstTurn = queue.queue[0];
|
|
105
|
+
return firstTurn
|
|
106
|
+
? queueTurnPreview(firstTurn, QUEUE_COLLAPSED_PREVIEW_CHARACTERS)
|
|
107
|
+
: queuePromptPreview(
|
|
108
|
+
queue.pendingInputs[0]?.summary ?? "",
|
|
109
|
+
QUEUE_COLLAPSED_PREVIEW_CHARACTERS,
|
|
110
|
+
);
|
|
111
|
+
}, [queue.pendingInputs, queue.queue]);
|
|
110
112
|
const sensors = useSensors(useSensor(PointerSensor, { activationConstraint: { distance: 6 } }));
|
|
111
113
|
|
|
112
114
|
const displayedQueue = useMemo(() => {
|
|
@@ -409,8 +411,8 @@ export function QueueSurface({
|
|
|
409
411
|
dir="auto"
|
|
410
412
|
>
|
|
411
413
|
{
|
|
412
|
-
|
|
413
|
-
queue.queue.find((turn) => turn.id === draggedTurnId)
|
|
414
|
+
queueTurnPreview(
|
|
415
|
+
queue.queue.find((turn) => turn.id === draggedTurnId),
|
|
414
416
|
QUEUE_ROW_PREVIEW_CHARACTERS,
|
|
415
417
|
).summary
|
|
416
418
|
}
|
|
@@ -490,6 +492,29 @@ type QueuePromptPreview = {
|
|
|
490
492
|
isFallback: boolean;
|
|
491
493
|
};
|
|
492
494
|
|
|
495
|
+
function annotationOnlyQueuePreview(count: number): QueuePromptPreview {
|
|
496
|
+
const summary = `${count} timeline ${count === 1 ? "annotation" : "annotations"}`;
|
|
497
|
+
return {
|
|
498
|
+
summary,
|
|
499
|
+
collapsedVisual: summary,
|
|
500
|
+
visibleStart: summary,
|
|
501
|
+
visibleIdentity: null,
|
|
502
|
+
visibleIdentityLabel: null,
|
|
503
|
+
isFallback: false,
|
|
504
|
+
};
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
function queueTurnPreview(
|
|
508
|
+
turn: SessionTurn | undefined,
|
|
509
|
+
maxCharacters: number,
|
|
510
|
+
): QueuePromptPreview {
|
|
511
|
+
if (!turn) return queuePromptPreview("", maxCharacters);
|
|
512
|
+
const annotations = turn.annotations ?? [];
|
|
513
|
+
return turn.prompt.length === 0 && annotations.length > 0
|
|
514
|
+
? annotationOnlyQueuePreview(annotations.length)
|
|
515
|
+
: queuePromptPreview(turn.prompt, maxCharacters);
|
|
516
|
+
}
|
|
517
|
+
|
|
493
518
|
/**
|
|
494
519
|
* Build a bounded head/tail summary of an arbitrary queued prompt. Sampling
|
|
495
520
|
* both ends distinguishes prompts with equal long prefixes. Each sampled edge
|
|
@@ -752,73 +777,94 @@ function isLowSurrogate(codeUnit: number): boolean {
|
|
|
752
777
|
|
|
753
778
|
function QueuePrompt({
|
|
754
779
|
prompt,
|
|
780
|
+
annotations,
|
|
755
781
|
index,
|
|
756
782
|
onDisclosureChange,
|
|
757
783
|
}: {
|
|
758
784
|
prompt: string;
|
|
785
|
+
annotations: readonly TimelineAnnotation[];
|
|
759
786
|
index: number;
|
|
760
787
|
onDisclosureChange: (expanded: boolean) => void;
|
|
761
788
|
}) {
|
|
762
789
|
const [expanded, setExpanded] = useState(false);
|
|
763
790
|
const fullContentId = useId();
|
|
764
|
-
const preview = useMemo(
|
|
791
|
+
const preview = useMemo(
|
|
792
|
+
() =>
|
|
793
|
+
prompt.length === 0 && annotations.length > 0
|
|
794
|
+
? annotationOnlyQueuePreview(annotations.length)
|
|
795
|
+
: queuePromptPreview(prompt, QUEUE_ROW_PREVIEW_CHARACTERS),
|
|
796
|
+
[annotations.length, prompt],
|
|
797
|
+
);
|
|
765
798
|
|
|
766
799
|
return (
|
|
767
800
|
<div className="w-full min-w-0 max-w-full">
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
801
|
+
{prompt ? (
|
|
802
|
+
<div
|
|
803
|
+
aria-label={`Queued prompt ${index + 1} summary: ${preview.summary}`}
|
|
804
|
+
className="max-w-full overflow-hidden text-og-control leading-5 text-fg"
|
|
805
|
+
data-testid={`queue-prompt-preview-${index + 1}`}
|
|
806
|
+
dir="auto"
|
|
807
|
+
role="note"
|
|
808
|
+
>
|
|
776
809
|
<span
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
dir="auto"
|
|
810
|
+
aria-hidden="true"
|
|
811
|
+
className="flex min-w-0 max-w-full items-baseline gap-2 sm:block"
|
|
780
812
|
>
|
|
781
|
-
{preview.visibleStart}
|
|
782
|
-
</span>
|
|
783
|
-
{preview.visibleIdentity && preview.visibleIdentityLabel ? (
|
|
784
813
|
<span
|
|
785
|
-
className="
|
|
786
|
-
data-testid={`queue-prompt-
|
|
814
|
+
className={`${preview.isFallback ? "" : "line-clamp-1 sm:line-clamp-2"} min-w-0 flex-1 whitespace-pre-wrap break-all [unicode-bidi:plaintext]`}
|
|
815
|
+
data-testid={`queue-prompt-start-${index + 1}`}
|
|
816
|
+
dir="auto"
|
|
787
817
|
>
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
818
|
+
{preview.visibleStart}
|
|
819
|
+
</span>
|
|
820
|
+
{preview.visibleIdentity && preview.visibleIdentityLabel ? (
|
|
791
821
|
<span
|
|
792
|
-
className="min-w-0
|
|
793
|
-
data-testid={`queue-prompt-identity-${index + 1}`}
|
|
794
|
-
dir="auto"
|
|
822
|
+
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"
|
|
823
|
+
data-testid={`queue-prompt-identity-row-${index + 1}`}
|
|
795
824
|
>
|
|
796
|
-
|
|
825
|
+
<span className="shrink-0 font-medium text-fg-subtle">
|
|
826
|
+
{preview.visibleIdentityLabel}
|
|
827
|
+
</span>
|
|
828
|
+
<span
|
|
829
|
+
className="min-w-0 overflow-hidden text-ellipsis whitespace-nowrap font-mono [unicode-bidi:plaintext]"
|
|
830
|
+
data-testid={`queue-prompt-identity-${index + 1}`}
|
|
831
|
+
dir="auto"
|
|
832
|
+
>
|
|
833
|
+
{preview.visibleIdentity}
|
|
834
|
+
</span>
|
|
797
835
|
</span>
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
</
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
aria-label={`${expanded ? "Hide" : "Show"} full content for queued prompt ${index + 1}`}
|
|
807
|
-
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]"
|
|
808
|
-
data-testid={`queue-prompt-disclosure-${index + 1}`}
|
|
809
|
-
onClick={() => {
|
|
810
|
-
const next = !expanded;
|
|
811
|
-
setExpanded(next);
|
|
812
|
-
onDisclosureChange(next);
|
|
813
|
-
}}
|
|
814
|
-
>
|
|
815
|
-
<ChevronDownIcon
|
|
816
|
-
aria-hidden="true"
|
|
817
|
-
className={`size-3 shrink-0 transition-transform ${expanded ? "rotate-180" : ""}`}
|
|
836
|
+
) : null}
|
|
837
|
+
</span>
|
|
838
|
+
</div>
|
|
839
|
+
) : null}
|
|
840
|
+
{annotations.length > 0 ? (
|
|
841
|
+
<TimelineAnnotationsChip
|
|
842
|
+
annotations={annotations}
|
|
843
|
+
className={prompt ? "mt-1" : undefined}
|
|
818
844
|
/>
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
845
|
+
) : null}
|
|
846
|
+
{prompt ? (
|
|
847
|
+
<button
|
|
848
|
+
type="button"
|
|
849
|
+
aria-controls={fullContentId}
|
|
850
|
+
aria-expanded={expanded}
|
|
851
|
+
aria-label={`${expanded ? "Hide" : "Show"} full content for queued prompt ${index + 1}`}
|
|
852
|
+
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]"
|
|
853
|
+
data-testid={`queue-prompt-disclosure-${index + 1}`}
|
|
854
|
+
onClick={() => {
|
|
855
|
+
const next = !expanded;
|
|
856
|
+
setExpanded(next);
|
|
857
|
+
onDisclosureChange(next);
|
|
858
|
+
}}
|
|
859
|
+
>
|
|
860
|
+
<ChevronDownIcon
|
|
861
|
+
aria-hidden="true"
|
|
862
|
+
className={`size-3 shrink-0 transition-transform ${expanded ? "rotate-180" : ""}`}
|
|
863
|
+
/>
|
|
864
|
+
{expanded ? "Hide full prompt" : "View full prompt"}
|
|
865
|
+
</button>
|
|
866
|
+
) : null}
|
|
867
|
+
{expanded && prompt ? (
|
|
822
868
|
<pre
|
|
823
869
|
id={fullContentId}
|
|
824
870
|
role="region"
|
|
@@ -850,7 +896,12 @@ function ReadOnlyQueueRow({
|
|
|
850
896
|
<li className="flex min-w-0 items-start gap-2 bg-surface px-3 py-2">
|
|
851
897
|
<span className="mt-1 shrink-0 font-mono text-og-xs text-fg-subtle">{index + 1}</span>
|
|
852
898
|
<div className="min-w-0 flex-1">
|
|
853
|
-
<QueuePrompt
|
|
899
|
+
<QueuePrompt
|
|
900
|
+
prompt={turn.prompt}
|
|
901
|
+
annotations={turn.annotations ?? []}
|
|
902
|
+
index={index}
|
|
903
|
+
onDisclosureChange={onDisclosureChange}
|
|
904
|
+
/>
|
|
854
905
|
{attachedInputs.length > 0 ? (
|
|
855
906
|
<PendingMachineInputs inputs={attachedInputs} attached />
|
|
856
907
|
) : null}
|
|
@@ -941,7 +992,12 @@ function SortableQueueRow({
|
|
|
941
992
|
{index + 1}
|
|
942
993
|
</span>
|
|
943
994
|
<div className="col-span-full row-start-2 min-w-0 sm:col-span-1 sm:col-start-3 sm:row-start-1">
|
|
944
|
-
<QueuePrompt
|
|
995
|
+
<QueuePrompt
|
|
996
|
+
prompt={turn.prompt}
|
|
997
|
+
annotations={turn.annotations ?? []}
|
|
998
|
+
index={index}
|
|
999
|
+
onDisclosureChange={onDisclosureChange}
|
|
1000
|
+
/>
|
|
945
1001
|
{attachedInputs.length > 0 ? (
|
|
946
1002
|
<PendingMachineInputs inputs={attachedInputs} attached />
|
|
947
1003
|
) : null}
|
|
@@ -319,8 +319,8 @@ export function SandboxFiles({
|
|
|
319
319
|
path={viewPath}
|
|
320
320
|
initialContents={fileView.content}
|
|
321
321
|
themeType={resolvedTheme}
|
|
322
|
-
onSave={(contents) =>
|
|
323
|
-
files.writeFile(viewPath, contents, { expectedContent:
|
|
322
|
+
onSave={(contents, expectedContents) =>
|
|
323
|
+
files.writeFile(viewPath, contents, { expectedContent: expectedContents })
|
|
324
324
|
}
|
|
325
325
|
onOverwrite={(contents) => files.writeFile(viewPath, contents, { force: true })}
|
|
326
326
|
onReload={() => setViewReloadRevision((revision) => revision + 1)}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import type { TerminalCapability } from "@opengeni/sdk";
|
|
2
2
|
import { type ReactNode, useEffect, useRef, useState } from "react";
|
|
3
3
|
import { cn } from "../lib/cn";
|
|
4
|
-
import { useTerminalStream } from "../hooks/use-terminal-stream";
|
|
4
|
+
import { type TerminalStreamStatus, useTerminalStream } from "../hooks/use-terminal-stream";
|
|
5
5
|
import type { UseSandboxTerminalResult } from "../hooks/use-sandbox-terminal";
|
|
6
6
|
import { resolveTerminalFont, xtermThemeFromTokens } from "../lib/xterm-theme";
|
|
7
|
+
import { sandboxAcceptsLiveIo } from "../lib/sandbox-liveness";
|
|
8
|
+
import { terminalCanAcquirePty } from "../lib/terminal-capability";
|
|
7
9
|
import { attachRenderer, type RendererLoaders, type RendererTier } from "../lib/xterm-renderer";
|
|
8
10
|
|
|
9
11
|
/**
|
|
@@ -60,7 +62,7 @@ export type SandboxTerminalProps = {
|
|
|
60
62
|
fontSize?: number | undefined;
|
|
61
63
|
/**
|
|
62
64
|
* Lease liveness (`cold` | `warming` | `warm` | `draining`). Drives the
|
|
63
|
-
* boot-in-terminal status lines: once the user has
|
|
65
|
+
* boot-in-terminal status lines: once the user has engaged the terminal and
|
|
64
66
|
* the box is not yet warm, a styled "● waking machine — Ns…" line is rendered
|
|
65
67
|
* INSIDE xterm (no overlay/spinner) until the live PTY connects.
|
|
66
68
|
*/
|
|
@@ -110,6 +112,44 @@ type XtermLike = {
|
|
|
110
112
|
};
|
|
111
113
|
type FitAddonLike = { fit: () => void };
|
|
112
114
|
|
|
115
|
+
export type TerminalSurfaceState =
|
|
116
|
+
| "loading"
|
|
117
|
+
| "connecting"
|
|
118
|
+
| "error"
|
|
119
|
+
| "waking"
|
|
120
|
+
| "output-only"
|
|
121
|
+
| "interactive";
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Stable semantic state for hosts and browser acceptance. The xterm helper
|
|
125
|
+
* textarea exists before the live PTY socket is ready, so its presence alone
|
|
126
|
+
* must never be treated as proof that keystrokes can reach the sandbox.
|
|
127
|
+
*/
|
|
128
|
+
export function terminalSurfaceState(input: {
|
|
129
|
+
ready: boolean;
|
|
130
|
+
acceptsInput: boolean;
|
|
131
|
+
inputPending: boolean;
|
|
132
|
+
ptyStatus: TerminalStreamStatus;
|
|
133
|
+
booting: boolean;
|
|
134
|
+
}): TerminalSurfaceState {
|
|
135
|
+
if (!input.ready) return "loading";
|
|
136
|
+
if (input.acceptsInput) return "interactive";
|
|
137
|
+
if (input.inputPending) return "connecting";
|
|
138
|
+
if (input.ptyStatus === "connecting") return "connecting";
|
|
139
|
+
if (input.ptyStatus === "error") return "error";
|
|
140
|
+
if (input.booting) return "waking";
|
|
141
|
+
return "output-only";
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export function subscribeTerminalInput(
|
|
145
|
+
term: Pick<XtermLike, "onData"> | null,
|
|
146
|
+
sink: ((data: string) => void) | null,
|
|
147
|
+
enabled: boolean,
|
|
148
|
+
): { dispose: () => void } | null {
|
|
149
|
+
if (!enabled || !term || !sink) return null;
|
|
150
|
+
return term.onData(sink);
|
|
151
|
+
}
|
|
152
|
+
|
|
113
153
|
/** Clear the transient wake line and put the first live prompt at cell 1,1.
|
|
114
154
|
* `Terminal.clear()` removes scrollback but deliberately preserves the cursor,
|
|
115
155
|
* which lets the first PTY frame append to the old wake message. */
|
|
@@ -193,50 +233,61 @@ export function SandboxTerminal({
|
|
|
193
233
|
const wroteFirehoseRef = useRef(false);
|
|
194
234
|
const bootActiveRef = useRef(false);
|
|
195
235
|
const [ready, setReady] = useState(false);
|
|
236
|
+
const [inputReady, setInputReady] = useState(false);
|
|
196
237
|
const [activated, setActivated] = useState(false);
|
|
197
238
|
|
|
198
239
|
// ── Interactive transport switch ─────────────────────────────────────────────
|
|
199
|
-
const
|
|
200
|
-
|
|
201
|
-
const ptyOutputQueueRef = useRef<string[]>([]);
|
|
240
|
+
const ptyDescriptor = terminalCapability?.transport === "pty-ws";
|
|
241
|
+
const ptyAttachable = terminalCanAcquirePty(terminalCapability);
|
|
202
242
|
const {
|
|
203
243
|
status: ptyStatus,
|
|
204
244
|
write: ptyWrite,
|
|
205
245
|
resize: resizePty,
|
|
206
246
|
connected: ptyConnected,
|
|
207
247
|
} = useTerminalStream({
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
248
|
+
// Connect only after xterm exists. This makes the renderer the sole output
|
|
249
|
+
// owner from the first websocket frame and removes an otherwise unbounded
|
|
250
|
+
// pre-mount output queue during large command bursts.
|
|
251
|
+
capability:
|
|
252
|
+
ptyAttachable && ready
|
|
253
|
+
? {
|
|
254
|
+
transport: "pty-ws",
|
|
255
|
+
url: ptyDescriptor ? terminalCapability!.url : null,
|
|
256
|
+
token: ptyDescriptor ? terminalCapability!.token : null,
|
|
257
|
+
expiresAt: ptyDescriptor ? terminalCapability!.expiresAt : null,
|
|
258
|
+
}
|
|
259
|
+
: null,
|
|
215
260
|
onOutput: (data) => {
|
|
216
|
-
|
|
217
|
-
if (term) term.write(data);
|
|
218
|
-
else ptyOutputQueueRef.current.push(data);
|
|
261
|
+
termRef.current?.write(data);
|
|
219
262
|
},
|
|
220
263
|
});
|
|
221
264
|
|
|
222
|
-
//
|
|
223
|
-
//
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
const
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
265
|
+
// A pty-ws capability exclusively owns the screen even while connecting or
|
|
266
|
+
// after a visible connection failure; never silently switch one terminal UI
|
|
267
|
+
// between two PTYs. Input is enabled during the handshake because the stream
|
|
268
|
+
// hook buffers it strictly and flushes only after ttyd auth succeeds.
|
|
269
|
+
const ptyMode = ptyDescriptor;
|
|
270
|
+
// Keep xterm stdin live for an attachable descriptor even before its URL has
|
|
271
|
+
// arrived. Focus/click triggers the grant; any immediately following input is
|
|
272
|
+
// bounded in the stream hook instead of disappearing in that HTTP interval.
|
|
273
|
+
const ptyCapturesInput = ptyAttachable && ptyStatus !== "error";
|
|
274
|
+
const interactive = !readOnly && (ptyAttachable ? ptyCapturesInput : result.write !== null);
|
|
275
|
+
// Public "interactive" means the mounted input subscription can reach a live
|
|
276
|
+
// PTY now. Before that point xterm still captures into the bounded queue, but
|
|
277
|
+
// acceptance and embedders see an explicit connecting state.
|
|
278
|
+
const acceptsInput = inputReady && (!ptyAttachable || ptyConnected);
|
|
279
|
+
const inputPending = inputReady && ptyAttachable && !ptyConnected && activated;
|
|
280
|
+
let terminalModeLabel: string | null;
|
|
281
|
+
if (readOnly) terminalModeLabel = "read-only";
|
|
282
|
+
else if (!ptyAttachable) terminalModeLabel = acceptsInput ? null : "output only";
|
|
283
|
+
else if (ptyStatus === "error") terminalModeLabel = "connection error";
|
|
284
|
+
else if (acceptsInput) terminalModeLabel = null;
|
|
285
|
+
else terminalModeLabel = activated ? "connecting" : "connect on input";
|
|
286
|
+
|
|
287
|
+
// Boot-in-terminal: after the user engages a not-yet-warm box, show styled
|
|
237
288
|
// status lines INSIDE xterm instead of an overlay — but only when there is no
|
|
238
289
|
// firehose transcript to show yet (otherwise the projected output is shown).
|
|
239
|
-
const warm = liveness
|
|
290
|
+
const warm = sandboxAcceptsLiveIo(liveness);
|
|
240
291
|
const booting =
|
|
241
292
|
activated &&
|
|
242
293
|
!ptyMode &&
|
|
@@ -244,6 +295,13 @@ export function SandboxTerminal({
|
|
|
244
295
|
liveness !== null &&
|
|
245
296
|
liveness !== undefined &&
|
|
246
297
|
result.chunks.length === 0;
|
|
298
|
+
const surfaceState = terminalSurfaceState({
|
|
299
|
+
ready,
|
|
300
|
+
acceptsInput,
|
|
301
|
+
inputPending,
|
|
302
|
+
ptyStatus,
|
|
303
|
+
booting,
|
|
304
|
+
});
|
|
247
305
|
|
|
248
306
|
function handleActivate() {
|
|
249
307
|
if (!activated) setActivated(true);
|
|
@@ -361,10 +419,6 @@ export function SandboxTerminal({
|
|
|
361
419
|
requestAnimationFrame(() => {
|
|
362
420
|
if (disposed) return;
|
|
363
421
|
settle();
|
|
364
|
-
if (ptyOutputQueueRef.current.length > 0) {
|
|
365
|
-
for (const data of ptyOutputQueueRef.current) term.write(data);
|
|
366
|
-
ptyOutputQueueRef.current = [];
|
|
367
|
-
}
|
|
368
422
|
el.setAttribute("data-og-term-ready", "true");
|
|
369
423
|
if (typeof globalThis.__OG_TERMINAL_DEBUG__ === "function") {
|
|
370
424
|
globalThis.__OG_TERMINAL_DEBUG__({
|
|
@@ -459,12 +513,19 @@ export function SandboxTerminal({
|
|
|
459
513
|
// socket; firehose mode uses the legacy ptyWrite-over-HTTP fn.
|
|
460
514
|
useEffect(() => {
|
|
461
515
|
const term = termRef.current;
|
|
462
|
-
if (!ready || !term || !interactive)
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
516
|
+
if (!ready || !term || !interactive) {
|
|
517
|
+
setInputReady(false);
|
|
518
|
+
return;
|
|
519
|
+
}
|
|
520
|
+
const sink = ptyAttachable ? ptyWrite : result.write;
|
|
521
|
+
if (!sink) {
|
|
522
|
+
setInputReady(false);
|
|
523
|
+
return;
|
|
524
|
+
}
|
|
525
|
+
const sub = subscribeTerminalInput(term, sink, true);
|
|
526
|
+
setInputReady(sub !== null);
|
|
527
|
+
return () => sub?.dispose();
|
|
528
|
+
}, [ready, interactive, ptyAttachable, ptyWrite, result.write]);
|
|
468
529
|
|
|
469
530
|
// In PTY mode, tell ttyd the window size on the xterm resize event.
|
|
470
531
|
useEffect(() => {
|
|
@@ -551,6 +612,10 @@ export function SandboxTerminal({
|
|
|
551
612
|
className="h-full w-full"
|
|
552
613
|
style={{ visibility: ready ? "visible" : "hidden" }}
|
|
553
614
|
data-opengeni-terminal
|
|
615
|
+
data-opengeni-terminal-ready={ready ? "true" : "false"}
|
|
616
|
+
data-opengeni-terminal-interactive={surfaceState === "interactive" ? "true" : "false"}
|
|
617
|
+
data-opengeni-terminal-state={surfaceState}
|
|
618
|
+
data-opengeni-terminal-status={ptyAttachable ? ptyStatus : "firehose"}
|
|
554
619
|
/>
|
|
555
620
|
</div>
|
|
556
621
|
</div>
|