@opengeni/react 3.5.1-canary.0 → 3.7.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.
Files changed (87) hide show
  1. package/dist/artifacts.d.ts +1 -1
  2. package/dist/artifacts.js +248 -6
  3. package/dist/artifacts.js.map +1 -1
  4. package/dist/{browser-viewer-E5DDEFQ4.js → browser-viewer-NTD6UIPR.js} +3 -3
  5. package/dist/{chunk-W2RGYBCV.js → chunk-24M4YBCL.js} +4 -4
  6. package/dist/{chunk-WY3MELVJ.js → chunk-5IXTJTK3.js} +1438 -397
  7. package/dist/chunk-5IXTJTK3.js.map +1 -0
  8. package/dist/chunk-5PQJOCX5.js +902 -0
  9. package/dist/chunk-5PQJOCX5.js.map +1 -0
  10. package/dist/{chunk-UNCXXIQR.js → chunk-INGB2N5R.js} +4310 -3982
  11. package/dist/chunk-INGB2N5R.js.map +1 -0
  12. package/dist/{chunk-TJFMMDQU.js → chunk-MOWYEBCQ.js} +1839 -17
  13. package/dist/chunk-MOWYEBCQ.js.map +1 -0
  14. package/dist/chunk-PAJU5KKL.js +331 -0
  15. package/dist/chunk-PAJU5KKL.js.map +1 -0
  16. package/dist/{chunk-VTOREEXF.js → chunk-PLYRL5ER.js} +24 -2
  17. package/dist/{chunk-VTOREEXF.js.map → chunk-PLYRL5ER.js.map} +1 -1
  18. package/dist/{chunk-YVCHAQZY.js → chunk-ZFOFY5ST.js} +27 -349
  19. package/dist/chunk-ZFOFY5ST.js.map +1 -0
  20. package/dist/client.d.ts +1 -1
  21. package/dist/components/artifacts/index.d.ts +1 -1
  22. package/dist/components/artifacts/published-html-artifact-frame.d.ts +46 -3
  23. package/dist/components/composer.d.ts +2 -0
  24. package/dist/components/session-chrome.d.ts +38 -5
  25. package/dist/components/session-commands-panel.d.ts +6 -0
  26. package/dist/components/session-conversation.d.ts +14 -0
  27. package/dist/components/timeline-anchor.d.ts +21 -0
  28. package/dist/composer.js +2 -3
  29. package/dist/conversation-timeline.d.ts +5 -0
  30. package/dist/{fleet-decision-row-GGCAT4E4.js → fleet-decision-row-YZ3ZKWMM.js} +2 -1
  31. package/dist/fleet-decision-row-YZ3ZKWMM.js.map +1 -0
  32. package/dist/hooks/use-file-attachments.d.ts +6 -0
  33. package/dist/hooks/use-sandbox-files.d.ts +4 -1
  34. package/dist/hooks/use-workspace-edit.d.ts +4 -0
  35. package/dist/index.d.ts +4 -1
  36. package/dist/index.js +823 -965
  37. package/dist/index.js.map +1 -1
  38. package/dist/interaction.js +2 -2
  39. package/dist/lib/format.d.ts +5 -0
  40. package/dist/machines.js +3 -2
  41. package/dist/session-ui.d.ts +3 -0
  42. package/dist/session-ui.js +14 -4
  43. package/dist/session.js +19 -19
  44. package/dist/timeline/registry.d.ts +2 -0
  45. package/dist/timeline/types.d.ts +4 -2
  46. package/package.json +2 -2
  47. package/src/artifacts.ts +3 -0
  48. package/src/client.ts +2 -1
  49. package/src/components/artifacts/index.ts +3 -0
  50. package/src/components/artifacts/published-html-artifact-frame.tsx +307 -4
  51. package/src/components/composer.tsx +89 -25
  52. package/src/components/machine-input-display.ts +6 -0
  53. package/src/components/message-timeline.tsx +351 -204
  54. package/src/components/sandbox-workspace.tsx +11 -1
  55. package/src/components/session-chrome.tsx +501 -128
  56. package/src/components/session-commands-panel.tsx +113 -0
  57. package/src/components/session-conversation.tsx +141 -0
  58. package/src/components/timeline-anchor.tsx +91 -0
  59. package/src/conversation-timeline.ts +83 -0
  60. package/src/hooks/use-file-attachments.ts +34 -0
  61. package/src/hooks/use-sandbox-files.ts +68 -20
  62. package/src/hooks/use-session-background-commands.ts +21 -10
  63. package/src/hooks/use-session-events.ts +56 -39
  64. package/src/hooks/use-session.ts +23 -2
  65. package/src/hooks/use-workspace-edit.ts +23 -5
  66. package/src/index.ts +4 -0
  67. package/src/lib/format.ts +32 -0
  68. package/src/session-ui.ts +3 -0
  69. package/src/timeline/fleet-decision-projection.ts +2 -1
  70. package/src/timeline/fleet-decision-row.tsx +1 -0
  71. package/src/timeline/projection.ts +157 -19
  72. package/src/timeline/registry.ts +15 -3
  73. package/src/timeline/tool-renderers.tsx +117 -1
  74. package/src/timeline/types.ts +12 -1
  75. package/styles/compiled.css +495 -411
  76. package/styles/index.css +23 -0
  77. package/dist/chunk-7EAFGICR.js +0 -302
  78. package/dist/chunk-7EAFGICR.js.map +0 -1
  79. package/dist/chunk-IB27C53Y.js +0 -2582
  80. package/dist/chunk-IB27C53Y.js.map +0 -1
  81. package/dist/chunk-TJFMMDQU.js.map +0 -1
  82. package/dist/chunk-UNCXXIQR.js.map +0 -1
  83. package/dist/chunk-WY3MELVJ.js.map +0 -1
  84. package/dist/chunk-YVCHAQZY.js.map +0 -1
  85. package/dist/fleet-decision-row-GGCAT4E4.js.map +0 -1
  86. /package/dist/{browser-viewer-E5DDEFQ4.js.map → browser-viewer-NTD6UIPR.js.map} +0 -0
  87. /package/dist/{chunk-W2RGYBCV.js.map → chunk-24M4YBCL.js.map} +0 -0
