@opengeni/react 5.1.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/artifacts.d.ts +2 -0
- package/dist/artifacts.js +1391 -2
- package/dist/artifacts.js.map +1 -1
- package/dist/chunk-2TKI3WEG.js +73 -0
- package/dist/chunk-2TKI3WEG.js.map +1 -0
- package/dist/{chunk-M2HNWZYR.js → chunk-IHQII5WO.js} +69 -18
- package/dist/chunk-IHQII5WO.js.map +1 -0
- package/dist/{chunk-5PQJOCX5.js → chunk-KANFU34B.js} +6 -4
- package/dist/chunk-KANFU34B.js.map +1 -0
- package/dist/{chunk-WS6D5BHH.js → chunk-O4NQNMPG.js} +2393 -2123
- package/dist/chunk-O4NQNMPG.js.map +1 -0
- package/dist/{chunk-HUMIRRYI.js → chunk-PZ27MCZP.js} +54 -19
- package/dist/chunk-PZ27MCZP.js.map +1 -0
- package/dist/{chunk-BRFMGY4L.js → chunk-UGMKPUEM.js} +28 -3
- package/dist/chunk-UGMKPUEM.js.map +1 -0
- package/dist/{chunk-BV5A4OTE.js → chunk-YS24CFDI.js} +44 -10
- package/dist/chunk-YS24CFDI.js.map +1 -0
- package/dist/components/artifacts/inline-html-document.d.ts +2 -0
- package/dist/components/artifacts/published-html-artifact-frame.d.ts +2 -0
- package/dist/components/artifacts/visualization-assets.gen.d.ts +2 -0
- package/dist/components/markdown.d.ts +13 -1
- package/dist/components/session-chrome.d.ts +6 -1
- package/dist/{computer-viewer-7TEZC6Y2.js → computer-viewer-CTFCJVS7.js} +2 -2
- package/dist/connect.js +1 -1
- package/dist/hooks/use-file-attachments.d.ts +2 -0
- package/dist/index.d.ts +6 -1
- package/dist/index.js +16 -5
- package/dist/index.js.map +1 -1
- package/dist/interaction.js +1 -1
- package/dist/{platform-activity-row-27LKAWZD.js → platform-activity-row-DUE2W74J.js} +6 -3
- package/dist/platform-activity-row-DUE2W74J.js.map +1 -0
- package/dist/session-ui.d.ts +2 -0
- package/dist/session-ui.js +7 -107
- package/dist/session-ui.js.map +1 -1
- package/dist/session.js +2 -2
- package/dist/sites-ui.d.ts +2 -1
- package/dist/sites.js +12 -4
- package/dist/sites.js.map +1 -1
- package/dist/timeline/activity-rail.d.ts +1 -0
- 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 +1 -2
- package/dist/timeline/retained-image.d.ts +16 -0
- package/dist/timeline/rolling-activity.d.ts +9 -0
- package/dist/timeline/shared.d.ts +4 -1
- package/dist/timeline/turn-summary.d.ts +4 -1
- package/dist/timeline/types.d.ts +13 -2
- package/package.json +4 -4
- package/src/artifacts.ts +2 -0
- package/src/components/artifacts/inline-html-document.ts +24 -0
- package/src/components/artifacts/published-html-artifact-frame.tsx +32 -2
- package/src/components/artifacts/visualization-assets/base.css +1015 -0
- package/src/components/artifacts/visualization-assets/helpers.html +349 -0
- package/src/components/artifacts/visualization-assets.gen.ts +3 -0
- package/src/components/computer-viewer.tsx +11 -3
- package/src/components/copy-button.tsx +7 -2
- package/src/components/markdown.tsx +111 -34
- package/src/components/message-timeline.tsx +48 -3
- package/src/components/session-chrome.tsx +14 -2
- package/src/hooks/use-computer-frame-stream.ts +17 -5
- package/src/hooks/use-computer-session.ts +36 -1
- package/src/hooks/use-file-attachments.ts +4 -1
- package/src/hooks/use-goal.ts +3 -1
- package/src/index.ts +12 -1
- package/src/session-ui.ts +3 -0
- package/src/sites-ui.tsx +23 -6
- package/src/timeline/activity-rail.tsx +31 -4
- 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 +5 -3
- package/src/timeline/projection.ts +40 -0
- package/src/timeline/retained-image.ts +91 -0
- package/src/timeline/rolling-activity.tsx +83 -0
- package/src/timeline/shared.tsx +33 -12
- package/src/timeline/tool-renderers.tsx +55 -91
- package/src/timeline/turn-summary.tsx +21 -15
- package/src/timeline/types.ts +14 -0
- package/styles/compiled.css +122 -0
- package/styles/index.css +49 -0
- package/dist/chunk-5PQJOCX5.js.map +0 -1
- package/dist/chunk-BRFMGY4L.js.map +0 -1
- package/dist/chunk-BV5A4OTE.js.map +0 -1
- package/dist/chunk-HUMIRRYI.js.map +0 -1
- package/dist/chunk-M2HNWZYR.js.map +0 -1
- package/dist/chunk-WS6D5BHH.js.map +0 -1
- package/dist/platform-activity-row-27LKAWZD.js.map +0 -1
- /package/dist/{computer-viewer-7TEZC6Y2.js.map → computer-viewer-CTFCJVS7.js.map} +0 -0
package/dist/interaction.js
CHANGED
|
@@ -6,7 +6,6 @@ function PlatformActivityRow({
|
|
|
6
6
|
t: displayName,
|
|
7
7
|
b: BotIcon,
|
|
8
8
|
m: Markdown,
|
|
9
|
-
r: truncate,
|
|
10
9
|
j,
|
|
11
10
|
s
|
|
12
11
|
}) {
|
|
@@ -19,7 +18,11 @@ function PlatformActivityRow({
|
|
|
19
18
|
children: "Thought"
|
|
20
19
|
}),
|
|
21
20
|
running: item.streaming,
|
|
22
|
-
|
|
21
|
+
compactPreview: item.text.replace(/\*\*|__|`/g, "").replace(/\s+/g, " "),
|
|
22
|
+
preview: j("span", {
|
|
23
|
+
className: "og-reasoning-preview",
|
|
24
|
+
children: j(Markdown, { streaming: item.streaming, children: item.text })
|
|
25
|
+
}),
|
|
23
26
|
children: j("div", {
|
|
24
27
|
className: "text-og-base leading-6 text-og-fg-muted [&_strong]:text-og-fg-muted",
|
|
25
28
|
children: j(Markdown, { streaming: item.streaming, children: item.text })
|
|
@@ -166,4 +169,4 @@ function startupDuration(durationMs) {
|
|
|
166
169
|
export {
|
|
167
170
|
PlatformActivityRow as default
|
|
168
171
|
};
|
|
169
|
-
//# sourceMappingURL=platform-activity-row-
|
|
172
|
+
//# sourceMappingURL=platform-activity-row-DUE2W74J.js.map
|
|
@@ -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,136 +18,34 @@ 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";
|
|
23
25
|
import "./chunk-NOSYBS2D.js";
|
|
24
26
|
import "./chunk-PAJU5KKL.js";
|
|
25
|
-
import "./chunk-
|
|
27
|
+
import "./chunk-IHQII5WO.js";
|
|
26
28
|
import "./chunk-JVYQRRC4.js";
|
|
27
29
|
import "./chunk-45XEUVTK.js";
|
|
28
30
|
import "./chunk-HQV2I5HV.js";
|
|
31
|
+
import "./chunk-2TKI3WEG.js";
|
|
29
32
|
import "./chunk-R4KRSFGA.js";
|
|
30
33
|
import "./chunk-VZTQ73XT.js";
|
|
31
34
|
import {
|
|
32
35
|
createOlderHistoryLoadReceipt
|
|
33
|
-
} from "./chunk-
|
|
36
|
+
} from "./chunk-PZ27MCZP.js";
|
|
34
37
|
import "./chunk-NYESIADM.js";
|
|
35
38
|
import "./chunk-PLYRL5ER.js";
|
|
36
39
|
import "./chunk-KZ73RL76.js";
|
|
37
40
|
import "./chunk-NEXLLTP4.js";
|
|
38
41
|
import "./chunk-VRBL3F5E.js";
|
|
39
42
|
import "./chunk-22KP6LR5.js";
|
|
40
|
-
|
|
41
|
-
// src/timeline/startup-timings.tsx
|
|
42
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
43
|
-
var LABELS = {
|
|
44
|
-
queue: "Worker queue",
|
|
45
|
-
sandbox: "Sandbox",
|
|
46
|
-
rig: "Rig",
|
|
47
|
-
repository: "Repository",
|
|
48
|
-
files: "Files",
|
|
49
|
-
tools: "Tools",
|
|
50
|
-
model_preparation: "Runtime & model request",
|
|
51
|
-
provider_first_byte: "First model response"
|
|
52
|
-
};
|
|
53
|
-
function StartupTimings({ phases }) {
|
|
54
|
-
if (!phases.length)
|
|
55
|
-
return /* @__PURE__ */ jsx("p", { className: "text-og-sm text-og-fg-subtle", children: "No startup timings recorded yet." });
|
|
56
|
-
const byTurn = /* @__PURE__ */ new Map();
|
|
57
|
-
for (const phase of phases) {
|
|
58
|
-
const group = byTurn.get(phase.turnId) ?? [];
|
|
59
|
-
group.push(phase);
|
|
60
|
-
byTurn.set(phase.turnId, group);
|
|
61
|
-
}
|
|
62
|
-
const turns = [...byTurn.entries()].map(([turnId, turnPhases]) => ({
|
|
63
|
-
turnId,
|
|
64
|
-
phases: turnPhases,
|
|
65
|
-
startedAt: turnPhases.reduce(
|
|
66
|
-
(earliest, phase) => phase.startedAt < earliest ? phase.startedAt : earliest,
|
|
67
|
-
turnPhases[0].startedAt
|
|
68
|
-
)
|
|
69
|
-
})).sort((a, b) => b.startedAt.localeCompare(a.startedAt));
|
|
70
|
-
return /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
71
|
-
/* @__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." }),
|
|
72
|
-
turns.map((turn, index) => /* @__PURE__ */ jsx(
|
|
73
|
-
StartupTurn,
|
|
74
|
-
{
|
|
75
|
-
...turn,
|
|
76
|
-
latest: index === 0 && turn.turnId !== null
|
|
77
|
-
},
|
|
78
|
-
turn.turnId ?? "unassigned"
|
|
79
|
-
))
|
|
80
|
-
] });
|
|
81
|
-
}
|
|
82
|
-
function StartupTurn({
|
|
83
|
-
turnId,
|
|
84
|
-
phases,
|
|
85
|
-
startedAt,
|
|
86
|
-
latest
|
|
87
|
-
}) {
|
|
88
|
-
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";
|
|
89
|
-
return /* @__PURE__ */ jsxs("details", { open: latest, className: "group border-b border-og-border pb-3", children: [
|
|
90
|
-
/* @__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: [
|
|
91
|
-
/* @__PURE__ */ jsx("span", { className: "font-medium", children: turnId === null ? "Unassigned events" : latest ? "Latest turn" : "Earlier turn" }),
|
|
92
|
-
/* @__PURE__ */ jsx("span", { className: "ml-2 text-og-xs text-og-fg-subtle", children: new Date(startedAt).toLocaleTimeString([], {
|
|
93
|
-
hour: "2-digit",
|
|
94
|
-
minute: "2-digit",
|
|
95
|
-
second: "2-digit"
|
|
96
|
-
}) }),
|
|
97
|
-
/* @__PURE__ */ jsx(
|
|
98
|
-
"span",
|
|
99
|
-
{
|
|
100
|
-
className: status === "Failed" ? "ml-2 text-og-xs text-og-status-failed" : "ml-2 text-og-xs text-og-fg-subtle",
|
|
101
|
-
children: status
|
|
102
|
-
}
|
|
103
|
-
),
|
|
104
|
-
/* @__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" })
|
|
105
|
-
] }),
|
|
106
|
-
/* @__PURE__ */ jsxs("div", { className: "pb-2", children: [
|
|
107
|
-
/* @__PURE__ */ jsxs("p", { className: "text-og-xs text-og-fg-subtle", children: [
|
|
108
|
-
"Started ",
|
|
109
|
-
/* @__PURE__ */ jsx("time", { dateTime: startedAt, children: new Date(startedAt).toLocaleString() })
|
|
110
|
-
] }),
|
|
111
|
-
/* @__PURE__ */ jsx("div", { className: "overflow-x-auto", children: /* @__PURE__ */ jsxs("table", { className: "w-full text-left text-og-xs", children: [
|
|
112
|
-
/* @__PURE__ */ jsxs("caption", { className: "sr-only", children: [
|
|
113
|
-
"Startup phases for ",
|
|
114
|
-
turnId ?? "unassigned events"
|
|
115
|
-
] }),
|
|
116
|
-
/* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { className: "border-b border-og-border text-og-fg-subtle", children: [
|
|
117
|
-
/* @__PURE__ */ jsx("th", { scope: "col", className: "py-2 font-medium", children: "Phase" }),
|
|
118
|
-
/* @__PURE__ */ jsx("th", { scope: "col", className: "px-3 py-2 font-medium", children: "Status" }),
|
|
119
|
-
/* @__PURE__ */ jsx("th", { scope: "col", className: "py-2 text-right font-medium", children: "Duration" })
|
|
120
|
-
] }) }),
|
|
121
|
-
/* @__PURE__ */ jsx("tbody", { children: phases.map((phase) => /* @__PURE__ */ jsxs(
|
|
122
|
-
"tr",
|
|
123
|
-
{
|
|
124
|
-
className: "border-b border-og-border/40",
|
|
125
|
-
title: `Turn: ${phase.turnId ?? "unknown"} \xB7 Started: ${phase.startedAt}`,
|
|
126
|
-
children: [
|
|
127
|
-
/* @__PURE__ */ jsx("th", { scope: "row", className: "py-2.5 font-normal text-og-fg-muted", children: LABELS[phase.phase] }),
|
|
128
|
-
/* @__PURE__ */ jsx(
|
|
129
|
-
"td",
|
|
130
|
-
{
|
|
131
|
-
className: `px-3 py-2.5 ${phase.status === "failed" ? "text-og-status-failed" : "text-og-fg-subtle"}`,
|
|
132
|
-
children: phase.status === "running" ? "In progress" : phase.status
|
|
133
|
-
}
|
|
134
|
-
),
|
|
135
|
-
/* @__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` })
|
|
136
|
-
]
|
|
137
|
-
},
|
|
138
|
-
phase.id
|
|
139
|
-
)) })
|
|
140
|
-
] }) })
|
|
141
|
-
] })
|
|
142
|
-
] });
|
|
143
|
-
}
|
|
144
43
|
export {
|
|
145
44
|
ApprovalSurface,
|
|
146
45
|
BUILT_IN_TURN_SUMMARY_FACET_IDS,
|
|
147
46
|
HumanInputForm,
|
|
148
47
|
HumanInputSurface,
|
|
48
|
+
KnowledgeActivityProvider,
|
|
149
49
|
MessageTimeline,
|
|
150
50
|
QueueSurface,
|
|
151
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,
|
package/dist/sites-ui.d.ts
CHANGED
|
@@ -11,9 +11,10 @@ type SiteScope = {
|
|
|
11
11
|
};
|
|
12
12
|
/** Shared native/embedded read boundary: pin content to the observed version,
|
|
13
13
|
* and never accept a response belonging to another workspace or Site. */
|
|
14
|
-
export declare function loadSiteSnapshot(client: Pick<SiteClient, "getWorkspaceArtifact" | "getWorkspaceArtifactHtml"
|
|
14
|
+
export declare function loadSiteSnapshot(client: Pick<SiteClient, "getWorkspaceArtifact" | "getWorkspaceArtifactHtml"> & Partial<Pick<OpenGeniClient, "getWorkspaceArtifactContent">>, workspaceId: string, siteId: string, options?: {
|
|
15
15
|
signal?: AbortSignal;
|
|
16
16
|
includeArchivedContent?: boolean;
|
|
17
|
+
versionId?: string;
|
|
17
18
|
}): Promise<{
|
|
18
19
|
detail: WorkspaceArtifactDetailResponse;
|
|
19
20
|
content: SiteDisplayContent | null;
|
package/dist/sites.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
PublishedHtmlArtifactFrame
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-UGMKPUEM.js";
|
|
4
4
|
|
|
5
5
|
// src/sites-ui.tsx
|
|
6
6
|
import { useEffect, useRef, useState } from "react";
|
|
@@ -11,16 +11,24 @@ async function loadSiteSnapshot(client, workspaceId, siteId, options = {}) {
|
|
|
11
11
|
options.signal?.throwIfAborted();
|
|
12
12
|
if (detail.artifact.id !== siteId || detail.artifact.workspaceId !== workspaceId)
|
|
13
13
|
throw new Error("Site scope mismatch");
|
|
14
|
-
const
|
|
15
|
-
const
|
|
14
|
+
const selectedVersion = options.versionId ? detail.versions.find((version) => version.id === options.versionId) : detail.artifact.currentVersion;
|
|
15
|
+
const versionId = options.versionId ?? selectedVersion?.id;
|
|
16
|
+
let content = selectedVersion && versionId && (detail.artifact.status === "active" || options.includeArchivedContent) ? {
|
|
16
17
|
artifactId: siteId,
|
|
17
18
|
versionId,
|
|
18
|
-
requestedTools:
|
|
19
|
+
requestedTools: selectedVersion.requestedTools,
|
|
19
20
|
html: await client.getWorkspaceArtifactHtml(workspaceId, siteId, {
|
|
20
21
|
...requestOptions,
|
|
21
22
|
versionId
|
|
22
23
|
})
|
|
23
24
|
} : null;
|
|
25
|
+
if (versionId && !selectedVersion && (detail.artifact.status === "active" || options.includeArchivedContent)) {
|
|
26
|
+
if (!client.getWorkspaceArtifactContent) throw new Error("Site version unavailable");
|
|
27
|
+
content = await client.getWorkspaceArtifactContent(workspaceId, siteId, {
|
|
28
|
+
...requestOptions,
|
|
29
|
+
versionId
|
|
30
|
+
});
|
|
31
|
+
}
|
|
24
32
|
options.signal?.throwIfAborted();
|
|
25
33
|
if (content && (content.artifactId !== siteId || content.versionId !== versionId))
|
|
26
34
|
throw new Error("Site content mismatch");
|
package/dist/sites.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/sites-ui.tsx"],"sourcesContent":["import { useEffect, useRef, useState } from \"react\";\nimport type {\n OpenGeniClient,\n WorkspaceArtifact,\n WorkspaceArtifactContentResponse,\n WorkspaceArtifactDetailResponse,\n WorkspaceArtifactListResponse,\n} from \"@opengeni/sdk\";\nimport {\n PublishedHtmlArtifactFrame,\n type PublishedHtmlArtifactToolBridge,\n} from \"./components/artifacts/published-html-artifact-frame\";\n\n/** Implement with an authenticated host proxy. Never put an organization key\n * in browser props; replace the client object when the host actor changes. */\nexport type SiteClient = Pick<\n OpenGeniClient,\n | \"listWorkspaceArtifacts\"\n | \"getWorkspaceArtifact\"\n | \"getWorkspaceArtifactHtml\"\n | \"rollbackWorkspaceArtifact\"\n | \"setWorkspaceArtifactStatus\"\n>;\ntype SiteDisplayContent = Pick<\n WorkspaceArtifactContentResponse,\n \"artifactId\" | \"versionId\" | \"html\" | \"requestedTools\"\n>;\ntype SiteScope = { client: SiteClient; workspaceId: string; className?: string };\n/** Shared native/embedded read boundary: pin content to the observed version,\n * and never accept a response belonging to another workspace or Site. */\nexport async function loadSiteSnapshot(\n client: Pick<SiteClient, \"getWorkspaceArtifact\" | \"getWorkspaceArtifactHtml\">,\n workspaceId: string,\n siteId: string,\n options: { signal?: AbortSignal; includeArchivedContent?: boolean } = {},\n): Promise<{\n detail: WorkspaceArtifactDetailResponse;\n content: SiteDisplayContent | null;\n}> {\n const requestOptions = options.signal ? { signal: options.signal } : {};\n const detail = await client.getWorkspaceArtifact(workspaceId, siteId, requestOptions);\n options.signal?.throwIfAborted();\n if (detail.artifact.id !== siteId || detail.artifact.workspaceId !== workspaceId)\n throw new Error(\"Site scope mismatch\");\n const versionId = detail.artifact.currentVersion?.id;\n const content =\n versionId && (detail.artifact.status === \"active\" || options.includeArchivedContent)\n ? {\n artifactId: siteId,\n versionId,\n requestedTools: detail.artifact.currentVersion!.requestedTools,\n html: await client.getWorkspaceArtifactHtml(workspaceId, siteId, {\n ...requestOptions,\n versionId,\n }),\n }\n : null;\n options.signal?.throwIfAborted();\n if (content && (content.artifactId !== siteId || content.versionId !== versionId))\n throw new Error(\"Site content mismatch\");\n return { detail: structuredClone(detail), content: content ? structuredClone(content) : null };\n}\nexport type SiteListProps = SiteScope & {\n status?: \"active\" | \"archived\";\n onOpen: (site: WorkspaceArtifact) => void;\n};\nexport type SiteDetailProps = SiteScope & {\n siteId: string;\n /** Presentation hint only: the backend still enforces artifacts:publish. */\n canPublish?: boolean;\n toolBridge?: PublishedHtmlArtifactToolBridge;\n};\n\nfunction useScopeKey(values: readonly unknown[]) {\n const [scope, setScope] = useState(values);\n const [generation, setGeneration] = useState(0);\n if (values.some((value, index) => value !== scope[index])) {\n setScope(values);\n setGeneration(generation + 1);\n }\n return generation;\n}\n\nexport function SiteList(props: SiteListProps) {\n const key = useScopeKey([props.client, props.workspaceId, props.status]);\n return <ScopedSiteList key={key} {...props} />;\n}\nfunction ScopedSiteList({\n client,\n workspaceId,\n status = \"active\",\n onOpen,\n className,\n}: SiteListProps) {\n const [page, setPage] = useState<WorkspaceArtifactListResponse | null>(null);\n const [cursor, setCursor] = useState<string | undefined>();\n const [error, setError] = useState(false);\n const [reload, setReload] = useState(0);\n useEffect(() => {\n const abort = new AbortController();\n setPage(null);\n setError(false);\n void Promise.resolve()\n .then(() =>\n client.listWorkspaceArtifacts(workspaceId, {\n status,\n ...(cursor ? { cursor } : {}),\n limit: 50,\n signal: abort.signal,\n }),\n )\n .then((result) => {\n if (!abort.signal.aborted) setPage(structuredClone(result));\n })\n .catch(() => {\n if (!abort.signal.aborted) setError(true);\n });\n return () => abort.abort();\n }, [client, workspaceId, status, cursor, reload]);\n return (\n <section className={className} aria-label=\"Sites\" aria-busy={!page && !error}>\n {error ? (\n <p role=\"alert\">Sites are unavailable or access has changed. Refresh to check access.</p>\n ) : !page ? (\n <p role=\"status\">Loading Sites…</p>\n ) : page.artifacts.length === 0 ? (\n <p role=\"status\">No {status} Sites.</p>\n ) : (\n <ul>\n {page.artifacts.map((site) => (\n <li key={site.id}>\n <button type=\"button\" onClick={() => onOpen(structuredClone(site))}>\n {site.title}\n </button>\n <p>{site.description}</p>\n <span>\n {site.status} · revision {site.currentVersion?.revision ?? \"unpublished\"}\n </span>\n </li>\n ))}\n </ul>\n )}\n {page?.nextCursor && (\n <button type=\"button\" onClick={() => setCursor(page.nextCursor!)}>\n Next page\n </button>\n )}\n {cursor && (\n <button type=\"button\" onClick={() => setCursor(undefined)}>\n First page\n </button>\n )}\n <button type=\"button\" onClick={() => setReload((value) => value + 1)}>\n Refresh Sites\n </button>\n </section>\n );\n}\n\nexport function SiteDetail(props: SiteDetailProps) {\n const key = useScopeKey([props.client, props.workspaceId, props.siteId]);\n return <ScopedSiteDetail key={key} {...props} />;\n}\nfunction ScopedSiteDetail({\n client,\n workspaceId,\n siteId,\n canPublish = false,\n toolBridge,\n className,\n}: SiteDetailProps) {\n const [loaded, setLoaded] = useState<{\n detail: WorkspaceArtifactDetailResponse;\n content: SiteDisplayContent | null;\n } | null>(null);\n const [error, setError] = useState(false);\n const [reload, setReload] = useState(0);\n const [busy, setBusy] = useState(false);\n const [rollbackId, setRollbackId] = useState(\"\");\n const [confirmation, setConfirmation] = useState<\"status\" | \"rollback\" | null>(null);\n const mutation = useRef<AbortController | null>(null);\n useEffect(() => () => mutation.current?.abort(), []);\n useEffect(() => {\n const abort = new AbortController();\n setLoaded(null);\n setError(false);\n setConfirmation(null);\n setRollbackId(\"\");\n void Promise.resolve()\n .then(async () => {\n const snapshot = await loadSiteSnapshot(client, workspaceId, siteId, {\n signal: abort.signal,\n });\n if (!abort.signal.aborted) setLoaded(snapshot);\n })\n .catch(() => {\n if (!abort.signal.aborted) {\n setLoaded(null);\n setError(true);\n }\n });\n return () => abort.abort();\n }, [client, workspaceId, siteId, reload]);\n // Recheck live read authority without rebuilding the iframe on every tick.\n // No overlapping polls, and failures remove the document and tool bridge.\n useEffect(() => {\n if (!loaded || busy) return;\n const abort = new AbortController();\n let checking = false;\n const timer = setInterval(() => {\n if (checking) return;\n checking = true;\n void Promise.resolve()\n .then(() => client.getWorkspaceArtifact(workspaceId, siteId, { signal: abort.signal }))\n .then((detail) => {\n if (abort.signal.aborted) return;\n if (detail.artifact.id !== siteId || detail.artifact.workspaceId !== workspaceId)\n throw new Error(\"Site scope mismatch\");\n if (\n detail.artifact.currentVersion?.id !== loaded.detail.artifact.currentVersion?.id ||\n detail.artifact.status !== loaded.detail.artifact.status\n ) {\n setLoaded(null);\n setReload((value) => value + 1);\n }\n })\n .catch(() => {\n if (!abort.signal.aborted) {\n setLoaded(null);\n setError(true);\n }\n })\n .finally(() => {\n checking = false;\n });\n }, 15_000);\n return () => {\n abort.abort();\n clearInterval(timer);\n };\n }, [client, workspaceId, siteId, loaded, busy]);\n const commit = async () => {\n const current = loaded?.detail.artifact.currentVersion;\n if (!canPublish || !loaded || !current || !confirmation || mutation.current) return;\n const abort = new AbortController();\n mutation.current = abort;\n setBusy(true);\n try {\n const common = { expectedCurrentVersionId: current.id, idempotencyKey: crypto.randomUUID() };\n if (confirmation === \"rollback\") {\n if (!loaded.detail.versions.some((version) => version.id === rollbackId))\n throw new Error(\"Unknown version\");\n await client.rollbackWorkspaceArtifact(\n workspaceId,\n siteId,\n { ...common, versionId: rollbackId, reason: \"Restore explicitly selected Site version\" },\n { signal: abort.signal },\n );\n } else {\n await client.setWorkspaceArtifactStatus(\n workspaceId,\n siteId,\n {\n ...common,\n status: loaded.detail.artifact.status === \"active\" ? \"archived\" : \"active\",\n reason: \"Explicit Site status change\",\n },\n { signal: abort.signal },\n );\n }\n if (!abort.signal.aborted) {\n setLoaded(null);\n setReload((value) => value + 1);\n }\n } catch {\n if (!abort.signal.aborted) {\n setLoaded(null);\n setError(true);\n }\n } finally {\n if (!abort.signal.aborted) {\n mutation.current = null;\n setBusy(false);\n setConfirmation(null);\n }\n }\n };\n const site = loaded?.detail.artifact;\n return (\n <section\n className={className}\n aria-label=\"Site details\"\n aria-busy={busy || (!loaded && !error)}\n >\n {error && (\n <p role=\"alert\">\n Site state could not be confirmed or access has changed. Refresh before continuing.\n </p>\n )}\n {!loaded && !error && <p role=\"status\">Loading Site…</p>}\n {site && (\n <>\n <h2>{site.title}</h2>\n <p>{site.description}</p>\n <p>\n {site.status} · revision {site.currentVersion?.revision ?? \"unpublished\"}\n </p>\n {loaded.content && (\n <PublishedHtmlArtifactFrame\n html={loaded.content.html}\n title={site.title}\n {...(toolBridge ? { toolBridge } : {})}\n />\n )}\n <h3>Versions</h3>\n <ul>\n {loaded.detail.versions.map((version) => (\n <li key={version.id}>\n Revision {version.revision} · {version.createdAt}\n {version.id === site.currentVersion?.id ? \" · current\" : \"\"}\n </li>\n ))}\n </ul>\n {loaded.detail.versionsTruncated && (\n <p>Older versions are not included in this response.</p>\n )}\n {canPublish && site.currentVersion && (\n <fieldset disabled={busy}>\n <legend>Manage Site</legend>\n <button type=\"button\" onClick={() => setConfirmation(\"status\")}>\n {site.status === \"active\" ? \"Archive Site\" : \"Restore Site\"}\n </button>\n <label>\n Version to restore\n <select\n value={rollbackId}\n onChange={(event) => {\n setRollbackId(event.target.value);\n setConfirmation(null);\n }}\n >\n <option value=\"\">Choose a version</option>\n {loaded.detail.versions\n .filter((version) => version.id !== site.currentVersion?.id)\n .map((version) => (\n <option key={version.id} value={version.id}>\n Revision {version.revision}\n </option>\n ))}\n </select>\n </label>\n <button\n type=\"button\"\n disabled={!rollbackId}\n onClick={() => setConfirmation(\"rollback\")}\n >\n Review rollback\n </button>\n {confirmation && (\n <div role=\"group\" aria-label=\"Confirm Site change\">\n <p>\n {confirmation === \"rollback\"\n ? \"Make the selected version current?\"\n : site.status === \"active\"\n ? \"Archive this Site for workspace users?\"\n : \"Restore this Site for workspace users?\"}\n </p>\n <button type=\"button\" onClick={() => void commit()}>\n Confirm change\n </button>\n <button type=\"button\" onClick={() => setConfirmation(null)}>\n Keep current state\n </button>\n </div>\n )}\n </fieldset>\n )}\n </>\n )}\n <button type=\"button\" disabled={busy} onClick={() => setReload((value) => value + 1)}>\n Refresh Site\n </button>\n </section>\n );\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/sites-ui.tsx"],"sourcesContent":["import { useEffect, useRef, useState } from \"react\";\nimport type {\n OpenGeniClient,\n WorkspaceArtifact,\n WorkspaceArtifactContentResponse,\n WorkspaceArtifactDetailResponse,\n WorkspaceArtifactListResponse,\n} from \"@opengeni/sdk\";\nimport {\n PublishedHtmlArtifactFrame,\n type PublishedHtmlArtifactToolBridge,\n} from \"./components/artifacts/published-html-artifact-frame\";\n\n/** Implement with an authenticated host proxy. Never put an organization key\n * in browser props; replace the client object when the host actor changes. */\nexport type SiteClient = Pick<\n OpenGeniClient,\n | \"listWorkspaceArtifacts\"\n | \"getWorkspaceArtifact\"\n | \"getWorkspaceArtifactHtml\"\n | \"rollbackWorkspaceArtifact\"\n | \"setWorkspaceArtifactStatus\"\n>;\ntype SiteDisplayContent = Pick<\n WorkspaceArtifactContentResponse,\n \"artifactId\" | \"versionId\" | \"html\" | \"requestedTools\"\n>;\ntype SiteScope = { client: SiteClient; workspaceId: string; className?: string };\n/** Shared native/embedded read boundary: pin content to the observed version,\n * and never accept a response belonging to another workspace or Site. */\nexport async function loadSiteSnapshot(\n client: Pick<SiteClient, \"getWorkspaceArtifact\" | \"getWorkspaceArtifactHtml\"> &\n Partial<Pick<OpenGeniClient, \"getWorkspaceArtifactContent\">>,\n workspaceId: string,\n siteId: string,\n options: { signal?: AbortSignal; includeArchivedContent?: boolean; versionId?: string } = {},\n): Promise<{\n detail: WorkspaceArtifactDetailResponse;\n content: SiteDisplayContent | null;\n}> {\n const requestOptions = options.signal ? { signal: options.signal } : {};\n const detail = await client.getWorkspaceArtifact(workspaceId, siteId, requestOptions);\n options.signal?.throwIfAborted();\n if (detail.artifact.id !== siteId || detail.artifact.workspaceId !== workspaceId)\n throw new Error(\"Site scope mismatch\");\n const selectedVersion = options.versionId\n ? detail.versions.find((version) => version.id === options.versionId)\n : detail.artifact.currentVersion;\n const versionId = options.versionId ?? selectedVersion?.id;\n let content: SiteDisplayContent | null =\n selectedVersion &&\n versionId &&\n (detail.artifact.status === \"active\" || options.includeArchivedContent)\n ? {\n artifactId: siteId,\n versionId,\n requestedTools: selectedVersion!.requestedTools,\n html: await client.getWorkspaceArtifactHtml(workspaceId, siteId, {\n ...requestOptions,\n versionId,\n }),\n }\n : null;\n if (\n versionId &&\n !selectedVersion &&\n (detail.artifact.status === \"active\" || options.includeArchivedContent)\n ) {\n if (!client.getWorkspaceArtifactContent) throw new Error(\"Site version unavailable\");\n content = await client.getWorkspaceArtifactContent(workspaceId, siteId, {\n ...requestOptions,\n versionId,\n });\n }\n options.signal?.throwIfAborted();\n if (content && (content.artifactId !== siteId || content.versionId !== versionId))\n throw new Error(\"Site content mismatch\");\n return { detail: structuredClone(detail), content: content ? structuredClone(content) : null };\n}\nexport type SiteListProps = SiteScope & {\n status?: \"active\" | \"archived\";\n onOpen: (site: WorkspaceArtifact) => void;\n};\nexport type SiteDetailProps = SiteScope & {\n siteId: string;\n /** Presentation hint only: the backend still enforces artifacts:publish. */\n canPublish?: boolean;\n toolBridge?: PublishedHtmlArtifactToolBridge;\n};\n\nfunction useScopeKey(values: readonly unknown[]) {\n const [scope, setScope] = useState(values);\n const [generation, setGeneration] = useState(0);\n if (values.some((value, index) => value !== scope[index])) {\n setScope(values);\n setGeneration(generation + 1);\n }\n return generation;\n}\n\nexport function SiteList(props: SiteListProps) {\n const key = useScopeKey([props.client, props.workspaceId, props.status]);\n return <ScopedSiteList key={key} {...props} />;\n}\nfunction ScopedSiteList({\n client,\n workspaceId,\n status = \"active\",\n onOpen,\n className,\n}: SiteListProps) {\n const [page, setPage] = useState<WorkspaceArtifactListResponse | null>(null);\n const [cursor, setCursor] = useState<string | undefined>();\n const [error, setError] = useState(false);\n const [reload, setReload] = useState(0);\n useEffect(() => {\n const abort = new AbortController();\n setPage(null);\n setError(false);\n void Promise.resolve()\n .then(() =>\n client.listWorkspaceArtifacts(workspaceId, {\n status,\n ...(cursor ? { cursor } : {}),\n limit: 50,\n signal: abort.signal,\n }),\n )\n .then((result) => {\n if (!abort.signal.aborted) setPage(structuredClone(result));\n })\n .catch(() => {\n if (!abort.signal.aborted) setError(true);\n });\n return () => abort.abort();\n }, [client, workspaceId, status, cursor, reload]);\n return (\n <section className={className} aria-label=\"Sites\" aria-busy={!page && !error}>\n {error ? (\n <p role=\"alert\">Sites are unavailable or access has changed. Refresh to check access.</p>\n ) : !page ? (\n <p role=\"status\">Loading Sites…</p>\n ) : page.artifacts.length === 0 ? (\n <p role=\"status\">No {status} Sites.</p>\n ) : (\n <ul>\n {page.artifacts.map((site) => (\n <li key={site.id}>\n <button type=\"button\" onClick={() => onOpen(structuredClone(site))}>\n {site.title}\n </button>\n <p>{site.description}</p>\n <span>\n {site.status} · revision {site.currentVersion?.revision ?? \"unpublished\"}\n </span>\n </li>\n ))}\n </ul>\n )}\n {page?.nextCursor && (\n <button type=\"button\" onClick={() => setCursor(page.nextCursor!)}>\n Next page\n </button>\n )}\n {cursor && (\n <button type=\"button\" onClick={() => setCursor(undefined)}>\n First page\n </button>\n )}\n <button type=\"button\" onClick={() => setReload((value) => value + 1)}>\n Refresh Sites\n </button>\n </section>\n );\n}\n\nexport function SiteDetail(props: SiteDetailProps) {\n const key = useScopeKey([props.client, props.workspaceId, props.siteId]);\n return <ScopedSiteDetail key={key} {...props} />;\n}\nfunction ScopedSiteDetail({\n client,\n workspaceId,\n siteId,\n canPublish = false,\n toolBridge,\n className,\n}: SiteDetailProps) {\n const [loaded, setLoaded] = useState<{\n detail: WorkspaceArtifactDetailResponse;\n content: SiteDisplayContent | null;\n } | null>(null);\n const [error, setError] = useState(false);\n const [reload, setReload] = useState(0);\n const [busy, setBusy] = useState(false);\n const [rollbackId, setRollbackId] = useState(\"\");\n const [confirmation, setConfirmation] = useState<\"status\" | \"rollback\" | null>(null);\n const mutation = useRef<AbortController | null>(null);\n useEffect(() => () => mutation.current?.abort(), []);\n useEffect(() => {\n const abort = new AbortController();\n setLoaded(null);\n setError(false);\n setConfirmation(null);\n setRollbackId(\"\");\n void Promise.resolve()\n .then(async () => {\n const snapshot = await loadSiteSnapshot(client, workspaceId, siteId, {\n signal: abort.signal,\n });\n if (!abort.signal.aborted) setLoaded(snapshot);\n })\n .catch(() => {\n if (!abort.signal.aborted) {\n setLoaded(null);\n setError(true);\n }\n });\n return () => abort.abort();\n }, [client, workspaceId, siteId, reload]);\n // Recheck live read authority without rebuilding the iframe on every tick.\n // No overlapping polls, and failures remove the document and tool bridge.\n useEffect(() => {\n if (!loaded || busy) return;\n const abort = new AbortController();\n let checking = false;\n const timer = setInterval(() => {\n if (checking) return;\n checking = true;\n void Promise.resolve()\n .then(() => client.getWorkspaceArtifact(workspaceId, siteId, { signal: abort.signal }))\n .then((detail) => {\n if (abort.signal.aborted) return;\n if (detail.artifact.id !== siteId || detail.artifact.workspaceId !== workspaceId)\n throw new Error(\"Site scope mismatch\");\n if (\n detail.artifact.currentVersion?.id !== loaded.detail.artifact.currentVersion?.id ||\n detail.artifact.status !== loaded.detail.artifact.status\n ) {\n setLoaded(null);\n setReload((value) => value + 1);\n }\n })\n .catch(() => {\n if (!abort.signal.aborted) {\n setLoaded(null);\n setError(true);\n }\n })\n .finally(() => {\n checking = false;\n });\n }, 15_000);\n return () => {\n abort.abort();\n clearInterval(timer);\n };\n }, [client, workspaceId, siteId, loaded, busy]);\n const commit = async () => {\n const current = loaded?.detail.artifact.currentVersion;\n if (!canPublish || !loaded || !current || !confirmation || mutation.current) return;\n const abort = new AbortController();\n mutation.current = abort;\n setBusy(true);\n try {\n const common = { expectedCurrentVersionId: current.id, idempotencyKey: crypto.randomUUID() };\n if (confirmation === \"rollback\") {\n if (!loaded.detail.versions.some((version) => version.id === rollbackId))\n throw new Error(\"Unknown version\");\n await client.rollbackWorkspaceArtifact(\n workspaceId,\n siteId,\n { ...common, versionId: rollbackId, reason: \"Restore explicitly selected Site version\" },\n { signal: abort.signal },\n );\n } else {\n await client.setWorkspaceArtifactStatus(\n workspaceId,\n siteId,\n {\n ...common,\n status: loaded.detail.artifact.status === \"active\" ? \"archived\" : \"active\",\n reason: \"Explicit Site status change\",\n },\n { signal: abort.signal },\n );\n }\n if (!abort.signal.aborted) {\n setLoaded(null);\n setReload((value) => value + 1);\n }\n } catch {\n if (!abort.signal.aborted) {\n setLoaded(null);\n setError(true);\n }\n } finally {\n if (!abort.signal.aborted) {\n mutation.current = null;\n setBusy(false);\n setConfirmation(null);\n }\n }\n };\n const site = loaded?.detail.artifact;\n return (\n <section\n className={className}\n aria-label=\"Site details\"\n aria-busy={busy || (!loaded && !error)}\n >\n {error && (\n <p role=\"alert\">\n Site state could not be confirmed or access has changed. Refresh before continuing.\n </p>\n )}\n {!loaded && !error && <p role=\"status\">Loading Site…</p>}\n {site && (\n <>\n <h2>{site.title}</h2>\n <p>{site.description}</p>\n <p>\n {site.status} · revision {site.currentVersion?.revision ?? \"unpublished\"}\n </p>\n {loaded.content && (\n <PublishedHtmlArtifactFrame\n html={loaded.content.html}\n title={site.title}\n {...(toolBridge ? { toolBridge } : {})}\n />\n )}\n <h3>Versions</h3>\n <ul>\n {loaded.detail.versions.map((version) => (\n <li key={version.id}>\n Revision {version.revision} · {version.createdAt}\n {version.id === site.currentVersion?.id ? \" · current\" : \"\"}\n </li>\n ))}\n </ul>\n {loaded.detail.versionsTruncated && (\n <p>Older versions are not included in this response.</p>\n )}\n {canPublish && site.currentVersion && (\n <fieldset disabled={busy}>\n <legend>Manage Site</legend>\n <button type=\"button\" onClick={() => setConfirmation(\"status\")}>\n {site.status === \"active\" ? \"Archive Site\" : \"Restore Site\"}\n </button>\n <label>\n Version to restore\n <select\n value={rollbackId}\n onChange={(event) => {\n setRollbackId(event.target.value);\n setConfirmation(null);\n }}\n >\n <option value=\"\">Choose a version</option>\n {loaded.detail.versions\n .filter((version) => version.id !== site.currentVersion?.id)\n .map((version) => (\n <option key={version.id} value={version.id}>\n Revision {version.revision}\n </option>\n ))}\n </select>\n </label>\n <button\n type=\"button\"\n disabled={!rollbackId}\n onClick={() => setConfirmation(\"rollback\")}\n >\n Review rollback\n </button>\n {confirmation && (\n <div role=\"group\" aria-label=\"Confirm Site change\">\n <p>\n {confirmation === \"rollback\"\n ? \"Make the selected version current?\"\n : site.status === \"active\"\n ? \"Archive this Site for workspace users?\"\n : \"Restore this Site for workspace users?\"}\n </p>\n <button type=\"button\" onClick={() => void commit()}>\n Confirm change\n </button>\n <button type=\"button\" onClick={() => setConfirmation(null)}>\n Keep current state\n </button>\n </div>\n )}\n </fieldset>\n )}\n </>\n )}\n <button type=\"button\" disabled={busy} onClick={() => setReload((value) => value + 1)}>\n Refresh Site\n </button>\n </section>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -22,3 +22,4 @@ export type ActivityRailProps = {
|
|
|
22
22
|
className?: string | undefined;
|
|
23
23
|
};
|
|
24
24
|
export declare function ActivityRail({ items, startupActive, toolRegistry, onOpenSession, onMemoryClick, loadRetainedScreenshot, loadRetainedArtifact, bare, className, }: ActivityRailProps): import("react").JSX.Element;
|
|
25
|
+
export declare function renderActivity(item: ActivityItem, toolRegistry: ToolRegistry, onOpenSession: ((sessionId: string) => void) | undefined, onMemoryClick: ((memoryId: string) => void) | undefined, loadRetainedScreenshot: RetainedScreenshotLoader | undefined, loadRetainedArtifact: RetainedArtifactLoader | undefined): import("react").JSX.Element;
|
|
@@ -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;
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import type { ReasoningItem, SandboxItem, StartupPhaseItem } from "./types.js";
|
|
2
2
|
type RowJsx = typeof import("react/jsx-runtime").jsx;
|
|
3
3
|
type RowJsxs = typeof import("react/jsx-runtime").jsxs;
|
|
4
|
-
export default function PlatformActivityRow({ item, d: ActivityDisclosure, p: PayloadBlock, t: displayName, b: BotIcon, m: Markdown,
|
|
4
|
+
export default function PlatformActivityRow({ item, d: ActivityDisclosure, p: PayloadBlock, t: displayName, b: BotIcon, m: Markdown, j, s, }: {
|
|
5
5
|
item: ReasoningItem | SandboxItem | StartupPhaseItem;
|
|
6
6
|
d: typeof import("./shared.js").ActivityDisclosure;
|
|
7
7
|
p: typeof import("./shared.js").PayloadBlock;
|
|
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>>;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { RetainedArtifactReference } from "@opengeni/sdk";
|
|
2
|
+
import type { ToolRendererProps } from "./registry.js";
|
|
3
|
+
type RetainedImageState = {
|
|
4
|
+
kind: "loading";
|
|
5
|
+
} | {
|
|
6
|
+
kind: "ready";
|
|
7
|
+
url: string;
|
|
8
|
+
} | {
|
|
9
|
+
kind: "unavailable";
|
|
10
|
+
label: string;
|
|
11
|
+
} | {
|
|
12
|
+
kind: "error";
|
|
13
|
+
message: string;
|
|
14
|
+
};
|
|
15
|
+
export declare function useRetainedImageObjectUrl(artifact: RetainedArtifactReference, load: ToolRendererProps["loadRetainedArtifact"]): RetainedImageState;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ToolRegistry } from "./registry.js";
|
|
2
|
+
import type { ActivityItem } from "./types.js";
|
|
3
|
+
/** One stable viewport; updates replace its content without moving the conversation. */
|
|
4
|
+
export declare function RollingActivity({ items, toolRegistry, previousItem, }: {
|
|
5
|
+
items: ActivityItem[];
|
|
6
|
+
/** The standalone item visible immediately before this reel mounted. */
|
|
7
|
+
previousItem?: ActivityItem | undefined;
|
|
8
|
+
toolRegistry?: ToolRegistry;
|
|
9
|
+
}): import("react").JSX.Element | null;
|
|
@@ -14,6 +14,8 @@ export declare function ToolCallTruncationProvider({ value, children, }: {
|
|
|
14
14
|
children: ReactNode;
|
|
15
15
|
}): import("react").JSX.Element;
|
|
16
16
|
export type ActivityDisclosureProps = {
|
|
17
|
+
/** Override the rolling preview; null keeps rapidly streaming details out of the header. */
|
|
18
|
+
compactPreview?: ReactNode;
|
|
17
19
|
icon: ReactNode;
|
|
18
20
|
/** Icon tint. Defaults to the muted foreground; renderers pass accent/failed. */
|
|
19
21
|
iconTone?: "accent" | "failed" | "running" | "muted" | undefined;
|
|
@@ -67,7 +69,8 @@ export type ActivityDisclosureProps = {
|
|
|
67
69
|
* inline media, and at most one right-gutter settle chip. Compact by default;
|
|
68
70
|
* the body mounts only when expanded.
|
|
69
71
|
*/
|
|
70
|
-
export declare
|
|
72
|
+
export declare const CompactActivityContext: import("react").Context<boolean>;
|
|
73
|
+
export declare function ActivityDisclosure({ icon, iconTone: iconToneProp, title, titleMono, running, preview, compactPreview, media, chip: chipProp, failed, cancelled, expandable, defaultOpen, children, }: ActivityDisclosureProps): import("react").JSX.Element;
|
|
71
74
|
export declare function TermBlock({ command, workdir, output, live, tailLines, failed, }: {
|
|
72
75
|
/**
|
|
73
76
|
* The command shown in the prompt header. Pass `null` when the row title
|
|
@@ -56,6 +56,8 @@ type ReplaceTurnSummaryFacets = Readonly<{
|
|
|
56
56
|
}>;
|
|
57
57
|
export type TurnSummaryFacetConfiguration = ModifyTurnSummaryFacets | ReplaceTurnSummaryFacets;
|
|
58
58
|
export type TurnSummaryOptions = Readonly<{
|
|
59
|
+
/** Experimental compact live activity reel. */
|
|
60
|
+
rolling?: boolean;
|
|
59
61
|
facets?: TurnSummaryFacetConfiguration;
|
|
60
62
|
}>;
|
|
61
63
|
export type TurnSummaryProps = {
|
|
@@ -73,6 +75,7 @@ export type TurnSummaryProps = {
|
|
|
73
75
|
durationMs?: number | undefined;
|
|
74
76
|
/** Start expanded. */
|
|
75
77
|
defaultOpen?: boolean | undefined;
|
|
78
|
+
liveHeader?: ReactNode;
|
|
76
79
|
/**
|
|
77
80
|
* A nested fold — a cluster or sub-turn INSIDE an already-expanded turn. It
|
|
78
81
|
* drops the bordered/filled chip and renders as a plain disclosure node on the
|
|
@@ -113,4 +116,4 @@ export type TurnSummaryProps = {
|
|
|
113
116
|
/** The rendered activity rail revealed on expand. */
|
|
114
117
|
children: ReactNode;
|
|
115
118
|
};
|
|
116
|
-
export declare function TurnSummary({ items, outcome, failureText, durationMs, defaultOpen, bare, facets: facetConfiguration, settleFold, foldKey, copyText, contextCompactionCount, children, }: TurnSummaryProps): import("react").JSX.Element;
|
|
119
|
+
export declare function TurnSummary({ items, outcome, failureText, durationMs, defaultOpen, liveHeader, bare, facets: facetConfiguration, settleFold, foldKey, copyText, contextCompactionCount, children, }: TurnSummaryProps): import("react").JSX.Element;
|
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;
|