@opengeni/react 5.2.0-canary.0 → 5.2.0-canary.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 +12 -0
- package/dist/{chunk-5PQJOCX5.js → chunk-KANFU34B.js} +6 -4
- package/dist/chunk-KANFU34B.js.map +1 -0
- package/dist/{chunk-QXJCNVSD.js → chunk-O4NQNMPG.js} +1534 -1315
- package/dist/chunk-O4NQNMPG.js.map +1 -0
- package/dist/{chunk-IYCR4343.js → chunk-PZ27MCZP.js} +36 -1
- package/dist/chunk-PZ27MCZP.js.map +1 -0
- package/dist/{chunk-T5FRXMC3.js → chunk-YS24CFDI.js} +24 -9
- package/dist/chunk-YS24CFDI.js.map +1 -0
- package/dist/components/session-chrome.d.ts +6 -1
- package/dist/{computer-viewer-AA4JH2AP.js → computer-viewer-CTFCJVS7.js} +2 -2
- package/dist/hooks/use-file-attachments.d.ts +2 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +12 -4
- package/dist/index.js.map +1 -1
- package/dist/interaction.js +1 -1
- package/dist/{platform-activity-row-UW4UVVM4.js → platform-activity-row-DUE2W74J.js} +1 -1
- package/dist/platform-activity-row-DUE2W74J.js.map +1 -0
- package/dist/session-ui.d.ts +2 -0
- package/dist/session-ui.js +5 -106
- package/dist/session-ui.js.map +1 -1
- package/dist/session.js +2 -2
- package/dist/timeline/genie-loading.d.ts +9 -1
- package/dist/timeline/index.d.ts +3 -1
- package/dist/timeline/knowledge-receipt.d.ts +17 -0
- package/dist/timeline/platform-activity-row.d.ts +0 -1
- package/dist/timeline/types.d.ts +13 -2
- package/package.json +3 -3
- package/src/components/computer-viewer.tsx +11 -3
- package/src/components/session-chrome.tsx +14 -2
- package/src/hooks/use-computer-frame-stream.ts +17 -5
- package/src/hooks/use-file-attachments.ts +4 -1
- package/src/hooks/use-goal.ts +3 -1
- package/src/index.ts +6 -0
- package/src/session-ui.ts +3 -0
- package/src/timeline/activity-rail.tsx +11 -1
- package/src/timeline/genie-loading.tsx +18 -4
- package/src/timeline/index.ts +4 -0
- package/src/timeline/knowledge-receipt.tsx +100 -0
- package/src/timeline/platform-activity-row.tsx +0 -1
- package/src/timeline/projection.ts +40 -0
- package/src/timeline/tool-renderers.tsx +48 -0
- package/src/timeline/types.ts +14 -0
- package/dist/chunk-5PQJOCX5.js.map +0 -1
- package/dist/chunk-IYCR4343.js.map +0 -1
- package/dist/chunk-QXJCNVSD.js.map +0 -1
- package/dist/chunk-T5FRXMC3.js.map +0 -1
- package/dist/platform-activity-row-UW4UVVM4.js.map +0 -1
- /package/dist/{computer-viewer-AA4JH2AP.js.map → computer-viewer-CTFCJVS7.js.map} +0 -0
package/dist/interaction.js
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/timeline/platform-activity-row.tsx"],"sourcesContent":["import type { ReasoningItem, SandboxItem, StartupPhaseItem } from \"./types\";\n\ntype RowJsx = typeof import(\"react/jsx-runtime\").jsx;\ntype RowJsxs = typeof import(\"react/jsx-runtime\").jsxs;\n\nexport default function PlatformActivityRow({\n item,\n d: ActivityDisclosure,\n p: PayloadBlock,\n t: displayName,\n b: BotIcon,\n m: Markdown,\n j,\n s,\n}: {\n item: ReasoningItem | SandboxItem | StartupPhaseItem;\n d: typeof import(\"./shared\").ActivityDisclosure;\n p: typeof import(\"./shared\").PayloadBlock;\n t: (name: string) => string;\n b: typeof import(\"lucide-react\").BotIcon;\n m: typeof import(\"../components/markdown\").Markdown;\n j: RowJsx;\n s: RowJsxs;\n}) {\n if (item.kind === \"reasoning\") {\n return j(ActivityDisclosure, {\n icon: brainIcon(j, s),\n iconTone: \"muted\",\n title: item.streaming\n ? \"Thinking\"\n : j(\"span\", {\n className: \"font-normal italic text-og-fg-subtle\",\n children: \"Thought\",\n }),\n running: item.streaming,\n compactPreview: item.text.replace(/\\*\\*|__|`/g, \"\").replace(/\\s+/g, \" \"),\n preview: j(\"span\", {\n className: \"og-reasoning-preview\",\n children: j(Markdown, { streaming: item.streaming, children: item.text }),\n }),\n children: j(\"div\", {\n className: \"text-og-base leading-6 text-og-fg-muted [&_strong]:text-og-fg-muted\",\n children: j(Markdown, { streaming: item.streaming, children: item.text }),\n }),\n });\n }\n if (item.kind === \"sandbox\") {\n return s(ActivityDisclosure, {\n icon: terminalIcon(j, s),\n iconTone:\n item.status === \"failed\" ? \"failed\" : item.status === \"running\" ? \"running\" : \"muted\",\n title: sandboxRowTitle(item, displayName),\n running: item.status === \"running\",\n failed: item.status === \"failed\",\n cancelled: item.status === \"cancelled\",\n preview: item.command ?? undefined,\n children: [\n item.command ? j(PayloadBlock, { label: \"Command\", value: item.command }, \"command\") : null,\n item.output ? j(PayloadBlock, { label: \"Output\", value: item.output }, \"output\") : null,\n ],\n });\n }\n\n const failed = item.status === \"failed\";\n const running = item.status === \"running\";\n const duration = startupDuration(item.durationMs);\n return j(ActivityDisclosure, {\n icon: j(BotIcon, { className: \"size-3.5\" }),\n iconTone: failed ? \"failed\" : running ? \"running\" : \"muted\",\n title:\n item.blockedReason === \"rotation_in_progress\"\n ? \"Waiting for sandbox rotation\"\n : startupPhaseTitle(item.phase, item.status, item.outcome),\n preview:\n item.phase === \"model_preparation\"\n ? \"Includes overlapping sandbox, rig, repository, and runtime setup shown below.\"\n : undefined,\n running,\n failed,\n cancelled: item.status === \"cancelled\",\n chip: duration ? { tone: failed ? \"bad\" : \"muted\", text: duration } : undefined,\n expandable: false,\n });\n}\n\nfunction brainIcon(j: RowJsx, s: RowJsxs) {\n return lucideIcon(j, s, \"brain\", [\n j(\"path\", { d: \"M 12 18V5\" }, \"spine\"),\n j(\"path\", { d: \"M15 13a4.17 4.17 0 0 1-3-4 4.17 4.17 0 0 1-3 4\" }, \"center\"),\n j(\"path\", { d: \"M17.598 6.5A3 3 0 1 0 12 5a3 3 0 1 0-5.598 1.5\" }, \"top\"),\n j(\"path\", { d: \"M17.997 5.125a4 4 0 0 1 2.526 5.77\" }, \"upper-right\"),\n j(\"path\", { d: \"M18 18a4 4 0 0 0 2-7.464\" }, \"right\"),\n j(\"path\", { d: \"M19.967 17.483A4 4 0 1 1 12 18a4 4 0 1 1-7.967-.517\" }, \"base\"),\n j(\"path\", { d: \"M6 18a4 4 0 0 1-2-7.464\" }, \"left\"),\n j(\"path\", { d: \"M6.003 5.125a4 4 0 0 0-2.526 5.77\" }, \"upper-left\"),\n ]);\n}\n\nfunction terminalIcon(j: RowJsx, s: RowJsxs) {\n return lucideIcon(j, s, \"square-terminal\", [\n j(\"path\", { d: \"m7 11 2-2-2-2\" }, \"prompt\"),\n j(\"path\", { d: \"M11 13h4\" }, \"cursor\"),\n j(\"rect\", { width: 18, height: 18, x: 3, y: 3, rx: 2, ry: 2 }, \"frame\"),\n ]);\n}\n\nfunction lucideIcon(j: RowJsx, s: RowJsxs, name: string, children: ReturnType<RowJsx>[]) {\n return s(\"svg\", {\n \"aria-hidden\": \"true\",\n className: `lucide lucide-${name} size-3.5`,\n fill: \"none\",\n height: 24,\n stroke: \"currentColor\",\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\",\n strokeWidth: 2,\n viewBox: \"0 0 24 24\",\n width: 24,\n children,\n });\n}\n\nfunction sandboxRowTitle(item: SandboxItem, displayName: (name: string) => string): string {\n if (item.name === \"sandbox.provision\") {\n return startupPhaseTitle(\n \"sandbox\",\n item.status === \"cancelled\" ? \"complete\" : item.status,\n item.origin ?? null,\n );\n }\n return displayName(item.name);\n}\n\nfunction startupPhaseTitle(\n phase: StartupPhaseItem[\"phase\"],\n status: StartupPhaseItem[\"status\"],\n outcome: StartupPhaseItem[\"outcome\"],\n): string {\n if (status === \"complete\" && phase === \"sandbox\" && outcome && outcome !== \"skipped\") {\n return `Sandbox ${outcome === \"resumed\" ? \"reattached\" : outcome}`;\n }\n if (status === \"complete\" && phase === \"rig\" && outcome === \"skipped\") {\n return \"Rig already ready\";\n }\n const statusIndex =\n status === \"running\" ? 0 : status === \"failed\" ? 1 : status === \"cancelled\" ? 2 : 3;\n return STARTUP_PHASE_TITLES[phase][statusIndex];\n}\n\nconst STARTUP_PHASE_TITLES: Record<\n StartupPhaseItem[\"phase\"],\n readonly [string, string, string, string]\n> = {\n queue: [\n \"Waiting for a worker\",\n \"Worker startup failed\",\n \"Worker wait interrupted\",\n \"Worker started\",\n ],\n sandbox: [\n \"Starting sandbox\",\n \"Sandbox didn’t start\",\n \"Sandbox startup interrupted\",\n \"Sandbox ready\",\n ],\n rig: [\"Setting up rig\", \"Rig setup failed\", \"Rig setup interrupted\", \"Rig ready\"],\n repository: [\n \"Preparing repository\",\n \"Repository preparation failed\",\n \"Repository preparation interrupted\",\n \"Repository ready\",\n ],\n files: [\n \"Preparing files\",\n \"File preparation failed\",\n \"File preparation interrupted\",\n \"Files ready\",\n ],\n tools: [\n \"Connecting tools\",\n \"Tool connection failed\",\n \"Tool connection interrupted\",\n \"Tools ready\",\n ],\n model_preparation: [\n \"Preparing runtime and model request\",\n \"Runtime/model preparation failed\",\n \"Runtime/model preparation interrupted\",\n \"Model request dispatched\",\n ],\n provider_first_byte: [\n \"Waiting for model\",\n \"Model didn’t respond\",\n \"Model wait interrupted\",\n \"Model started responding\",\n ],\n};\n\nfunction startupDuration(durationMs: number | null): string | null {\n if (durationMs === null || !Number.isFinite(durationMs) || durationMs < 0) return null;\n if (durationMs < 1_000) return `${Math.round(durationMs)}ms`;\n if (durationMs < 60_000) return `${(durationMs / 1_000).toFixed(1)}s`;\n const minutes = Math.floor(durationMs / 60_000);\n const seconds = Math.round((durationMs % 60_000) / 1_000);\n return `${minutes}m ${String(seconds).padStart(2, \"0\")}s`;\n}\n"],"mappings":"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","names":[]}
|
package/dist/session-ui.d.ts
CHANGED
|
@@ -19,6 +19,8 @@ export type { QueueSurfaceProps } from "./components/queue-surface.js";
|
|
|
19
19
|
export { SessionChrome, sessionChromeGoalPillExplanation, sessionChromeGoalPillLabel, sessionChromeGoalPillState, } from "./components/session-chrome.js";
|
|
20
20
|
export type { SessionChromeAgentsSignal, SessionChromeProps, SessionChromeSignalId, SessionChromeSignalTone, } from "./components/session-chrome.js";
|
|
21
21
|
export { SessionCommandsPanel } from "./components/session-commands-panel.js";
|
|
22
|
+
export { KnowledgeActivityProvider } from "./timeline/knowledge-receipt.js";
|
|
23
|
+
export type { KnowledgeActivityActions } from "./timeline/knowledge-receipt.js";
|
|
22
24
|
export { StartupTimings } from "./timeline/startup-timings.js";
|
|
23
25
|
export { useStartupDetails, setStartupDetails } from "./timeline/startup-preference.js";
|
|
24
26
|
export type { GenieLoadingOptions } from "./timeline/genie-loading.js";
|
package/dist/session-ui.js
CHANGED
|
@@ -3,11 +3,13 @@ import {
|
|
|
3
3
|
BUILT_IN_TURN_SUMMARY_FACET_IDS,
|
|
4
4
|
HumanInputForm,
|
|
5
5
|
HumanInputSurface,
|
|
6
|
+
KnowledgeActivityProvider,
|
|
6
7
|
MessageTimeline,
|
|
7
8
|
QueueSurface,
|
|
8
9
|
SessionChrome,
|
|
9
10
|
SessionCommandsPanel,
|
|
10
11
|
SessionConversation,
|
|
12
|
+
StartupTimings,
|
|
11
13
|
TimelineRow,
|
|
12
14
|
UserMessageBody,
|
|
13
15
|
sessionChromeGoalPillExplanation,
|
|
@@ -16,7 +18,7 @@ import {
|
|
|
16
18
|
setStartupDetails,
|
|
17
19
|
useStartupDetails,
|
|
18
20
|
userMessageLikelyNeedsDisclosure
|
|
19
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-O4NQNMPG.js";
|
|
20
22
|
import "./chunk-YBM6CQRU.js";
|
|
21
23
|
import "./chunk-5M6VTFJ5.js";
|
|
22
24
|
import "./chunk-ZYRGEKWS.js";
|
|
@@ -31,122 +33,19 @@ import "./chunk-R4KRSFGA.js";
|
|
|
31
33
|
import "./chunk-VZTQ73XT.js";
|
|
32
34
|
import {
|
|
33
35
|
createOlderHistoryLoadReceipt
|
|
34
|
-
} from "./chunk-
|
|
36
|
+
} from "./chunk-PZ27MCZP.js";
|
|
35
37
|
import "./chunk-NYESIADM.js";
|
|
36
38
|
import "./chunk-PLYRL5ER.js";
|
|
37
39
|
import "./chunk-KZ73RL76.js";
|
|
38
40
|
import "./chunk-NEXLLTP4.js";
|
|
39
41
|
import "./chunk-VRBL3F5E.js";
|
|
40
42
|
import "./chunk-22KP6LR5.js";
|
|
41
|
-
|
|
42
|
-
// src/timeline/startup-timings.tsx
|
|
43
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
44
|
-
var LABELS = {
|
|
45
|
-
queue: "Worker queue",
|
|
46
|
-
sandbox: "Sandbox",
|
|
47
|
-
rig: "Rig",
|
|
48
|
-
repository: "Repository",
|
|
49
|
-
files: "Files",
|
|
50
|
-
tools: "Tools",
|
|
51
|
-
model_preparation: "Runtime & model request",
|
|
52
|
-
provider_first_byte: "First model response"
|
|
53
|
-
};
|
|
54
|
-
function StartupTimings({ phases }) {
|
|
55
|
-
if (!phases.length)
|
|
56
|
-
return /* @__PURE__ */ jsx("p", { className: "text-og-sm text-og-fg-subtle", children: "No startup timings recorded yet." });
|
|
57
|
-
const byTurn = /* @__PURE__ */ new Map();
|
|
58
|
-
for (const phase of phases) {
|
|
59
|
-
const group = byTurn.get(phase.turnId) ?? [];
|
|
60
|
-
group.push(phase);
|
|
61
|
-
byTurn.set(phase.turnId, group);
|
|
62
|
-
}
|
|
63
|
-
const turns = [...byTurn.entries()].map(([turnId, turnPhases]) => ({
|
|
64
|
-
turnId,
|
|
65
|
-
phases: turnPhases,
|
|
66
|
-
startedAt: turnPhases.reduce(
|
|
67
|
-
(earliest, phase) => phase.startedAt < earliest ? phase.startedAt : earliest,
|
|
68
|
-
turnPhases[0].startedAt
|
|
69
|
-
)
|
|
70
|
-
})).sort((a, b) => b.startedAt.localeCompare(a.startedAt));
|
|
71
|
-
return /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
72
|
-
/* @__PURE__ */ jsx("p", { className: "text-og-xs text-og-fg-subtle", children: "Each turn has its own startup. Phases can overlap; durations are not additive." }),
|
|
73
|
-
turns.map((turn, index) => /* @__PURE__ */ jsx(
|
|
74
|
-
StartupTurn,
|
|
75
|
-
{
|
|
76
|
-
...turn,
|
|
77
|
-
latest: index === 0 && turn.turnId !== null
|
|
78
|
-
},
|
|
79
|
-
turn.turnId ?? "unassigned"
|
|
80
|
-
))
|
|
81
|
-
] });
|
|
82
|
-
}
|
|
83
|
-
function StartupTurn({
|
|
84
|
-
turnId,
|
|
85
|
-
phases,
|
|
86
|
-
startedAt,
|
|
87
|
-
latest
|
|
88
|
-
}) {
|
|
89
|
-
const status = phases.some((phase) => phase.status === "failed") ? "Failed" : phases.some((phase) => phase.status === "running") ? "In progress" : phases.some((phase) => phase.status === "cancelled") ? "Interrupted" : "Ready";
|
|
90
|
-
return /* @__PURE__ */ jsxs("details", { open: latest, className: "group border-b border-og-border pb-3", children: [
|
|
91
|
-
/* @__PURE__ */ jsxs("summary", { className: "cursor-pointer rounded py-3 text-og-sm text-og-fg-muted focus-visible:outline-2 focus-visible:outline-og-accent", children: [
|
|
92
|
-
/* @__PURE__ */ jsx("span", { className: "font-medium", children: turnId === null ? "Unassigned events" : latest ? "Latest turn" : "Earlier turn" }),
|
|
93
|
-
/* @__PURE__ */ jsx("span", { className: "ml-2 text-og-xs text-og-fg-subtle", children: new Date(startedAt).toLocaleTimeString([], {
|
|
94
|
-
hour: "2-digit",
|
|
95
|
-
minute: "2-digit",
|
|
96
|
-
second: "2-digit"
|
|
97
|
-
}) }),
|
|
98
|
-
/* @__PURE__ */ jsx(
|
|
99
|
-
"span",
|
|
100
|
-
{
|
|
101
|
-
className: status === "Failed" ? "ml-2 text-og-xs text-og-status-failed" : "ml-2 text-og-xs text-og-fg-subtle",
|
|
102
|
-
children: status
|
|
103
|
-
}
|
|
104
|
-
),
|
|
105
|
-
/* @__PURE__ */ jsx("span", { className: "mt-1 block break-all pl-4 font-og-mono text-og-xs text-og-fg-subtle", children: turnId ?? "No turn ID recorded" })
|
|
106
|
-
] }),
|
|
107
|
-
/* @__PURE__ */ jsxs("div", { className: "pb-2", children: [
|
|
108
|
-
/* @__PURE__ */ jsxs("p", { className: "text-og-xs text-og-fg-subtle", children: [
|
|
109
|
-
"Started ",
|
|
110
|
-
/* @__PURE__ */ jsx("time", { dateTime: startedAt, children: new Date(startedAt).toLocaleString() })
|
|
111
|
-
] }),
|
|
112
|
-
/* @__PURE__ */ jsx("div", { className: "overflow-x-auto", children: /* @__PURE__ */ jsxs("table", { className: "w-full text-left text-og-xs", children: [
|
|
113
|
-
/* @__PURE__ */ jsxs("caption", { className: "sr-only", children: [
|
|
114
|
-
"Startup phases for ",
|
|
115
|
-
turnId ?? "unassigned events"
|
|
116
|
-
] }),
|
|
117
|
-
/* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { className: "border-b border-og-border text-og-fg-subtle", children: [
|
|
118
|
-
/* @__PURE__ */ jsx("th", { scope: "col", className: "py-2 font-medium", children: "Phase" }),
|
|
119
|
-
/* @__PURE__ */ jsx("th", { scope: "col", className: "px-3 py-2 font-medium", children: "Status" }),
|
|
120
|
-
/* @__PURE__ */ jsx("th", { scope: "col", className: "py-2 text-right font-medium", children: "Duration" })
|
|
121
|
-
] }) }),
|
|
122
|
-
/* @__PURE__ */ jsx("tbody", { children: phases.map((phase) => /* @__PURE__ */ jsxs(
|
|
123
|
-
"tr",
|
|
124
|
-
{
|
|
125
|
-
className: "border-b border-og-border/40",
|
|
126
|
-
title: `Turn: ${phase.turnId ?? "unknown"} \xB7 Started: ${phase.startedAt}`,
|
|
127
|
-
children: [
|
|
128
|
-
/* @__PURE__ */ jsx("th", { scope: "row", className: "py-2.5 font-normal text-og-fg-muted", children: LABELS[phase.phase] }),
|
|
129
|
-
/* @__PURE__ */ jsx(
|
|
130
|
-
"td",
|
|
131
|
-
{
|
|
132
|
-
className: `px-3 py-2.5 ${phase.status === "failed" ? "text-og-status-failed" : "text-og-fg-subtle"}`,
|
|
133
|
-
children: phase.status === "running" ? "In progress" : phase.status
|
|
134
|
-
}
|
|
135
|
-
),
|
|
136
|
-
/* @__PURE__ */ jsx("td", { className: "py-2.5 text-right font-og-mono tabular-nums text-og-fg-muted", children: phase.durationMs === null ? "\u2014" : phase.durationMs < 1e3 ? `${Math.round(phase.durationMs)} ms` : `${(phase.durationMs / 1e3).toFixed(1)} s` })
|
|
137
|
-
]
|
|
138
|
-
},
|
|
139
|
-
phase.id
|
|
140
|
-
)) })
|
|
141
|
-
] }) })
|
|
142
|
-
] })
|
|
143
|
-
] });
|
|
144
|
-
}
|
|
145
43
|
export {
|
|
146
44
|
ApprovalSurface,
|
|
147
45
|
BUILT_IN_TURN_SUMMARY_FACET_IDS,
|
|
148
46
|
HumanInputForm,
|
|
149
47
|
HumanInputSurface,
|
|
48
|
+
KnowledgeActivityProvider,
|
|
150
49
|
MessageTimeline,
|
|
151
50
|
QueueSurface,
|
|
152
51
|
SessionChrome,
|
package/dist/session-ui.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/dist/session.js
CHANGED
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
useSessionControl,
|
|
11
11
|
useSessionLineage,
|
|
12
12
|
useSessionMcpApprovalPolicy
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-KANFU34B.js";
|
|
14
14
|
import {
|
|
15
15
|
buildTimeline,
|
|
16
16
|
createOlderHistoryLoadReceipt,
|
|
@@ -28,7 +28,7 @@ import {
|
|
|
28
28
|
useSession,
|
|
29
29
|
useSessionEvents,
|
|
30
30
|
useTurnQueue
|
|
31
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-PZ27MCZP.js";
|
|
32
32
|
import {
|
|
33
33
|
FILE_ONLY_MESSAGE_TEXT,
|
|
34
34
|
composeSendInput,
|
|
@@ -8,7 +8,15 @@ export type GenieLoadingOptions = {
|
|
|
8
8
|
/** Replace the visual while preserving SDK loading visibility and transitions. */
|
|
9
9
|
render?: (props: GenieLoadingRenderProps) => ReactNode;
|
|
10
10
|
phrases?: readonly string[];
|
|
11
|
-
/**
|
|
11
|
+
/** Native copy overrides. Omitted messages retain the default English copy. */
|
|
12
|
+
messages?: {
|
|
13
|
+
status?: string;
|
|
14
|
+
slowStatus?: string;
|
|
15
|
+
slowText?: string;
|
|
16
|
+
showDetails?: string;
|
|
17
|
+
hideDetails?: string;
|
|
18
|
+
};
|
|
19
|
+
/** Public adapter options; the renderer dependency's declarations stay private. */
|
|
12
20
|
orb?: {
|
|
13
21
|
state?: "working" | "searching" | "solving" | "listening" | "connecting" | "weaving" | "composing" | "breathing" | "shaping";
|
|
14
22
|
size?: 64 | 20;
|
package/dist/timeline/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { buildTimeline, creditExhaustedFromEvents, extractSessionRef, groupTimeline, sessionStatusFromEvents, mcpToolLeaf, toolDisplayName, toolMatchesLeaf, } from "./projection.js";
|
|
2
|
-
export type { ActivityItem, AgentMessageItem, AuthNeededItem, ContextCompactionItem, FleetDecisionItem, FleetDecisionScoreItem, GoalItem, HumanInputAnswerSummary, HumanInputItem, MachineInputBatchItem, MachineInputMember, MemoryItem, NoticeItem, ReasoningItem, SandboxItem, StartupPhase, StartupPhaseItem, SessionStatusItem, TimelineGroup, TimelineItem, TimelineAnnotationSourceDescriptor, TurnEndItem, ToolCallItem, UserMessageItem, WorkerCompletionItem, WorkerItem, } from "./types.js";
|
|
2
|
+
export type { ActivityItem, AgentMessageItem, AuthNeededItem, ContextCompactionItem, FleetDecisionItem, FleetDecisionScoreItem, GoalItem, HumanInputAnswerSummary, HumanInputItem, MachineInputBatchItem, MachineInputMember, MemoryItem, KnowledgeItem, NoticeItem, ReasoningItem, SandboxItem, StartupPhase, StartupPhaseItem, SessionStatusItem, TimelineGroup, TimelineItem, TimelineAnnotationSourceDescriptor, TurnEndItem, ToolCallItem, UserMessageItem, WorkerCompletionItem, WorkerItem, } from "./types.js";
|
|
3
3
|
export { createToolRegistry, rawTypeOf } from "./registry.js";
|
|
4
4
|
export type { CreateToolRegistryOptions, RetainedArtifactLoader, RetainedScreenshotLoader, VideoArtifactPlaybackLoader, ToolRegistry, ToolRegistryEntry, ToolRenderer, ToolRendererProps, } from "./registry.js";
|
|
5
5
|
export { createDefaultToolRegistry, defaultToolRegistry } from "./tool-renderers.js";
|
|
@@ -18,3 +18,5 @@ export { BUILT_IN_TURN_SUMMARY_FACET_IDS, TurnSummary, useTurnSettleOpen } from
|
|
|
18
18
|
export type { BuiltInTurnSummaryFacetId, TurnOutcome, TurnSummaryContext, TurnSummaryFacet, TurnSummaryFacetConfiguration, TurnSummaryFacetResult, TurnSummaryOptions, TurnSummaryProps, } from "./turn-summary.js";
|
|
19
19
|
export { applyPatchOps, applyPatchOpsFromToolItem, parseFreeformApplyPatch, controlCaret, execTruncated, isApplyPatch, isExecSessionLostBanner, looksBinary, parseExecBannerSessionId, parseToolArgs, sandboxCommandExitCode, stripExecBanner, tailPeek, unwrapMcpOutput, v4aToGitFileDiff, } from "./parsers.js";
|
|
20
20
|
export type { ApplyPatchOperation } from "./parsers.js";
|
|
21
|
+
export { KnowledgeActivityProvider } from "./knowledge-receipt.js";
|
|
22
|
+
export type { KnowledgeActivityActions } from "./knowledge-receipt.js";
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
export type KnowledgeActivityActions = {
|
|
3
|
+
onInspect?: ((entryId: string) => void) | undefined;
|
|
4
|
+
onRetryFile?: ((fileId: string) => Promise<boolean | void>) | undefined;
|
|
5
|
+
retryDisabled?: boolean | undefined;
|
|
6
|
+
};
|
|
7
|
+
export declare function KnowledgeActivityProvider({ children, ...actions }: KnowledgeActivityActions & {
|
|
8
|
+
children: ReactNode;
|
|
9
|
+
}): import("react").JSX.Element;
|
|
10
|
+
/** A saved/pending result never opens or blocks the human-input surface. */
|
|
11
|
+
export declare function KnowledgeReceiptRow(props: {
|
|
12
|
+
outcome: "published" | "pending" | "rejected" | "archived" | "failed";
|
|
13
|
+
entryId?: string | undefined;
|
|
14
|
+
fileId?: string | undefined;
|
|
15
|
+
title?: string | undefined;
|
|
16
|
+
source?: boolean | undefined;
|
|
17
|
+
}): import("react").JSX.Element;
|
|
@@ -8,7 +8,6 @@ export default function PlatformActivityRow({ item, d: ActivityDisclosure, p: Pa
|
|
|
8
8
|
t: (name: string) => string;
|
|
9
9
|
b: typeof import("lucide-react").BotIcon;
|
|
10
10
|
m: typeof import("../components/markdown.js").Markdown;
|
|
11
|
-
r: typeof import("../lib/format.js").truncate;
|
|
12
11
|
j: RowJsx;
|
|
13
12
|
s: RowJsxs;
|
|
14
13
|
}): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
|
package/dist/timeline/types.d.ts
CHANGED
|
@@ -185,6 +185,17 @@ export type StartupPhaseItem = {
|
|
|
185
185
|
* `onMemoryClick` handler the row also deep-links to the record in its memory
|
|
186
186
|
* pane; without one it is non-interactive rich content.
|
|
187
187
|
*/
|
|
188
|
+
export type KnowledgeItem = {
|
|
189
|
+
kind: "knowledge";
|
|
190
|
+
id: string;
|
|
191
|
+
turnId: string | null;
|
|
192
|
+
status: "complete" | "failed";
|
|
193
|
+
outcome: "published" | "pending" | "rejected" | "archived" | "failed";
|
|
194
|
+
fileId?: string | undefined;
|
|
195
|
+
filename?: string | undefined;
|
|
196
|
+
entryId?: string | undefined;
|
|
197
|
+
occurredAt: string;
|
|
198
|
+
};
|
|
188
199
|
export type MemoryItem = {
|
|
189
200
|
kind: "memory";
|
|
190
201
|
id: string;
|
|
@@ -361,9 +372,9 @@ export type TurnEndItem = {
|
|
|
361
372
|
failureText: string | null;
|
|
362
373
|
occurredAt: string;
|
|
363
374
|
};
|
|
364
|
-
export type TimelineItem = UserMessageItem | HumanInputItem | AgentMessageItem | ReasoningItem | ToolCallItem | WorkerItem | WorkerCompletionItem | SandboxItem | StartupPhaseItem | SessionStatusItem | GoalItem | NoticeItem | ContextCompactionItem | MachineInputBatchItem | AuthNeededItem | MemoryItem | FleetDecisionItem | TurnEndItem;
|
|
375
|
+
export type TimelineItem = UserMessageItem | HumanInputItem | AgentMessageItem | ReasoningItem | ToolCallItem | WorkerItem | WorkerCompletionItem | SandboxItem | StartupPhaseItem | SessionStatusItem | GoalItem | NoticeItem | ContextCompactionItem | MachineInputBatchItem | AuthNeededItem | MemoryItem | KnowledgeItem | FleetDecisionItem | TurnEndItem;
|
|
365
376
|
/** Activity items cluster between chat messages (reasoning, tools, workers, sandbox, memory). */
|
|
366
|
-
export type ActivityItem = ReasoningItem | ToolCallItem | WorkerItem | SandboxItem | StartupPhaseItem | MemoryItem | FleetDecisionItem;
|
|
377
|
+
export type ActivityItem = ReasoningItem | ToolCallItem | WorkerItem | SandboxItem | StartupPhaseItem | MemoryItem | KnowledgeItem | FleetDecisionItem;
|
|
367
378
|
export type TimelineGroup = {
|
|
368
379
|
kind: "item";
|
|
369
380
|
item: TimelineItem;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opengeni/react",
|
|
3
|
-
"version": "5.2.0-canary.
|
|
3
|
+
"version": "5.2.0-canary.1",
|
|
4
4
|
"description": "React hooks and styled components for OpenGeni: live session streaming, chat composer, message timeline, session status, and fleet views — token-themed (CSS variables), dark-first, built on Tailwind v4 + Radix + Motion.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -133,8 +133,8 @@
|
|
|
133
133
|
"@dnd-kit/utilities": "3.2.2",
|
|
134
134
|
"@fontsource-variable/noto-sans-arabic": "5.2.10",
|
|
135
135
|
"@fontsource-variable/noto-sans-jp": "5.2.10",
|
|
136
|
-
"@opengeni/connect": "^0.2.0-canary.
|
|
137
|
-
"@opengeni/sdk": "^5.1.0-canary.
|
|
136
|
+
"@opengeni/connect": "^0.2.0-canary.8",
|
|
137
|
+
"@opengeni/sdk": "^5.1.0-canary.2",
|
|
138
138
|
"clsx": "^2.1.1",
|
|
139
139
|
"dequal": "2.0.3",
|
|
140
140
|
"lucide-react": "^1.8.0",
|
|
@@ -567,7 +567,12 @@ export function ComputerViewer({
|
|
|
567
567
|
if (relevant[0]) selectComputerSession({ sessionId: relevant[0].id, pinned: false });
|
|
568
568
|
}}
|
|
569
569
|
onCreate={hideGenericCreate ? undefined : createComputer}
|
|
570
|
-
onRefresh={() =>
|
|
570
|
+
onRefresh={() => {
|
|
571
|
+
if (frames.state === "error" && !generationLossSelected && !generationLossFrames) {
|
|
572
|
+
frames.reconnect();
|
|
573
|
+
}
|
|
574
|
+
void Promise.all([refreshRegistry(), refreshComputer()]);
|
|
575
|
+
}}
|
|
571
576
|
/>
|
|
572
577
|
<InteractionInterventionBanner
|
|
573
578
|
interventions={selectedInterventions}
|
|
@@ -1031,8 +1036,11 @@ function ComputerViewport(props: {
|
|
|
1031
1036
|
actionRef.current = props.onAction;
|
|
1032
1037
|
readClipboardRef.current = props.onReadClipboard;
|
|
1033
1038
|
errorRef.current = props.onError;
|
|
1039
|
+
const streamFailed = props.connectionState === "error";
|
|
1034
1040
|
const rawInputEnabled =
|
|
1035
|
-
!
|
|
1041
|
+
!streamFailed &&
|
|
1042
|
+
!props.machineLocked &&
|
|
1043
|
+
(!props.backgroundActions || props.target?.kind === "screen" || props.target?.focused === true);
|
|
1036
1044
|
|
|
1037
1045
|
const paintQueuedFrames = useCallback(() => {
|
|
1038
1046
|
if (decodingFrameRef.current) return;
|
|
@@ -1346,7 +1354,7 @@ function ComputerViewport(props: {
|
|
|
1346
1354
|
if (inputRef.current) inputRef.current.value = "";
|
|
1347
1355
|
};
|
|
1348
1356
|
|
|
1349
|
-
const showCanvas = props.frame !== null && !props.machineLocked;
|
|
1357
|
+
const showCanvas = props.frame !== null && !props.machineLocked && !streamFailed;
|
|
1350
1358
|
return (
|
|
1351
1359
|
<div className="relative min-h-0 flex-1 overflow-hidden bg-black">
|
|
1352
1360
|
<canvas
|
|
@@ -100,6 +100,11 @@ export type SessionChromeProps = {
|
|
|
100
100
|
queue: UseTurnQueueResult;
|
|
101
101
|
/** Needed for queue edit → composer checkout. Omit with `readOnly`. */
|
|
102
102
|
composer?: ComposerState | undefined;
|
|
103
|
+
/** Focus the composer after a successful queue checkout has applied its draft.
|
|
104
|
+
* Connect to the composer controller's `focusInput`, or a custom input ref.
|
|
105
|
+
* Never called for failed checkout or while replacement awaits confirmation.
|
|
106
|
+
*/
|
|
107
|
+
onComposerFocus?: (() => void) | undefined;
|
|
103
108
|
goal?: UseGoalResult | null | undefined;
|
|
104
109
|
/** Expanded agents body (host supplies tree / list). */
|
|
105
110
|
agentsPanel?: ReactNode;
|
|
@@ -431,6 +436,7 @@ export function SessionChrome({
|
|
|
431
436
|
sessionStatus,
|
|
432
437
|
queue,
|
|
433
438
|
composer,
|
|
439
|
+
onComposerFocus,
|
|
434
440
|
goal,
|
|
435
441
|
agentsPanel,
|
|
436
442
|
commandsPanel,
|
|
@@ -802,7 +808,10 @@ export function SessionChrome({
|
|
|
802
808
|
expectedDraftRevision: composer.draftRevision,
|
|
803
809
|
replaceDraft: true,
|
|
804
810
|
});
|
|
805
|
-
if (checkedOut)
|
|
811
|
+
if (checkedOut) {
|
|
812
|
+
composer.applyDraft(checkedOut);
|
|
813
|
+
onComposerFocus?.();
|
|
814
|
+
}
|
|
806
815
|
})();
|
|
807
816
|
}
|
|
808
817
|
: undefined
|
|
@@ -819,7 +828,10 @@ export function SessionChrome({
|
|
|
819
828
|
expectedDraftRevision: composer.draftRevision,
|
|
820
829
|
replaceDraft: false,
|
|
821
830
|
});
|
|
822
|
-
if (checkedOut)
|
|
831
|
+
if (checkedOut) {
|
|
832
|
+
composer.applyDraft(checkedOut);
|
|
833
|
+
onComposerFocus?.();
|
|
834
|
+
}
|
|
823
835
|
})();
|
|
824
836
|
},
|
|
825
837
|
);
|
|
@@ -159,9 +159,19 @@ export function useComputerFrameStream(
|
|
|
159
159
|
pendingFrame = null;
|
|
160
160
|
};
|
|
161
161
|
|
|
162
|
+
const clearRecoveryTimers = () => {
|
|
163
|
+
if (reconnectTimer) clearTimeout(reconnectTimer);
|
|
164
|
+
if (expiryTimer) clearTimeout(expiryTimer);
|
|
165
|
+
reconnectTimer = null;
|
|
166
|
+
expiryTimer = null;
|
|
167
|
+
};
|
|
168
|
+
|
|
162
169
|
const scheduleReconnect = () => {
|
|
163
170
|
if (disposed || reconnectTimer) return;
|
|
164
|
-
if (failures >= MAX_AUTOMATIC_RECONNECTS_WITHOUT_A_FRAME)
|
|
171
|
+
if (failures >= MAX_AUTOMATIC_RECONNECTS_WITHOUT_A_FRAME) {
|
|
172
|
+
clearRecoveryTimers();
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
165
175
|
const delay = Math.min(5_000, 250 * 2 ** Math.min(failures, 5));
|
|
166
176
|
failures += 1;
|
|
167
177
|
setResult((current) => ({ ...current, state: "reconnecting" }));
|
|
@@ -177,6 +187,7 @@ export function useComputerFrameStream(
|
|
|
177
187
|
setResult((current) => ({ ...current, state: "error", error }));
|
|
178
188
|
clearSocket();
|
|
179
189
|
if (reconnectAutomatically) scheduleReconnect();
|
|
190
|
+
else clearRecoveryTimers();
|
|
180
191
|
};
|
|
181
192
|
|
|
182
193
|
const onOpen = (source: ComputerFrameWebSocket) => {
|
|
@@ -295,8 +306,7 @@ export function useComputerFrameStream(
|
|
|
295
306
|
|
|
296
307
|
const onClose = (source: ComputerFrameWebSocket) => {
|
|
297
308
|
if (disposed || source !== socket) return;
|
|
298
|
-
|
|
299
|
-
scheduleReconnect();
|
|
309
|
+
fail(new Error("Desktop view lost connection."));
|
|
300
310
|
};
|
|
301
311
|
|
|
302
312
|
const connectSocket = () => {
|
|
@@ -366,6 +376,9 @@ export function useComputerFrameStream(
|
|
|
366
376
|
throw new Error("desktop attachment does not match the requested resource");
|
|
367
377
|
}
|
|
368
378
|
controllerGeneration = attachment.controllerGeneration;
|
|
379
|
+
// A fresh attachment owns a new producer whose sequence can restart.
|
|
380
|
+
// Transport reconnects reuse the attachment and retain their sequence fence.
|
|
381
|
+
latestRef.current = { key: "", sequence: -1 };
|
|
369
382
|
activeAttachment = attachment;
|
|
370
383
|
activeStream = attachment.stream;
|
|
371
384
|
attachmentExpiresAt = Date.parse(attachment.expiresAt);
|
|
@@ -406,8 +419,7 @@ export function useComputerFrameStream(
|
|
|
406
419
|
disposed = true;
|
|
407
420
|
pendingFrame = null;
|
|
408
421
|
attachmentAbort.abort();
|
|
409
|
-
|
|
410
|
-
if (expiryTimer) clearTimeout(expiryTimer);
|
|
422
|
+
clearRecoveryTimers();
|
|
411
423
|
clearSocket(true);
|
|
412
424
|
};
|
|
413
425
|
}, [client, enabled, nonce, options.computerSessionId, options.targetId, workspaceId]);
|
|
@@ -13,6 +13,8 @@ export type UseFileAttachmentsOptions = EmbeddedFileAttachmentClientOverride & {
|
|
|
13
13
|
* UseFileAttachmentsResult.addFiles} (the explicit picker / drop path)
|
|
14
14
|
* bypasses it.
|
|
15
15
|
*/
|
|
16
|
+
/** Retain original uploads in the chat owner’s personal scope when private. */
|
|
17
|
+
scope?: "workspace" | "personal";
|
|
16
18
|
pasteFilter?: ((file: File) => boolean) | undefined;
|
|
17
19
|
};
|
|
18
20
|
|
|
@@ -212,6 +214,7 @@ export function useFileAttachments(
|
|
|
212
214
|
filename: file.name || "file",
|
|
213
215
|
contentType: file.type || "application/octet-stream",
|
|
214
216
|
data: file,
|
|
217
|
+
...(options.scope ? { scope: options.scope } : {}),
|
|
215
218
|
})
|
|
216
219
|
.then((asset) => {
|
|
217
220
|
if (scopeGeneration.current !== generation) return;
|
|
@@ -252,7 +255,7 @@ export function useFileAttachments(
|
|
|
252
255
|
);
|
|
253
256
|
});
|
|
254
257
|
},
|
|
255
|
-
[client, workspaceId],
|
|
258
|
+
[client, workspaceId, options.scope],
|
|
256
259
|
);
|
|
257
260
|
|
|
258
261
|
const addFiles = useCallback(
|
package/src/hooks/use-goal.ts
CHANGED
|
@@ -138,7 +138,9 @@ export function useGoal(
|
|
|
138
138
|
return;
|
|
139
139
|
}
|
|
140
140
|
if (sharedFeed) {
|
|
141
|
-
|
|
141
|
+
// A shared log supplies invalidations, not the authoritative goal snapshot.
|
|
142
|
+
setLoading(true);
|
|
143
|
+
void load();
|
|
142
144
|
return () => {
|
|
143
145
|
retireLoads();
|
|
144
146
|
};
|
package/src/index.ts
CHANGED
|
@@ -617,3 +617,9 @@ export {
|
|
|
617
617
|
tryParseJson,
|
|
618
618
|
} from "./lib/format";
|
|
619
619
|
export { SessionCommandsPanel } from "./components/session-commands-panel";
|
|
620
|
+
|
|
621
|
+
export { KnowledgeActivityProvider } from "./timeline/knowledge-receipt";
|
|
622
|
+
export type { KnowledgeActivityActions } from "./timeline/knowledge-receipt";
|
|
623
|
+
|
|
624
|
+
export { StartupTimings } from "./timeline/startup-timings";
|
|
625
|
+
export { setStartupDetails, useStartupDetails } from "./timeline/startup-preference";
|
package/src/session-ui.ts
CHANGED
|
@@ -46,6 +46,9 @@ export type {
|
|
|
46
46
|
SessionChromeSignalTone,
|
|
47
47
|
} from "./components/session-chrome";
|
|
48
48
|
export { SessionCommandsPanel } from "./components/session-commands-panel";
|
|
49
|
+
|
|
50
|
+
export { KnowledgeActivityProvider } from "./timeline/knowledge-receipt";
|
|
51
|
+
export type { KnowledgeActivityActions } from "./timeline/knowledge-receipt";
|
|
49
52
|
export { StartupTimings } from "./timeline/startup-timings";
|
|
50
53
|
export { useStartupDetails, setStartupDetails } from "./timeline/startup-preference";
|
|
51
54
|
export type { GenieLoadingOptions } from "./timeline/genie-loading";
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { KnowledgeReceiptRow } from "./knowledge-receipt";
|
|
1
2
|
import { AnimatePresence, motion, useReducedMotion } from "motion/react";
|
|
2
3
|
import { GenieLoading } from "./genie-loading";
|
|
3
4
|
import { useStartupDetails } from "./startup-preference";
|
|
@@ -241,7 +242,6 @@ export function renderActivity(
|
|
|
241
242
|
t={toolDisplayName}
|
|
242
243
|
b={BotIcon}
|
|
243
244
|
m={Markdown}
|
|
244
|
-
r={truncate}
|
|
245
245
|
j={rowJsx}
|
|
246
246
|
s={rowJsxs}
|
|
247
247
|
/>
|
|
@@ -261,6 +261,16 @@ export function renderActivity(
|
|
|
261
261
|
}
|
|
262
262
|
case "worker":
|
|
263
263
|
return <WorkerRow item={item} onOpenSession={onOpenSession} />;
|
|
264
|
+
case "knowledge":
|
|
265
|
+
return (
|
|
266
|
+
<KnowledgeReceiptRow
|
|
267
|
+
outcome={item.outcome}
|
|
268
|
+
entryId={item.entryId}
|
|
269
|
+
fileId={item.fileId}
|
|
270
|
+
title={item.filename}
|
|
271
|
+
source={Boolean(item.fileId)}
|
|
272
|
+
/>
|
|
273
|
+
);
|
|
264
274
|
case "memory":
|
|
265
275
|
return <MemoryRow item={item} onMemoryClick={onMemoryClick} />;
|
|
266
276
|
case "fleet-decision":
|
|
@@ -12,7 +12,15 @@ export type GenieLoadingOptions = {
|
|
|
12
12
|
/** Replace the visual while preserving SDK loading visibility and transitions. */
|
|
13
13
|
render?: (props: GenieLoadingRenderProps) => ReactNode;
|
|
14
14
|
phrases?: readonly string[];
|
|
15
|
-
/**
|
|
15
|
+
/** Native copy overrides. Omitted messages retain the default English copy. */
|
|
16
|
+
messages?: {
|
|
17
|
+
status?: string;
|
|
18
|
+
slowStatus?: string;
|
|
19
|
+
slowText?: string;
|
|
20
|
+
showDetails?: string;
|
|
21
|
+
hideDetails?: string;
|
|
22
|
+
};
|
|
23
|
+
/** Public adapter options; the renderer dependency's declarations stay private. */
|
|
16
24
|
orb?: {
|
|
17
25
|
state?:
|
|
18
26
|
| "working"
|
|
@@ -90,10 +98,14 @@ export function GenieLoading({
|
|
|
90
98
|
</div>
|
|
91
99
|
<div className="og-genie-copy">
|
|
92
100
|
<span className="sr-only" role="status">
|
|
93
|
-
{slow
|
|
101
|
+
{slow
|
|
102
|
+
? (options?.messages?.slowStatus ?? "Preparing your task. Taking longer than usual.")
|
|
103
|
+
: (options?.messages?.status ?? "Preparing your task.")}
|
|
94
104
|
</span>
|
|
95
105
|
<span key={slow ? "slow" : phrase} className="og-genie-phrase" aria-hidden="true">
|
|
96
|
-
{slow
|
|
106
|
+
{slow
|
|
107
|
+
? (options?.messages?.slowText ?? "A little longer than usual…")
|
|
108
|
+
: phrases[phrase % phrases.length]}
|
|
97
109
|
</span>
|
|
98
110
|
{showDetails || detailsOpen ? (
|
|
99
111
|
<button
|
|
@@ -102,7 +114,9 @@ export function GenieLoading({
|
|
|
102
114
|
aria-expanded={detailsOpen}
|
|
103
115
|
onClick={onShowDetails}
|
|
104
116
|
>
|
|
105
|
-
{detailsOpen
|
|
117
|
+
{detailsOpen
|
|
118
|
+
? (options?.messages?.hideDetails ?? "Hide details")
|
|
119
|
+
: (options?.messages?.showDetails ?? "Behind the magic")}
|
|
106
120
|
<span aria-hidden="true"> ↗</span>
|
|
107
121
|
</button>
|
|
108
122
|
) : null}
|