@opengeni/react 3.3.2 → 3.7.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.
Files changed (79) hide show
  1. package/dist/artifacts.d.ts +1 -1
  2. package/dist/artifacts.js +241 -18
  3. package/dist/artifacts.js.map +1 -1
  4. package/dist/{browser-viewer-MKKFRRRV.js → browser-viewer-E5DDEFQ4.js} +3 -3
  5. package/dist/{chunk-2DZVYHVO.js → chunk-4JFUT22W.js} +39 -13
  6. package/dist/chunk-4JFUT22W.js.map +1 -0
  7. package/dist/{chunk-ELIYWBZR.js → chunk-BV5A4OTE.js} +4 -4
  8. package/dist/{chunk-3AGBGTRT.js → chunk-C6WDLHBA.js} +148 -26
  9. package/dist/chunk-C6WDLHBA.js.map +1 -0
  10. package/dist/{chunk-YG4QEQF5.js → chunk-DOK4KZF2.js} +7863 -7736
  11. package/dist/chunk-DOK4KZF2.js.map +1 -0
  12. package/dist/{chunk-JAQ5K7W6.js → chunk-FJBOU2TH.js} +167 -58
  13. package/dist/chunk-FJBOU2TH.js.map +1 -0
  14. package/dist/{chunk-XYRDDSXF.js → chunk-R55HFTT3.js} +80 -34
  15. package/dist/chunk-R55HFTT3.js.map +1 -0
  16. package/dist/{chunk-ZPBTI3TE.js → chunk-W2RGYBCV.js} +4 -4
  17. package/dist/{chunk-WSK7G5LE.js → chunk-W3OUAH6M.js} +80 -80
  18. package/dist/chunk-W3OUAH6M.js.map +1 -0
  19. package/dist/{chunk-X4A66EWZ.js → chunk-WMGF4Z7X.js} +41 -43
  20. package/dist/chunk-WMGF4Z7X.js.map +1 -0
  21. package/dist/client.d.ts +1 -1
  22. package/dist/components/artifacts/index.d.ts +1 -1
  23. package/dist/components/artifacts/published-html-artifact-frame.d.ts +45 -3
  24. package/dist/components/composer.d.ts +2 -0
  25. package/dist/components/session-chrome.d.ts +1 -1
  26. package/dist/composer.js +4 -4
  27. package/dist/{computer-viewer-FWEZISW4.js → computer-viewer-7TEZC6Y2.js} +3 -3
  28. package/dist/{fleet-decision-row-GGCAT4E4.js → fleet-decision-row-YZ3ZKWMM.js} +2 -1
  29. package/dist/fleet-decision-row-YZ3ZKWMM.js.map +1 -0
  30. package/dist/hooks/use-file-attachments.d.ts +8 -0
  31. package/dist/hooks/use-sandbox-files.d.ts +4 -1
  32. package/dist/hooks/use-session-events.d.ts +1 -1
  33. package/dist/hooks/use-workspace-edit.d.ts +4 -0
  34. package/dist/index.js +195 -141
  35. package/dist/index.js.map +1 -1
  36. package/dist/interaction.js +3 -3
  37. package/dist/model-policy.d.ts +2 -1
  38. package/dist/model-policy.js +1 -1
  39. package/dist/{queue-surface-implementation-BSKUWHRI.js → queue-surface-implementation-XL2A6PBM.js} +2 -2
  40. package/dist/realtime.js +2 -2
  41. package/dist/session-ui.js +6 -6
  42. package/dist/session.js +4 -4
  43. package/dist/timeline/registry.d.ts +2 -0
  44. package/dist/timeline/types.d.ts +3 -1
  45. package/package.json +2 -2
  46. package/src/artifacts.ts +3 -0
  47. package/src/client.ts +2 -1
  48. package/src/components/artifacts/index.ts +3 -0
  49. package/src/components/artifacts/published-html-artifact-frame.tsx +284 -4
  50. package/src/components/composer.tsx +103 -29
  51. package/src/components/message-timeline.tsx +48 -10
  52. package/src/components/model-policy-picker.tsx +37 -10
  53. package/src/components/sandbox-workspace.tsx +18 -7
  54. package/src/components/session-chrome.tsx +3 -3
  55. package/src/hooks/use-file-attachments.ts +62 -2
  56. package/src/hooks/use-sandbox-files.ts +68 -20
  57. package/src/hooks/use-session-events.ts +176 -21
  58. package/src/hooks/use-workspace-edit.ts +23 -5
  59. package/src/model-policy.ts +48 -53
  60. package/src/timeline/fleet-decision-projection.ts +2 -1
  61. package/src/timeline/fleet-decision-row.tsx +1 -0
  62. package/src/timeline/projection.ts +157 -8
  63. package/src/timeline/registry.ts +15 -3
  64. package/src/timeline/tool-renderers.tsx +117 -1
  65. package/src/timeline/types.ts +10 -1
  66. package/styles/compiled.css +5 -0
  67. package/dist/chunk-2DZVYHVO.js.map +0 -1
  68. package/dist/chunk-3AGBGTRT.js.map +0 -1
  69. package/dist/chunk-JAQ5K7W6.js.map +0 -1
  70. package/dist/chunk-WSK7G5LE.js.map +0 -1
  71. package/dist/chunk-X4A66EWZ.js.map +0 -1
  72. package/dist/chunk-XYRDDSXF.js.map +0 -1
  73. package/dist/chunk-YG4QEQF5.js.map +0 -1
  74. package/dist/fleet-decision-row-GGCAT4E4.js.map +0 -1
  75. /package/dist/{browser-viewer-MKKFRRRV.js.map → browser-viewer-E5DDEFQ4.js.map} +0 -0
  76. /package/dist/{chunk-ELIYWBZR.js.map → chunk-BV5A4OTE.js.map} +0 -0
  77. /package/dist/{chunk-ZPBTI3TE.js.map → chunk-W2RGYBCV.js.map} +0 -0
  78. /package/dist/{computer-viewer-FWEZISW4.js.map → computer-viewer-7TEZC6Y2.js.map} +0 -0
  79. /package/dist/{queue-surface-implementation-BSKUWHRI.js.map → queue-surface-implementation-XL2A6PBM.js.map} +0 -0
@@ -15,15 +15,15 @@ import {
15
15
  encodeStreamOpen,
16
16
  interactionHostPlatform
17
17
  } from "./chunk-5YK2ZDIG.js";
18
+ import {
19
+ copyTextToClipboard
20
+ } from "./chunk-JVYQRRC4.js";
18
21
  import {
19
22
  usePageLiveActivity
20
23
  } from "./chunk-KZ73RL76.js";