@@ -28,16 +28,23 @@
28
28
  * Inbox has no product dismiss API; pass `onDismissIncoming` when the host
29
29
  * wants a visible action (dev harness may use a local dummy).
30
30
  *
31
+ * Queue opens by default when chrome is idle and at least one authoritative
32
+ * prompt is queued. Closing the queue dismisses that session's offer until
33
+ * occupancy drains; a different session on the same chrome instance may
34
+ * offer again. An in-flight optimistic Send never opens the drawer —
35
+ * admission stays a paint-only receipt on the chip so layout does not jump
36
+ * under the pointer.
37
+ *
31
38
  * Segment switches keep the panel shell mounted and crossfade content. The
32
39
  * shell uses one CSS grid-track transition for deliberate open/close actions;
33
40
  * live queue reconciliation never feeds measurements back into layout.
34
41
  */
35
- import type { SessionGoal } from "@opengeni/sdk";
42
+ import type { SessionGoal, SessionTurn } from "@opengeni/sdk";
36
43
  import { type ReactNode } from "react";
37
- import type { ComposerState } from "../hooks/use-composer.js";
44
+ import type { ComposerOptimisticMessage, ComposerState } from "../hooks/use-composer.js";
38
45
  import type { UseGoalResult } from "../hooks/use-goal.js";
39
46
  import type { UseTurnQueueResult } from "../hooks/use-turn-queue.js";
40
- export type SessionChromeSignalId = "incoming" | "steering" | "queue" | "goal" | "agents";
47
+ export type SessionChromeSignalId = "incoming" | "steering" | "queue" | "goal" | "agents" | "commands";
41
48
  export type SessionChromeSignalTone = "neutral" | "accent" | "waiting" | "running";
