@opengeni/react 7.0.0 → 7.1.0-canary.35916963870001

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 (68) hide show
  1. package/README.md +34 -0
  2. package/dist/approvals.d.ts +2 -1
  3. package/dist/{chunk-D5NOQPLR.js → chunk-CJCVYUKK.js} +25 -15
  4. package/dist/chunk-CJCVYUKK.js.map +1 -0
  5. package/dist/{chunk-IYUPN32E.js → chunk-DBPVUGQT.js} +6 -1
  6. package/dist/{chunk-IYUPN32E.js.map → chunk-DBPVUGQT.js.map} +1 -1
  7. package/dist/{chunk-JKLGJQO5.js → chunk-HJDDS2L6.js} +35 -15
  8. package/dist/chunk-HJDDS2L6.js.map +1 -0
  9. package/dist/{chunk-5GAL23FF.js → chunk-IOLPHOF4.js} +2 -5
  10. package/dist/chunk-IOLPHOF4.js.map +1 -0
  11. package/dist/{chunk-D7GAPJ3V.js → chunk-RAJYEBEG.js} +63 -30
  12. package/dist/chunk-RAJYEBEG.js.map +1 -0
  13. package/dist/{chunk-IP4BUBKH.js → chunk-TA4W6KBP.js} +24 -13
  14. package/dist/chunk-TA4W6KBP.js.map +1 -0
  15. package/dist/{chunk-UXE5SSNN.js → chunk-U56XI627.js} +2 -2
  16. package/dist/{chunk-JPHDWKZE.js → chunk-X7YDBAQD.js} +12 -7
  17. package/dist/chunk-X7YDBAQD.js.map +1 -0
  18. package/dist/{chunk-HJ5VJ4JB.js → chunk-ZA4K7YY2.js} +73 -15
  19. package/dist/chunk-ZA4K7YY2.js.map +1 -0
  20. package/dist/components/markdown.d.ts +2 -0
  21. package/dist/components/model-policy-picker.d.ts +17 -1
  22. package/dist/components/session-conversation.d.ts +3 -0
  23. package/dist/composer.d.ts +1 -1
  24. package/dist/composer.js +4 -4
  25. package/dist/connect.js +1 -1
  26. package/dist/hooks/use-session-events.d.ts +6 -1
  27. package/dist/index.d.ts +1 -1
  28. package/dist/index.js +10 -13
  29. package/dist/index.js.map +1 -1
  30. package/dist/machines.js +1 -1
  31. package/dist/{model-policy-picker-menu-RVOQ4ZZG.js → model-policy-picker-menu-S3SF65AH.js} +4 -4
  32. package/dist/model-policy.js +1 -1
  33. package/dist/realtime.js +2 -2
  34. package/dist/session-ui.js +6 -6
  35. package/dist/session.js +2 -2
  36. package/dist/timeline/tool-display-name.d.ts +2 -1
  37. package/dist/timeline/types.d.ts +2 -1
  38. package/package.json +3 -3
  39. package/src/approvals.ts +8 -1
  40. package/src/components/approval-surface.tsx +12 -2
  41. package/src/components/machine-card.tsx +5 -5
  42. package/src/components/machine-dock-bar.tsx +1 -1
  43. package/src/components/machines/machine-detail.tsx +5 -2
  44. package/src/components/markdown.tsx +101 -55
  45. package/src/components/model-policy-picker-menu.tsx +131 -33
  46. package/src/components/model-policy-picker.tsx +61 -12
  47. package/src/components/session-commands-panel.tsx +8 -3
  48. package/src/components/session-conversation.tsx +5 -1
  49. package/src/composer.ts +1 -0
  50. package/src/hooks/use-last-started-turn-policy.ts +3 -7
  51. package/src/hooks/use-session-events.ts +32 -7
  52. package/src/index.ts +1 -0
  53. package/src/model-policy.ts +1 -4
  54. package/src/timeline/projection.ts +4 -0
  55. package/src/timeline/rolling-activity.tsx +4 -2
  56. package/src/timeline/tool-display-name.ts +8 -6
  57. package/src/timeline/tool-renderers.tsx +5 -3
  58. package/src/timeline/types.ts +2 -0
  59. package/styles/compiled.css +15 -0
  60. package/dist/chunk-5GAL23FF.js.map +0 -1
  61. package/dist/chunk-D5NOQPLR.js.map +0 -1
  62. package/dist/chunk-D7GAPJ3V.js.map +0 -1
  63. package/dist/chunk-HJ5VJ4JB.js.map +0 -1
  64. package/dist/chunk-IP4BUBKH.js.map +0 -1
  65. package/dist/chunk-JKLGJQO5.js.map +0 -1
  66. package/dist/chunk-JPHDWKZE.js.map +0 -1
  67. /package/dist/{chunk-UXE5SSNN.js.map → chunk-U56XI627.js.map} +0 -0
  68. /package/dist/{model-policy-picker-menu-RVOQ4ZZG.js.map → model-policy-picker-menu-S3SF65AH.js.map} +0 -0
@@ -3,7 +3,7 @@ import {
3
3
  PickerNavRow,
4
4
  defaultModelPolicyPickerMessages,
5
5
  effectiveRows
6
- } from "./chunk-IP4BUBKH.js";
6
+ } from "./chunk-TA4W6KBP.js";
7
7
  import {
8
8
  coerceReasoningEffortForModel,
9
9
  effortOptionsForModel,
@@ -12,13 +12,13 @@ import {
12
12
  labelReasoningEffort,
13
13
  payerSummaryForModel,
14
14
  runnableLatencyModesForModel
15
- } from "./chunk-5GAL23FF.js";
15
+ } from "./chunk-IOLPHOF4.js";
16
16
  import {
17
17
  cn
18
18
  } from "./chunk-22KP6LR5.js";
19
19
 
20
20
  // src/components/model-policy-picker-menu.tsx
21
- import { CheckIcon, SearchIcon, ZapIcon } from "lucide-react";
21
+ import { ArrowRightIcon, CheckIcon, SearchIcon, ZapIcon } from "lucide-react";
22
22
  import { useRef, useState } from "react";
23
23
  import { Popover, RadioGroup } from "radix-ui";