21
24
  import {
22
25
  useEmbeddedBrowserInteraction
23
26
  } from "./chunk-NEXLLTP4.js";
24
- import {
25
- copyTextToClipboard
26
- } from "./chunk-JVYQRRC4.js";
27
27
  import {
28
28
  formatBytes
29
29
  } from "./chunk-VTOREEXF.js";
@@ -3904,4 +3904,4 @@ export {
3904
3904
  useSiteAuthConnections,
3905
3905
  BrowserViewer
3906
3906
  };
3907
- //# sourceMappingURL=chunk-ZPBTI3TE.js.map
3907
+ //# sourceMappingURL=chunk-W2RGYBCV.js.map
@@ -2,6 +2,69 @@ import {
2
2
  cn
3
3
  } from "./chunk-22KP6LR5.js";
4
4
 
5
+ // src/components/timeline-annotations.tsx
6
+ import { Suspense, lazy, useRef, useState } from "react";
7
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
8
+ var TimelineAnnotationsDialog = lazy(() => import("./timeline-annotations-dialog-U7EVLR75.js"));
9
+ function TimelineAnnotationsChip({
10
+ annotations,
11
+ editable = false,
12
+ focusAnnotationId,
13
+ onFocusConsumed,
14
+ onUpdate,
15
+ onRemove,
16
+ onRevealSource,
17
+ className
18
+ }) {
19
+ const [open, setOpen] = useState(false);
20
+ const triggerRef = useRef(null);
21
+ if (annotations.length === 0) return null;
22
+ const focusRequested = Boolean(
23
+ focusAnnotationId && annotations.some((item) => item.id === focusAnnotationId)
24
+ );
25
+ const visible = open || focusRequested;
26
+ const countLabel = `${annotations.length} ${annotations.length === 1 ? "annotation" : "annotations"}`;
27
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
28
+ /* @__PURE__ */ jsx(
29
+ "button",
30
+ {
31
+ ref: triggerRef,
32
+ type: "button",
33
+ className: cn(
34
+ "inline-flex min-h-8 items-center gap-1.5 rounded-full border border-og-border bg-og-surface-1 px-2.5 py-1 text-og-sm font-medium text-og-fg-muted outline-hidden transition hover:bg-og-surface-2 hover:text-og-fg focus-visible:ring-2 focus-visible:ring-og-accent pointer-coarse:min-h-[44px]",
35
+ className
36
+ ),
37
+ "aria-label": `Review ${countLabel}`,
38
+ "aria-haspopup": "dialog",
39
+ "aria-expanded": visible,
40
+ onClick: () => setOpen((current) => !current),
41
+ children: countLabel
42
+ }
43
+ ),
44
+ visible ? /* @__PURE__ */ jsx(Suspense, { fallback: null, children: /* @__PURE__ */ jsx(
45
+ TimelineAnnotationsDialog,
46
+ {
47
+ annotations,
48
+ editable,
49
+ focusAnnotationId,
50
+ onFocusConsumed: () => {
51
+ setOpen(true);
52
+ onFocusConsumed?.();
53
+ },
54
+ onUpdate,
55
+ onRemove,
56
+ onRevealSource,
57
+ triggerRef,
58
+ countLabel,
59
+ onDismiss: (restoreFocus) => {
60
+ setOpen(false);
61
+ if (restoreFocus) triggerRef.current?.focus();
62
+ }
63
+ }
64
+ ) }) : null
65
+ ] });
66
+ }
67
+
5
68
  // src/components/queue-draft-policy.ts