42
49
  export type SessionChromeAgentsSignal = {
43
50
  count: number;
@@ -45,12 +52,16 @@ export type SessionChromeAgentsSignal = {
45
52
  tone?: SessionChromeSignalTone | undefined;
46
53
  };
47
54
  export type SessionChromeProps = {
55
+ compact?: boolean;
48
56
  queue: UseTurnQueueResult;
49
57
  /** Needed for queue edit → composer checkout. Omit with `readOnly`. */
50
58
  composer?: ComposerState | undefined;
51
59
  goal?: UseGoalResult | null | undefined;
52
60
  /** Expanded agents body (host supplies tree / list). */
53
61
  agentsPanel?: ReactNode;
62
+ /** Active commands only. The host mounts the body only when opened. */
63
+ commandsPanel?: ReactNode;
64
+ commandsCount?: number | undefined;
54
65
  /** Chip summary; when `count > 0` the agents segment appears. */
55
66
  agentsSignal?: SessionChromeAgentsSignal | undefined;
56
67
  /**
@@ -73,11 +84,33 @@ type GoalPillRecord = Pick<SessionGoal, "status" | "pausedReason"> & {
73
84
  export declare function sessionChromeGoalPillLabel(state: GoalPillState, record: GoalPillRecord | null | undefined): string;
74
85
  /**
75
86
  * One human sentence explaining WHY the goal is not pursuing right now: the
76
- * pause reason, the agent's own `goal_wait` hold (reason + deadline), or the
87
+ * pause reason, the agent's own `wait_for_input` hold (reason + deadline), or the
77
88
  * next idle-backoff check time. Null when the state needs no explanation.
78
89
  */
79
90
  export declare function sessionChromeGoalPillExplanation(state: GoalPillState, record: GoalPillRecord | null | undefined): string | null;
91
+ export declare function countAuthoritativeQueuedTurns(turns: readonly SessionTurn[], mutationFor: UseTurnQueueResult["mutationFor"]): number;
92
+ export declare function countOptimisticQueuedMessages(messages: readonly ComposerOptimisticMessage[] | undefined, queuedTurnIds: ReadonlySet<string>, snapshot: UseTurnQueueResult["snapshot"]): number;
93
+ /**
94
+ * First uncontrolled segment. An existing authoritative queue opens itself
95
+ * when the host did not pick another default; optimistic-only occupancy
96
+ * stays collapsed so a live Send does not shove a drawer under the pointer.
97
+ */
98
+ export declare function sessionChromeInitialActive(input: {
99
+ defaultActive: SessionChromeSignalId | null;
100
+ authoritativeQueuedCount: number;
101
+ }): SessionChromeSignalId | null;
102
+ /**
103
+ * Whether idle chrome should offer the queue panel. A dismissed session
104
+ * stays collapsed until occupancy drains. Controlled hosts own this.
105
+ */
106
+ export declare function sessionChromeShouldOfferQueue(input: {
107
+ controlled: boolean;
108
+ active: SessionChromeSignalId | null;
109
+ activityOpen: boolean;
110
+ authoritativeQueuedCount: number;
111
+ suppressed: boolean;
112
+ }): boolean;
80
113
  /** Select pill state from the goal's authoritative continuation projection. */
81
114
  export declare function sessionChromeGoalPillState(goalStatus: "active" | "paused" | "completed", continuation: SessionGoal["continuation"] | null | undefined): GoalPillState;
82
- export declare function SessionChrome({ queue, composer, goal, agentsPanel, agentsSignal, onDismissIncoming, readOnly, className, active: activeControlled, defaultActive, onActiveChange, }: SessionChromeProps): import("react").JSX.Element | null;
115
+ export declare function SessionChrome({ compact, queue, composer, goal, agentsPanel, commandsPanel, commandsCount, agentsSignal, onDismissIncoming, readOnly, className, active: activeControlled, defaultActive, onActiveChange, }: SessionChromeProps): import("react").JSX.Element | null;
83
116
  export {};
@@ -0,0 +1,6 @@
1
+ import type { UseSessionBackgroundCommandsResult } from "../hooks/use-session-background-commands.js";
2
+ /** The current session's live commands. Settled commands belong to the timeline. */
3
+ export declare function SessionCommandsPanel({ commands: state, readOnly, }: {
4
+ commands: UseSessionBackgroundCommandsResult;
5
+ readOnly?: boolean;
6
+ }): import("react").JSX.Element;
@@ -0,0 +1,14 @@
1
+ import { type CSSProperties } from "react";
2
+ import { type ClientOverride } from "../session-context.js";
3
+ import { type ChatComposerProps } from "./chat-composer.js";
4
+ export type SessionConversationProps = ClientOverride & {
5
+ sessionId: string;
6
+ className?: string;
7
+ /** Defaults to filling the host. The host owns available height. */
8
+ height?: CSSProperties["height"];
9
+ /** Presentation/custom controls only; queue and delivery wiring stay owned here. */
10
+ composerProps?: Omit<ChatComposerProps, "composer" | "effectiveControl" | "queuedAheadCount">;
11
+ };
12
+ /** Complete existing-session conversation. Uses the provider's normal SDK client
13
+ * (including Site clients), one shared event feed, and authoritative queue state. */
14
+ export declare function SessionConversation(props: SessionConversationProps): import("react").JSX.Element;
@@ -0,0 +1,21 @@
1
+ import { Component, type ReactNode } from "react";
2
+ type Anchor = {
3
+ element: HTMLElement;
4
+ key: string | null;
5
+ text: string | null;
6
+ top: number;
7
+ };
8
+ export type TimelineAnchor = Anchor[];
9
+ /** Read the old DOM immediately before React changes it, not when a fetch starts. */
10
+ export declare class TimelineBeforeLayout extends Component<{
11
+ capture: () => void;
12
+ children: ReactNode;
13
+ }> {
14
+ getSnapshotBeforeUpdate(): null;
15
+ componentDidUpdate(): void;
16
+ render(): ReactNode;
17
+ }
18
+ export declare function captureTimelineAnchor(scroller: HTMLElement): TimelineAnchor | null;
19
+ /** Return only the correction native browser anchoring has not already made. */
20
+ export declare function timelineAnchorCorrection(scroller: HTMLElement, anchors: TimelineAnchor): number | null;
21
+ export {};
package/dist/composer.js CHANGED
@@ -37,7 +37,7 @@ import {
37
37
  useChatComposer,
38
38
  useChatComposerController,
39
39
  useVoiceInput
40
- } from "./chunk-UNCXXIQR.js";
40
+ } from "./chunk-INGB2N5R.js";
41
41
  import {
42
42
  BillingClassMark,
43
43
  ModelPolicyPicker,
@@ -47,12 +47,11 @@ import {
47
47
  PickerNavRow,
48
48
  defaultModelPolicyPickerMessages
49
49
  } from "./chunk-4JFUT22W.js";
50
- import "./chunk-7EAFGICR.js";
51
50
  import "./chunk-VZTQ73XT.js";
52
51
  import "./chunk-IOLVN74D.js";
52
+ import "./chunk-PLYRL5ER.js";
53
53
  import "./chunk-KZ73RL76.js";
54
54
  import "./chunk-NEXLLTP4.js";
55
- import "./chunk-VTOREEXF.js";
56
55
  import "./chunk-WMGF4Z7X.js";
57
56
  import "./chunk-22KP6LR5.js";
58
57
  export {
@@ -0,0 +1,5 @@
1
+ import type { ComposerState } from "./hooks/use-composer.js";
2
+ import type { UseTurnQueueResult } from "./hooks/use-turn-queue.js";
3
+ import type { TimelineItem } from "./timeline/types.js";
4
+ /** Keep pending prompts in the queue, not duplicated in the conversation. */
5
+ export declare function conversationTimeline(items: TimelineItem[], queue: Pick<UseTurnQueueResult, "queue" | "snapshot" | "acceptedSteers">, composer: Pick<ComposerState, "optimisticMessages" | "retryOptimisticMessage" | "removeOptimisticMessage">): TimelineItem[];
@@ -23,6 +23,7 @@ var FLEET_ACTUAL_REASON_LABEL = {
23
23
  rotation: "Rotated for capacity",
24
24
  active: "Used the active subscription",
25
25
  all_capped: "All observed subscriptions were capped",
26
+ allocator_disabled: "The policy-selected subscription was disabled for new allocations",
26
27
  none: "No production candidate was selected"
27
28
  };
28
29
  var FLEET_SHADOW_REASON_LABEL = {
@@ -348,4 +349,4 @@ function formatFleetScore(value) {
348
349
  export {
349
350
  FleetDecisionRow as default
350
351
  };
351
- //# sourceMappingURL=fleet-decision-row-GGCAT4E4.js.map
352
+ //# sourceMappingURL=fleet-decision-row-YZ3ZKWMM.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/timeline/fleet-decision-row.tsx"],"sourcesContent":["import type { FleetDecisionItem } from \"./types\";\n\ntype RowJsx = typeof import(\"react/jsx-runtime\").jsx;\ntype RowJsxs = typeof import(\"react/jsx-runtime\").jsxs;\n\nfunction GaugeMark({ className, j, s }: { className: string; j: RowJsx; s: RowJsxs }) {\n return s(\"svg\", {\n \"aria-hidden\": \"true\",\n className,\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 j(\"path\", { d: \"m 12 14 4-4\" }, \"needle\"),\n j(\"path\", { d: \"M3.34 19a10 10 0 1 1 17.32 0\" }, \"arc\"),\n ],\n });\n}\n\nconst FLEET_ACTUAL_REASON_LABEL: Record<FleetDecisionItem[\"actualReason\"], string> = {\n lease_reused: \"Reused the fenced lease\",\n pin: \"Kept the session pin\",\n rotation: \"Rotated for capacity\",\n active: \"Used the active subscription\",\n all_capped: \"All observed subscriptions were capped\",\n allocator_disabled: \"The policy-selected subscription was disabled for new allocations\",\n none: \"No production candidate was selected\",\n};\n\nconst FLEET_SHADOW_REASON_LABEL: Record<FleetDecisionItem[\"shadowReason\"], string> = {\n fenced_in_flight: \"Kept the fenced in-flight assignment\",\n fenced_candidate_missing: \"The fenced assignment was missing from the snapshot\",\n admission_paced: \"Admission would have been paced\",\n no_eligible_candidate: \"No candidate passed the policy checks\",\n overlay_isolated_empty: \"Explicit isolation left no eligible candidate\",\n best_score: \"Selected the lowest-pressure candidate\",\n affinity_best: \"Session affinity was already best\",\n hysteresis_hold: \"Hysteresis avoided a low-value switch\",\n};\n\nconst FLEET_COMPARISON_LABEL: Record<FleetDecisionItem[\"comparison\"], string> = {\n match: \"Production and shadow matched\",\n different_candidate: \"Shadow preferred another candidate\",\n different_outcome: \"Production and shadow outcomes differed\",\n not_comparable_truncated: \"Comparison limited by bounded candidate data\",\n};\n\nconst FLEET_ADMISSION_REASON_LABEL: Record<FleetDecisionItem[\"admissionReason\"], string> = {\n fenced_in_flight: \"In-flight assignment was fenced\",\n pacing_disabled: \"Admission pacing was disabled\",\n capacity_unknown: \"Capacity was unknown, so work remained admissible\",\n capacity_available: \"Observed capacity was available\",\n work_conserving_borrow: \"Idle capacity was borrowed for standard work\",\n manager_priority: \"Standard work was paced for queued manager demand\",\n standard_starvation_bound: \"The standard-work starvation bound was reached\",\n capacity_saturated: \"Observed dynamic capacity was saturated\",\n emergency_fuse: \"The emergency fuse blocked new work\",\n};\n\nconst FLEET_REJECTION_LABEL: Record<\n Exclude<FleetDecisionItem[\"scores\"][number][\"rejectionReason\"], null>,\n string\n> = {\n allocator_disabled: \"Allocator disabled\",\n unavailable: \"Unavailable\",\n cooling: \"Cooling down\",\n quota_ceiling: \"Quota ceiling reached\",\n overlay_isolation: \"Outside explicit isolation\",\n};\n\nconst FLEET_CONFIDENCE_LABEL: Record<FleetDecisionItem[\"confidence\"], string> = {\n unknown: \"Unknown confidence\",\n low: \"Low confidence\",\n medium: \"Medium confidence\",\n high: \"High confidence\",\n};\n\nexport default function FleetDecisionRow({\n item,\n d: ActivityDisclosure,\n b: BodyNote,\n j,\n s,\n}: {\n item: FleetDecisionItem;\n d: typeof import(\"./shared\").ActivityDisclosure;\n b: typeof import(\"./shared\").BodyNote;\n j: RowJsx;\n s: RowJsxs;\n}) {\n const scoreRowsHidden = item.scoreRowsTruncatedCount > 0;\n const scores =\n item.scores.length > 0\n ? j(\n \"div\",\n {\n className: \"min-w-0\",\n children: [\n j(\n \"h4\",\n {\n className: \"text-og-sm font-medium text-og-fg\",\n children: \"Bounded candidate scores\",\n },\n \"heading\",\n ),\n j(\n \"p\",\n {\n className: \"mt-0.5 text-og-xs leading-5 text-og-fg-subtle\",\n children:\n \"Lower scores rank first. Candidate aliases are temporary and local to this event.\",\n },\n \"description\",\n ),\n j(\n \"ul\",\n {\n className: \"mt-2 flex min-w-0 flex-col gap-1.5\",\n \"aria-label\": \"Candidate scores\",\n children: item.scores.map((score) =>\n s(\n \"li\",\n {\n className:\n \"flex min-w-0 flex-col gap-1 rounded-og-sm bg-og-surface-1 px-2.5 py-2 text-og-sm sm:flex-row sm:items-center sm:gap-3\",\n children: [\n j(\n \"span\",\n {\n className: \"font-og-mono text-og-fg\",\n children: score.candidateKey,\n },\n \"candidate\",\n ),\n j(\n \"span\",\n {\n className: \"min-w-0 text-og-fg-muted sm:flex-1\",\n children: score.eligible\n ? \"Eligible\"\n : score.rejectionReason\n ? FLEET_REJECTION_LABEL[score.rejectionReason]\n : \"Unavailable\",\n },\n \"eligibility\",\n ),\n s(\n \"span\",\n {\n className: \"font-og-mono text-og-fg-subtle\",\n children: [\n \"score \",\n formatFleetScore(score.total),\n \" ·\",\n \" \",\n FLEET_CONFIDENCE_LABEL[score.confidence],\n ],\n },\n \"score\",\n ),\n ],\n },\n score.candidateKey,\n ),\n ),\n },\n \"rows\",\n ),\n ],\n },\n \"score-list\",\n )\n : null;\n const truncated =\n item.truncatedCandidateCount > 0\n ? j(\n BodyNote,\n {\n tone: \"muted\",\n children: [\n item.truncatedCandidateCount,\n \" additional \",\n item.truncatedCandidateCount === 1 ? \"candidate was\" : \"candidates were\",\n \" excluded from this bounded replay record.\",\n ],\n },\n \"truncated\",\n )\n : null;\n const hidden = scoreRowsHidden\n ? j(\n BodyNote,\n {\n tone: \"muted\",\n children: [\n item.scoreRowsTruncatedCount,\n \" additional \",\n item.scoreRowsTruncatedCount === 1 ? \"score row was\" : \"score rows were\",\n \" hidden by this view’s safety limit.\",\n ],\n },\n \"hidden\",\n )\n : null;\n return j(ActivityDisclosure, {\n icon: j(GaugeMark, { className: \"size-3.5\", j, s }),\n iconTone: \"muted\",\n title: \"Fleet policy shadow\",\n preview: FLEET_COMPARISON_LABEL[item.comparison],\n chip: {\n tone: \"muted\",\n text:\n item.comparison === \"match\"\n ? \"matched\"\n : item.comparison === \"not_comparable_truncated\"\n ? \"limited\"\n : \"different\",\n },\n children: s(\"section\", {\n \"aria-label\": \"Fleet policy shadow details\",\n className: \"flex min-w-0 flex-col gap-3\",\n children: [\n j(\n BodyNote,\n {\n tone: \"muted\",\n children:\n \"Shadow observation only — it did not change the subscription serving this turn.\",\n },\n \"observation\",\n ),\n j(\n \"dl\",\n {\n className: \"grid min-w-0 grid-cols-1 gap-x-5 gap-y-3 sm:grid-cols-2\",\n children: [\n j(\n FleetDetail,\n {\n term: \"Production\",\n value: fleetOutcomeLabel(item.actualOutcome, item.actualCandidateKey),\n note: FLEET_ACTUAL_REASON_LABEL[item.actualReason],\n j,\n s,\n },\n \"production\",\n ),\n j(\n FleetDetail,\n {\n term: \"Shadow policy\",\n value: fleetOutcomeLabel(item.shadowOutcome, item.shadowCandidateKey),\n note: FLEET_SHADOW_REASON_LABEL[item.shadowReason],\n j,\n s,\n },\n \"shadow\",\n ),\n j(\n FleetDetail,\n {\n term: \"Comparison\",\n value: FLEET_COMPARISON_LABEL[item.comparison],\n j,\n s,\n },\n \"comparison\",\n ),\n j(\n FleetDetail,\n {\n term: \"Decision confidence\",\n value: FLEET_CONFIDENCE_LABEL[item.confidence],\n j,\n s,\n },\n \"confidence\",\n ),\n j(\n FleetDetail,\n {\n term: \"Admission\",\n value:\n item.admissionOutcome === \"admit\"\n ? \"Would admit new work\"\n : \"Would pace new work\",\n note: FLEET_ADMISSION_REASON_LABEL[item.admissionReason],\n j,\n s,\n },\n \"admission\",\n ),\n j(\n FleetDetail,\n {\n term: \"Observed candidates\",\n value: `${item.candidateCount} in the bounded replay`,\n j,\n s,\n },\n \"candidate-count\",\n ),\n j(\n FleetDetail,\n {\n term: \"Idle-capacity borrowing\",\n value: item.borrowedIdleCapacity ? \"Borrowed for standard work\" : \"Not borrowed\",\n j,\n s,\n },\n \"idle-capacity\",\n ),\n j(\n FleetDetail,\n {\n term: \"Named-policy borrowing\",\n value: item.borrowedOverlayCapacity\n ? \"Borrowed outside the preferred group\"\n : \"Not borrowed\",\n j,\n s,\n },\n \"named-policy\",\n ),\n j(\n FleetDetail,\n {\n term: \"Stranded capacity\",\n value:\n item.strandedEligibleCount === 0\n ? \"None\"\n : `${item.strandedEligibleCount} eligible ${item.strandedEligibleCount === 1 ? \"candidate\" : \"candidates\"}`,\n note:\n item.strandedEligibleCount > 0\n ? \"Capacity excluded by explicit isolation; existing fenced turns are unchanged.\"\n : undefined,\n j,\n s,\n },\n \"stranded-capacity\",\n ),\n ],\n },\n \"details\",\n ),\n scores,\n truncated,\n hidden,\n ],\n }),\n });\n}\n\nfunction FleetDetail({\n term,\n value,\n note,\n j,\n s,\n}: {\n term: string;\n value: string;\n note?: string | undefined;\n j: RowJsx;\n s: RowJsxs;\n}) {\n return j(\"div\", {\n className: \"min-w-0\",\n children: [\n j(\n \"dt\",\n {\n className: \"text-og-xs font-medium uppercase tracking-wide text-og-fg-subtle\",\n children: term,\n },\n \"term\",\n ),\n s(\n \"dd\",\n {\n className: \"mt-0.5 break-words text-og-sm text-og-fg-muted\",\n children: [\n j(\"span\", { className: \"text-og-fg\", children: value }, \"value\"),\n note\n ? j(\"span\", { className: \"mt-0.5 block leading-5\", children: note }, \"note\")\n : null,\n ],\n },\n \"description\",\n ),\n ],\n });\n}\n\nfunction fleetOutcomeLabel(\n outcome: FleetDecisionItem[\"actualOutcome\"] | FleetDecisionItem[\"shadowOutcome\"],\n candidateKey: string | null,\n): string {\n if (outcome === \"selected\" && candidateKey) return `Selected ${candidateKey}`;\n if (outcome === \"waiting\") return \"Waiting for capacity\";\n if (outcome === \"paced\") return \"Paced before placement\";\n return \"No candidate selected\";\n}\n\nfunction formatFleetScore(value: number): string {\n return new Intl.NumberFormat(\"en-US\", { maximumFractionDigits: 2 }).format(value);\n}\n"],"mappings":"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","names":[]}
@@ -47,6 +47,12 @@ export type UseFileAttachmentsResult = {
47
47
  }) => void;
48
48
  /** Restore already-ready server assets without recreating browser-local bytes. */
49
49
  restoreReadyFiles: (files: Iterable<FileAsset>) => void;
50
+ /**
51
+ * Resolve a ready image's short-lived server preview URL on demand. Optional
52
+ * for upload-only embedded clients; local object-URL previews remain usable
53
+ * without it.
54
+ */
55
+ loadPreview?: ((id: string, signal?: AbortSignal) => Promise<string | undefined>) | undefined;
50
56
  /**
51
57
  * Re-run the upload for a `failed` attachment, in place (same id, same
52
58
  * source file). No-op for an id that isn't a known failed upload.
@@ -1,4 +1,4 @@
1
- import type { FsReadResponse, FsWriteResponse, OpenGeniRequestOptions, SessionCapabilities, SessionEvent, WorkspaceCaptureManifest } from "@opengeni/sdk";
1
+ import type { FileSystemRouteIdentity, FsReadResponse, FsWriteResponse, OpenGeniRequestOptions, SessionCapabilities, SessionEvent, WorkspaceCaptureManifest } from "@opengeni/sdk";
2
2
  import { type ClientOverride } from "../provider.js";
3
3
  /** The git-status overlay a file row may carry (tints modified files in the tree). */
4
4
  export type FileTreeStatus = "added" | "modified" | "deleted" | "renamed" | "untracked";
@@ -47,6 +47,9 @@ export type UseSandboxFilesOptions = ClientOverride & {
47
47
  events?: SessionEvent[] | undefined;
48
48
  /** Initial path to list (workspace root by default). */
49
49
  rootPath?: string | undefined;
50
+ /** Exact capability identity for the selected filesystem route. A route/root
51
+ * change resets this hook and makes stale provider requests fail retryably. */
52
+ route?: FileSystemRouteIdentity | undefined;
50
53
  /** Hold off the initial list (e.g. panel collapsed). Default true. */
51
54
  enabled?: boolean | undefined;
52
55
  /** Pause live reads/invalidation while preserving the last rendered result. */
@@ -1,3 +1,4 @@
1
+ import type { FileSystemRouteIdentity } from "@opengeni/sdk";
1
2
  import { type ClientOverride } from "../provider.js";
2
3
  /**
3
4
  * The wake-on-edit state machine. This hook owns the logic and the UI renders
@@ -27,6 +28,9 @@ export type UseWorkspaceEditOptions = ClientOverride & {
27
28
  path?: string | null | undefined;
28
29
  /** The capture-served content loaded into the editor — the flush base (C2). */
29
30
  baseContent?: string | null | undefined;
31
+ /** Exact capability identity for the selected filesystem route. A route/root
32
+ * change discards the buffered edit and makes stale flushes fail retryably. */
33
+ route?: FileSystemRouteIdentity | undefined;
30
34
  /** `capabilities.liveness` — "warm" | "draining" | "cold". Drives the flush. */
31
35
  liveness?: string | undefined;
32
36
  /** True while the host is actively warming the box (attach in flight, not warm
package/dist/index.d.ts CHANGED
@@ -112,6 +112,8 @@ export type { ConfirmState, SlashCommandContext, SlashCommandHandlers, UseSlashC
112
112
  export { CommandPalette } from "./components/command-palette.js";
113
113
  export type { CommandPaletteProps } from "./components/command-palette.js";
114
114
  export { ChatComposer } from "./components/chat-composer.js";
115
+ export { SessionConversation } from "./components/session-conversation.js";
116
+ export type { SessionConversationProps } from "./components/session-conversation.js";
115
117
  export type { ChatComposerProps } from "./components/chat-composer.js";
116
118
  export { ComposerTranscriptionControl } from "./components/composer-transcription-control.js";
117
119
  export type { ComposerTranscriptionControlProps, ComposerTranscriptionMessages, } from "./components/composer-transcription-control.js";
@@ -167,4 +169,5 @@ export type { SuperGrokAccountsClientLike, UseSuperGrokAccountsOptions, UseSuper
167
169
  export { gitFileDiffToPatch } from "./lib/git-patch.js";
168
170
  export { xtermThemeFromTokens } from "./lib/xterm-theme.js";
169
171
  export { cn } from "./lib/cn.js";
170
- export { CREDIT_EXHAUSTION_MESSAGE, formatBytes, formatClockTime, formatRelativeTime, humanizeFailureReason, isCreditExhaustion, stringifyPayload, truncate, tryParseJson, } from "./lib/format.js";
172
+ export { CREDIT_EXHAUSTION_MESSAGE, formatBytes, formatClockTime, formatRelativeTime, humanizeFailureReason, presentFailure, isCreditExhaustion, stringifyPayload, truncate, tryParseJson, } from "./lib/format.js";
173
+ export { SessionCommandsPanel } from "./components/session-commands-panel.js";