@opengeni/react 0.45.0 → 0.48.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +68 -12
- package/dist/{chunk-U3CSCMWA.js → chunk-FK6VG4LL.js} +9 -13
- package/dist/chunk-FK6VG4LL.js.map +1 -0
- package/dist/{chunk-HFO4ERGQ.js → chunk-FWXGSNXT.js} +2 -2
- package/dist/{chunk-SRFUT2ZU.js → chunk-I4MPFDRP.js} +119 -63
- package/dist/chunk-I4MPFDRP.js.map +1 -0
- package/dist/{chunk-EB67J347.js → chunk-KZ73RL76.js} +111 -31
- package/dist/chunk-KZ73RL76.js.map +1 -0
- package/dist/{chunk-LWR4MXSS.js → chunk-LHLYWG5R.js} +10 -1
- package/dist/chunk-LHLYWG5R.js.map +1 -0
- package/dist/{chunk-L3EWO3UK.js → chunk-NJ7M2B6Z.js} +445 -84
- package/dist/chunk-NJ7M2B6Z.js.map +1 -0
- package/dist/{chunk-VCBFUSUZ.js → chunk-O4VXOBGF.js} +3 -3
- package/dist/{chunk-VCBFUSUZ.js.map → chunk-O4VXOBGF.js.map} +1 -1
- package/dist/{chunk-6EDV6YFE.js → chunk-OL6QVXGF.js} +121 -29
- package/dist/chunk-OL6QVXGF.js.map +1 -0
- package/dist/chunk-VZTQ73XT.js +86 -0
- package/dist/chunk-VZTQ73XT.js.map +1 -0
- package/dist/{chunk-EHSYZ4KP.js → chunk-WYA65Y3F.js} +16 -16
- package/dist/chunk-WYA65Y3F.js.map +1 -0
- package/dist/{chunk-FD72GJMK.js → chunk-XCNTXWBB.js} +274 -125
- package/dist/chunk-XCNTXWBB.js.map +1 -0
- package/dist/client.d.ts +1 -1
- package/dist/components/chat-composer.d.ts +7 -2
- package/dist/components/composer-transcription-control.d.ts +2 -0
- package/dist/components/composer.d.ts +14 -0
- package/dist/components/machines/machine-detail.d.ts +3 -1
- package/dist/components/machines-dashboard.d.ts +3 -3
- package/dist/components/message-timeline.d.ts +12 -2
- package/dist/components/sandbox-files.d.ts +2 -2
- package/dist/components/sandbox-terminal.d.ts +29 -0
- package/dist/components/sandbox-workspace.d.ts +5 -1
- package/dist/components/workspace-dock.d.ts +3 -1
- package/dist/composer.d.ts +2 -2
- package/dist/composer.js +6 -6
- package/dist/hooks/internal.d.ts +6 -0
- package/dist/hooks/use-codex-accounts.d.ts +1 -1
- package/dist/hooks/use-environments.d.ts +10 -4
- package/dist/hooks/use-machines.d.ts +7 -0
- package/dist/hooks/use-sandbox-files.d.ts +19 -0
- package/dist/hooks/use-sandbox-git.d.ts +7 -0
- package/dist/hooks/use-transcription.d.ts +2 -2
- package/dist/hooks/use-voice-input.d.ts +13 -4
- package/dist/index.d.ts +6 -5
- package/dist/index.js +904 -538
- package/dist/index.js.map +1 -1
- package/dist/lib/composer-responsive-context.d.ts +9 -0
- package/dist/lib/use-portal-token-style.d.ts +14 -3
- package/dist/machines.js +2 -2
- package/dist/{queue-surface-implementation-J4XJFKRW.js → queue-surface-implementation-U5JFG7HT.js} +19 -18
- package/dist/queue-surface-implementation-U5JFG7HT.js.map +1 -0
- package/dist/realtime/realtime-control.d.ts +9 -0
- package/dist/realtime.js +29 -32
- package/dist/realtime.js.map +1 -1
- package/dist/session-ui.js +5 -5
- package/dist/session.js +4 -4
- package/dist/timeline/activity-rail.d.ts +3 -2
- package/dist/timeline/index.d.ts +2 -2
- package/dist/timeline/parsers.d.ts +3 -3
- package/dist/timeline/registry.d.ts +3 -0
- package/dist/timeline/screenshot-lightbox.d.ts +1 -1
- package/dist/timeline/types.d.ts +4 -0
- package/dist/voice-recording-store.d.ts +8 -2
- package/package.json +20 -4
- package/src/client.ts +3 -0
- package/src/components/chat-composer.tsx +12 -2
- package/src/components/code-editor.tsx +1 -1
- package/src/components/command-palette.tsx +1 -1
- package/src/components/composer-transcription-control.tsx +41 -16
- package/src/components/composer.tsx +52 -26
- package/src/components/copy-button.tsx +2 -2
- package/src/components/desktop-viewer.tsx +2 -2
- package/src/components/file-browser.tsx +39 -17
- package/src/components/human-input-form.tsx +2 -2
- package/src/components/machine-card.tsx +1 -1
- package/src/components/machines/machine-detail.tsx +39 -15
- package/src/components/machines-dashboard.tsx +7 -6
- package/src/components/message-timeline.tsx +44 -11
- package/src/components/model-picker.tsx +2 -2
- package/src/components/model-policy-picker.tsx +16 -15
- package/src/components/queue-surface-implementation.tsx +20 -16
- package/src/components/queue-surface-state.tsx +2 -2
- package/src/components/sandbox-files.tsx +140 -60
- package/src/components/sandbox-terminal.tsx +24 -5
- package/src/components/sandbox-workspace.tsx +180 -142
- package/src/components/session-chrome.tsx +14 -14
- package/src/components/tooltip.tsx +13 -16
- package/src/components/user-message-body.tsx +1 -1
- package/src/components/workbench-changes.tsx +4 -4
- package/src/components/workspace-dock.tsx +13 -5
- package/src/composer.ts +3 -0
- package/src/hooks/internal.ts +132 -38
- package/src/hooks/use-codex-accounts.ts +4 -4
- package/src/hooks/use-environments.ts +24 -5
- package/src/hooks/use-file-attachments.ts +70 -32
- package/src/hooks/use-goal.ts +17 -5
- package/src/hooks/use-machines.ts +47 -1
- package/src/hooks/use-sandbox-files.ts +310 -59
- package/src/hooks/use-sandbox-git.ts +148 -41
- package/src/hooks/use-session-capabilities.ts +35 -24
- package/src/hooks/use-session-events.ts +18 -4
- package/src/hooks/use-transcription.ts +4 -14
- package/src/hooks/use-turn-queue.ts +17 -5
- package/src/hooks/use-voice-input.ts +481 -36
- package/src/hooks/use-windowed-sections.ts +9 -7
- package/src/index.ts +11 -6
- package/src/lib/composer-responsive-context.ts +15 -0
- package/src/lib/use-portal-token-style.ts +60 -15
- package/src/provider.tsx +52 -7
- package/src/realtime/dropdown-menu.tsx +15 -19
- package/src/realtime/realtime-control.tsx +18 -7
- package/src/timeline/activity-rail.tsx +15 -6
- package/src/timeline/index.ts +1 -1
- package/src/timeline/parsers.ts +33 -20
- package/src/timeline/projection.ts +23 -0
- package/src/timeline/registry.ts +7 -0
- package/src/timeline/screenshot-lightbox.tsx +15 -4
- package/src/timeline/shared.tsx +8 -8
- package/src/timeline/tool-renderers.tsx +166 -22
- package/src/timeline/turn-summary.tsx +6 -6
- package/src/timeline/types.ts +4 -0
- package/src/voice-recording-store.ts +15 -0
- package/styles/compiled.css +5065 -0
- package/styles/compiled.d.ts +2 -0
- package/styles/effective-tokens.css +27 -0
- package/styles/index.css +3 -0
- package/styles/responsive.css +196 -0
- package/styles/responsive.d.ts +2 -0
- package/styles/tokens.css +50 -17
- package/dist/chunk-6EDV6YFE.js.map +0 -1
- package/dist/chunk-EB67J347.js.map +0 -1
- package/dist/chunk-EHSYZ4KP.js.map +0 -1
- package/dist/chunk-FD72GJMK.js.map +0 -1
- package/dist/chunk-JB5725BI.js +0 -48
- package/dist/chunk-JB5725BI.js.map +0 -1
- package/dist/chunk-L3EWO3UK.js.map +0 -1
- package/dist/chunk-LWR4MXSS.js.map +0 -1
- package/dist/chunk-SRFUT2ZU.js.map +0 -1
- package/dist/chunk-U3CSCMWA.js.map +0 -1
- package/dist/queue-surface-implementation-J4XJFKRW.js.map +0 -1
- /package/dist/{chunk-HFO4ERGQ.js.map → chunk-FWXGSNXT.js.map} +0 -0
|
@@ -68,7 +68,7 @@ function QueueErrorAlert({
|
|
|
68
68
|
role: "region",
|
|
69
69
|
"aria-label": "Queue error details",
|
|
70
70
|
tabIndex: 0,
|
|
71
|
-
className: "max-h-[min(5rem,20dvh)] min-w-0 max-w-full flex-[1_1_5rem] overflow-auto overscroll-contain whitespace-pre-wrap rounded-sm outline-
|
|
71
|
+
className: "max-h-[min(5rem,20dvh)] min-w-0 max-w-full flex-[1_1_5rem] overflow-auto overscroll-contain whitespace-pre-wrap rounded-sm outline-hidden [overflow-wrap:anywhere] [unicode-bidi:plaintext] focus-visible:ring-2 focus-visible:ring-ring/40",
|
|
72
72
|
"data-testid": "queue-error-message",
|
|
73
73
|
dir: "auto",
|
|
74
74
|
children: (queue.mutationError ?? queue.error)?.message
|
|
@@ -84,7 +84,7 @@ function QueueErrorAlert({
|
|
|
84
84
|
},
|
|
85
85
|
"aria-label": "Dismiss queue error and retry",
|
|
86
86
|
title: "Retry loading the queue",
|
|
87
|
-
className: "ms-auto inline-flex size-7 shrink-0 items-center justify-center self-start rounded-md outline-
|
|
87
|
+
className: "ms-auto inline-flex size-7 shrink-0 items-center justify-center self-start rounded-md outline-hidden transition-colors hover:bg-surface-3 focus-visible:ring-2 focus-visible:ring-ring/40 motion-reduce:transition-none pointer-coarse:size-[44px]",
|
|
88
88
|
children: /* @__PURE__ */ jsx(RotateCwIcon, { className: "size-3.5" })
|
|
89
89
|
}
|
|
90
90
|
)
|
|
@@ -99,4 +99,4 @@ export {
|
|
|
99
99
|
QueueStoppingStatus,
|
|
100
100
|
QueueErrorAlert
|
|
101
101
|
};
|
|
102
|
-
//# sourceMappingURL=chunk-
|
|
102
|
+
//# sourceMappingURL=chunk-O4VXOBGF.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/queue-draft-policy.ts","../src/components/queue-surface-state.tsx"],"sourcesContent":["import type { ComposerState } from \"../hooks/use-composer\";\n\n/**\n * Decide whether checking out a queued prompt would replace current composer\n * content. `hasDraftContent` reads the synchronous draft refs, so this stays\n * correct even when a controlled input update has not rendered yet.\n */\nexport function requestQueueDraftEdit(\n composer: Pick<ComposerState, \"hasDraftContent\">,\n confirmReplacement: () => void,\n editImmediately: () => void,\n): void {\n if (composer.hasDraftContent()) {\n confirmReplacement();\n } else {\n editImmediately();\n }\n}\n","import { Loader2Icon, RotateCwIcon } from \"lucide-react\";\n\nimport type { UseTurnQueueResult } from \"../hooks/use-turn-queue\";\n\ntype QueueStateProps = {\n queue: UseTurnQueueResult;\n};\n\nexport function EmptyQueueStateSurface({ queue }: QueueStateProps) {\n const hasError = Boolean(queue.error || queue.mutationError);\n return (\n <div\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 ? (\n <QueueStoppingStatus queue={queue} dividerAfter={hasError} />\n ) : null}\n {hasError ? <QueueErrorAlert queue={queue} /> : null}\n </div>\n </div>\n );\n}\n\nexport function QueueStoppingStatus({\n queue,\n dividerAfter = false,\n}: QueueStateProps & { dividerAfter?: boolean }) {\n return (\n <div\n role=\"status\"\n aria-live=\"polite\"\n className={`flex min-h-11 items-center gap-2.5 bg-status-waiting/[0.07] px-3 py-2 text-og-control text-fg ${\n dividerAfter ? \"border-b border-status-waiting/20\" : \"\"\n }`}\n data-testid=\"stopping-previous-attempt\"\n >\n <Loader2Icon\n aria-hidden=\"true\"\n className=\"size-3.5 shrink-0 animate-spin text-status-waiting motion-reduce:animate-none\"\n />\n <span className=\"min-w-0\">\n <span className=\"font-medium\">\n {queue.effectiveControl?.state === \"paused\"\n ? \"Stopping current attempt…\"\n : \"Stopping previous attempt…\"}\n </span>{\" \"}\n <span className=\"text-fg-muted\">\n {queue.effectiveControl?.state === \"paused\"\n ? \"Queued work stays saved until you resume.\"\n : \"Queued work is saved and starts automatically.\"}\n </span>\n </span>\n </div>\n );\n}\n\nexport function QueueErrorAlert({\n queue,\n dividerBefore = false,\n}: QueueStateProps & { dividerBefore?: boolean }) {\n return (\n <div className={`${dividerBefore ? \"border-t border-border\" : \"\"} p-2`}>\n <div\n role=\"alert\"\n className=\"flex min-w-0 max-w-full flex-wrap items-start gap-2 rounded-md bg-status-failed/10 px-2 py-1.5 text-og-control text-status-failed\"\n >\n <span\n role=\"region\"\n aria-label=\"Queue error details\"\n tabIndex={0}\n className=\"max-h-[min(5rem,20dvh)] min-w-0 max-w-full flex-[1_1_5rem] overflow-auto overscroll-contain whitespace-pre-wrap rounded-sm outline-
|
|
1
|
+
{"version":3,"sources":["../src/components/queue-draft-policy.ts","../src/components/queue-surface-state.tsx"],"sourcesContent":["import type { ComposerState } from \"../hooks/use-composer\";\n\n/**\n * Decide whether checking out a queued prompt would replace current composer\n * content. `hasDraftContent` reads the synchronous draft refs, so this stays\n * correct even when a controlled input update has not rendered yet.\n */\nexport function requestQueueDraftEdit(\n composer: Pick<ComposerState, \"hasDraftContent\">,\n confirmReplacement: () => void,\n editImmediately: () => void,\n): void {\n if (composer.hasDraftContent()) {\n confirmReplacement();\n } else {\n editImmediately();\n }\n}\n","import { Loader2Icon, RotateCwIcon } from \"lucide-react\";\n\nimport type { UseTurnQueueResult } from \"../hooks/use-turn-queue\";\n\ntype QueueStateProps = {\n queue: UseTurnQueueResult;\n};\n\nexport function EmptyQueueStateSurface({ queue }: QueueStateProps) {\n const hasError = Boolean(queue.error || queue.mutationError);\n return (\n <div\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 ? (\n <QueueStoppingStatus queue={queue} dividerAfter={hasError} />\n ) : null}\n {hasError ? <QueueErrorAlert queue={queue} /> : null}\n </div>\n </div>\n );\n}\n\nexport function QueueStoppingStatus({\n queue,\n dividerAfter = false,\n}: QueueStateProps & { dividerAfter?: boolean }) {\n return (\n <div\n role=\"status\"\n aria-live=\"polite\"\n className={`flex min-h-11 items-center gap-2.5 bg-status-waiting/[0.07] px-3 py-2 text-og-control text-fg ${\n dividerAfter ? \"border-b border-status-waiting/20\" : \"\"\n }`}\n data-testid=\"stopping-previous-attempt\"\n >\n <Loader2Icon\n aria-hidden=\"true\"\n className=\"size-3.5 shrink-0 animate-spin text-status-waiting motion-reduce:animate-none\"\n />\n <span className=\"min-w-0\">\n <span className=\"font-medium\">\n {queue.effectiveControl?.state === \"paused\"\n ? \"Stopping current attempt…\"\n : \"Stopping previous attempt…\"}\n </span>{\" \"}\n <span className=\"text-fg-muted\">\n {queue.effectiveControl?.state === \"paused\"\n ? \"Queued work stays saved until you resume.\"\n : \"Queued work is saved and starts automatically.\"}\n </span>\n </span>\n </div>\n );\n}\n\nexport function QueueErrorAlert({\n queue,\n dividerBefore = false,\n}: QueueStateProps & { dividerBefore?: boolean }) {\n return (\n <div className={`${dividerBefore ? \"border-t border-border\" : \"\"} p-2`}>\n <div\n role=\"alert\"\n className=\"flex min-w-0 max-w-full flex-wrap items-start gap-2 rounded-md bg-status-failed/10 px-2 py-1.5 text-og-control text-status-failed\"\n >\n <span\n role=\"region\"\n aria-label=\"Queue error details\"\n tabIndex={0}\n className=\"max-h-[min(5rem,20dvh)] min-w-0 max-w-full flex-[1_1_5rem] overflow-auto overscroll-contain whitespace-pre-wrap rounded-sm outline-hidden [overflow-wrap:anywhere] [unicode-bidi:plaintext] focus-visible:ring-2 focus-visible:ring-ring/40\"\n data-testid=\"queue-error-message\"\n dir=\"auto\"\n >\n {(queue.mutationError ?? queue.error)?.message}\n </span>\n <button\n type=\"button\"\n onClick={() => {\n queue.clearMutationError();\n void queue.refresh();\n }}\n aria-label=\"Dismiss queue error and retry\"\n title=\"Retry loading the queue\"\n className=\"ms-auto inline-flex size-7 shrink-0 items-center justify-center self-start rounded-md outline-hidden transition-colors hover:bg-surface-3 focus-visible:ring-2 focus-visible:ring-ring/40 motion-reduce:transition-none pointer-coarse:size-[44px]\"\n >\n <RotateCwIcon className=\"size-3.5\" />\n </button>\n </div>\n </div>\n );\n}\n"],"mappings":";AAOO,SAAS,sBACd,UACA,oBACA,iBACM;AACN,MAAI,SAAS,gBAAgB,GAAG;AAC9B,uBAAmB;AAAA,EACrB,OAAO;AACL,oBAAgB;AAAA,EAClB;AACF;;;ACjBA,SAAS,aAAa,oBAAoB;AAepC,SAEI,KAFJ;AAPC,SAAS,uBAAuB,EAAE,MAAM,GAAoB;AACjE,QAAM,WAAW,QAAQ,MAAM,SAAS,MAAM,aAAa;AAC3D,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAU;AAAA,MACV,eAAY;AAAA,MAEZ,+BAAC,SAAI,WAAU,2EACZ;AAAA,cAAM,0BACL,oBAAC,uBAAoB,OAAc,cAAc,UAAU,IACzD;AAAA,QACH,WAAW,oBAAC,mBAAgB,OAAc,IAAK;AAAA,SAClD;AAAA;AAAA,EACF;AAEJ;AAEO,SAAS,oBAAoB;AAAA,EAClC;AAAA,EACA,eAAe;AACjB,GAAiD;AAC/C,SACE;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,aAAU;AAAA,MACV,WAAW,iGACT,eAAe,sCAAsC,EACvD;AAAA,MACA,eAAY;AAAA,MAEZ;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,eAAY;AAAA,YACZ,WAAU;AAAA;AAAA,QACZ;AAAA,QACA,qBAAC,UAAK,WAAU,WACd;AAAA,8BAAC,UAAK,WAAU,eACb,gBAAM,kBAAkB,UAAU,WAC/B,mCACA,mCACN;AAAA,UAAQ;AAAA,UACR,oBAAC,UAAK,WAAU,iBACb,gBAAM,kBAAkB,UAAU,WAC/B,8CACA,kDACN;AAAA,WACF;AAAA;AAAA;AAAA,EACF;AAEJ;AAEO,SAAS,gBAAgB;AAAA,EAC9B;AAAA,EACA,gBAAgB;AAClB,GAAkD;AAChD,SACE,oBAAC,SAAI,WAAW,GAAG,gBAAgB,2BAA2B,EAAE,QAC9D;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,WAAU;AAAA,MAEV;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,cAAW;AAAA,YACX,UAAU;AAAA,YACV,WAAU;AAAA,YACV,eAAY;AAAA,YACZ,KAAI;AAAA,YAEF,iBAAM,iBAAiB,MAAM,QAAQ;AAAA;AAAA,QACzC;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,SAAS,MAAM;AACb,oBAAM,mBAAmB;AACzB,mBAAK,MAAM,QAAQ;AAAA,YACrB;AAAA,YACA,cAAW;AAAA,YACX,OAAM;AAAA,YACN,WAAU;AAAA,YAEV,8BAAC,gBAAa,WAAU,YAAW;AAAA;AAAA,QACrC;AAAA;AAAA;AAAA,EACF,GACF;AAEJ;","names":[]}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
useMutationRunner,
|
|
3
|
+
usePageLiveActivity,
|
|
3
4
|
usePolledValue
|
|
4
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-KZ73RL76.js";
|
|
5
6
|
import {
|
|
6
7
|
OpenGeniContext,
|
|
7
8
|
useOpenGeni
|
|
@@ -533,7 +534,7 @@ function MachineCard({
|
|
|
533
534
|
className: cn(
|
|
534
535
|
"og-root group relative flex flex-col gap-3 overflow-hidden rounded-og-lg border border-og-border",
|
|
535
536
|
"bg-og-surface-1 p-4 shadow-og-sm transition-colors",
|
|
536
|
-
openable && "cursor-pointer hover:border-og-border-strong focus-visible:border-og-accent/60 focus-visible:outline-
|
|
537
|
+
openable && "cursor-pointer hover:border-og-border-strong focus-visible:border-og-accent/60 focus-visible:outline-hidden",
|
|
537
538
|
machine.active && "border-og-accent/40",
|
|
538
539
|
className
|
|
539
540
|
),
|
|
@@ -886,7 +887,14 @@ function MetricHistoryChart({
|
|
|
886
887
|
}
|
|
887
888
|
|
|
888
889
|
// src/components/machines/machine-detail.tsx
|
|
889
|
-
import {
|
|
890
|
+
import {
|
|
891
|
+
ArrowLeftIcon,
|
|
892
|
+
CpuIcon as CpuIcon2,
|
|
893
|
+
LaptopIcon as LaptopIcon2,
|
|
894
|
+
RadioIcon,
|
|
895
|
+
ServerIcon as ServerIcon2,
|
|
896
|
+
Trash2Icon
|
|
897
|
+
} from "lucide-react";
|
|
890
898
|
|
|
891
899
|
// src/components/machines/series.ts
|
|
892
900
|
var METRIC_WINDOWS = ["15m", "1h", "6h", "24h"];
|
|
@@ -985,6 +993,7 @@ function MachineDetail({
|
|
|
985
993
|
onWindowChange,
|
|
986
994
|
loadingSeries,
|
|
987
995
|
onBack,
|
|
996
|
+
onRemove,
|
|
988
997
|
now = Date.now(),
|
|
989
998
|
className
|
|
990
999
|
}) {
|
|
@@ -1015,20 +1024,36 @@ function MachineDetail({
|
|
|
1015
1024
|
machine.arch
|
|
1016
1025
|
] })
|
|
1017
1026
|
] }),
|
|
1018
|
-
/* @__PURE__ */
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1027
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex shrink-0 items-center gap-2", children: [
|
|
1028
|
+
onRemove && machine.enrollmentId && !machine.isSessionGroup ? /* @__PURE__ */ jsxs7(
|
|
1029
|
+
"button",
|
|
1030
|
+
{
|
|
1031
|
+
type: "button",
|
|
1032
|
+
"data-remove-machine": true,
|
|
1033
|
+
"aria-label": `Remove machine ${machine.name}`,
|
|
1034
|
+
onClick: () => onRemove(machine),
|
|
1035
|
+
className: "inline-flex min-h-9 items-center gap-1.5 rounded-og-sm border border-og-status-failed/40 px-2.5 py-1 font-medium text-og-xs text-og-status-failed transition-colors hover:bg-og-status-failed/10 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-og-status-failed/50 pointer-coarse:min-h-11",
|
|
1036
|
+
children: [
|
|
1037
|
+
/* @__PURE__ */ jsx7(Trash2Icon, { className: "size-3.5", "aria-hidden": true }),
|
|
1038
|
+
/* @__PURE__ */ jsx7("span", { className: "hidden sm:inline", children: "Remove machine" })
|
|
1039
|
+
]
|
|
1040
|
+
}
|
|
1041
|
+
) : null,
|
|
1042
|
+
/* @__PURE__ */ jsx7("div", { className: "flex items-center gap-0.5 rounded-og-md border border-og-border bg-og-surface-1 p-0.5", children: METRIC_WINDOWS.map((w) => /* @__PURE__ */ jsx7(
|
|
1043
|
+
"button",
|
|
1044
|
+
{
|
|
1045
|
+
type: "button",
|
|
1046
|
+
onClick: () => onWindowChange(w),
|
|
1047
|
+
"data-active": w === window2,
|
|
1048
|
+
className: cn(
|
|
1049
|
+
"rounded-og-sm px-2 py-1 font-og-mono text-og-xs transition-colors",
|
|
1050
|
+
w === window2 ? "bg-og-surface-3 text-og-fg shadow-og-sm" : "text-og-fg-subtle hover:text-og-fg-muted"
|
|
1051
|
+
),
|
|
1052
|
+
children: w
|
|
1053
|
+
},
|
|
1054
|
+
w
|
|
1055
|
+
)) })
|
|
1056
|
+
] })
|
|
1032
1057
|
] }),
|
|
1033
1058
|
/* @__PURE__ */ jsxs7(
|
|
1034
1059
|
"div",
|
|
@@ -1144,7 +1169,7 @@ function EmptyState({ onEnroll }) {
|
|
|
1144
1169
|
/* @__PURE__ */ jsx8("span", { className: "flex size-10 items-center justify-center rounded-full bg-og-surface-2 text-og-fg-subtle", children: /* @__PURE__ */ jsx8(LaptopIcon3, { className: "size-5", "aria-hidden": true }) }),
|
|
1145
1170
|
/* @__PURE__ */ jsxs8("div", { className: "space-y-1", children: [
|
|
1146
1171
|
/* @__PURE__ */ jsx8("p", { className: "text-og-base font-medium text-og-fg", children: "No machines yet" }),
|
|
1147
|
-
/* @__PURE__ */ jsx8("p", { className: "max-w-xs text-og-sm text-og-fg-muted", children: "
|
|
1172
|
+
/* @__PURE__ */ jsx8("p", { className: "max-w-xs text-og-sm text-og-fg-muted", children: "Connect your own computer to run the agent on it \u2014 your files, your terminal, your desktop." })
|
|
1148
1173
|
] }),
|
|
1149
1174
|
onEnroll ? /* @__PURE__ */ jsxs8(
|
|
1150
1175
|
"button",
|
|
@@ -1155,7 +1180,7 @@ function EmptyState({ onEnroll }) {
|
|
|
1155
1180
|
className: "inline-flex items-center gap-1.5 rounded-og-sm bg-og-accent px-3 py-1.5 text-og-sm font-medium text-og-accent-fg transition-colors hover:bg-og-accent-strong pointer-coarse:min-h-11",
|
|
1156
1181
|
children: [
|
|
1157
1182
|
/* @__PURE__ */ jsx8(PlusIcon, { className: "size-3.5", "aria-hidden": true }),
|
|
1158
|
-
"
|
|
1183
|
+
"Connect a machine"
|
|
1159
1184
|
]
|
|
1160
1185
|
}
|
|
1161
1186
|
) : null
|
|
@@ -1195,7 +1220,7 @@ function Header({
|
|
|
1195
1220
|
className: "inline-flex items-center gap-1.5 rounded-og-sm border border-og-border px-2.5 py-1 text-og-sm font-medium text-og-fg-muted transition-colors hover:border-og-border-strong hover:text-og-fg pointer-coarse:min-h-11",
|
|
1196
1221
|
children: [
|
|
1197
1222
|
/* @__PURE__ */ jsx8(PlusIcon, { className: "size-3.5", "aria-hidden": true }),
|
|
1198
|
-
"
|
|
1223
|
+
"Connect a machine"
|
|
1199
1224
|
]
|
|
1200
1225
|
}
|
|
1201
1226
|
) : null
|
|
@@ -1724,6 +1749,9 @@ function OpenGeniProvider({
|
|
|
1724
1749
|
);
|
|
1725
1750
|
const callbackRef = useRef2(onWorkspaceControlEvent);
|
|
1726
1751
|
const reconcilersRef = useRef2(/* @__PURE__ */ new Map());
|
|
1752
|
+
const reconcileInFlightRef = useRef2(/* @__PURE__ */ new Map());
|
|
1753
|
+
const workspaceControlSequencesRef = useRef2(/* @__PURE__ */ new Map());
|
|
1754
|
+
const pageLive = usePageLiveActivity();
|
|
1727
1755
|
callbackRef.current = onWorkspaceControlEvent;
|
|
1728
1756
|
const verifyApiContract = useCallback(async () => {
|
|
1729
1757
|
try {
|
|
@@ -1756,28 +1784,54 @@ function OpenGeniProvider({
|
|
|
1756
1784
|
[]
|
|
1757
1785
|
);
|
|
1758
1786
|
const reconcileSession = useMemo(
|
|
1759
|
-
() =>
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1787
|
+
() => (sessionId) => {
|
|
1788
|
+
const existing = reconcileInFlightRef.current.get(sessionId);
|
|
1789
|
+
if (existing) return existing;
|
|
1790
|
+
const promise = (async () => {
|
|
1791
|
+
await withTimeout(verifyApiContract(), 1e4, "API contract reconciliation");
|
|
1792
|
+
const callbacks = [...reconcilersRef.current.get(sessionId)?.values() ?? []];
|
|
1793
|
+
await withTimeout(
|
|
1794
|
+
Promise.all(callbacks.map((reconcile) => reconcile())).then(() => void 0),
|
|
1795
|
+
15e3,
|
|
1796
|
+
"session reconciliation"
|
|
1797
|
+
);
|
|
1798
|
+
})().finally(() => {
|
|
1799
|
+
if (reconcileInFlightRef.current.get(sessionId) === promise) {
|
|
1800
|
+
reconcileInFlightRef.current.delete(sessionId);
|
|
1801
|
+
}
|
|
1802
|
+
});
|
|
1803
|
+
reconcileInFlightRef.current.set(sessionId, promise);
|
|
1804
|
+
return promise;
|
|
1763
1805
|
},
|
|
1764
1806
|
[verifyApiContract]
|
|
1765
1807
|
);
|
|
1766
1808
|
useEffect(() => {
|
|
1809
|
+
if (!pageLive) {
|
|
1810
|
+
setWorkspaceControlConnectionState("idle");
|
|
1811
|
+
return;
|
|
1812
|
+
}
|
|
1767
1813
|
const controller = new AbortController();
|
|
1768
|
-
setWorkspaceControlEvent(null);
|
|
1769
1814
|
setWorkspaceControlConnectionState("connecting");
|
|
1770
1815
|
void (async () => {
|
|
1771
1816
|
try {
|
|
1772
1817
|
await verifyApiContract();
|
|
1773
1818
|
const workspace = await client.getWorkspace(workspaceId);
|
|
1819
|
+
const resumeAfter = Math.max(
|
|
1820
|
+
workspaceControlSequencesRef.current.get(workspaceId) ?? 0,
|
|
1821
|
+
workspace.inferenceControl.revision
|
|
1822
|
+
);
|
|
1823
|
+
workspaceControlSequencesRef.current.set(workspaceId, resumeAfter);
|
|
1774
1824
|
const stream = client.streamWorkspaceControlEvents(workspaceId, {
|
|
1775
|
-
after:
|
|
1825
|
+
after: resumeAfter,
|
|
1776
1826
|
signal: controller.signal,
|
|
1777
1827
|
onStateChange: setWorkspaceControlConnectionState
|
|
1778
1828
|
});
|
|
1779
1829
|
for await (const event of stream) {
|
|
1780
1830
|
if (controller.signal.aborted) return;
|
|
1831
|
+
workspaceControlSequencesRef.current.set(
|
|
1832
|
+
workspaceId,
|
|
1833
|
+
Math.max(workspaceControlSequencesRef.current.get(workspaceId) ?? 0, event.sequence)
|
|
1834
|
+
);
|
|
1781
1835
|
setWorkspaceControlEvent(
|
|
1782
1836
|
(current) => !current || event.sequence > current.sequence ? event : current
|
|
1783
1837
|
);
|
|
@@ -1792,7 +1846,7 @@ function OpenGeniProvider({
|
|
|
1792
1846
|
}
|
|
1793
1847
|
})();
|
|
1794
1848
|
return () => controller.abort();
|
|
1795
|
-
}, [client, verifyApiContract, workspaceId]);
|
|
1849
|
+
}, [client, pageLive, verifyApiContract, workspaceId]);
|
|
1796
1850
|
const value = useMemo(
|
|
1797
1851
|
() => ({
|
|
1798
1852
|
client,
|
|
@@ -1816,6 +1870,20 @@ function OpenGeniProvider({
|
|
|
1816
1870
|
contractMismatch ? /* @__PURE__ */ jsx12(ApiContractMismatchScreen, { mismatch: contractMismatch }) : null
|
|
1817
1871
|
] });
|
|
1818
1872
|
}
|
|
1873
|
+
function withTimeout(promise, timeoutMs, label) {
|
|
1874
|
+
let timer;
|
|
1875
|
+
return Promise.race([
|
|
1876
|
+
promise,
|
|
1877
|
+
new Promise((_resolve, reject) => {
|
|
1878
|
+
timer = setTimeout(
|
|
1879
|
+
() => reject(new Error(`${label} timed out after ${timeoutMs}ms`)),
|
|
1880
|
+
timeoutMs
|
|
1881
|
+
);
|
|
1882
|
+
})
|
|
1883
|
+
]).finally(() => {
|
|
1884
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
1885
|
+
});
|
|
1886
|
+
}
|
|
1819
1887
|
function ApiContractMismatchScreen({ mismatch }) {
|
|
1820
1888
|
return /* @__PURE__ */ jsx12(
|
|
1821
1889
|
"div",
|
|
@@ -1884,8 +1952,11 @@ function useMachines(options = {}) {
|
|
|
1884
1952
|
const { run, mutating, mutationError, clearMutationError } = useMutationRunner(identityKey);
|
|
1885
1953
|
const [attachState, setAttachState] = useState4(() => ({ identity: identityKey, sandboxId: null }));
|
|
1886
1954
|
const attachingSandboxId = attachState.identity === identityKey ? attachState.sandboxId : null;
|
|
1955
|
+
const [removeState, setRemoveState] = useState4(() => ({ identity: identityKey, enrollmentId: null }));
|
|
1956
|
+
const removingEnrollmentId = removeState.identity === identityKey ? removeState.enrollmentId : null;
|
|
1887
1957
|
const data = loadedData ?? EMPTY;
|
|
1888
1958
|
const canAttach = sessionId !== void 0 && (typeof machinesClient.attachMachine === "function" || typeof machinesClient.swapActiveSandbox === "function");
|
|
1959
|
+
const canRemove = typeof machinesClient.removeEnrollment === "function";
|
|
1889
1960
|
const attach = useCallback2(
|
|
1890
1961
|
async (sandboxId) => {
|
|
1891
1962
|
if (sessionId === void 0) return false;
|
|
@@ -1912,6 +1983,24 @@ function useMachines(options = {}) {
|
|
|
1912
1983
|
},
|
|
1913
1984
|
[machinesClient, workspaceId]
|
|
1914
1985
|
);
|
|
1986
|
+
const remove = useCallback2(
|
|
1987
|
+
async (enrollmentId, request = {}) => {
|
|
1988
|
+
if (!machinesClient.removeEnrollment) return null;
|
|
1989
|
+
const ownedIdentity = identityKey;
|
|
1990
|
+
setRemoveState({ identity: ownedIdentity, enrollmentId });
|
|
1991
|
+
const result = await run(
|
|
1992
|
+
() => machinesClient.removeEnrollment(workspaceId, enrollmentId, request)
|
|
1993
|
+
);
|
|
1994
|
+
if (identityRef.current === ownedIdentity) {
|
|
1995
|
+
setRemoveState({ identity: ownedIdentity, enrollmentId: null });
|
|
1996
|
+
if (result?.outcome === "removed" || result?.outcome === "already_removed") {
|
|
1997
|
+
await refresh();
|
|
1998
|
+
}
|
|
1999
|
+
}
|
|
2000
|
+
return result;
|
|
2001
|
+
},
|
|
2002
|
+
[machinesClient, workspaceId, identityKey, run, refresh]
|
|
2003
|
+
);
|
|
1915
2004
|
return {
|
|
1916
2005
|
machines: data.machines,
|
|
1917
2006
|
activeSandboxId: data.activeSandboxId,
|
|
@@ -1922,8 +2011,11 @@ function useMachines(options = {}) {
|
|
|
1922
2011
|
attach,
|
|
1923
2012
|
canAttach,
|
|
1924
2013
|
fetchSeries,
|
|
1925
|
-
attaching: mutating,
|
|
2014
|
+
attaching: mutating && attachingSandboxId !== null,
|
|
1926
2015
|
attachingSandboxId,
|
|
2016
|
+
remove,
|
|
2017
|
+
canRemove,
|
|
2018
|
+
removingEnrollmentId,
|
|
1927
2019
|
mutationError,
|
|
1928
2020
|
clearMutationError
|
|
1929
2021
|
};
|
|
@@ -1957,4 +2049,4 @@ export {
|
|
|
1957
2049
|
OpenGeniProvider,
|
|
1958
2050
|
useMachines
|
|
1959
2051
|
};
|
|
1960
|
-
//# sourceMappingURL=chunk-
|
|
2052
|
+
//# sourceMappingURL=chunk-OL6QVXGF.js.map
|