@opengeni/react 5.2.0-canary.0 → 6.0.0-canary.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -0
- package/dist/artifacts.d.ts +1 -1
- package/dist/artifacts.js +3 -1
- package/dist/artifacts.js.map +1 -1
- package/dist/{chunk-QXJCNVSD.js → chunk-CC7AVRIJ.js} +1769 -1493
- package/dist/chunk-CC7AVRIJ.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-IYCR4343.js → chunk-PZ27MCZP.js} +36 -1
- package/dist/chunk-PZ27MCZP.js.map +1 -0
- package/dist/{chunk-2TKI3WEG.js → chunk-WYWRYUNQ.js} +12 -1
- package/dist/chunk-WYWRYUNQ.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/connect.js +11 -19
- package/dist/connect.js.map +1 -1
- package/dist/hooks/use-file-attachments.d.ts +2 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +13 -5
- 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 +6 -107
- 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/retained-image.d.ts +2 -0
- package/dist/timeline/types.d.ts +13 -2
- package/package.json +3 -3
- package/src/artifacts.ts +1 -1
- package/src/components/computer-viewer.tsx +11 -3
- package/src/components/message-timeline.tsx +42 -12
- package/src/components/session-chrome.tsx +14 -2
- package/src/connection-catalog.tsx +8 -21
- 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/retained-image.ts +12 -0
- package/src/timeline/tool-renderers.tsx +115 -16
- package/src/timeline/types.ts +14 -0
- package/dist/chunk-2TKI3WEG.js.map +0 -1
- 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":";AAKe,SAAR,oBAAqC;AAAA,EAC1C;AAAA,EACA,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH;AAAA,EACA;AACF,GASG;AACD,MAAI,KAAK,SAAS,aAAa;AAC7B,WAAO,EAAE,oBAAoB;AAAA,MAC3B,MAAM,UAAU,GAAG,CAAC;AAAA,MACpB,UAAU;AAAA,MACV,OAAO,KAAK,YACR,aACA,EAAE,QAAQ;AAAA,QACR,WAAW;AAAA,QACX,UAAU;AAAA,MACZ,CAAC;AAAA,MACL,SAAS,KAAK;AAAA,MACd,gBAAgB,KAAK,KAAK,QAAQ,cAAc,EAAE,EAAE,QAAQ,QAAQ,GAAG;AAAA,MACvE,SAAS,EAAE,QAAQ;AAAA,QACjB,WAAW;AAAA,QACX,UAAU,EAAE,UAAU,EAAE,WAAW,KAAK,WAAW,UAAU,KAAK,KAAK,CAAC;AAAA,MAC1E,CAAC;AAAA,MACD,UAAU,EAAE,OAAO;AAAA,QACjB,WAAW;AAAA,QACX,UAAU,EAAE,UAAU,EAAE,WAAW,KAAK,WAAW,UAAU,KAAK,KAAK,CAAC;AAAA,MAC1E,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AACA,MAAI,KAAK,SAAS,WAAW;AAC3B,WAAO,EAAE,oBAAoB;AAAA,MAC3B,MAAM,aAAa,GAAG,CAAC;AAAA,MACvB,UACE,KAAK,WAAW,WAAW,WAAW,KAAK,WAAW,YAAY,YAAY;AAAA,MAChF,OAAO,gBAAgB,MAAM,WAAW;AAAA,MACxC,SAAS,KAAK,WAAW;AAAA,MACzB,QAAQ,KAAK,WAAW;AAAA,MACxB,WAAW,KAAK,WAAW;AAAA,MAC3B,SAAS,KAAK,WAAW;AAAA,MACzB,UAAU;AAAA,QACR,KAAK,UAAU,EAAE,cAAc,EAAE,OAAO,WAAW,OAAO,KAAK,QAAQ,GAAG,SAAS,IAAI;AAAA,QACvF,KAAK,SAAS,EAAE,cAAc,EAAE,OAAO,UAAU,OAAO,KAAK,OAAO,GAAG,QAAQ,IAAI;AAAA,MACrF;AAAA,IACF,CAAC;AAAA,EACH;AAEA,QAAM,SAAS,KAAK,WAAW;AAC/B,QAAM,UAAU,KAAK,WAAW;AAChC,QAAM,WAAW,gBAAgB,KAAK,UAAU;AAChD,SAAO,EAAE,oBAAoB;AAAA,IAC3B,MAAM,EAAE,SAAS,EAAE,WAAW,WAAW,CAAC;AAAA,IAC1C,UAAU,SAAS,WAAW,UAAU,YAAY;AAAA,IACpD,OACE,KAAK,kBAAkB,yBACnB,iCACA,kBAAkB,KAAK,OAAO,KAAK,QAAQ,KAAK,OAAO;AAAA,IAC7D,SACE,KAAK,UAAU,sBACX,kFACA;AAAA,IACN;AAAA,IACA;AAAA,IACA,WAAW,KAAK,WAAW;AAAA,IAC3B,MAAM,WAAW,EAAE,MAAM,SAAS,QAAQ,SAAS,MAAM,SAAS,IAAI;AAAA,IACtE,YAAY;AAAA,EACd,CAAC;AACH;AAEA,SAAS,UAAU,GAAW,GAAY;AACxC,SAAO,WAAW,GAAG,GAAG,SAAS;AAAA,IAC/B,EAAE,QAAQ,EAAE,GAAG,YAAY,GAAG,OAAO;AAAA,IACrC,EAAE,QAAQ,EAAE,GAAG,iDAAiD,GAAG,QAAQ;AAAA,IAC3E,EAAE,QAAQ,EAAE,GAAG,iDAAiD,GAAG,KAAK;AAAA,IACxE,EAAE,QAAQ,EAAE,GAAG,qCAAqC,GAAG,aAAa;AAAA,IACpE,EAAE,QAAQ,EAAE,GAAG,2BAA2B,GAAG,OAAO;AAAA,IACpD,EAAE,QAAQ,EAAE,GAAG,sDAAsD,GAAG,MAAM;AAAA,IAC9E,EAAE,QAAQ,EAAE,GAAG,0BAA0B,GAAG,MAAM;AAAA,IAClD,EAAE,QAAQ,EAAE,GAAG,oCAAoC,GAAG,YAAY;AAAA,EACpE,CAAC;AACH;AAEA,SAAS,aAAa,GAAW,GAAY;AAC3C,SAAO,WAAW,GAAG,GAAG,mBAAmB;AAAA,IACzC,EAAE,QAAQ,EAAE,GAAG,gBAAgB,GAAG,QAAQ;AAAA,IAC1C,EAAE,QAAQ,EAAE,GAAG,WAAW,GAAG,QAAQ;AAAA,IACrC,EAAE,QAAQ,EAAE,OAAO,IAAI,QAAQ,IAAI,GAAG,GAAG,GAAG,GAAG,IAAI,GAAG,IAAI,EAAE,GAAG,OAAO;AAAA,EACxE,CAAC;AACH;AAEA,SAAS,WAAW,GAAW,GAAY,MAAc,UAAgC;AACvF,SAAO,EAAE,OAAO;AAAA,IACd,eAAe;AAAA,IACf,WAAW,iBAAiB,IAAI;AAAA,IAChC,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,eAAe;AAAA,IACf,gBAAgB;AAAA,IAChB,aAAa;AAAA,IACb,SAAS;AAAA,IACT,OAAO;AAAA,IACP;AAAA,EACF,CAAC;AACH;AAEA,SAAS,gBAAgB,MAAmB,aAA+C;AACzF,MAAI,KAAK,SAAS,qBAAqB;AACrC,WAAO;AAAA,MACL;AAAA,MACA,KAAK,WAAW,cAAc,aAAa,KAAK;AAAA,MAChD,KAAK,UAAU;AAAA,IACjB;AAAA,EACF;AACA,SAAO,YAAY,KAAK,IAAI;AAC9B;AAEA,SAAS,kBACP,OACA,QACA,SACQ;AACR,MAAI,WAAW,cAAc,UAAU,aAAa,WAAW,YAAY,WAAW;AACpF,WAAO,WAAW,YAAY,YAAY,eAAe,OAAO;AAAA,EAClE;AACA,MAAI,WAAW,cAAc,UAAU,SAAS,YAAY,WAAW;AACrE,WAAO;AAAA,EACT;AACA,QAAM,cACJ,WAAW,YAAY,IAAI,WAAW,WAAW,IAAI,WAAW,cAAc,IAAI;AACpF,SAAO,qBAAqB,KAAK,EAAE,WAAW;AAChD;AAEA,IAAM,uBAGF;AAAA,EACF,OAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,SAAS;AAAA,IACP;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,KAAK,CAAC,kBAAkB,oBAAoB,yBAAyB,WAAW;AAAA,EAChF,YAAY;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,OAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,OAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,mBAAmB;AAAA,IACjB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,qBAAqB;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,gBAAgB,YAA0C;AACjE,MAAI,eAAe,QAAQ,CAAC,OAAO,SAAS,UAAU,KAAK,aAAa,EAAG,QAAO;AAClF,MAAI,aAAa,IAAO,QAAO,GAAG,KAAK,MAAM,UAAU,CAAC;AACxD,MAAI,aAAa,IAAQ,QAAO,IAAI,aAAa,KAAO,QAAQ,CAAC,CAAC;AAClE,QAAM,UAAU,KAAK,MAAM,aAAa,GAAM;AAC9C,QAAM,UAAU,KAAK,MAAO,aAAa,MAAU,GAAK;AACxD,SAAO,GAAG,OAAO,KAAK,OAAO,OAAO,EAAE,SAAS,GAAG,GAAG,CAAC;AACxD;","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-CC7AVRIJ.js";
|
|
20
22
|
import "./chunk-YBM6CQRU.js";
|
|
21
23
|
import "./chunk-5M6VTFJ5.js";
|
|
22
24
|
import "./chunk-ZYRGEKWS.js";
|
|
@@ -26,127 +28,24 @@ import "./chunk-IHQII5WO.js";
|
|
|
26
28
|
import "./chunk-JVYQRRC4.js";
|
|
27
29
|
import "./chunk-45XEUVTK.js";
|
|
28
30
|
import "./chunk-HQV2I5HV.js";
|
|
29
|
-
import "./chunk-
|
|
31
|
+
import "./chunk-WYWRYUNQ.js";
|
|
30
32
|
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>>;
|
|
@@ -12,5 +12,7 @@ type RetainedImageState = {
|
|
|
12
12
|
kind: "error";
|
|
13
13
|
message: string;
|
|
14
14
|
};
|
|
15
|
+
/** Shared browser preview allowlist; other published files remain downloads. */
|
|
16
|
+
export declare function isRetainedImageContentType(contentType: string): boolean;
|
|
15
17
|
export declare function useRetainedImageObjectUrl(artifact: RetainedArtifactReference, load: ToolRendererProps["loadRetainedArtifact"]): RetainedImageState;
|
|
16
18
|
export {};
|
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": "
|
|
3
|
+
"version": "6.0.0-canary.0",
|
|
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": "^
|
|
136
|
+
"@opengeni/connect": "^0.2.0-canary.9",
|
|
137
|
+
"@opengeni/sdk": "^6.0.0-canary.0",
|
|
138
138
|
"clsx": "^2.1.1",
|
|
139
139
|
"dequal": "2.0.3",
|
|
140
140
|
"lucide-react": "^1.8.0",
|
package/src/artifacts.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { inlineHtmlDocument } from "./components/artifacts/inline-html-document";
|
|
2
|
-
export { useRetainedImageObjectUrl } from "./timeline/retained-image";
|
|
2
|
+
export { isRetainedImageContentType, useRetainedImageObjectUrl } from "./timeline/retained-image";
|
|
3
3
|
/** Public artifact surfaces. Import from `@opengeni/react/artifacts`. */
|
|
4
4
|
export {
|
|
5
5
|
ArtifactSurface,
|
|
@@ -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
|
|
@@ -2,6 +2,10 @@ import { RollingActivity } from "../timeline/rolling-activity";
|
|
|
2
2
|
import { GenieLoadingOptionsContext, type GenieLoadingOptions } from "../timeline/genie-loading";
|
|
3
3
|
import { ChildSessionLink } from "./child-session-link";
|
|
4
4
|
import { useStartupDetails } from "../timeline/startup-preference";
|
|
5
|
+
import { parseSandboxFileArtifactReceipt } from "@opengeni/sdk";
|
|
6
|
+
import { unwrapMcpOutput } from "../timeline/parsers";
|
|
7
|
+
import { isRetainedImageContentType } from "../timeline/retained-image";
|
|
8
|
+
import { mcpToolLeaf } from "../timeline/tool-display-name";
|
|
5
9
|
import type {
|
|
6
10
|
DraftTimelineAnnotation,
|
|
7
11
|
MediaGenerationResult,
|
|
@@ -2537,9 +2541,15 @@ const TimelineGroupView = memo(function TimelineGroupView({
|
|
|
2537
2541
|
// Settled (or live-fold) activity clusters get a chip. Inside an expanded
|
|
2538
2542
|
// turn that is the second layer — quiet nested chips under the outer turn
|
|
2539
2543
|
// summary when contiguous activity naturally clusters (≥2 only).
|
|
2544
|
+
const containsPresentedImage = timelineGroupContainsPresentedImage(group);
|
|
2545
|
+
const hasRememberedImageFold =
|
|
2546
|
+
group.kind === "activity" && containsPresentedImage && foldMemory?.has(group.id);
|
|
2547
|
+
// Primary images stay visible through live narration and the turn wrap.
|
|
2548
|
+
// Manual collapse still belongs to TurnSummary's existing fold memory.
|
|
2540
2549
|
const activityShouldFold =
|
|
2541
|
-
group.kind === "activity" &&
|
|
2542
|
-
|
|
2550
|
+
group.kind === "activity" &&
|
|
2551
|
+
!containsPresentedImage &&
|
|
2552
|
+
!!(group.outcome || (foldLiveCluster && clusterIsSettled(group)));
|
|
2543
2553
|
// Latch live→folded so a top-level shell that was already mounted open can
|
|
2544
2554
|
// start the settle beat without remounting bare rail → wrapper.
|
|
2545
2555
|
const liveActivitySettle = useLiveSettleFold(activityShouldFold && !insideTurn);
|
|
@@ -2548,7 +2558,7 @@ const TimelineGroupView = memo(function TimelineGroupView({
|
|
|
2548
2558
|
group.kind === "turn" &&
|
|
2549
2559
|
(group.outcome === "failed" ||
|
|
2550
2560
|
timelineGroupContainsAuthNeeded(group) ||
|
|
2551
|
-
|
|
2561
|
+
containsPresentedImage);
|
|
2552
2562
|
// activity-* → turn-* remount: carry resting state so settleFold does not
|
|
2553
2563
|
// re-open a chip the reader already watched collapse.
|
|
2554
2564
|
if (group.kind === "turn" && foldMemory && !insideTurn) {
|
|
@@ -2589,6 +2599,7 @@ const TimelineGroupView = memo(function TimelineGroupView({
|
|
|
2589
2599
|
if (
|
|
2590
2600
|
turnSummary?.rolling &&
|
|
2591
2601
|
!startupDetails &&
|
|
2602
|
+
!hasRememberedImageFold &&
|
|
2592
2603
|
group.items.filter((item) => item.kind !== "startup-phase").length === 1
|
|
2593
2604
|
) {
|
|
2594
2605
|
return (
|
|
@@ -2620,8 +2631,12 @@ const TimelineGroupView = memo(function TimelineGroupView({
|
|
|
2620
2631
|
!startupDetails &&
|
|
2621
2632
|
visibleActivity.length === 1 &&
|
|
2622
2633
|
visibleActivity[0]?.kind === "reasoning";
|
|
2634
|
+
// Untouched images stay primary output, but a reader-owned image fold
|
|
2635
|
+
// must keep its shell across a multi-cluster wrap. A bare rail would
|
|
2636
|
+
// bypass the remembered choice; retaining either state also lets the
|
|
2637
|
+
// reader reopen and close the same chip after settlement.
|
|
2623
2638
|
const useNestedChip =
|
|
2624
|
-
nestClusterChips && activityShouldFold
|
|
2639
|
+
nestClusterChips && (activityShouldFold || hasRememberedImageFold) && !singleThought;
|
|
2625
2640
|
if (!useNestedChip) {
|
|
2626
2641
|
return (
|
|
2627
2642
|
<ActivityRail
|
|
@@ -2663,16 +2678,24 @@ const TimelineGroupView = memo(function TimelineGroupView({
|
|
|
2663
2678
|
// flips settleFold (collapse) instead of remounting bare rail → wrapper.
|
|
2664
2679
|
return (
|
|
2665
2680
|
<TurnSummary
|
|
2681
|
+
// Apply the primary-output default when a rolling activity first
|
|
2682
|
+
// produces an image; the stable foldKey still preserves user choices.
|
|
2683
|
+
key={containsPresentedImage ? "primary-image" : "activity"}
|
|
2666
2684
|
items={group.items}
|
|
2667
2685
|
outcome={group.outcome}
|
|
2668
2686
|
failureText={group.failureText}
|
|
2669
2687
|
defaultOpen={
|
|
2670
|
-
group.outcome === "failed" ||
|
|
2688
|
+
group.outcome === "failed" ||
|
|
2689
|
+
containsPresentedImage ||
|
|
2690
|
+
(!turnSummary?.rolling && !activityShouldFold)
|
|
2671
2691
|
? true
|
|
2672
2692
|
: undefined
|
|
2673
2693
|
}
|
|
2674
2694
|
liveHeader={
|
|
2675
|
-
turnSummary?.rolling &&
|
|
2695
|
+
turnSummary?.rolling &&
|
|
2696
|
+
!containsPresentedImage &&
|
|
2697
|
+
!group.outcome &&
|
|
2698
|
+
!foldLiveCluster ? (
|
|
2676
2699
|
<RollingActivity
|
|
2677
2700
|
items={group.items}
|
|
2678
2701
|
toolRegistry={toolRegistry}
|
|
@@ -2862,17 +2885,24 @@ function timelineGroupContainsAuthNeeded(group: TimelineGroup): boolean {
|
|
|
2862
2885
|
}
|
|
2863
2886
|
}
|
|
2864
2887
|
|
|
2865
|
-
/**
|
|
2866
|
-
function
|
|
2888
|
+
/** Deliberately published images are primary output, not incidental screenshots. */
|
|
2889
|
+
function timelineGroupContainsPresentedImage(group: TimelineGroup): boolean {
|
|
2867
2890
|
switch (group.kind) {
|
|
2868
2891
|
case "item":
|
|
2869
2892
|
return false;
|
|
2870
2893
|
case "activity":
|
|
2871
|
-
return group.items.some(
|
|
2872
|
-
(item
|
|
2873
|
-
|
|
2894
|
+
return group.items.some((item) => {
|
|
2895
|
+
if (item.kind !== "tool-call") return false;
|
|
2896
|
+
const name = mcpToolLeaf(item.name);
|
|
2897
|
+
if (name === "generate_image" || name === "image_generation_call") return true;
|
|
2898
|
+
if (item.status !== "complete" || name !== "sandbox_file_publish") return false;
|
|
2899
|
+
const output = unwrapMcpOutput(item.output);
|
|
2900
|
+
if (output.isError) return false;
|
|
2901
|
+
const receipt = parseSandboxFileArtifactReceipt(output.text);
|
|
2902
|
+
return receipt !== null && isRetainedImageContentType(receipt.artifact.contentType);
|
|
2903
|
+
});
|
|
2874
2904
|
case "turn":
|
|
2875
|
-
return group.groups.some(
|
|
2905
|
+
return group.groups.some(timelineGroupContainsPresentedImage);
|
|
2876
2906
|
}
|
|
2877
2907
|
}
|
|
2878
2908
|
|
|
@@ -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
|
);
|
|
@@ -26,22 +26,11 @@ export type ConnectionCatalogProps = {
|
|
|
26
26
|
emptyMessage?: string;
|
|
27
27
|
};
|
|
28
28
|
|
|
29
|
-
function
|
|
30
|
-
option,
|
|
31
|
-
name = option.name,
|
|
32
|
-
}: {
|
|
33
|
-
option: ConnectionCatalogOption;
|
|
34
|
-
name?: string;
|
|
35
|
-
}) {
|
|
29
|
+
function ConnectionDetailsIndicator() {
|
|
36
30
|
return (
|
|
37
|
-
<
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
aria-label={`View ${name} details`}
|
|
41
|
-
onClick={option.onOpen}
|
|
42
|
-
>
|
|
43
|
-
<span aria-hidden>{option.connected ? "›" : "+"}</span>
|
|
44
|
-
</button>
|
|
31
|
+
<span aria-hidden className="og-connection-group-chevron">
|
|
32
|
+
›
|
|
33
|
+
</span>
|
|
45
34
|
);
|
|
46
35
|
}
|
|
47
36
|
|
|
@@ -54,10 +43,9 @@ export function ConnectionOptionRow({ option }: { option: ConnectionCatalogOptio
|
|
|
54
43
|
<span>{option.description}</span>
|
|
55
44
|
</span>
|
|
56
45
|
<span className="og-connection-catalog-status">{option.status}</span>
|
|
46
|
+
{!option.action ? <ConnectionDetailsIndicator /> : null}
|
|
57
47
|
</button>
|
|
58
|
-
<span className="og-connection-option-action">
|
|
59
|
-
{option.action ?? <ConnectionDetailsAction option={option} />}
|
|
60
|
-
</span>
|
|
48
|
+
{option.action ? <span className="og-connection-option-action">{option.action}</span> : null}
|
|
61
49
|
</div>
|
|
62
50
|
);
|
|
63
51
|
}
|
|
@@ -91,10 +79,9 @@ export function ConnectionServiceRow({ service }: { service: ConnectionCatalogSe
|
|
|
91
79
|
onClick={service.options[0]!.onOpen}
|
|
92
80
|
>
|
|
93
81
|
{identity}
|
|
82
|
+
{!service.options[0]?.action ? <ConnectionDetailsIndicator /> : null}
|
|
94
83
|
</button>
|
|
95
|
-
{service.options[0]?.action
|
|
96
|
-
<ConnectionDetailsAction option={service.options[0]!} name={service.name} />
|
|
97
|
-
)}
|
|
84
|
+
{service.options[0]?.action}
|
|
98
85
|
</div>
|
|
99
86
|
) : (
|
|
100
87
|
<details className="og-connection-catalog-service">
|