24
24
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
@@ -29,11 +29,19 @@ function ModelPolicyPickerMenu(props) {
29
29
  const selected = findPickerRow(rows, props.model);
30
30
  const words = query.toLowerCase().trim().split(/\s+/).filter(Boolean);
31
31
  const filtered = rows.filter((row) => {
32
- const text = `${row.label} ${row.id} ${row.providerLabel} ${row.billingClassLabel} ${payerSummaryForModel(row.catalog)}`.toLowerCase();
32
+ const description = props.groupPresentation?.[row.billingClass]?.description;
33
+ const text = `${row.label} ${row.id} ${row.providerLabel} ${row.billingClassLabel} ${description === void 0 ? payerSummaryForModel(row.catalog) : description ?? ""}`.toLowerCase();
33
34
  return words.every((word) => text.includes(word));
34
35
  });
35
36
  const matchingIds = new Set(filtered.map((row) => row.id));
36
- const groups = groupPickerRowsByBillingClass(rows, { codexOnly: props.codexOnly === true }).map((group) => ({ ...group, rows: group.rows.filter((row) => matchingIds.has(row.id)) })).filter((group) => group.rows.length > 0);
37
+ const groups = groupPickerRowsByBillingClass(rows, { codexOnly: props.codexOnly === true }).map((group) => {
38
+ const override = props.groupPresentation?.[group.billingClass]?.description;
39
+ return {
40
+ ...group,
41
+ rows: group.rows.filter((row) => matchingIds.has(row.id)),
42
+ description: override === void 0 ? group.billingClass === "opengeni_credits" ? null : messages.billingHints[group.billingClass] : override
43
+ };
44
+ }).filter((group) => group.rows.length > 0);
37
45
  const choose = (row) => {
38
46
  if (!row.selectable || props.disabled) return;
39
47
  if (row.id !== props.model) props.onModelChange(row.id);
@@ -51,7 +59,7 @@ function ModelPolicyPickerMenu(props) {
51
59
  hint: row.unavailableReason ?? void 0,
52
60
  disabled: props.disabled || !row.selectable,
53
61
  title: [row.label, row.unavailableReason].filter(Boolean).join(" \xB7 "),
54
- active: row.id === props.model,
62
+ active: row.selectable && row.id === props.model,
55
63
  showChevron: false,
56
64
  trailing: row.catalog.cost === "free" || row.id === props.model ? /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-2", children: [
57
65
  row.catalog.cost === "free" ? /* @__PURE__ */ jsx("span", { className: "rounded-og-sm bg-og-surface-2 px-1.5 py-0.5 text-og-control text-og-fg-muted", children: messages.free }) : null,
@@ -82,7 +90,7 @@ function ModelPolicyPickerMenu(props) {
82
90
  buttons[next]?.focus();
83
91
  },
84
92
  children: [
85
- /* @__PURE__ */ jsx("div", { className: "border-b border-og-border py-1", children: /* @__PURE__ */ jsxs("label", { className: "og-model-policy-search flex items-center gap-2 rounded-og-sm px-2 py-1 focus-within:outline-2 focus-within:-outline-offset-2 focus-within:outline-og-accent/40", children: [
93
+ rows.some((row) => row.selectable) ? /* @__PURE__ */ jsx("div", { className: "border-b border-og-border py-1", children: /* @__PURE__ */ jsxs("label", { className: "og-model-policy-search flex items-center gap-2 rounded-og-sm px-2 py-1 focus-within:outline-2 focus-within:-outline-offset-2 focus-within:outline-og-accent/40", children: [
86
94
  /* @__PURE__ */ jsx(SearchIcon, { className: "size-4 shrink-0 text-og-fg-subtle", "aria-hidden": true }),
87
95
  /* @__PURE__ */ jsx(
88
96
  "input",
@@ -101,14 +109,14 @@ function ModelPolicyPickerMenu(props) {
101
109
  className: "og-model-policy-search-input h-8 min-w-0 flex-1 bg-transparent text-og-menu text-og-fg outline-hidden placeholder:text-og-fg-subtle"
102
110
  }
103
111
  )
104
- ] }) }),
112
+ ] }) }) : null,
105
113
  props.error ? /* @__PURE__ */ jsx("p", { className: "px-2 py-2 text-og-control text-og-status-failed", role: "alert", children: props.error }) : null,
106
114
  /* @__PURE__ */ jsx(
107
115
  "div",
108
116
  {
109
117
  className: "min-h-0 flex-1 overflow-y-auto overscroll-contain py-1",
110
118
  "data-testid": "model-picker-models",
111
- children: props.loading ? /* @__PURE__ */ jsx("p", { className: "px-2 py-3 text-og-control text-og-fg-subtle", children: messages.loading }) : /* @__PURE__ */ jsxs(Fragment, { children: [
119
+ children: props.loading ? /* @__PURE__ */ jsx("p", { className: "px-2 py-3 text-og-control text-og-fg-subtle", children: messages.loading }) : rows.some((row) => row.selectable) ? /* @__PURE__ */ jsxs(Fragment, { children: [
112
120
  groups.map((group) => /* @__PURE__ */ jsxs(
113
121
  "section",
114
122
  {
@@ -116,20 +124,27 @@ function ModelPolicyPickerMenu(props) {
116
124
  className: "py-2.5 first:pt-1 [&+section]:border-t [&+section]:border-og-border",
117
125
  children: [
118
126
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 px-2.5 py-1.5 text-og-control font-semibold text-og-fg", children: [
119
- /* @__PURE__ */ jsx(BillingClassMark, { billingClass: group.billingClass, "aria-label": "" }),
120
- group.label
127
+ /* @__PURE__ */ jsx(
128
+ BillingClassMark,
129
+ {
130
+ billingClass: group.billingClass,
131
+ presentation: props.groupPresentation?.[group.billingClass],
132
+ "aria-label": ""
133
+ }
134
+ ),
135
+ /* @__PURE__ */ jsx("span", { className: "min-w-0 break-words", children: group.label })
121
136
  ] }),
122
- group.billingClass !== "opengeni_credits" ? /* @__PURE__ */ jsx("p", { className: "px-2.5 pb-2 text-og-control text-og-fg-subtle", children: messages.billingHints[group.billingClass] }) : null,
137
+ group.description ? /* @__PURE__ */ jsx("p", { className: "break-words px-2.5 pb-2 text-og-control text-og-fg-subtle", children: group.description }) : null,
123
138
  group.rows.map(modelRow)
124
139
  ]
125
140
  },
126
141
  group.billingClass
127
142
  )),
128
143
  filtered.length === 0 ? /* @__PURE__ */ jsx("p", { className: "px-2 py-4 text-og-control text-og-fg-subtle", children: words.length ? messages.noMatches : messages.noModels }) : null
129
- ] })
144
+ ] }) : props.connectModelsHref || rows.length > 0 ? /* @__PURE__ */ jsx(ConnectModelsPanel, { href: props.connectModelsHref, messages }) : /* @__PURE__ */ jsx("p", { className: "px-2 py-4 text-og-control text-og-fg-subtle", children: messages.noModels })
130
145
  }
131
146
  ),
132
- selected && (props.hasImageAttachments && selected.catalog.capabilities?.inputModalities.includes("image") === false || effortOptionsForModel(selected.catalog).length > 1 && selected.catalog.capabilities?.reasoning.runnable !== false || props.allowLatencyMode !== false && runnableLatencyModesForModel(selected.catalog).includes("fast")) ? /* @__PURE__ */ jsxs("div", { className: "border-t border-og-border px-2.5 py-2.5", children: [
147
+ rows.some((row) => row.selectable) && selected && (props.hasImageAttachments && selected.catalog.capabilities?.inputModalities.includes("image") === false || effortOptionsForModel(selected.catalog).length > 1 && selected.catalog.capabilities?.reasoning.runnable !== false || props.allowLatencyMode !== false && runnableLatencyModesForModel(selected.catalog).includes("fast")) ? /* @__PURE__ */ jsxs("div", { className: "border-t border-og-border px-2.5 py-2.5", children: [
133
148
  props.hasImageAttachments && selected.catalog.capabilities?.inputModalities.includes("image") === false ? /* @__PURE__ */ jsx("p", { className: "pb-1.5 text-og-control leading-relaxed text-og-fg-subtle", children: messages.unsupportedAttachments }) : null,
134
149
  /* @__PURE__ */ jsx(ModelThinkingControls, { ...props })
135
150
  ] }) : null
@@ -137,6 +152,49 @@ function ModelPolicyPickerMenu(props) {
137
152
  }
138
153
  );
139
154
  }
155
+ var CONNECT_MODEL_OPTIONS = [
156
+ { billingClass: "codex_subscription", title: "Codex", detail: "ChatGPT" },
157
+ { billingClass: "supergrok_subscription", title: "SuperGrok", detail: "xAI" },
158
+ { billingClass: "byok", title: "AI Gateway", detail: "Vercel" },
159
+ { billingClass: "external", title: "OpenRouter", detail: "API key" }
160
+ ];
161
+ function ConnectModelsPanel(props) {
162
+ return /* @__PURE__ */ jsxs("div", { className: "px-1.5 pb-1.5 pt-2", "data-testid": "model-picker-connect", children: [
163
+ /* @__PURE__ */ jsxs("div", { className: "px-1.5 pb-3", children: [
164
+ /* @__PURE__ */ jsx("p", { className: "text-og-menu font-medium tracking-tight text-og-fg", children: props.messages.connectTitle }),
165
+ /* @__PURE__ */ jsx("p", { className: "mt-1 text-og-control leading-snug text-og-fg-subtle", children: props.messages.connectBody })
166
+ ] }),
167
+ /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 gap-1", children: CONNECT_MODEL_OPTIONS.map((option) => {
168
+ const content = /* @__PURE__ */ jsxs(Fragment, { children: [
169
+ /* @__PURE__ */ jsx("span", { className: "flex size-8 shrink-0 items-center justify-center rounded-og-md bg-og-surface-2 text-og-fg", children: /* @__PURE__ */ jsx(
170
+ BillingClassMark,
171
+ {
172
+ billingClass: option.billingClass,
173
+ "aria-label": "",
174
+ className: "size-4 text-og-fg"
175
+ }
176
+ ) }),
177
+ /* @__PURE__ */ jsxs("span", { className: "min-w-0", children: [
178
+ /* @__PURE__ */ jsx("span", { className: "block truncate text-og-control font-medium text-og-fg", children: option.title }),
179
+ /* @__PURE__ */ jsx("span", { className: "block truncate text-og-control text-og-fg-subtle", children: option.detail })
180
+ ] })
181
+ ] });
182
+ const className = "flex min-w-0 items-center gap-2 rounded-og-md px-1.5 py-1.5 outline-hidden transition-colors hover:bg-og-surface-2 focus-visible:ring-2 focus-visible:ring-og-accent/40";
183
+ return props.href ? /* @__PURE__ */ jsx("a", { href: props.href, className, children: content }, option.title) : /* @__PURE__ */ jsx("div", { className, children: content }, option.title);
184
+ }) }),
185
+ props.href ? /* @__PURE__ */ jsxs(
186
+ "a",
187
+ {
188
+ href: props.href,
189
+ className: "mt-2 flex h-9 w-full items-center justify-center gap-1.5 rounded-og-md bg-og-fg text-og-control font-medium text-og-surface-1 outline-hidden transition-opacity hover:opacity-90 focus-visible:ring-2 focus-visible:ring-og-accent/40",
190
+ children: [
191
+ props.messages.connectAction,
192
+ /* @__PURE__ */ jsx(ArrowRightIcon, { className: "size-3.5", "aria-hidden": true })
193
+ ]
194
+ }
195
+ ) : /* @__PURE__ */ jsx("p", { className: "px-1.5 pt-3 text-og-control text-og-fg-subtle", children: props.messages.noModels })
196
+ ] });
197
+ }
140
198
  function ModelThinkingControls(props) {
141
199
  const selected = findPickerRow(effectiveRows(props), props.model);
142
200
  if (!selected) return null;
@@ -229,4 +287,4 @@ export {
229
287
  ModelPolicyPickerMenu,
230
288
  ModelPolicyPickerPopover
231
289
  };
232
- //# sourceMappingURL=chunk-HJ5VJ4JB.js.map
290
+ //# sourceMappingURL=chunk-ZA4K7YY2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/model-policy-picker-menu.tsx"],"sourcesContent":["import type { ClientModel, ReasoningEffort } from \"@opengeni/sdk\";\nimport { ArrowRightIcon, CheckIcon, SearchIcon, ZapIcon } from \"lucide-react\";\nimport { useRef, useState, type RefObject, type CSSProperties } from \"react\";\nimport { Popover, RadioGroup } from \"radix-ui\";\nimport { cn } from \"../lib/cn\";\nimport {\n coerceReasoningEffortForModel,\n effortOptionsForModel,\n findPickerRow,\n groupPickerRowsByBillingClass,\n labelReasoningEffort,\n payerSummaryForModel,\n runnableLatencyModesForModel,\n type PickerModelRow,\n} from \"../model-policy\";\nimport {\n BillingClassMark,\n defaultModelPolicyPickerMessages,\n effectiveRows,\n PickerNavRow,\n type ModelPolicyPickerProps,\n} from \"./model-policy-picker\";\ntype ClientPickerModelRow = PickerModelRow<ClientModel>;\n\n/** Model selection stays flat; reasoning never becomes a navigation destination. */\nexport function ModelPolicyPickerMenu(props: ModelPolicyPickerProps) {\n const messages = { ...defaultModelPolicyPickerMessages, ...props.messages };\n const [query, setQuery] = useState(\"\");\n const rows = effectiveRows(props);\n const selected = findPickerRow(rows, props.model);\n const words = query.toLowerCase().trim().split(/\\s+/).filter(Boolean);\n const filtered = rows.filter((row) => {\n const description = props.groupPresentation?.[row.billingClass]?.description;\n const text =\n `${row.label} ${row.id} ${row.providerLabel} ${row.billingClassLabel} ${description === undefined ? payerSummaryForModel(row.catalog) : (description ?? \"\")}`.toLowerCase();\n return words.every((word) => text.includes(word));\n });\n const matchingIds = new Set(filtered.map((row) => row.id));\n const groups = groupPickerRowsByBillingClass(rows, { codexOnly: props.codexOnly === true })\n .map((group) => {\n const override = props.groupPresentation?.[group.billingClass]?.description;\n return {\n ...group,\n rows: group.rows.filter((row) => matchingIds.has(row.id)),\n description:\n override === undefined\n ? group.billingClass === \"opengeni_credits\"\n ? null\n : messages.billingHints[group.billingClass]\n : override,\n };\n })\n .filter((group) => group.rows.length > 0);\n const choose = (row: ClientPickerModelRow) => {\n if (!row.selectable || props.disabled) return;\n if (row.id !== props.model) props.onModelChange(row.id);\n const effort = coerceReasoningEffortForModel(row.catalog, props.effort);\n // Hosts may commit the combined model/effort draft through this callback.\n props.onEffortChange(effort);\n if (\n props.latencyMode !== \"standard\" &&\n !runnableLatencyModesForModel(row.catalog).includes(props.latencyMode)\n ) {\n props.onLatencyModeChange(\"standard\");\n }\n props.onOpenChange?.(false);\n };\n const modelRow = (row: ClientPickerModelRow) => (\n <PickerNavRow\n key={row.id}\n label={row.label}\n hint={row.unavailableReason ?? undefined}\n disabled={props.disabled || !row.selectable}\n title={[row.label, row.unavailableReason].filter(Boolean).join(\" · \")}\n active={row.selectable && row.id === props.model}\n showChevron={false}\n trailing={\n row.catalog.cost === \"free\" || row.id === props.model ? (\n <span className=\"flex items-center gap-2\">\n {row.catalog.cost === \"free\" ? (\n <span className=\"rounded-og-sm bg-og-surface-2 px-1.5 py-0.5 text-og-control text-og-fg-muted\">\n {messages.free}\n </span>\n ) : null}\n {row.id === props.model ? (\n <CheckIcon className=\"size-3.5\" aria-label={messages.selected} />\n ) : null}\n </span>\n ) : null\n }\n testId={`model-picker-choice-${row.id}`}\n onClick={() => choose(row)}\n />\n );\n return (\n <div\n data-testid=\"model-picker-menu\"\n className=\"flex min-h-0 flex-col\"\n onKeyDown={(event) => {\n if (\n !(event.target instanceof HTMLButtonElement) ||\n ![\"ArrowDown\", \"ArrowUp\", \"Home\", \"End\"].includes(event.key)\n )\n return;\n const buttons = Array.from(\n event.currentTarget.querySelectorAll<HTMLButtonElement>(\n '[data-testid^=\"model-picker-choice-\"]:not(:disabled)',\n ),\n );\n const index = buttons.indexOf(event.target);\n if (index < 0) return;\n event.preventDefault();\n const next =\n event.key === \"Home\"\n ? 0\n : event.key === \"End\"\n ? buttons.length - 1\n : (index + (event.key === \"ArrowDown\" ? 1 : -1) + buttons.length) % buttons.length;\n buttons[next]?.focus();\n }}\n >\n {rows.some((row) => row.selectable) ? (\n <div className=\"border-b border-og-border py-1\">\n <label className=\"og-model-policy-search flex items-center gap-2 rounded-og-sm px-2 py-1 focus-within:outline-2 focus-within:-outline-offset-2 focus-within:outline-og-accent/40\">\n <SearchIcon className=\"size-4 shrink-0 text-og-fg-subtle\" aria-hidden />\n <input\n aria-label={messages.searchLabel}\n placeholder={messages.searchPlaceholder}\n value={query}\n onChange={(event) => setQuery(event.target.value)}\n onKeyDown={(event) => {\n if (event.key !== \"Escape\" && event.key !== \"Tab\") event.stopPropagation();\n if (event.key === \"ArrowDown\") {\n event.preventDefault();\n event.currentTarget\n .closest('[data-testid=\"model-picker-menu\"]')\n ?.querySelector<HTMLButtonElement>(\"button:not(:disabled)\")\n ?.focus();\n }\n }}\n className=\"og-model-policy-search-input h-8 min-w-0 flex-1 bg-transparent text-og-menu text-og-fg outline-hidden placeholder:text-og-fg-subtle\"\n />\n </label>\n </div>\n ) : null}\n {props.error ? (\n <p className=\"px-2 py-2 text-og-control text-og-status-failed\" role=\"alert\">\n {props.error}\n </p>\n ) : null}\n <div\n className=\"min-h-0 flex-1 overflow-y-auto overscroll-contain py-1\"\n data-testid=\"model-picker-models\"\n >\n {props.loading ? (\n <p className=\"px-2 py-3 text-og-control text-og-fg-subtle\">{messages.loading}</p>\n ) : rows.some((row) => row.selectable) ? (\n <>\n {groups.map((group) => (\n <section\n key={group.billingClass}\n aria-label={group.label}\n className=\"py-2.5 first:pt-1 [&+section]:border-t [&+section]:border-og-border\"\n >\n <div className=\"flex items-center gap-2 px-2.5 py-1.5 text-og-control font-semibold text-og-fg\">\n <BillingClassMark\n billingClass={group.billingClass}\n presentation={props.groupPresentation?.[group.billingClass]}\n aria-label=\"\"\n />\n <span className=\"min-w-0 break-words\">{group.label}</span>\n </div>\n {group.description ? (\n <p className=\"break-words px-2.5 pb-2 text-og-control text-og-fg-subtle\">\n {group.description}\n </p>\n ) : null}\n {group.rows.map(modelRow)}\n </section>\n ))}\n {filtered.length === 0 ? (\n <p className=\"px-2 py-4 text-og-control text-og-fg-subtle\">\n {words.length ? messages.noMatches : messages.noModels}\n </p>\n ) : null}\n </>\n ) : props.connectModelsHref || rows.length > 0 ? (\n <ConnectModelsPanel href={props.connectModelsHref} messages={messages} />\n ) : (\n <p className=\"px-2 py-4 text-og-control text-og-fg-subtle\">{messages.noModels}</p>\n )}\n </div>\n {rows.some((row) => row.selectable) &&\n selected &&\n ((props.hasImageAttachments &&\n selected.catalog.capabilities?.inputModalities.includes(\"image\") === false) ||\n (effortOptionsForModel(selected.catalog).length > 1 &&\n selected.catalog.capabilities?.reasoning.runnable !== false) ||\n (props.allowLatencyMode !== false &&\n runnableLatencyModesForModel(selected.catalog).includes(\"fast\"))) ? (\n <div className=\"border-t border-og-border px-2.5 py-2.5\">\n {props.hasImageAttachments &&\n selected.catalog.capabilities?.inputModalities.includes(\"image\") === false ? (\n <p className=\"pb-1.5 text-og-control leading-relaxed text-og-fg-subtle\">\n {messages.unsupportedAttachments}\n </p>\n ) : null}\n <ModelThinkingControls {...props} />\n </div>\n ) : null}\n </div>\n );\n}\n\nconst CONNECT_MODEL_OPTIONS: Array<{\n billingClass: \"codex_subscription\" | \"supergrok_subscription\" | \"byok\" | \"external\";\n title: string;\n detail: string;\n}> = [\n { billingClass: \"codex_subscription\", title: \"Codex\", detail: \"ChatGPT\" },\n { billingClass: \"supergrok_subscription\", title: \"SuperGrok\", detail: \"xAI\" },\n { billingClass: \"byok\", title: \"AI Gateway\", detail: \"Vercel\" },\n { billingClass: \"external\", title: \"OpenRouter\", detail: \"API key\" },\n];\n\nfunction ConnectModelsPanel(props: {\n href: string | undefined;\n messages: typeof defaultModelPolicyPickerMessages;\n}) {\n return (\n <div className=\"px-1.5 pb-1.5 pt-2\" data-testid=\"model-picker-connect\">\n <div className=\"px-1.5 pb-3\">\n <p className=\"text-og-menu font-medium tracking-tight text-og-fg\">\n {props.messages.connectTitle}\n </p>\n <p className=\"mt-1 text-og-control leading-snug text-og-fg-subtle\">\n {props.messages.connectBody}\n </p>\n </div>\n <div className=\"grid grid-cols-2 gap-1\">\n {CONNECT_MODEL_OPTIONS.map((option) => {\n const content = (\n <>\n <span className=\"flex size-8 shrink-0 items-center justify-center rounded-og-md bg-og-surface-2 text-og-fg\">\n <BillingClassMark\n billingClass={option.billingClass}\n aria-label=\"\"\n className=\"size-4 text-og-fg\"\n />\n </span>\n <span className=\"min-w-0\">\n <span className=\"block truncate text-og-control font-medium text-og-fg\">\n {option.title}\n </span>\n <span className=\"block truncate text-og-control text-og-fg-subtle\">\n {option.detail}\n </span>\n </span>\n </>\n );\n const className =\n \"flex min-w-0 items-center gap-2 rounded-og-md px-1.5 py-1.5 outline-hidden transition-colors hover:bg-og-surface-2 focus-visible:ring-2 focus-visible:ring-og-accent/40\";\n return props.href ? (\n <a key={option.title} href={props.href} className={className}>\n {content}\n </a>\n ) : (\n <div key={option.title} className={className}>\n {content}\n </div>\n );\n })}\n </div>\n {props.href ? (\n <a\n href={props.href}\n className=\"mt-2 flex h-9 w-full items-center justify-center gap-1.5 rounded-og-md bg-og-fg text-og-control font-medium text-og-surface-1 outline-hidden transition-opacity hover:opacity-90 focus-visible:ring-2 focus-visible:ring-og-accent/40\"\n >\n {props.messages.connectAction}\n <ArrowRightIcon className=\"size-3.5\" aria-hidden />\n </a>\n ) : (\n <p className=\"px-1.5 pt-3 text-og-control text-og-fg-subtle\">{props.messages.noModels}</p>\n )}\n </div>\n );\n}\n\nfunction ModelThinkingControls(props: ModelPolicyPickerProps) {\n const selected = findPickerRow(effectiveRows(props), props.model);\n if (!selected) return null;\n const efforts = effortOptionsForModel(selected.catalog);\n const messages = { ...defaultModelPolicyPickerMessages, ...props.messages };\n const supportsFast = runnableLatencyModesForModel(selected.catalog).includes(\"fast\");\n const showThinking =\n efforts.length > 1 && selected.catalog.capabilities?.reasoning.runnable !== false;\n const showFast = supportsFast && props.allowLatencyMode !== false;\n if (!showThinking && !showFast) return null;\n return (\n <div className=\"space-y-2 text-og-control\" data-testid=\"model-picker-reasoning\">\n <div className=\"flex min-h-7 items-center justify-between gap-3\">\n {showThinking ? <span className=\"text-og-fg-subtle\">{messages.thinking}</span> : <span />}\n {showFast ? (\n <button\n type=\"button\"\n data-testid=\"model-picker-fast\"\n disabled={props.disabled || !selected.selectable}\n aria-pressed={props.latencyMode === \"fast\"}\n title={messages.fast + \" · \" + messages.fastRateHint}\n onClick={() =>\n props.onLatencyModeChange(props.latencyMode === \"fast\" ? \"standard\" : \"fast\")\n }\n className=\"flex min-h-8 shrink-0 items-center gap-1.5 whitespace-nowrap rounded-og-sm px-2 text-og-fg-muted hover:bg-og-surface-2 focus-visible:ring-2 focus-visible:ring-og-accent/40 disabled:opacity-50\"\n >\n <ZapIcon className={cn(\"size-3.5\", props.latencyMode === \"fast\" && \"fill-current\")} />\n {messages.fast}\n <span className=\"text-og-fg-subtle\">{messages.fastRateHint}</span>\n </button>\n ) : null}\n </div>\n {showThinking ? (\n <RadioGroup.Root\n aria-label={messages.thinkingEffort}\n value={coerceReasoningEffortForModel(selected.catalog, props.effort)}\n disabled={props.disabled || !selected.selectable}\n onValueChange={(value) => props.onEffortChange(value as ReasoningEffort)}\n orientation=\"horizontal\"\n className=\"flex flex-wrap gap-0.5 rounded-og-md bg-og-surface-2 p-0.5\"\n >\n {efforts.map((effort) => (\n <RadioGroup.Item\n key={effort}\n value={effort}\n aria-label={labelReasoningEffort(effort)}\n title={labelReasoningEffort(effort)}\n className=\"min-h-8 min-w-10 flex-1 cursor-pointer whitespace-nowrap rounded-og-sm px-1.5 text-og-control text-og-fg-muted outline-hidden transition-colors hover:text-og-fg focus-visible:ring-2 focus-visible:ring-og-accent/40 data-[state=checked]:bg-og-surface-1 data-[state=checked]:text-og-fg data-[state=checked]:shadow-sm disabled:cursor-not-allowed disabled:opacity-50\"\n >\n {effort === \"xhigh\" ? \"X-high\" : labelReasoningEffort(effort)}\n </RadioGroup.Item>\n ))}\n </RadioGroup.Root>\n ) : null}\n </div>\n );\n}\n\nexport function ModelPolicyPickerPopover(\n props: ModelPolicyPickerProps & {\n anchor: RefObject<HTMLButtonElement | null>;\n contentId: string;\n portalStyle: CSSProperties;\n },\n) {\n const outside = useRef(false);\n const messages = { ...defaultModelPolicyPickerMessages, ...props.messages };\n return (\n <Popover.Root open onOpenChange={(open) => props.onOpenChange?.(open)}>\n <Popover.Anchor virtualRef={props.anchor} />\n <Popover.Portal>\n <Popover.Content\n id={props.contentId}\n aria-label={messages.label}\n align=\"start\"\n side={props.menuSide ?? \"bottom\"}\n sideOffset={8}\n collisionPadding={12}\n onInteractOutside={(event) => {\n if (props.anchor.current?.contains(event.target as Node)) event.preventDefault();\n else outside.current = true;\n }}\n onCloseAutoFocus={(event) => {\n event.preventDefault();\n if (!outside.current) props.anchor.current?.focus();\n }}\n className={cn(\n \"og-root og-model-policy-menu z-50 flex max-h-[min(32rem,var(--radix-popover-content-available-height))] w-[22rem] max-w-[calc(100vw-16px)] flex-col overflow-hidden rounded-og-lg border border-og-border bg-og-surface-1 p-[var(--og-model-picker-menu-padding)] text-og-fg shadow-og-lg\",\n props.contentClassName,\n )}\n style={{ ...props.portalStyle, ...props.contentStyle }}\n data-testid=\"model-picker-content\"\n >\n <ModelPolicyPickerMenu {...props} />\n </Popover.Content>\n </Popover.Portal>\n </Popover.Root>\n );\n}\n"],"mappings":"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","names":[]}
@@ -19,6 +19,8 @@ export type MarkdownInteractiveBlock = {
19
19
  content: string;
20
20
  };
21
21
  export type MarkdownProps = {
22
+ /** Resolve a retained-file reference to the host's authenticated artifact page. */
23
+ artifactHref?: ((artifactId: string) => string) | undefined;
22
24
  /** Reveals a bounded source excerpt; closing Find retains it until explicit restore. */
23
25
  searchTarget?: TimelineSearchTarget | null | undefined;
24
26
  renderImage?: ((image: {
@@ -2,10 +2,21 @@ import type { ClientModel, LatencyMode, ReasoningEffort } from "@opengeni/sdk";
2
2
  import { type CSSProperties, type ReactNode } from "react";
3
3
  import { type PickerBillingClass, type PickerModelRow } from "../model-policy.js";
4
4
  type ClientPickerModelRow = PickerModelRow<ClientModel>;
5
+ /** Presentation only; never changes model identity, billing or availability. */
6
+ export type ModelPolicyPickerGroupPresentation = Partial<Record<PickerBillingClass, {
7
+ label?: string | undefined;
8
+ /** Omit to preserve the default; null hides the supporting text. */
9
+ description?: string | null | undefined;
10
+ /** Decorative, non-interactive content. Omit for the default; null hides it. */
11
+ icon?: ReactNode | undefined;
12
+ }>>;
5
13
  export type ModelPolicyPickerMessages = {
6
14
  label: string;
7
15
  loading: string;
8
16
  noModels: string;
17
+ connectTitle: string;
18
+ connectBody: string;
19
+ connectAction: string;
9
20
  thinking: string;
10
21
  fast: string;
11
22
  fastRateHint: string;
@@ -22,6 +33,8 @@ export type ModelPolicyPickerMessages = {
22
33
  };
23
34
  export declare const defaultModelPolicyPickerMessages: ModelPolicyPickerMessages;
24
35
  export type ModelPolicyPickerProps = {
36
+ /** Host branding for payment-source groups, shared by menu and trigger. */
37
+ groupPresentation?: ModelPolicyPickerGroupPresentation | undefined;
25
38
  /** Lightweight deployment models. Catalog rows take precedence when supplied. */
26
39
  models?: ClientModel[] | undefined;
27
40
  /** Warn only when the draft actually contains images this model cannot view. */
@@ -47,6 +60,8 @@ export type ModelPolicyPickerProps = {
47
60
  menuSide?: "top" | "bottom" | undefined;
48
61
  /** Hide latency controls on surfaces whose saved policy does not include latency. */
49
62
  allowLatencyMode?: boolean | undefined;
63
+ /** Settings → Models. Shown when the catalog has no model that can run. */
64
+ connectModelsHref?: string | undefined;
50
65
  /** Classes for the portalled menu surface. Prefer --og-* tokens for theming. */
51
66
  contentClassName?: string | undefined;
52
67
  /** Inline styles for the portalled menu, applied after inherited --og-* tokens. */
@@ -59,9 +74,10 @@ export type ModelPolicyPickerProps = {
59
74
  };
60
75
  export declare function BillingClassMark(props: {
61
76
  billingClass: PickerBillingClass;
77
+ presentation?: ModelPolicyPickerGroupPresentation[PickerBillingClass] | undefined;
62
78
  className?: string | undefined;
63
79
  "aria-label"?: string | undefined;
64
- }): import("react").JSX.Element;
80
+ }): import("react").JSX.Element | null;
65
81
  export declare function effectiveRows(props: ModelPolicyPickerProps): ClientPickerModelRow[];
66
82
  export declare function PickerNavRow(props: {
67
83
  label: string;
@@ -2,9 +2,12 @@ import { type CSSProperties } from "react";
2
2
  import { type ClientOverride } from "../session-context.js";
3
3
  import { type ChatComposerProps } from "./chat-composer.js";
4
4
  import { type HumanInputSurfaceProps } from "./human-input-surface.js";
5
+ import { type MessageTimelineProps } from "./message-timeline.js";
5
6
  import type { UserMessageDisclosureLabels } from "./user-message-body.js";
6
7
  export type SessionConversationProps = ClientOverride & {
7
8
  sessionId: string;
9
+ /** Host-owned artifact links, previews and other message presentation. */
10
+ renderMessageText?: MessageTimelineProps["renderMessageText"];
8
11
  /** Localized actions for already-sent user-message disclosure. */
9
12
  userMessageDisclosureLabels?: UserMessageDisclosureLabels | undefined;
10
13
  loadSkillReview?: HumanInputSurfaceProps["loadSkillReview"];
@@ -5,7 +5,7 @@
5
5
  */
6
6
  export { OPEN_WORKSTREAM_CONTROL_EVENT } from "./workstream-control-event.js";
7
7
  export { BillingClassMark, ModelPolicyPicker, PickerAnimatedPage, PickerBackHeader, PickerNavRow, defaultModelPolicyPickerMessages, } from "./components/model-policy-picker.js";
8
- export type { ModelPolicyPickerMessages, ModelPolicyPickerProps, } from "./components/model-policy-picker.js";
8
+ export type { ModelPolicyPickerMessages, ModelPolicyPickerProps, ModelPolicyPickerGroupPresentation, } from "./components/model-policy-picker.js";
9
9
  export { Actions, AttachButton, Attachments, CommandPalette, Confirmation, Controls, Footer, Frame, Help, Hint, Input, ModelPicker, PauseButton, PausedState, RestoredResources, Root, SendButton, Status, Surface, defaultChatComposerMessages, useChatComposer, useChatComposerController, } from "./components/composer.js";
10
10
  export type { ChatComposerController, ChatComposerContextValue, ChatComposerMessages, ComposerActionsProps, ComposerAttachButtonProps, ComposerCommandPaletteProps, ComposerControlLinks, ComposerControlState, ComposerControlsProps, ComposerDelivery, ComposerDraftState, ComposerFooterProps, ComposerFrameProps, ComposerHintProps, ComposerInputProps, ComposerModelPickerProps, ComposerPauseButtonProps, ComposerRootProps, ComposerSendButtonProps, ComposerSubmitBlocker, ComposerSubmitMode, ComposerSurfaceProps, ResponsiveBasis, UseChatComposerControllerOptions, } from "./components/composer.js";
11
11
  export { ComposerTranscriptionControl } from "./components/composer-transcription-control.js";
package/dist/composer.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  ModelPolicyPickerMenu
3
- } from "./chunk-HJ5VJ4JB.js";
3
+ } from "./chunk-ZA4K7YY2.js";
4
4
  import {
5
5
  Actions,
6
6
  AttachButton,
@@ -40,7 +40,7 @@ import {
40
40
  useChatComposer,
41
41
  useChatComposerController,
42
42
  useVoiceInput
43
- } from "./chunk-UXE5SSNN.js";
43
+ } from "./chunk-U56XI627.js";
44
44
  import "./chunk-BRM6FVZA.js";
45
45
  import {
46
46
  BillingClassMark,
@@ -49,13 +49,13 @@ import {
49
49
  PickerBackHeader,
50
50
  PickerNavRow,
51
51
  defaultModelPolicyPickerMessages
52
- } from "./chunk-IP4BUBKH.js";
52
+ } from "./chunk-TA4W6KBP.js";
53
53
  import "./chunk-VZTQ73XT.js";
54
54
  import "./chunk-AKOMC3VO.js";
55
55
  import "./chunk-KZ73RL76.js";
56
56
  import "./chunk-PLYRL5ER.js";
57
57
  import "./chunk-NEXLLTP4.js";
58
- import "./chunk-5GAL23FF.js";
58
+ import "./chunk-IOLPHOF4.js";
59
59
  import "./chunk-22KP6LR5.js";
60
60
  export {
61
61
  Actions,
package/dist/connect.js CHANGED
@@ -6,7 +6,7 @@ import {
6
6
  } from "./chunk-5UONOQ3Y.js";
7
7
  import {
8
8
  Markdown
9
- } from "./chunk-D7GAPJ3V.js";
9
+ } from "./chunk-RAJYEBEG.js";
10
10
  import "./chunk-2VHARTBL.js";
11
11
  import {
12
12
  copyTextToClipboard
@@ -69,7 +69,7 @@ export type UseSessionEventsResult = {
69
69
  error: Error | null;
70
70
  };
71
71
  export declare const SESSION_EVENT_BROWSER_MAX_BYTES: number;
72
- export declare const SESSION_EVENT_BROWSER_MAX_COUNT = 10000;
72
+ export declare const SESSION_EVENT_BROWSER_MAX_COUNT = 200000;
73
73
  export declare const SESSION_EVENT_BROWSER_PENDING_MAX_BYTES: number;
74
74
  export declare const SESSION_EVENT_BROWSER_PENDING_MAX_COUNT = 256;
75
75
  export type BrowserSessionEventWindow = {
@@ -98,3 +98,8 @@ export declare function boundBrowserSessionEventWindow(events: readonly SessionE
98
98
  maxCount?: number;
99
99
  direction?: "newest" | "oldest";
100
100
  }): BrowserSessionEventWindow;
101
+ /** @internal Append immutable events without serializing the retained history again. */
102
+ export declare function appendBrowserSessionEventWindow(current: BrowserSessionEventWindow, batch: readonly SessionEvent[], options?: {
103
+ maxBytes?: number;
104
+ maxCount?: number;
105
+ }): BrowserSessionEventWindow;
package/dist/index.d.ts CHANGED
@@ -128,7 +128,7 @@ export { ModelPicker } from "./components/model-picker.js";
128
128
  export type { ModelPickerProps } from "./components/model-picker.js";
129
129
  export { BillingClassMark, ModelPolicyPicker, PickerAnimatedPage, PickerBackHeader, PickerNavRow, defaultModelPolicyPickerMessages, } from "./components/model-policy-picker.js";
130
130
  export { ModelPolicyPickerMenu } from "./components/model-policy-picker-menu.js";
131
- export type { ModelPolicyPickerMessages, ModelPolicyPickerProps, } from "./components/model-policy-picker.js";
131
+ export type { ModelPolicyPickerMessages, ModelPolicyPickerProps, ModelPolicyPickerGroupPresentation, } from "./components/model-policy-picker.js";
132
132
  export { advancedSourceSummary, availabilityReasonLabel, billingClassForModel, billingClassLabel, coerceReasoningEffortForModel, defaultEffortForModel, effortOptionsForModel, findPickerRow, groupPickerRowsByBillingClass, labelLatencyMode, labelReasoningEffort, payerSummaryForModel, modelUsesCredits, projectClientModelRows, projectPickerRows, runnableLatencyModesForModel, sortPickerRows, } from "./model-policy.js";
133
133
  export type { LatencyModeId, PickerBillingClass, PickerModelRow } from "./model-policy.js";
134
134
  export { MessageTimeline, TimelineRow } from "./components/message-timeline.js";
package/dist/index.js CHANGED
@@ -28,7 +28,7 @@ import {
28
28
  healthPulses,
29
29
  pointsFor,
30
30
  useMachines
31
- } from "./chunk-JPHDWKZE.js";
31
+ } from "./chunk-X7YDBAQD.js";
32
32
  import {
33
33
  McpConnectionCard,
34
34
  SessionCapabilityFrame,
@@ -51,7 +51,7 @@ import {
51
51
  } from "./chunk-5YK2ZDIG.js";
52
52
  import {
53
53
  ModelPolicyPickerMenu
54
- } from "./chunk-HJ5VJ4JB.js";
54
+ } from "./chunk-ZA4K7YY2.js";
55
55
  import {
56
56
  ActivityRail,
57
57
  ApprovalSurface,
@@ -108,7 +108,7 @@ import {
108
108
  useWorkspaceModelCatalog,
109
109
  userMessageLikelyNeedsDisclosure,
110
110
  v4aToGitFileDiff
111
- } from "./chunk-D5NOQPLR.js";
111
+ } from "./chunk-CJCVYUKK.js";
112
112
  import "./chunk-GEN54DU5.js";
113
113
  import "./chunk-GBPCZH3Y.js";
114
114
  import "./chunk-ZYRGEKWS.js";
@@ -132,7 +132,7 @@ import {
132
132
  retainedImageId,
133
133
  sandboxFileLocationFromHref,
134
134
  sandboxFilePathFromHref
135
- } from "./chunk-D7GAPJ3V.js";
135
+ } from "./chunk-RAJYEBEG.js";
136
136
  import "./chunk-2VHARTBL.js";
137
137
  import {
138
138
  copyTextToClipboard,
@@ -170,7 +170,7 @@ import {
170
170
  useSlashCommands,
171
171
  useTranscription,
172
172
  useVoiceInput
173
- } from "./chunk-UXE5SSNN.js";
173
+ } from "./chunk-U56XI627.js";
174
174
  import {
175
175
  LightboxProvider,
176
176
  Tooltip,
@@ -188,7 +188,7 @@ import {
188
188
  PickerBackHeader,
189
189
  PickerNavRow,
190
190
  defaultModelPolicyPickerMessages
191
- } from "./chunk-IP4BUBKH.js";
191
+ } from "./chunk-TA4W6KBP.js";
192
192
  import {
193
193
  usePortalTokenSource,
194
194
  usePortalTokenStyle
@@ -205,7 +205,7 @@ import {
205
205
  useSessionControl,
206
206
  useSessionLineage,
207
207
  useSessionMcpApprovalPolicy
208
- } from "./chunk-IYUPN32E.js";
208
+ } from "./chunk-DBPVUGQT.js";
209
209
  import {
210
210
  SESSION_EVENT_BROWSER_MAX_BYTES,
211
211
  SESSION_EVENT_BROWSER_MAX_COUNT,
@@ -229,7 +229,7 @@ import {
229
229
  useSession,
230
230
  useSessionEvents,
231
231
  useTurnQueue
232
- } from "./chunk-JKLGJQO5.js";
232
+ } from "./chunk-HJDDS2L6.js";
233
233
  import {
234
234
  FILE_ONLY_MESSAGE_TEXT,
235
235
  composeSendInput,
@@ -279,7 +279,7 @@ import {
279
279
  projectPickerRows,
280
280
  runnableLatencyModesForModel,
281
281
  sortPickerRows
282
- } from "./chunk-5GAL23FF.js";
282
+ } from "./chunk-IOLPHOF4.js";
283
283
  import {
284
284
  cn
285
285
  } from "./chunk-22KP6LR5.js";
@@ -455,7 +455,7 @@ function policyFromTurn(turn) {
455
455
  };
456
456
  }
457
457
  function useLastStartedTurnPolicy(sessionId, options = {}) {
458
- const { client, workspaceId, workspaceControlEvent, registerSessionReconciler } = useOpenGeni(options);
458
+ const { client, workspaceId, registerSessionReconciler } = useOpenGeni(options);
459
459
  const enabled = (options.enabled ?? true) && Boolean(sessionId);
460
460
  const load = useCallback(
461
461
  async (signal) => {
@@ -472,9 +472,6 @@ function useLastStartedTurnPolicy(sessionId, options = {}) {
472
472
  pollIntervalMs: options.pollIntervalMs,
473
473
  enabled
474
474
  });
475
- useEffect2(() => {
476
- if (enabled && workspaceControlEvent) void refresh();
477
- }, [enabled, refresh, workspaceControlEvent]);
478
475
  useEffect2(() => {
479
476
  if (!sessionId || !enabled) return;
480
477
  return registerSessionReconciler(sessionId, "last-started-turn-policy", refresh);