@opengeni/react 1.4.4 → 1.4.5-canary.37458084490001
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-3ZC6QPOM.js +174 -0
- package/dist/chunk-3ZC6QPOM.js.map +1 -0
- package/dist/{chunk-YVFRBXST.js → chunk-4BCVCJSU.js} +2 -2
- 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-I6OY3MWC.js → chunk-6FOTSVWU.js} +2 -2
- package/dist/{chunk-IUHHPMAX.js → chunk-7RRBX5EM.js} +14 -85
- package/dist/chunk-7RRBX5EM.js.map +1 -0
- package/dist/{chunk-L2J3PU7A.js → chunk-7ZB7I3KP.js} +24 -98
- package/dist/chunk-7ZB7I3KP.js.map +1 -0
- 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-IYQCWGU5.js → chunk-GHJU7XG7.js} +35 -62
- package/dist/chunk-GHJU7XG7.js.map +1 -0
- package/dist/{chunk-G6YRCIYJ.js → chunk-HNVWMDNN.js} +55 -60
- package/dist/chunk-HNVWMDNN.js.map +1 -0
- 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-XS67YG5R.js → chunk-IX3K4THH.js} +24 -3
- package/dist/chunk-IX3K4THH.js.map +1 -0
- 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-C5BF4L26.js → chunk-KHF2VRXF.js} +7 -7
- package/dist/{chunk-QMMCJGFI.js → chunk-L5OKM2VX.js} +2 -2
- package/dist/chunk-LHF6BVM4.js +83 -0
- package/dist/chunk-LHF6BVM4.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-RI42H5IU.js +326 -0
- package/dist/chunk-RI42H5IU.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-EAOSEIXB.js → chunk-TZQSHCZN.js} +692 -1996
- package/dist/chunk-TZQSHCZN.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-3ZFWWJ6O.js} +6 -4
- package/dist/{embedded-voice-NIL4RDX3.js.map → embedded-voice-3ZFWWJ6O.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/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-SWC6QEVN.js} +3 -3
- package/dist/lib/clipboard.d.ts +7 -0
- package/dist/lib/provider-recovery.d.ts +49 -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-NM4RPTY6.js} +6 -4
- package/dist/model-policy-picker-menu-NM4RPTY6.js.map +1 -0
- package/dist/model-policy.d.ts +10 -0
- package/dist/model-policy.js +5 -1
- 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-RCVCMXG7.js} +5 -5
- package/dist/sandbox-files-RCVCMXG7.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-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 +96 -0
- package/dist/session-list-model.js +219 -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 +47 -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 +4 -144
- 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 +15 -148
- 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/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/model-mark-paths.ts +53 -0
- package/src/model-picker-model.ts +330 -0
- package/src/model-policy.ts +43 -2
- 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-attention-model.ts +59 -0
- package/src/session-feedback-model.ts +95 -0
- package/src/session-list-model.ts +327 -0
- package/src/session-status-model.ts +62 -0
- package/src/testing/session-scenarios.ts +326 -0
- package/src/timeline/activity-rail.tsx +5 -17
- package/src/timeline/genie-copy.ts +19 -0
- package/src/timeline/genie-loading.tsx +13 -18
- 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/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 +226 -1025
- 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 +3 -0
- package/styles/connect.css +4 -0
- 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-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-YVFRBXST.js.map → chunk-4BCVCJSU.js.map} +0 -0
- /package/dist/{chunk-I6OY3MWC.js.map → chunk-6FOTSVWU.js.map} +0 -0
- /package/dist/{chunk-PBCZL4JP.js.map → chunk-INIZSNXT.js.map} +0 -0
- /package/dist/{chunk-C5BF4L26.js.map → chunk-KHF2VRXF.js.map} +0 -0
- /package/dist/{chunk-QMMCJGFI.js.map → chunk-L5OKM2VX.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-SWC6QEVN.js.map} +0 -0
- /package/dist/{sandbox-files-34CJJNOY.js.map → model-mark-paths.js.map} +0 -0
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import type { SandboxItem, StartupPhaseItem, WorkerItem } from "./types";
|
|
2
|
+
|
|
3
|
+
/* Pure titles and durations for platform activity rows (startup phases and
|
|
4
|
+
sandbox operations), shared by DOM and non-DOM renderers. */
|
|
5
|
+
|
|
6
|
+
export function sandboxRowTitle(item: SandboxItem, displayName: (name: string) => string): string {
|
|
7
|
+
if (item.name === "sandbox.provision") {
|
|
8
|
+
return startupPhaseTitle(
|
|
9
|
+
"sandbox",
|
|
10
|
+
item.status === "cancelled" ? "complete" : item.status,
|
|
11
|
+
item.origin ?? null,
|
|
12
|
+
);
|
|
13
|
+
}
|
|
14
|
+
return displayName(item.name);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function startupPhaseTitle(
|
|
18
|
+
phase: StartupPhaseItem["phase"],
|
|
19
|
+
status: StartupPhaseItem["status"],
|
|
20
|
+
outcome: StartupPhaseItem["outcome"],
|
|
21
|
+
): string {
|
|
22
|
+
if (status === "complete" && phase === "sandbox" && outcome && outcome !== "skipped") {
|
|
23
|
+
return `Sandbox ${outcome === "resumed" ? "reattached" : outcome}`;
|
|
24
|
+
}
|
|
25
|
+
if (status === "complete" && phase === "rig" && outcome === "skipped") {
|
|
26
|
+
return "Sandbox Environment already ready";
|
|
27
|
+
}
|
|
28
|
+
const statusIndex =
|
|
29
|
+
status === "running" ? 0 : status === "failed" ? 1 : status === "cancelled" ? 2 : 3;
|
|
30
|
+
return STARTUP_PHASE_TITLES[phase][statusIndex];
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export const STARTUP_WAIT_TITLES: Record<NonNullable<StartupPhaseItem["blockedReason"]>, string> = {
|
|
34
|
+
capture_in_progress: "Waiting for sandbox checkpoint",
|
|
35
|
+
rotation_in_progress: "Waiting for sandbox rotation",
|
|
36
|
+
provider_recovery_in_progress: "Waiting for sandbox recovery",
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const STARTUP_PHASE_TITLES: Record<
|
|
40
|
+
StartupPhaseItem["phase"],
|
|
41
|
+
readonly [string, string, string, string]
|
|
42
|
+
> = {
|
|
43
|
+
queue: [
|
|
44
|
+
"Waiting for a worker",
|
|
45
|
+
"Worker startup failed",
|
|
46
|
+
"Worker wait interrupted",
|
|
47
|
+
"Worker started",
|
|
48
|
+
],
|
|
49
|
+
sandbox: [
|
|
50
|
+
"Starting sandbox",
|
|
51
|
+
"Sandbox didn’t start",
|
|
52
|
+
"Sandbox startup interrupted",
|
|
53
|
+
"Sandbox ready",
|
|
54
|
+
],
|
|
55
|
+
rig: [
|
|
56
|
+
"Setting up sandbox environment",
|
|
57
|
+
"Sandbox Environment setup failed",
|
|
58
|
+
"Sandbox Environment setup interrupted",
|
|
59
|
+
"Sandbox Environment ready",
|
|
60
|
+
],
|
|
61
|
+
repository: [
|
|
62
|
+
"Preparing repository",
|
|
63
|
+
"Repository preparation failed",
|
|
64
|
+
"Repository preparation interrupted",
|
|
65
|
+
"Repository ready",
|
|
66
|
+
],
|
|
67
|
+
files: [
|
|
68
|
+
"Preparing files",
|
|
69
|
+
"File preparation failed",
|
|
70
|
+
"File preparation interrupted",
|
|
71
|
+
"Files ready",
|
|
72
|
+
],
|
|
73
|
+
tools: [
|
|
74
|
+
"Connecting tools",
|
|
75
|
+
"Tool connection failed",
|
|
76
|
+
"Tool connection interrupted",
|
|
77
|
+
"Tools ready",
|
|
78
|
+
],
|
|
79
|
+
model_preparation: [
|
|
80
|
+
"Preparing runtime and model request",
|
|
81
|
+
"Runtime/model preparation failed",
|
|
82
|
+
"Runtime/model preparation interrupted",
|
|
83
|
+
"Model request dispatched",
|
|
84
|
+
],
|
|
85
|
+
provider_first_byte: [
|
|
86
|
+
"Waiting for model",
|
|
87
|
+
"Model didn’t respond",
|
|
88
|
+
"Model wait interrupted",
|
|
89
|
+
"Model started responding",
|
|
90
|
+
],
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
export function startupDuration(durationMs: number | null): string | null {
|
|
94
|
+
if (durationMs === null || !Number.isFinite(durationMs) || durationMs < 0) return null;
|
|
95
|
+
if (durationMs < 1_000) return `${Math.round(durationMs)}ms`;
|
|
96
|
+
if (durationMs < 60_000) return `${(durationMs / 1_000).toFixed(1)}s`;
|
|
97
|
+
const minutes = Math.floor(durationMs / 60_000);
|
|
98
|
+
const seconds = Math.round((durationMs % 60_000) / 1_000);
|
|
99
|
+
return `${minutes}m ${String(seconds).padStart(2, "0")}s`;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/** The worker step title for a spawn or message, by status. */
|
|
103
|
+
export function workerRowTitle(item: Pick<WorkerItem, "action" | "status">): string {
|
|
104
|
+
const running = item.status === "running";
|
|
105
|
+
const failed = item.status === "failed";
|
|
106
|
+
const cancelled = item.status === "cancelled";
|
|
107
|
+
return item.action === "spawn"
|
|
108
|
+
? running
|
|
109
|
+
? "Spawning worker"
|
|
110
|
+
: failed
|
|
111
|
+
? "Worker spawn failed"
|
|
112
|
+
: cancelled
|
|
113
|
+
? "Worker interrupted"
|
|
114
|
+
: "Worker spawned"
|
|
115
|
+
: running
|
|
116
|
+
? "Messaging worker"
|
|
117
|
+
: failed
|
|
118
|
+
? "Worker message failed"
|
|
119
|
+
: cancelled
|
|
120
|
+
? "Worker interrupted"
|
|
121
|
+
: "Worker messaged";
|
|
122
|
+
}
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
import {
|
|
2
|
+
sandboxRowTitle,
|
|
3
|
+
startupDuration,
|
|
4
|
+
startupPhaseTitle,
|
|
5
|
+
STARTUP_WAIT_TITLES,
|
|
6
|
+
} from "./platform-activity-presentation";
|
|
1
7
|
import type { ReasoningItem, SandboxItem, StartupPhaseItem } from "./types";
|
|
2
8
|
|
|
3
9
|
type RowJsx = typeof import("react/jsx-runtime").jsx;
|
|
@@ -118,99 +124,3 @@ function lucideIcon(j: RowJsx, s: RowJsxs, name: string, children: ReturnType<Ro
|
|
|
118
124
|
children,
|
|
119
125
|
});
|
|
120
126
|
}
|
|
121
|
-
|
|
122
|
-
function sandboxRowTitle(item: SandboxItem, displayName: (name: string) => string): string {
|
|
123
|
-
if (item.name === "sandbox.provision") {
|
|
124
|
-
return startupPhaseTitle(
|
|
125
|
-
"sandbox",
|
|
126
|
-
item.status === "cancelled" ? "complete" : item.status,
|
|
127
|
-
item.origin ?? null,
|
|
128
|
-
);
|
|
129
|
-
}
|
|
130
|
-
return displayName(item.name);
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
function startupPhaseTitle(
|
|
134
|
-
phase: StartupPhaseItem["phase"],
|
|
135
|
-
status: StartupPhaseItem["status"],
|
|
136
|
-
outcome: StartupPhaseItem["outcome"],
|
|
137
|
-
): string {
|
|
138
|
-
if (status === "complete" && phase === "sandbox" && outcome && outcome !== "skipped") {
|
|
139
|
-
return `Sandbox ${outcome === "resumed" ? "reattached" : outcome}`;
|
|
140
|
-
}
|
|
141
|
-
if (status === "complete" && phase === "rig" && outcome === "skipped") {
|
|
142
|
-
return "Sandbox Environment already ready";
|
|
143
|
-
}
|
|
144
|
-
const statusIndex =
|
|
145
|
-
status === "running" ? 0 : status === "failed" ? 1 : status === "cancelled" ? 2 : 3;
|
|
146
|
-
return STARTUP_PHASE_TITLES[phase][statusIndex];
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
const STARTUP_WAIT_TITLES: Record<NonNullable<StartupPhaseItem["blockedReason"]>, string> = {
|
|
150
|
-
capture_in_progress: "Waiting for sandbox checkpoint",
|
|
151
|
-
rotation_in_progress: "Waiting for sandbox rotation",
|
|
152
|
-
provider_recovery_in_progress: "Waiting for sandbox recovery",
|
|
153
|
-
};
|
|
154
|
-
|
|
155
|
-
const STARTUP_PHASE_TITLES: Record<
|
|
156
|
-
StartupPhaseItem["phase"],
|
|
157
|
-
readonly [string, string, string, string]
|
|
158
|
-
> = {
|
|
159
|
-
queue: [
|
|
160
|
-
"Waiting for a worker",
|
|
161
|
-
"Worker startup failed",
|
|
162
|
-
"Worker wait interrupted",
|
|
163
|
-
"Worker started",
|
|
164
|
-
],
|
|
165
|
-
sandbox: [
|
|
166
|
-
"Starting sandbox",
|
|
167
|
-
"Sandbox didn’t start",
|
|
168
|
-
"Sandbox startup interrupted",
|
|
169
|
-
"Sandbox ready",
|
|
170
|
-
],
|
|
171
|
-
rig: [
|
|
172
|
-
"Setting up sandbox environment",
|
|
173
|
-
"Sandbox Environment setup failed",
|
|
174
|
-
"Sandbox Environment setup interrupted",
|
|
175
|
-
"Sandbox Environment ready",
|
|
176
|
-
],
|
|
177
|
-
repository: [
|
|
178
|
-
"Preparing repository",
|
|
179
|
-
"Repository preparation failed",
|
|
180
|
-
"Repository preparation interrupted",
|
|
181
|
-
"Repository ready",
|
|
182
|
-
],
|
|
183
|
-
files: [
|
|
184
|
-
"Preparing files",
|
|
185
|
-
"File preparation failed",
|
|
186
|
-
"File preparation interrupted",
|
|
187
|
-
"Files ready",
|
|
188
|
-
],
|
|
189
|
-
tools: [
|
|
190
|
-
"Connecting tools",
|
|
191
|
-
"Tool connection failed",
|
|
192
|
-
"Tool connection interrupted",
|
|
193
|
-
"Tools ready",
|
|
194
|
-
],
|
|
195
|
-
model_preparation: [
|
|
196
|
-
"Preparing runtime and model request",
|
|
197
|
-
"Runtime/model preparation failed",
|
|
198
|
-
"Runtime/model preparation interrupted",
|
|
199
|
-
"Model request dispatched",
|
|
200
|
-
],
|
|
201
|
-
provider_first_byte: [
|
|
202
|
-
"Waiting for model",
|
|
203
|
-
"Model didn’t respond",
|
|
204
|
-
"Model wait interrupted",
|
|
205
|
-
"Model started responding",
|
|
206
|
-
],
|
|
207
|
-
};
|
|
208
|
-
|
|
209
|
-
function startupDuration(durationMs: number | null): string | null {
|
|
210
|
-
if (durationMs === null || !Number.isFinite(durationMs) || durationMs < 0) return null;
|
|
211
|
-
if (durationMs < 1_000) return `${Math.round(durationMs)}ms`;
|
|
212
|
-
if (durationMs < 60_000) return `${(durationMs / 1_000).toFixed(1)}s`;
|
|
213
|
-
const minutes = Math.floor(durationMs / 60_000);
|
|
214
|
-
const seconds = Math.round((durationMs % 60_000) / 1_000);
|
|
215
|
-
return `${minutes}m ${String(seconds).padStart(2, "0")}s`;
|
|
216
|
-
}
|
|
@@ -20,7 +20,15 @@ export function isRetainedImageContentType(contentType: string): boolean {
|
|
|
20
20
|
].includes(contentType);
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
/**
|
|
23
|
+
/** A published patch, applied locally with `git apply`. */
|
|
24
|
+
export function isPatchFilename(filename: string): boolean {
|
|
25
|
+
return /\.(patch|diff)$/iu.test(filename.trim());
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Deliberately published images and patches are primary output, not
|
|
30
|
+
* incidental screenshots or work files.
|
|
31
|
+
*/
|
|
24
32
|
export function activityPresentsImage(items: readonly ActivityItem[]): boolean {
|
|
25
33
|
return items.some((item) => {
|
|
26
34
|
if (item.kind !== "tool-call") return false;
|
|
@@ -30,7 +38,13 @@ export function activityPresentsImage(items: readonly ActivityItem[]): boolean {
|
|
|
30
38
|
const output = normalizeMcpOutput(item.output);
|
|
31
39
|
if (output.isError) return false;
|
|
32
40
|
const receipt = parseSandboxFileArtifactReceipt(output.text);
|
|
33
|
-
return
|
|
41
|
+
return (
|
|
42
|
+
receipt !== null &&
|
|
43
|
+
(isRetainedImageContentType(receipt.artifact.contentType) ||
|
|
44
|
+
// A published patch is the deliverable when there's no pull request:
|
|
45
|
+
// keep its card (with the apply command) visible like an image.
|
|
46
|
+
isPatchFilename(receipt.filename))
|
|
47
|
+
);
|
|
34
48
|
});
|
|
35
49
|
}
|
|
36
50
|
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* "Back to your message": which prompt the reader is reading the answer to, and
|
|
3
|
+
* whether that prompt has scrolled out of view. Renderer-neutral geometry so
|
|
4
|
+
* the web timeline (DOM rects) and native timelines (layout offsets) agree.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/** How far above the viewport a prompt must be before the pill appears. */
|
|
8
|
+
export const QUESTION_NAV_HIDDEN_PX = 24;
|
|
9
|
+
/** Breathing room above the question when the reader jumps back to it. */
|
|
10
|
+
export const QUESTION_NAV_MARGIN_PX = 12;
|
|
11
|
+
|
|
12
|
+
export type QuestionNavPrompt = { key: string; top: number; bottom: number };
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* The last prompt before the reading position (the viewport's middle) owns the
|
|
16
|
+
* response in view; it is a target only once it has scrolled fully above the
|
|
17
|
+
* viewport. Prompts are in document order; coordinates share one axis.
|
|
18
|
+
*/
|
|
19
|
+
export function questionNavTarget(
|
|
20
|
+
prompts: readonly QuestionNavPrompt[],
|
|
21
|
+
view: { top: number; height: number },
|
|
22
|
+
): string | null {
|
|
23
|
+
const middle = view.top + view.height / 2;
|
|
24
|
+
const prompt = [...prompts].reverse().find((candidate) => candidate.top <= middle);
|
|
25
|
+
if (!prompt) return null;
|
|
26
|
+
if (prompt.top >= view.top - QUESTION_NAV_HIDDEN_PX || prompt.bottom > view.top) return null;
|
|
27
|
+
return prompt.key;
|
|
28
|
+
}
|
package/src/timeline/registry.ts
CHANGED
|
@@ -35,7 +35,17 @@ export type RetainedScreenshotLoader = (
|
|
|
35
35
|
export type RetainedArtifactLoader = (
|
|
36
36
|
artifact: RetainedArtifactReference,
|
|
37
37
|
signal: AbortSignal,
|
|
38
|
-
|
|
38
|
+
options?: RetainedArtifactLoadOptions,
|
|
39
|
+
) => Promise<Uint8Array | { url: string; expiresAt?: string | undefined } | null>;
|
|
40
|
+
|
|
41
|
+
export type RetainedArtifactLoadOptions = {
|
|
42
|
+
/**
|
|
43
|
+
* Ask for a short-lived download URL instead of bytes, for example to build a
|
|
44
|
+
* copyable `curl … | git apply` command. A loader that cannot mint one may
|
|
45
|
+
* still return bytes; callers must handle that.
|
|
46
|
+
*/
|
|
47
|
+
prefer?: "url" | undefined;
|
|
48
|
+
};
|
|
39
49
|
|
|
40
50
|
/** Mint an expiring source for native browser playback without loading video bytes in JS. */
|
|
41
51
|
export type VideoArtifactPlaybackLoader = (
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { OpenGeniClient, RetainedArtifactReference } from "@opengeni/sdk";
|
|
2
2
|
import type {
|
|
3
|
+
RetainedArtifactLoadOptions,
|
|
3
4
|
RetainedArtifactLoader,
|
|
4
5
|
RetainedScreenshotLoader,
|
|
5
6
|
VideoArtifactPlaybackLoader,
|
|
@@ -21,21 +22,25 @@ export type RetainedVideoLoaderClient = Pick<OpenGeniClient, "createVideoArtifac
|
|
|
21
22
|
* Bind permanent retained-artifact retrieval (generated images, published
|
|
22
23
|
* files) to one authenticated workspace, for `MessageTimeline`'s
|
|
23
24
|
* `loadRetainedArtifact`. Images get a short-lived URL; files are assembled
|
|
24
|
-
* from verified byte ranges.
|
|
25
|
+
* from verified byte ranges unless the caller asks for a URL.
|
|
25
26
|
*/
|
|
26
27
|
export function createWorkspaceRetainedArtifactLoader(
|
|
27
28
|
client: RetainedArtifactLoaderClient,
|
|
28
29
|
workspaceId: string,
|
|
29
30
|
): RetainedArtifactLoader {
|
|
30
|
-
return async (
|
|
31
|
-
|
|
31
|
+
return async (
|
|
32
|
+
artifact: RetainedArtifactReference,
|
|
33
|
+
signal: AbortSignal,
|
|
34
|
+
options?: RetainedArtifactLoadOptions,
|
|
35
|
+
) => {
|
|
36
|
+
if (artifact.kind === "file" && options?.prefer !== "url") {
|
|
32
37
|
const download = await client.downloadRetainedArtifact(workspaceId, artifact, { signal });
|
|
33
38
|
return download.bytes;
|
|
34
39
|
}
|
|
35
40
|
const download = await client.createRetainedArtifactDownloadUrl(workspaceId, artifact, {
|
|
36
41
|
signal,
|
|
37
42
|
});
|
|
38
|
-
return { url: download.url };
|
|
43
|
+
return { url: download.url, expiresAt: download.expiresAt };
|
|
39
44
|
};
|
|
40
45
|
}
|
|
41
46
|
|
|
@@ -7,6 +7,7 @@ import { defaultToolRegistry } from "./tool-renderers";
|
|
|
7
7
|
import type { ToolRegistry } from "./registry";
|
|
8
8
|
import { toolDisplayName } from "./tool-display-name";
|
|
9
9
|
import type { ActivityItem } from "./types";
|
|
10
|
+
import { rollingActivityItem } from "./work-presentation";
|
|
10
11
|
|
|
11
12
|
/** One stable viewport; updates replace its content without moving the conversation. */
|
|
12
13
|
export function RollingActivity({
|
|
@@ -25,21 +26,11 @@ export function RollingActivity({
|
|
|
25
26
|
const reduced = useReducedMotion();
|
|
26
27
|
const [mounted, setMounted] = useState(false);
|
|
27
28
|
useEffect(() => setMounted(true), []);
|
|
28
|
-
// Progress notes have their own line in the status row; the reel shows steps
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
);
|
|
32
|
-
const
|
|
33
|
-
item.kind === "reasoning" ? item.streaming : "status" in item && item.status === "running",
|
|
34
|
-
);
|
|
35
|
-
// Advance with the event order; finishing a parallel tool must not replay an older one.
|
|
36
|
-
const item =
|
|
37
|
-
!mounted && previousItem && previousItem.kind !== "agent-message" ? previousItem : work.at(-1);
|
|
38
|
-
if (!item) return null;
|
|
39
|
-
const earlierCount = Math.max(
|
|
40
|
-
0,
|
|
41
|
-
work.findIndex((entry) => entry.id === item.id),
|
|
42
|
-
);
|
|
29
|
+
// Progress notes have their own line in the status row; the reel shows steps, advancing
|
|
30
|
+
// with the event order so finishing a parallel tool never replays an older one.
|
|
31
|
+
const selected = rollingActivityItem(items, previousItem, mounted);
|
|
32
|
+
if (!selected) return null;
|
|
33
|
+
const { item, earlierCount } = selected;
|
|
43
34
|
const fallback = (
|
|
44
35
|
<span className="og-rolling-label">
|
|
45
36
|
<WrenchIcon className="size-3.5" />
|
|
@@ -49,10 +40,7 @@ export function RollingActivity({
|
|
|
49
40
|
</span>
|
|
50
41
|
);
|
|
51
42
|
return (
|
|
52
|
-
<span
|
|
53
|
-
className="og-rolling-status"
|
|
54
|
-
data-running={active.some((entry) => entry.id === item.id) ? "true" : undefined}
|
|
55
|
-
>
|
|
43
|
+
<span className="og-rolling-status" data-running={selected.running ? "true" : undefined}>
|
|
56
44
|
<span className="sr-only">
|
|
57
45
|
{item.kind === "tool-call"
|
|
58
46
|
? toolDisplayName(item.name, item.display)
|