6
69
  function requestQueueDraftEdit(composer, confirmReplacement, editImmediately) {
7
70
  if (composer.hasDraftContent()) {
@@ -13,17 +76,17 @@ function requestQueueDraftEdit(composer, confirmReplacement, editImmediately) {
13
76
 
14
77
  // src/components/queue-surface-state.tsx
15
78
  import { Loader2Icon, RotateCwIcon } from "lucide-react";
16
- import { jsx, jsxs } from "react/jsx-runtime";
79
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
17
80
  function EmptyQueueStateSurface({ queue }) {
18
81
  const hasError = Boolean(queue.error || queue.mutationError);
19
- return /* @__PURE__ */ jsx(
82
+ return /* @__PURE__ */ jsx2(
20
83
  "div",
21
84
  {
22
85
  className: "og-root mx-auto mb-2 w-full max-w-3xl shrink-0 px-4 sm:px-6",
23
86
  "data-testid": "queue-surface",
24
- children: /* @__PURE__ */ jsxs("div", { className: "overflow-hidden rounded-lg border border-border bg-surface/80 shadow-sm", children: [
25
- queue.stoppingPreviousAttempt ? /* @__PURE__ */ jsx(QueueStoppingStatus, { queue, dividerAfter: hasError }) : null,
26
- hasError ? /* @__PURE__ */ jsx(QueueErrorAlert, { queue }) : null
87
+ children: /* @__PURE__ */ jsxs2("div", { className: "overflow-hidden rounded-lg border border-border bg-surface/80 shadow-sm", children: [
88
+ queue.stoppingPreviousAttempt ? /* @__PURE__ */ jsx2(QueueStoppingStatus, { queue, dividerAfter: hasError }) : null,
89
+ hasError ? /* @__PURE__ */ jsx2(QueueErrorAlert, { queue }) : null
27
90
  ] })
28
91
  }
29
92
  );
@@ -32,7 +95,7 @@ function QueueStoppingStatus({
32
95
  queue,
33
96
  dividerAfter = false
34
97
  }) {
35
- return /* @__PURE__ */ jsxs(
98
+ return /* @__PURE__ */ jsxs2(
36
99
  "div",
37
100
  {
38
101
  role: "status",
@@ -40,17 +103,17 @@ function QueueStoppingStatus({
40
103
  className: `flex min-h-11 items-center gap-2.5 bg-status-waiting/[0.07] px-3 py-2 text-og-control text-fg ${dividerAfter ? "border-b border-status-waiting/20" : ""}`,
41
104
  "data-testid": "stopping-previous-attempt",
42
105
  children: [
43
- /* @__PURE__ */ jsx(
106
+ /* @__PURE__ */ jsx2(
44
107
  Loader2Icon,
45
108
  {
46
109
  "aria-hidden": "true",
47
110
  className: "size-3.5 shrink-0 animate-spin text-status-waiting motion-reduce:animate-none"
48
111
  }
49
112
  ),
50
- /* @__PURE__ */ jsxs("span", { className: "min-w-0", children: [
51
- /* @__PURE__ */ jsx("span", { className: "font-medium", children: queue.effectiveControl?.state === "paused" ? "Stopping current attempt\u2026" : "Stopping previous attempt\u2026" }),
113
+ /* @__PURE__ */ jsxs2("span", { className: "min-w-0", children: [
114
+ /* @__PURE__ */ jsx2("span", { className: "font-medium", children: queue.effectiveControl?.state === "paused" ? "Stopping current attempt\u2026" : "Stopping previous attempt\u2026" }),
52
115
  " ",
53
- /* @__PURE__ */ jsx("span", { className: "text-fg-muted", children: queue.effectiveControl?.state === "paused" ? "Queued work stays saved until you resume." : "Queued work is saved and starts automatically." })
116
+ /* @__PURE__ */ jsx2("span", { className: "text-fg-muted", children: queue.effectiveControl?.state === "paused" ? "Queued work stays saved until you resume." : "Queued work is saved and starts automatically." })
54
117
  ] })
55
118
  ]
56
119
  }
@@ -60,13 +123,13 @@ function QueueErrorAlert({
60
123
  queue,
61
124
  dividerBefore = false
62
125
  }) {
63
- return /* @__PURE__ */ jsx("div", { className: `${dividerBefore ? "border-t border-border" : ""} p-2`, children: /* @__PURE__ */ jsxs(
126
+ return /* @__PURE__ */ jsx2("div", { className: `${dividerBefore ? "border-t border-border" : ""} p-2`, children: /* @__PURE__ */ jsxs2(
64
127
  "div",
65
128
  {
66
129
  role: "alert",
67
130
  className: "flex min-w-0 max-w-full flex-wrap items-start gap-2 rounded-md bg-status-failed/10 px-2 py-1.5 text-og-control text-status-failed",
68
131
  children: [
69
- /* @__PURE__ */ jsx(
132
+ /* @__PURE__ */ jsx2(
70
133
  "span",
71
134
  {
72
135
  role: "region",
@@ -78,7 +141,7 @@ function QueueErrorAlert({
78
141
  children: (queue.mutationError ?? queue.error)?.message
79
142
  }
80
143
  ),
81
- /* @__PURE__ */ jsx(
144
+ /* @__PURE__ */ jsx2(
82
145
  "button",
83
146
  {
84
147
  type: "button",
@@ -89,7 +152,7 @@ function QueueErrorAlert({
89
152
  "aria-label": "Dismiss queue error and retry",
90
153
  title: "Retry loading the queue",
91
154
  className: "ms-auto inline-flex size-7 shrink-0 items-center justify-center self-start rounded-md outline-hidden transition-colors hover:bg-surface-3 focus-visible:ring-2 focus-visible:ring-ring/40 motion-reduce:transition-none pointer-coarse:size-[44px]",
92
- children: /* @__PURE__ */ jsx(RotateCwIcon, { className: "size-3.5" })
155
+ children: /* @__PURE__ */ jsx2(RotateCwIcon, { className: "size-3.5" })
93
156
  }
94
157
  )
95
158
  ]
@@ -97,74 +160,11 @@ function QueueErrorAlert({
97
160
  ) });
98
161
  }
99
162
 
100
- // src/components/timeline-annotations.tsx
101
- import { Suspense, lazy, useRef, useState } from "react";
102
- import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
103
- var TimelineAnnotationsDialog = lazy(() => import("./timeline-annotations-dialog-U7EVLR75.js"));
104
- function TimelineAnnotationsChip({
105
- annotations,
106
- editable = false,
107
- focusAnnotationId,
108
- onFocusConsumed,
109
- onUpdate,
110
- onRemove,
111
- onRevealSource,
112
- className
113
- }) {
114
- const [open, setOpen] = useState(false);
115
- const triggerRef = useRef(null);
116
- if (annotations.length === 0) return null;
117
- const focusRequested = Boolean(
118
- focusAnnotationId && annotations.some((item) => item.id === focusAnnotationId)
119
- );
120
- const visible = open || focusRequested;
121
- const countLabel = `${annotations.length} ${annotations.length === 1 ? "annotation" : "annotations"}`;
122
- return /* @__PURE__ */ jsxs2(Fragment, { children: [
123
- /* @__PURE__ */ jsx2(
124
- "button",
125
- {
126
- ref: triggerRef,
127
- type: "button",
128
- className: cn(
129
- "inline-flex min-h-8 items-center gap-1.5 rounded-full border border-og-border bg-og-surface-1 px-2.5 py-1 text-og-sm font-medium text-og-fg-muted outline-hidden transition hover:bg-og-surface-2 hover:text-og-fg focus-visible:ring-2 focus-visible:ring-og-accent pointer-coarse:min-h-[44px]",
130
- className
131
- ),
132
- "aria-label": `Review ${countLabel}`,
133
- "aria-haspopup": "dialog",
134
- "aria-expanded": visible,
135
- onClick: () => setOpen((current) => !current),
136
- children: countLabel
137
- }
138
- ),
139
- visible ? /* @__PURE__ */ jsx2(Suspense, { fallback: null, children: /* @__PURE__ */ jsx2(
140
- TimelineAnnotationsDialog,
141
- {
142
- annotations,
143
- editable,
144
- focusAnnotationId,
145
- onFocusConsumed: () => {
146
- setOpen(true);
147
- onFocusConsumed?.();
148
- },
149
- onUpdate,
150
- onRemove,
151
- onRevealSource,
152
- triggerRef,
153
- countLabel,
154
- onDismiss: (restoreFocus) => {
155
- setOpen(false);
156
- if (restoreFocus) triggerRef.current?.focus();
157
- }
158
- }
159
- ) }) : null
160
- ] });
161
- }
162
-
163
163
  export {
164
+ TimelineAnnotationsChip,
164
165
  requestQueueDraftEdit,
165
166
  EmptyQueueStateSurface,
166
167
  QueueStoppingStatus,
167
- QueueErrorAlert,
168
- TimelineAnnotationsChip
168
+ QueueErrorAlert
169
169
  };
170
- //# sourceMappingURL=chunk-WSK7G5LE.js.map
170
+ //# sourceMappingURL=chunk-W3OUAH6M.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/timeline-annotations.tsx","../src/components/queue-draft-policy.ts","../src/components/queue-surface-state.tsx"],"sourcesContent":["import type {\n DraftTimelineAnnotation,\n TimelineAnnotation,\n TimelineAnnotationSource,\n} from \"@opengeni/sdk\";\nimport { Suspense, lazy, useRef, useState } from \"react\";\nimport { cn } from \"../lib/cn\";\n\nexport type TimelineAnnotationLike = DraftTimelineAnnotation | TimelineAnnotation;\n\nconst TimelineAnnotationsDialog = lazy(() => import(\"./timeline-annotations-dialog\"));\n\nexport function TimelineAnnotationsChip({\n annotations,\n editable = false,\n focusAnnotationId,\n onFocusConsumed,\n onUpdate,\n onRemove,\n onRevealSource,\n className,\n}: {\n annotations: readonly TimelineAnnotationLike[];\n editable?: boolean | undefined;\n focusAnnotationId?: string | null | undefined;\n onFocusConsumed?: (() => void) | undefined;\n onUpdate?: ((id: string, note: string) => void) | undefined;\n onRemove?: ((id: string) => void) | undefined;\n onRevealSource?: ((source: TimelineAnnotationSource) => boolean) | undefined;\n className?: string | undefined;\n}) {\n const [open, setOpen] = useState(false);\n const triggerRef = useRef<HTMLButtonElement | null>(null);\n\n if (annotations.length === 0) return null;\n const focusRequested = Boolean(\n focusAnnotationId && annotations.some((item) => item.id === focusAnnotationId),\n );\n const visible = open || focusRequested;\n const countLabel = `${annotations.length} ${annotations.length === 1 ? \"annotation\" : \"annotations\"}`;\n\n return (\n <>\n <button\n ref={triggerRef}\n type=\"button\"\n className={cn(\n \"inline-flex min-h-8 items-center gap-1.5 rounded-full border border-og-border bg-og-surface-1 px-2.5 py-1 text-og-sm font-medium text-og-fg-muted outline-hidden transition hover:bg-og-surface-2 hover:text-og-fg focus-visible:ring-2 focus-visible:ring-og-accent pointer-coarse:min-h-[44px]\",\n className,\n )}\n aria-label={`Review ${countLabel}`}\n aria-haspopup=\"dialog\"\n aria-expanded={visible}\n onClick={() => setOpen((current) => !current)}\n >\n {countLabel}\n </button>\n {visible ? (\n <Suspense fallback={null}>\n <TimelineAnnotationsDialog\n annotations={annotations}\n editable={editable}\n focusAnnotationId={focusAnnotationId}\n onFocusConsumed={() => {\n setOpen(true);\n onFocusConsumed?.();\n }}\n onUpdate={onUpdate}\n onRemove={onRemove}\n onRevealSource={onRevealSource}\n triggerRef={triggerRef}\n countLabel={countLabel}\n onDismiss={(restoreFocus) => {\n setOpen(false);\n if (restoreFocus) triggerRef.current?.focus();\n }}\n />\n </Suspense>\n ) : null}\n </>\n );\n}\n\nexport default TimelineAnnotationsChip;\n","import type { ComposerState } from \"../hooks/use-composer\";\n\n/**\n * Decide whether checking out a queued prompt would replace current composer\n * content. `hasDraftContent` reads the synchronous draft refs, so this stays\n * correct even when a controlled input update has not rendered yet.\n */\nexport function requestQueueDraftEdit(\n composer: Pick<ComposerState, \"hasDraftContent\">,\n confirmReplacement: () => void,\n editImmediately: () => void,\n): void {\n if (composer.hasDraftContent()) {\n confirmReplacement();\n } else {\n editImmediately();\n }\n}\n","import { Loader2Icon, RotateCwIcon } from \"lucide-react\";\n\nimport type { UseTurnQueueResult } from \"../hooks/use-turn-queue\";\n\ntype QueueStateProps = {\n queue: UseTurnQueueResult;\n};\n\nexport function EmptyQueueStateSurface({ queue }: QueueStateProps) {\n const hasError = Boolean(queue.error || queue.mutationError);\n return (\n <div\n className=\"og-root mx-auto mb-2 w-full max-w-3xl shrink-0 px-4 sm:px-6\"\n data-testid=\"queue-surface\"\n >\n <div className=\"overflow-hidden rounded-lg border border-border bg-surface/80 shadow-sm\">\n {queue.stoppingPreviousAttempt ? (\n <QueueStoppingStatus queue={queue} dividerAfter={hasError} />\n ) : null}\n {hasError ? <QueueErrorAlert queue={queue} /> : null}\n </div>\n </div>\n );\n}\n\nexport function QueueStoppingStatus({\n queue,\n dividerAfter = false,\n}: QueueStateProps & { dividerAfter?: boolean }) {\n return (\n <div\n role=\"status\"\n aria-live=\"polite\"\n className={`flex min-h-11 items-center gap-2.5 bg-status-waiting/[0.07] px-3 py-2 text-og-control text-fg ${\n dividerAfter ? \"border-b border-status-waiting/20\" : \"\"\n }`}\n data-testid=\"stopping-previous-attempt\"\n >\n <Loader2Icon\n aria-hidden=\"true\"\n className=\"size-3.5 shrink-0 animate-spin text-status-waiting motion-reduce:animate-none\"\n />\n <span className=\"min-w-0\">\n <span className=\"font-medium\">\n {queue.effectiveControl?.state === \"paused\"\n ? \"Stopping current attempt…\"\n : \"Stopping previous attempt…\"}\n </span>{\" \"}\n <span className=\"text-fg-muted\">\n {queue.effectiveControl?.state === \"paused\"\n ? \"Queued work stays saved until you resume.\"\n : \"Queued work is saved and starts automatically.\"}\n </span>\n </span>\n </div>\n );\n}\n\nexport function QueueErrorAlert({\n queue,\n dividerBefore = false,\n}: QueueStateProps & { dividerBefore?: boolean }) {\n return (\n <div className={`${dividerBefore ? \"border-t border-border\" : \"\"} p-2`}>\n <div\n role=\"alert\"\n className=\"flex min-w-0 max-w-full flex-wrap items-start gap-2 rounded-md bg-status-failed/10 px-2 py-1.5 text-og-control text-status-failed\"\n >\n <span\n role=\"region\"\n aria-label=\"Queue error details\"\n tabIndex={0}\n className=\"max-h-[min(5rem,20dvh)] min-w-0 max-w-full flex-[1_1_5rem] overflow-auto overscroll-contain whitespace-pre-wrap rounded-sm outline-hidden [overflow-wrap:anywhere] [unicode-bidi:plaintext] focus-visible:ring-2 focus-visible:ring-ring/40\"\n data-testid=\"queue-error-message\"\n dir=\"auto\"\n >\n {(queue.mutationError ?? queue.error)?.message}\n </span>\n <button\n type=\"button\"\n onClick={() => {\n queue.clearMutationError();\n void queue.refresh();\n }}\n aria-label=\"Dismiss queue error and retry\"\n title=\"Retry loading the queue\"\n className=\"ms-auto inline-flex size-7 shrink-0 items-center justify-center self-start rounded-md outline-hidden transition-colors hover:bg-surface-3 focus-visible:ring-2 focus-visible:ring-ring/40 motion-reduce:transition-none pointer-coarse:size-[44px]\"\n >\n <RotateCwIcon className=\"size-3.5\" />\n </button>\n </div>\n </div>\n );\n}\n"],"mappings":"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","names":["jsx","jsxs"]}
@@ -1,17 +1,15 @@
1
1
  // src/model-policy.ts
2
- var BILLING_CLASS_ORDER = [
3
- "opengeni_credits",
4
- "external",
5
- "codex_subscription",
6
- "supergrok_subscription",
7
- "byok"
8
- ];
2
+ import {
3
+ compareModelPickerOrder,
4
+ modelPickerBillingClassFor
5
+ } from "@opengeni/sdk/model-picker-order";
9
6
  var BILLING_CLASS_LABELS = {
10
7
  opengeni_credits: "OpenGeni",
11
8
  external: "External",
12
9
  codex_subscription: "Codex",
13
10
  supergrok_subscription: "SuperGrok",
14
- byok: "Your Gateway"
11
+ byok: "Workspace providers",
12
+ organization_byok: "Organization providers"
15
13
  };
16
14
  var AVAILABILITY_REASON_LABELS = {
17
15
  missing_credential: "Credentials required",
@@ -23,31 +21,13 @@ var AVAILABILITY_REASON_LABELS = {
23
21
  unsupported: "Unsupported"
24
22
  };
25
23
  function billingClassForModel(model) {
26
- if (model.billing?.metering === "external" && model.billing.upstreamPayer === "deployment") {
27
- return "external";
24
+ if (model.provider === "organization-gateway" || model.provider === "organization-openrouter") {
25
+ return "organization_byok";
28
26
  }
29
- if (model.source === "supergrok") {
30
- return "supergrok_subscription";
31
- }
32
- if (model.source === "codex") {
33
- return "codex_subscription";
34
- }
35
- if (model.source === "workspace_gateway") {
36
- return "byok";
37
- }
38
- if (model.credentialSource?.kind === "connected_subscription") {
39
- return model.credentialSource.provider === "xai" ? "supergrok_subscription" : "codex_subscription";
40
- }
41
- if (model.credentialSource?.kind === "workspace_connection") {
27
+ if (model.provider === "workspace-gateway" || model.provider === "workspace-openrouter") {
42
28
  return "byok";
43
29
  }
44
- if (model.billing?.upstreamPayer === "connected_subscription") {
45
- return "codex_subscription";
46
- }
47
- if (model.billing?.upstreamPayer === "workspace") {
48
- return "byok";
49
- }
50
- return "opengeni_credits";
30
+ return modelPickerBillingClassFor(model);
51
31
  }
52
32
  function billingClassLabel(billingClass) {
53
33
  return BILLING_CLASS_LABELS[billingClass];
@@ -101,6 +81,18 @@ function labelReasoningEffort(effort) {
101
81
  return effort.slice(0, 1).toUpperCase() + effort.slice(1);
102
82
  }
103
83
  function payerSummaryForModel(model) {
84
+ if (model.cost === "free") {
85
+ return "Free in this deployment";
86
+ }
87
+ if (model.cost === "credits") {
88
+ return "OpenGeni credits";
89
+ }
90
+ if (model.cost === "subscription") {
91
+ return model.source === "supergrok" ? "SuperGrok subscription \xB7 external billing" : "Codex subscription \xB7 external billing";
92
+ }
93
+ if (model.cost === "workspace") {
94
+ return workspaceProviderPayerSummary(model);
95
+ }
104
96
  const billing = model.billing;
105
97
  if (!billing) {
106
98
  return "Route unknown";
@@ -112,7 +104,7 @@ function payerSummaryForModel(model) {
112
104
  return model.source === "supergrok" ? "SuperGrok subscription \xB7 external billing" : "Codex subscription \xB7 external billing";
113
105
  }
114
106
  if (billing.upstreamPayer === "workspace") {
115
- return "Billed to your AI Gateway";
107
+ return workspaceProviderPayerSummary(model);
116
108
  }
117
109
  return "External provider \xB7 no OpenGeni credits";
118
110
  }
@@ -125,13 +117,28 @@ function advancedSourceSummary(model) {
125
117
  return source.provider === "xai" ? "Connected SuperGrok subscription" : "Connected Codex subscription";
126
118
  }
127
119
  if (source.kind === "workspace_connection") {
128
- return "Workspace AI Gateway";
120
+ if (model.provider === "workspace-openrouter") {
121
+ return "Workspace OpenRouter connection";
122
+ }
123
+ if (model.provider === "workspace-gateway" || model.source === "workspace_gateway") {
124
+ return "Workspace Vercel AI Gateway";
125
+ }
126
+ return "Workspace provider connection";
129
127
  }
130
128
  if (source.kind === "deployment") {
131
129
  return source.mechanism === "azure_ad_bearer" ? "Deployment Azure identity" : "Deployment API key";
132
130
  }
133
131
  return null;
134
132
  }
133
+ function workspaceProviderPayerSummary(model) {
134
+ if (model.provider === "workspace-openrouter") {
135
+ return "Billed to the workspace OpenRouter account";
136
+ }
137
+ if (model.provider === "workspace-gateway" || model.source === "workspace_gateway") {
138
+ return "Billed to the workspace Vercel account";
139
+ }
140
+ return "Billed to the workspace provider account";
141
+ }
135
142
  function projectPickerRows(models) {
136
143
  return models.filter((catalog) => {
137
144
  const billingClass = billingClassForModel(catalog);
@@ -170,16 +177,7 @@ function projectClientModelRows(models) {
170
177
  });
171
178
  }
172
179
  function sortPickerRows(rows) {
173
- return [...rows].sort((left, right) => {
174
- const classDelta = BILLING_CLASS_ORDER.indexOf(left.billingClass) - BILLING_CLASS_ORDER.indexOf(right.billingClass);
175
- if (classDelta !== 0) {
176
- return classDelta;
177
- }
178
- if (left.selectable !== right.selectable) {
179
- return left.selectable ? -1 : 1;
180
- }
181
- return left.label.localeCompare(right.label);
182
- });
180
+ return [...rows].sort(compareModelPickerOrder);
183
181
  }
184
182
  function findPickerRow(rows, modelId) {
185
183
  return rows.find((row) => row.id === modelId) ?? null;
@@ -220,4 +218,4 @@ export {
220
218
  findPickerRow,
221
219
  groupPickerRowsByBillingClass
222
220
  };
223
- //# sourceMappingURL=chunk-X4A66EWZ.js.map
221
+ //# sourceMappingURL=chunk-WMGF4Z7X.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/model-policy.ts"],"sourcesContent":["import {\n compareModelPickerOrder,\n modelPickerBillingClassFor,\n type ModelPickerBillingClass,\n} from \"@opengeni/sdk/model-picker-order\";\nimport type { ClientModel, ReasoningEffort, WorkspaceModelCatalogModel } from \"@opengeni/sdk\";\n\nexport type PickerBillingClass = ModelPickerBillingClass;\n\nexport type PickerModelRow<TCatalog extends ClientModel = WorkspaceModelCatalogModel> = {\n id: string;\n label: string;\n /** Catalog-curated compact label for dense UI; fall back to `label` when absent. */\n shortLabel?: string | undefined;\n billingClass: PickerBillingClass;\n billingClassLabel: string;\n selectable: boolean;\n unavailableReason: string | null;\n provider: string;\n providerLabel: string;\n catalog: TCatalog;\n};\n\nexport type LatencyModeId = \"standard\" | \"priority\" | \"fast\";\n\nconst BILLING_CLASS_LABELS: Record<PickerBillingClass, string> = {\n opengeni_credits: \"OpenGeni\",\n external: \"External\",\n codex_subscription: \"Codex\",\n supergrok_subscription: \"SuperGrok\",\n byok: \"Workspace providers\",\n organization_byok: \"Organization providers\",\n};\n\nconst AVAILABILITY_REASON_LABELS: Record<string, string> = {\n missing_credential: \"Credentials required\",\n needs_reauth: \"Reconnect required\",\n credential_not_ready: \"Credential not ready\",\n not_entitled: \"Not entitled\",\n provider_unhealthy: \"Provider unavailable\",\n policy_blocked: \"Blocked by workspace policy\",\n unsupported: \"Unsupported\",\n};\n\nexport function billingClassForModel(model: ClientModel): PickerBillingClass {\n if (model.provider === \"organization-gateway\" || model.provider === \"organization-openrouter\") {\n return \"organization_byok\";\n }\n if (model.provider === \"workspace-gateway\" || model.provider === \"workspace-openrouter\") {\n return \"byok\";\n }\n return modelPickerBillingClassFor(model);\n}\n\nexport function billingClassLabel(billingClass: PickerBillingClass): string {\n return BILLING_CLASS_LABELS[billingClass];\n}\n\nexport function availabilityReasonLabel(\n reason: WorkspaceModelCatalogModel[\"availability\"][\"reason\"],\n): string | null {\n if (!reason) {\n return null;\n }\n return AVAILABILITY_REASON_LABELS[reason] ?? \"Unavailable\";\n}\n\nexport function effortOptionsForModel(model: ClientModel): ReasoningEffort[] {\n const efforts = model.capabilities?.reasoning.efforts;\n if (!efforts || efforts.length === 0) {\n return [\"low\"];\n }\n const order: ReasoningEffort[] = [\"none\", \"minimal\", \"low\", \"medium\", \"high\", \"xhigh\", \"max\"];\n return order.filter((effort) => efforts.includes(effort));\n}\n\nexport function defaultEffortForModel(model: ClientModel): ReasoningEffort {\n const options = effortOptionsForModel(model);\n const configured = model.capabilities?.reasoning.defaultEffort;\n if (configured && options.includes(configured)) {\n return configured;\n }\n return options[0] ?? \"low\";\n}\n\nexport function coerceReasoningEffortForModel(\n model: ClientModel,\n effort: ReasoningEffort,\n): ReasoningEffort {\n const options = effortOptionsForModel(model);\n if (options.includes(effort)) {\n return effort;\n }\n return defaultEffortForModel(model);\n}\n\nexport function runnableLatencyModesForModel(model: ClientModel): LatencyModeId[] {\n const modes = model.capabilities?.latencyModes ?? [];\n return modes.filter((mode) => mode.runnable).map((mode) => mode.id);\n}\n\nexport function labelLatencyMode(mode: LatencyModeId): string {\n if (mode === \"fast\") {\n return \"Fast\";\n }\n if (mode === \"priority\") {\n return \"Priority\";\n }\n return \"Standard\";\n}\n\nexport function labelReasoningEffort(effort: ReasoningEffort): string {\n if (effort === \"xhigh\") {\n return \"Extra high\";\n }\n return effort.slice(0, 1).toUpperCase() + effort.slice(1);\n}\n\nexport function payerSummaryForModel(model: ClientModel): string {\n if (model.cost === \"free\") {\n return \"Free in this deployment\";\n }\n if (model.cost === \"credits\") {\n return \"OpenGeni credits\";\n }\n if (model.cost === \"subscription\") {\n return model.source === \"supergrok\"\n ? \"SuperGrok subscription · external billing\"\n : \"Codex subscription · external billing\";\n }\n if (model.cost === \"workspace\") {\n return workspaceProviderPayerSummary(model);\n }\n\n // Older client-config payloads do not carry `cost`; preserve their existing\n // settlement-derived label until every deployment has rolled forward.\n const billing = model.billing;\n if (!billing) {\n return \"Route unknown\";\n }\n if (billing.metering === \"opengeni_credits\") {\n return \"OpenGeni credits · automatic managed route\";\n }\n if (billing.upstreamPayer === \"connected_subscription\") {\n return model.source === \"supergrok\"\n ? \"SuperGrok subscription · external billing\"\n : \"Codex subscription · external billing\";\n }\n if (billing.upstreamPayer === \"workspace\") {\n return workspaceProviderPayerSummary(model);\n }\n return \"External provider · no OpenGeni credits\";\n}\n\nexport function advancedSourceSummary(model: ClientModel): string | null {\n const source = model.credentialSource;\n if (!source) {\n return model.billing?.metering === \"external\" && model.billing.upstreamPayer === \"deployment\"\n ? \"Deployment route · no authentication\"\n : null;\n }\n if (source.kind === \"connected_subscription\") {\n return source.provider === \"xai\"\n ? \"Connected SuperGrok subscription\"\n : \"Connected Codex subscription\";\n }\n if (source.kind === \"workspace_connection\") {\n if (model.provider === \"workspace-openrouter\") {\n return \"Workspace OpenRouter connection\";\n }\n if (model.provider === \"workspace-gateway\" || model.source === \"workspace_gateway\") {\n return \"Workspace Vercel AI Gateway\";\n }\n return \"Workspace provider connection\";\n }\n if (source.kind === \"deployment\") {\n return source.mechanism === \"azure_ad_bearer\"\n ? \"Deployment Azure identity\"\n : \"Deployment API key\";\n }\n return null;\n}\n\nfunction workspaceProviderPayerSummary(model: ClientModel): string {\n if (model.provider === \"workspace-openrouter\") {\n return \"Billed to the workspace OpenRouter account\";\n }\n if (model.provider === \"workspace-gateway\" || model.source === \"workspace_gateway\") {\n return \"Billed to the workspace Vercel account\";\n }\n return \"Billed to the workspace provider account\";\n}\n\nexport function projectPickerRows(models: WorkspaceModelCatalogModel[]): PickerModelRow[] {\n return models\n .filter((catalog) => {\n const billingClass = billingClassForModel(catalog);\n return billingClass === \"opengeni_credits\" || catalog.credentialReadiness.status === \"ready\";\n })\n .map((catalog) => {\n const billingClass = billingClassForModel(catalog);\n return {\n id: catalog.id,\n label: catalog.label,\n ...(catalog.shortLabel ? { shortLabel: catalog.shortLabel } : {}),\n billingClass,\n billingClassLabel: billingClassLabel(billingClass),\n selectable: catalog.availability.selectable,\n unavailableReason: catalog.availability.selectable\n ? null\n : availabilityReasonLabel(catalog.availability.reason),\n provider: catalog.provider,\n providerLabel: catalog.providerLabel,\n catalog,\n };\n });\n}\n\n/** Project the lightweight client-config model list into the same picker contract. */\nexport function projectClientModelRows(models: ClientModel[]): PickerModelRow<ClientModel>[] {\n return models.map((catalog) => {\n const billingClass = billingClassForModel(catalog);\n return {\n id: catalog.id,\n label: catalog.label,\n ...(catalog.shortLabel ? { shortLabel: catalog.shortLabel } : {}),\n billingClass,\n billingClassLabel: billingClassLabel(billingClass),\n selectable: true,\n unavailableReason: null,\n provider: catalog.provider,\n providerLabel: catalog.providerLabel,\n catalog,\n };\n });\n}\n\nexport function sortPickerRows<TCatalog extends ClientModel>(\n rows: PickerModelRow<TCatalog>[],\n): PickerModelRow<TCatalog>[] {\n return [...rows].sort(compareModelPickerOrder);\n}\n\nexport function findPickerRow<TCatalog extends ClientModel>(\n rows: PickerModelRow<TCatalog>[],\n modelId: string,\n): PickerModelRow<TCatalog> | null {\n return rows.find((row) => row.id === modelId) ?? null;\n}\n\nexport function groupPickerRowsByBillingClass(\n rows: PickerModelRow[],\n): Array<{ billingClass: PickerBillingClass; label: string; rows: PickerModelRow[] }>;\nexport function groupPickerRowsByBillingClass<TCatalog extends ClientModel>(\n rows: PickerModelRow<TCatalog>[],\n): Array<{\n billingClass: PickerBillingClass;\n label: string;\n rows: PickerModelRow<TCatalog>[];\n}>;\nexport function groupPickerRowsByBillingClass<TCatalog extends ClientModel>(\n rows: PickerModelRow<TCatalog>[],\n): Array<{\n billingClass: PickerBillingClass;\n label: string;\n rows: PickerModelRow<TCatalog>[];\n}> {\n const sorted = sortPickerRows(rows);\n const groups: Array<{\n billingClass: PickerBillingClass;\n label: string;\n rows: PickerModelRow<TCatalog>[];\n }> = [];\n for (const row of sorted) {\n const existing = groups.find((group) => group.billingClass === row.billingClass);\n if (existing) {\n existing.rows.push(row);\n continue;\n }\n groups.push({\n billingClass: row.billingClass,\n label: row.billingClassLabel,\n rows: [row],\n });\n }\n return groups;\n}\n"],"mappings":"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","names":[]}
package/dist/client.d.ts CHANGED
@@ -26,7 +26,7 @@ export type EmbeddedGoalClientLike = EmbeddedSessionEventClientLike & Pick<OpenG
26
26
  /** Exact client surface required by {@link useSessionLineage}. */
27
27
  export type EmbeddedSessionLineageClientLike = EmbeddedSessionEventClientLike & Pick<OpenGeniClient, "getSessionLineage">;
28
28
  /** Exact client surface required by {@link useFileAttachments}. */
29
- export type EmbeddedFileAttachmentClientLike = Pick<OpenGeniClient, "uploadFile">;
29
+ export type EmbeddedFileAttachmentClientLike = Pick<OpenGeniClient, "uploadFile"> & Partial<Pick<OpenGeniClient, "createFileDownloadUrl">>;
30
30
  /** Exact client surface required by structured human-input hooks. */
31
31
  export type EmbeddedHumanInputSessionClientLike = EmbeddedSessionEventClientLike & Pick<OpenGeniClient, "listHumanInputRequests" | "submitHumanInputResponse">;
32
32
  /** Exact client surface required by MCP approval-policy hooks. */
@@ -1,5 +1,5 @@
1
1
  export { ArtifactSurface, type ArtifactModality, type ArtifactSurfaceProps, } from "./artifact-surface.js";
2
- export { PUBLISHED_HTML_ARTIFACT_IFRAME_SANDBOX, PublishedHtmlArtifactFrame, type PublishedHtmlArtifactFrameProps, } from "./published-html-artifact-frame.js";
2
+ export { PUBLISHED_HTML_ARTIFACT_IFRAME_SANDBOX, PublishedHtmlArtifactFrame, openGeniSiteBridgePortFromBootstrap, publishedHtmlArtifactDocument, type PublishedHtmlArtifactFrameProps, type PublishedHtmlArtifactToolBridge, } from "./published-html-artifact-frame.js";
3
3
  export { SpreadsheetArtifactSurface, SpreadsheetGrid, SpreadsheetProjectionGrid, type SpreadsheetArtifactSurfaceProps, type SpreadsheetCommit, type SpreadsheetRangeCommit, type SpreadsheetGridProps, type SpreadsheetGridProjection, type SpreadsheetProjectionCell, type SpreadsheetProjectionGridProps, type SpreadsheetSelection, type SpreadsheetViewport, } from "./spreadsheet-grid.js";
4
4
  export { EditableSpreadsheetArtifactSurface, EditableSpreadsheetGrid, type EditableSpreadsheetArtifactSurfaceProps, type EditableSpreadsheetGridProps, } from "./editable-spreadsheet.js";
5
5
  export { BrowserEditableArtifactWorkbench, EditableArtifactWorkbench, EditableArtifactWorkbenchHost, type BrowserEditableArtifactWorkbenchOptions, type BrowserEditableArtifactWorkbenchProps, type EditableArtifactWorkbenchHostProps, type EditableArtifactWorkbenchProps, } from "./editable-artifact-workbench.js";
@@ -1,14 +1,56 @@
1
- import type { CSSProperties } from "react";
1
+ import { type OpenGeniSiteToolCatalog } from "@opengeni/sdk/site";
2
+ import type { ToolGatewayCallRequest, ToolGatewayCallResponse, ToolGatewayDeclarationsResponse } from "@opengeni/sdk";
3
+ import { type CSSProperties } from "react";
2
4
  export declare const PUBLISHED_HTML_ARTIFACT_IFRAME_SANDBOX: string;
3
5
  export type PublishedHtmlArtifactFrameProps = {
4
6
  html: string;
5
7
  title: string;
6
8
  className?: string;
7
9
  style?: CSSProperties;
10
+ toolBridge?: PublishedHtmlArtifactToolBridge;
8
11
  };
12
+ export type PublishedHtmlArtifactToolBridge = {
13
+ catalog: (options: {
14
+ signal: AbortSignal;
15
+ }) => Promise<OpenGeniSiteToolCatalog>;
16
+ call: (request: ToolGatewayCallRequest, options: {
17
+ signal: AbortSignal;
18
+ }) => Promise<ToolGatewayCallResponse>;
19
+ declarations?: (options: {
20
+ signal: AbortSignal;
21
+ }) => Promise<ToolGatewayDeclarationsResponse>;
22
+ };
23
+ export declare function publishedHtmlArtifactDocument(html: string, toolBridgeEnabled: boolean): string;
9
24
  /**
10
25
  * Render exact published HTML in an opaque-origin iframe. Artifact scripts,
11
- * external resources, forms, popups, and downloads work without granting
12
- * parent-origin authority, shared cookies/storage, or top-level navigation.
26
+ * external resources, forms, popups, downloads, and the host-filtered tool
27
+ * bridge work without granting parent-origin authority, shared cookies/storage,
28
+ * or top-level navigation.
13
29
  */
14
30
  export declare function PublishedHtmlArtifactFrame(props: PublishedHtmlArtifactFrameProps): import("react").JSX.Element;
31
+ export declare class SiteBridgeRequestRegistry {
32
+ private readonly controllersByPort;
33
+ replacePort(port: MessagePort): void;
34
+ start(port: MessagePort, requestId: string): AbortController | null;
35
+ cancel(port: MessagePort, requestId: string): void;
36
+ complete(port: MessagePort, requestId: string, controller: AbortController): void;
37
+ closePort(port: MessagePort): void;
38
+ closeAll(): void;
39
+ }
40
+ export declare class SiteBridgeDocumentLease {
41
+ private readonly attachToolPort;
42
+ private readonly closeActivePorts;
43
+ private readonly createMessageChannel;
44
+ private loaded;
45
+ private bootstrapPort;
46
+ constructor(attachToolPort: (data: unknown, ports: readonly MessagePort[]) => void, closeActivePorts: () => void, createMessageChannel?: () => MessageChannel);
47
+ load(frameWindow: Pick<Window, "postMessage">): boolean;
48
+ close(): void;
49
+ }
50
+ export declare function openGeniSiteBridgePortFromBootstrap(data: unknown, ports: readonly MessagePort[]): MessagePort | null;
51
+ export declare function siteBridgeError(error: unknown): {
52
+ code: string;
53
+ message: string;
54
+ retryable: boolean;
55
+ outcomeUnknown: boolean;
56
+ };
@@ -57,6 +57,7 @@ export type ChatComposerMessages = {
57
57
  uploading: string;
58
58
  uploadFailed: string;
59
59
  previewAttachment: (name: string) => string;
60
+ previewUnavailable?: string | undefined;
60
61
  attachmentPreviewLabel: string;
61
62
  downloadAttachment: (name: string) => string;
62
63
  closeAttachmentPreview: string;
@@ -165,6 +166,7 @@ export declare function useChatComposerController({ delivery, draft, control, ef
165
166
  uploading: string;
166
167
  uploadFailed: string;
167
168
  previewAttachment: (name: string) => string;
169
+ previewUnavailable?: string | undefined;
168
170
  attachmentPreviewLabel: string;
169
171
  downloadAttachment: (name: string) => string;
170
172
  closeAttachmentPreview: string;
@@ -73,7 +73,7 @@ type GoalPillRecord = Pick<SessionGoal, "status" | "pausedReason"> & {
73
73
  export declare function sessionChromeGoalPillLabel(state: GoalPillState, record: GoalPillRecord | null | undefined): string;
74
74
  /**
75
75
  * 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
76
+ * pause reason, the agent's own `wait_for_input` hold (reason + deadline), or the
77
77
  * next idle-backoff check time. Null when the state needs no explanation.
78
78
  */
79
79
  export declare function sessionChromeGoalPillExplanation(state: GoalPillState, record: GoalPillRecord | null | undefined): string | null;
package/dist/composer.js CHANGED
@@ -37,8 +37,7 @@ import {
37
37
  useChatComposer,
38
38
  useChatComposerController,
39
39
  useVoiceInput
40
- } from "./chunk-XYRDDSXF.js";
41
- import "./chunk-IOLVN74D.js";
40
+ } from "./chunk-R55HFTT3.js";
42
41
  import {
43
42
  BillingClassMark,
44
43
  ModelPolicyPicker,
@@ -47,13 +46,14 @@ import {
47
46
  PickerBackHeader,
48
47
  PickerNavRow,
49
48
  defaultModelPolicyPickerMessages
50
- } from "./chunk-2DZVYHVO.js";
51
- import "./chunk-X4A66EWZ.js";
49
+ } from "./chunk-4JFUT22W.js";
52
50
  import "./chunk-7EAFGICR.js";
53
51
  import "./chunk-VZTQ73XT.js";
52
+ import "./chunk-IOLVN74D.js";
54
53
  import "./chunk-KZ73RL76.js";
55
54
  import "./chunk-NEXLLTP4.js";
56
55
  import "./chunk-VTOREEXF.js";
56
+ import "./chunk-WMGF4Z7X.js";
57
57
  import "./chunk-22KP6LR5.js";
58
58
  export {
59
59
  Actions,
@@ -1,16 +1,16 @@
1
1
  import {
2
2
  ComputerViewer,
3
3
  computerKey
4
- } from "./chunk-ELIYWBZR.js";
4
+ } from "./chunk-BV5A4OTE.js";
5
5
  import "./chunk-H5YGYNXS.js";
6
6
  import "./chunk-4MDLEHXL.js";
7
7
  import "./chunk-5YK2ZDIG.js";
8
+ import "./chunk-JVYQRRC4.js";
8
9
  import "./chunk-KZ73RL76.js";
9
10
  import "./chunk-NEXLLTP4.js";
10
- import "./chunk-JVYQRRC4.js";
11
11
  import "./chunk-22KP6LR5.js";
12
12
  export {
13
13
  ComputerViewer,
14
14
  computerKey
15
15
  };
16
- //# sourceMappingURL=computer-viewer-FWEZISW4.js.map
16
+ //# sourceMappingURL=computer-viewer-7TEZC6Y2.js.map
@@ -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