@opengeni/react 7.6.1 → 7.7.0-canary.37111190284001

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 (145) hide show
  1. package/README.md +47 -2
  2. package/dist/{browser-viewer-5X47I6T2.js → browser-viewer-63TXMINB.js} +6 -5
  3. package/dist/{chunk-5EXGU7UF.js → chunk-55DDDVKU.js} +3 -3
  4. package/dist/{chunk-UINDK6C3.js → chunk-7CYYXWHU.js} +5 -8
  5. package/dist/chunk-7CYYXWHU.js.map +1 -0
  6. package/dist/{chunk-LZ3KHA55.js → chunk-A2L5N3EI.js} +332 -339
  7. package/dist/chunk-A2L5N3EI.js.map +1 -0
  8. package/dist/{chunk-KGENSZKS.js → chunk-AAG4R3QN.js} +4 -3
  9. package/dist/chunk-AAG4R3QN.js.map +1 -0
  10. package/dist/{chunk-Z3DISEQN.js → chunk-CWWKTNKK.js} +35 -18
  11. package/dist/chunk-CWWKTNKK.js.map +1 -0
  12. package/dist/{chunk-WZ55DVGK.js → chunk-ELCE5SXV.js} +8 -4
  13. package/dist/chunk-ELCE5SXV.js.map +1 -0
  14. package/dist/{chunk-YSMMDOOE.js → chunk-GISEVGS6.js} +10 -2
  15. package/dist/chunk-GISEVGS6.js.map +1 -0
  16. package/dist/{chunk-BI57CQUV.js → chunk-I7IWRQLN.js} +2 -2
  17. package/dist/{chunk-XA6R7DJQ.js → chunk-IQUCRAT7.js} +3 -3
  18. package/dist/{chunk-CHPKSLPN.js → chunk-NBZ64YY7.js} +4 -2
  19. package/dist/chunk-NBZ64YY7.js.map +1 -0
  20. package/dist/{chunk-DV2DBNPQ.js → chunk-Q5QBEZIQ.js} +48 -29
  21. package/dist/chunk-Q5QBEZIQ.js.map +1 -0
  22. package/dist/{chunk-FGBCYQOT.js → chunk-RDKBXMWX.js} +120 -74
  23. package/dist/chunk-RDKBXMWX.js.map +1 -0
  24. package/dist/{chunk-45GE35O7.js → chunk-TKB4SB44.js} +10 -2
  25. package/dist/chunk-TKB4SB44.js.map +1 -0
  26. package/dist/{chunk-YCGBREUV.js → chunk-TOAH2BKA.js} +6 -2
  27. package/dist/{chunk-YCGBREUV.js.map → chunk-TOAH2BKA.js.map} +1 -1
  28. package/dist/chunk-UGLEYEMP.js +33 -0
  29. package/dist/chunk-UGLEYEMP.js.map +1 -0
  30. package/dist/{chunk-UJRYEWZI.js → chunk-UTRTG6LH.js} +48 -8
  31. package/dist/chunk-UTRTG6LH.js.map +1 -0
  32. package/dist/{chunk-YRYF2GLG.js → chunk-WYVLAAJA.js} +39 -31
  33. package/dist/chunk-WYVLAAJA.js.map +1 -0
  34. package/dist/{chunk-VGIKFIO2.js → chunk-XOAMRDDK.js} +6 -3
  35. package/dist/chunk-XOAMRDDK.js.map +1 -0
  36. package/dist/{chunk-6NEZPF53.js → chunk-YN7I3STW.js} +153 -32
  37. package/dist/chunk-YN7I3STW.js.map +1 -0
  38. package/dist/{chunk-KZ73RL76.js → chunk-YQEAA6LT.js} +7 -3
  39. package/dist/chunk-YQEAA6LT.js.map +1 -0
  40. package/dist/client.d.ts +4 -1
  41. package/dist/commands/types.d.ts +2 -0
  42. package/dist/components/approval-surface.d.ts +15 -0
  43. package/dist/components/session-conversation.d.ts +3 -0
  44. package/dist/composer.js +8 -7
  45. package/dist/{computer-viewer-7GF35SNY.js → computer-viewer-X2MBRZY4.js} +5 -4
  46. package/dist/connect.js +3 -3
  47. package/dist/hooks/use-browser-session.d.ts +4 -0
  48. package/dist/hooks/use-composer.d.ts +2 -0
  49. package/dist/hooks/use-computer-session.d.ts +2 -0
  50. package/dist/hooks/use-file-attachments.d.ts +2 -0
  51. package/dist/hooks/use-session-events.d.ts +1 -1
  52. package/dist/hooks/use-workspace-sessions.d.ts +15 -5
  53. package/dist/index.d.ts +2 -2
  54. package/dist/index.js +28 -21
  55. package/dist/index.js.map +1 -1
  56. package/dist/interaction.d.ts +1 -1
  57. package/dist/interaction.js +6 -5
  58. package/dist/interaction.js.map +1 -1
  59. package/dist/{latest-question-3BJGKQQ6.js → latest-question-CNEZ5KAN.js} +3 -3
  60. package/dist/lib/error-message.d.ts +7 -0
  61. package/dist/lib/format.d.ts +27 -3
  62. package/dist/lib/interaction-errors.d.ts +3 -0
  63. package/dist/machines.js +5 -4
  64. package/dist/{model-policy-picker-menu-PUTA5JOB.js → model-policy-picker-menu-GN2LTB7Z.js} +4 -4
  65. package/dist/model-policy.js +1 -1
  66. package/dist/provider.d.ts +5 -1
  67. package/dist/{queue-surface-implementation-2CAQAIHM.js → queue-surface-implementation-HENWYFWA.js} +3 -2
  68. package/dist/{queue-surface-implementation-2CAQAIHM.js.map → queue-surface-implementation-HENWYFWA.js.map} +1 -1
  69. package/dist/realtime.js +2 -2
  70. package/dist/{sandbox-files-AEJTWGT4.js → sandbox-files-BBC47SLD.js} +4 -3
  71. package/dist/session-ui.d.ts +1 -1
  72. package/dist/session-ui.js +13 -12
  73. package/dist/session-ui.js.map +1 -1
  74. package/dist/session.js +7 -6
  75. package/dist/usage.js +2 -1
  76. package/dist/usage.js.map +1 -1
  77. package/package.json +3 -3
  78. package/src/client.ts +5 -1
  79. package/src/commands/registry.ts +18 -15
  80. package/src/commands/types.ts +2 -0
  81. package/src/components/approval-surface.tsx +166 -42
  82. package/src/components/browser-viewer.tsx +38 -9
  83. package/src/components/composer.tsx +9 -2
  84. package/src/components/computer-viewer.tsx +160 -30
  85. package/src/components/generated-video-player.tsx +4 -2
  86. package/src/components/human-input-form.tsx +18 -5
  87. package/src/components/message-timeline.tsx +120 -168
  88. package/src/components/model-policy-picker.tsx +2 -15
  89. package/src/components/open-geni-chat.tsx +11 -4
  90. package/src/components/queue-surface-state.tsx +3 -1
  91. package/src/components/session-chrome.tsx +5 -2
  92. package/src/components/session-commands-panel.tsx +3 -1
  93. package/src/components/session-conversation.tsx +10 -3
  94. package/src/components/session-list.tsx +7 -5
  95. package/src/components/session-mcp-capability-card.tsx +11 -1
  96. package/src/hooks/internal.ts +3 -2
  97. package/src/hooks/use-browser-session.ts +115 -79
  98. package/src/hooks/use-composer.ts +70 -31
  99. package/src/hooks/use-computer-session.ts +57 -6
  100. package/src/hooks/use-file-attachments.ts +16 -3
  101. package/src/hooks/use-goal.ts +2 -1
  102. package/src/hooks/use-session-capabilities.ts +3 -2
  103. package/src/hooks/use-session-events.ts +15 -8
  104. package/src/hooks/use-slash-commands.ts +6 -11
  105. package/src/hooks/use-turn-queue.ts +2 -1
  106. package/src/hooks/use-workspace-sessions.ts +40 -7
  107. package/src/index.ts +7 -2
  108. package/src/interaction.ts +1 -0
  109. package/src/lib/error-message.ts +37 -0
  110. package/src/lib/format.ts +73 -9
  111. package/src/lib/interaction-errors.ts +15 -0
  112. package/src/model-policy.ts +6 -1
  113. package/src/provider.tsx +12 -4
  114. package/src/session-ui.ts +1 -1
  115. package/src/timeline/projection.ts +12 -1
  116. package/styles/compiled.css +14 -30
  117. package/dist/chunk-45GE35O7.js.map +0 -1
  118. package/dist/chunk-6NEZPF53.js.map +0 -1
  119. package/dist/chunk-CHPKSLPN.js.map +0 -1
  120. package/dist/chunk-DV2DBNPQ.js.map +0 -1
  121. package/dist/chunk-FGBCYQOT.js.map +0 -1
  122. package/dist/chunk-KGENSZKS.js.map +0 -1
  123. package/dist/chunk-KZ73RL76.js.map +0 -1
  124. package/dist/chunk-LZ3KHA55.js.map +0 -1
  125. package/dist/chunk-UINDK6C3.js.map +0 -1
  126. package/dist/chunk-UJRYEWZI.js.map +0 -1
  127. package/dist/chunk-VGIKFIO2.js.map +0 -1
  128. package/dist/chunk-WZ55DVGK.js.map +0 -1
  129. package/dist/chunk-YRYF2GLG.js.map +0 -1
  130. package/dist/chunk-YSMMDOOE.js.map +0 -1
  131. package/dist/chunk-Z3DISEQN.js.map +0 -1
  132. package/dist/components/timeline-pill-geometry.d.ts +0 -8
  133. package/dist/components/timeline-pill-placement.d.ts +0 -24
  134. package/dist/timeline-pill-geometry-Z23V243M.js +0 -110
  135. package/dist/timeline-pill-geometry-Z23V243M.js.map +0 -1
  136. package/src/components/timeline-pill-geometry.ts +0 -169
  137. package/src/components/timeline-pill-placement.ts +0 -99
  138. /package/dist/{browser-viewer-5X47I6T2.js.map → browser-viewer-63TXMINB.js.map} +0 -0
  139. /package/dist/{chunk-5EXGU7UF.js.map → chunk-55DDDVKU.js.map} +0 -0
  140. /package/dist/{chunk-BI57CQUV.js.map → chunk-I7IWRQLN.js.map} +0 -0
  141. /package/dist/{chunk-XA6R7DJQ.js.map → chunk-IQUCRAT7.js.map} +0 -0
  142. /package/dist/{computer-viewer-7GF35SNY.js.map → computer-viewer-X2MBRZY4.js.map} +0 -0
  143. /package/dist/{latest-question-3BJGKQQ6.js.map → latest-question-CNEZ5KAN.js.map} +0 -0
  144. /package/dist/{model-policy-picker-menu-PUTA5JOB.js.map → model-policy-picker-menu-GN2LTB7Z.js.map} +0 -0
  145. /package/dist/{sandbox-files-AEJTWGT4.js.map → sandbox-files-BBC47SLD.js.map} +0 -0
package/README.md CHANGED
@@ -605,6 +605,11 @@ explicit activation brings a tab forward. The override ends when its controller
605
605
  detaches. Native **App controls** also work in the background where supported.
606
606
  Physical desktop mouse/keyboard input shares the foreground seat; **Bring to front**
607
607
  makes that change explicit.
608
+ Computer frames fit the dock while preserving their proportions. Resizing or
609
+ reopening the dock refits the visible image without changing capture resolution
610
+ or the coordinates sent to the computer.
611
+
612
+ Desktop IME candidates and their selection keys stay local; only committed text is sent.
608
613
 
609
614
  A managed browser's attachment authority error keeps a same-browser **Reconnect**
610
615
  action available. It obtains a fresh server-authorized attachment without creating
@@ -651,6 +656,12 @@ returned ComputerSession must be the exact placement/window the browser uses.
651
656
  `onOpenComputer` then changes the host layout to that resource—it must not open a
652
657
  lookalike desktop. Closing either viewer never ends its durable resource.
653
658
 
659
+ `ComputerViewer` disables input when its control service is unavailable, even if
660
+ frames keep arriving. Reconnect refreshes the selected desktop's controls and
661
+ frames. App accessibility inspection failures leave independent live input
662
+ available; `useComputerSession().controlError` reports service loss separately
663
+ from the hook's general `error`.
664
+
654
665
  If the chat's latest browser was lost or failed, the viewer names it and explains
655
666
  why it is unavailable instead of showing the ordinary empty state. It offers the
656
667
  existing new-browser controls without reopening the lost controller or selecting
@@ -774,7 +785,8 @@ state remains application-owned; durable draft and session state remain in
774
785
 
775
786
  - `useSessionEvents(sessionId)` — loads a compact, bounded tail window by
776
787
  default, then live-streams on the SDK's exactly-once/ordered event delivery.
777
- Initial replay is capped at three 5000-row raw pages and `loadOlder` at two;
788
+ Initial replay reads one 1000-row raw page, with at most one extra page to
789
+ recover a dense turn's boundary; `loadOlder` is capped at two such pages;
778
790
  timeline group density is only an early stop. It returns the raw windowed
779
791
  `events`, projected `timeline`, latest `sessionStatus`, connection state, and
780
792
  older-history controls (`hasOlder`, `loadingOlder`, `loadOlder`). Pass
@@ -789,6 +801,8 @@ state remains application-owned; durable draft and session state remain in
789
801
  window.
790
802
  - Browser retention limits are exported as `SESSION_EVENT_BROWSER_MAX_BYTES`
791
803
  and `SESSION_EVENT_BROWSER_MAX_COUNT`; they do not change fetch page sizes.
804
+ The live working set is at most 16 MiB or 20,000 events. One event larger than
805
+ the byte target stays complete in a window of its own.
792
806
  Live appends reuse the retained window's byte total, measuring only incoming
793
807
  and evicted events. History still pages when either retention limit is reached.
794
808
  - Newer history uses `hasNewer`, `loadingNewer`, and `loadNewer`. A failed
@@ -845,7 +859,10 @@ state remains application-owned; durable draft and session state remain in
845
859
  - `useSlashCommands(...)` — the slash-command palette state (registry + parsing +
846
860
  handlers) behind `CommandPalette`.
847
861
  - `useWorkspaceSessions()` / `useScheduledTasks()` — workspace lists for
848
- fleet/manager views (optional polling).
862
+ fleet/manager views (optional polling). `useWorkspaceSessions({ projection:
863
+ "summary" })` returns compact list entries; omit the option for full sessions.
864
+ Scripted clients can omit the summary method and the hook projects full pages
865
+ locally while retaining cancellation and causal read revisions.
849
866
  - `useVariableSets()` — workspace variable sets with metadata-only generic
850
867
  reads and create/update/remove/set/delete operations. Dedicated permissioned
851
868
  exact-value reveal is part of the held React/UI train rather than an
@@ -1256,6 +1273,11 @@ can translate its search, current-selection, empty-result, attachment-warning, a
1256
1273
  thinking labels through `messages`, and override payment descriptions through
1257
1274
  `messages.billingHints`.
1258
1275
 
1276
+ The stock deployment-provided group is labeled **Models**, with a generic model
1277
+ icon. It can contain both credit-backed and free models; the **Free** badge
1278
+ depends on the model's explicit cost, not its group. Genuine external-provider
1279
+ and subscription identities retain their own labels and marks.
1280
+
1259
1281
  Hosts can rebrand the full picker without replacing its interaction logic:
1260
1282
 
1261
1283
  ```tsx
@@ -1284,6 +1306,29 @@ are unchanged. The type `ModelPolicyPickerGroupPresentation` is exported from
1284
1306
  both `@opengeni/react` and `@opengeni/react/composer`. The native `ModelPicker`
1285
1307
  is a separate control; this API targets the full `ModelPolicyPicker` shown above.
1286
1308
 
1309
+ The complete conversation uses this same neutral picker. Customize its appearance
1310
+ without replacing composer controls through `SessionConversation.modelPickerProps`,
1311
+ or through `OpenGeniChat.conversationProps`:
1312
+
1313
+ ```tsx
1314
+ <OpenGeniChat
1315
+ client={client}
1316
+ workspaceId={workspaceId}
1317
+ conversationProps={{
1318
+ modelPickerProps: {
1319
+ groupPresentation: {
1320
+ opengeni_credits: { label: "Acme Assist", icon: <AcmeMark aria-hidden="true" /> },
1321
+ },
1322
+ messages: { label: "Choose a model" },
1323
+ },
1324
+ }}
1325
+ />
1326
+ ```
1327
+
1328
+ `modelPickerProps` accepts only `groupPresentation` and `messages`; it does not
1329
+ enable a hidden picker or change policy, model availability or callbacks. Keep
1330
+ model-picker visibility controlled by `modelPicker` and the client configuration.
1331
+
1287
1332
  For a rendered example, open the composer-responsive demo with `?branding=host`.
1288
1333
 
1289
1334
  Subscription descriptions appear once per provider group. Free models carry a
@@ -1,15 +1,16 @@
1
1
  import {
2
2
  BrowserViewer
3
- } from "./chunk-FGBCYQOT.js";
4
- import "./chunk-YSMMDOOE.js";
3
+ } from "./chunk-RDKBXMWX.js";
4
+ import "./chunk-GISEVGS6.js";
5
5
  import "./chunk-JVYQRRC4.js";
6
6
  import "./chunk-RHREZ7BO.js";
7
- import "./chunk-UJRYEWZI.js";
7
+ import "./chunk-UTRTG6LH.js";
8
8
  import "./chunk-5J4FOW6Q.js";
9
- import "./chunk-KZ73RL76.js";
9
+ import "./chunk-YQEAA6LT.js";
10
+ import "./chunk-UGLEYEMP.js";
10
11
  import "./chunk-NEXLLTP4.js";
11
12
  import "./chunk-22KP6LR5.js";
12
13
  export {
13
14
  BrowserViewer
14
15
  };
15
- //# sourceMappingURL=browser-viewer-5X47I6T2.js.map
16
+ //# sourceMappingURL=browser-viewer-63TXMINB.js.map
@@ -3,7 +3,7 @@ import {
3
3
  PickerNavRow,
4
4
  defaultModelPolicyPickerMessages,
5
5
  effectiveRows
6
- } from "./chunk-UINDK6C3.js";
6
+ } from "./chunk-7CYYXWHU.js";
7
7
  import {
8
8
  MENU_CHECK_CLASS,
9
9
  MENU_LABEL_CLASS,
@@ -18,7 +18,7 @@ import {
18
18
  labelReasoningEffort,
19
19
  payerSummaryForModel,
20
20
  runnableLatencyModesForModel
21
- } from "./chunk-CHPKSLPN.js";
21
+ } from "./chunk-NBZ64YY7.js";
22
22
  import {
23
23
  cn
24
24
  } from "./chunk-22KP6LR5.js";
@@ -305,4 +305,4 @@ export {
305
305
  ModelPolicyPickerMenu,
306
306
  ModelPolicyPickerPopover
307
307
  };
308
- //# sourceMappingURL=chunk-5EXGU7UF.js.map
308
+ //# sourceMappingURL=chunk-55DDDVKU.js.map
@@ -6,7 +6,7 @@ import {
6
6
  findPickerRow,
7
7
  labelReasoningEffort,
8
8
  projectClientModelRows
9
- } from "./chunk-CHPKSLPN.js";
9
+ } from "./chunk-NBZ64YY7.js";
10
10
  import {
11
11
  usePortalTokenSource,
12
12
  usePortalTokenStyle
@@ -47,7 +47,7 @@ import {
47
47
  } from "react";
48
48
  import { Fragment, jsx as jsx3, jsxs } from "react/jsx-runtime";
49
49
  var LazyModelPolicyPickerMenu = lazy(
50
- () => import("./model-policy-picker-menu-PUTA5JOB.js").then(({ ModelPolicyPickerPopover }) => ({
50
+ () => import("./model-policy-picker-menu-GN2LTB7Z.js").then(({ ModelPolicyPickerPopover }) => ({
51
51
  default: ModelPolicyPickerPopover
52
52
  }))
53
53
  );
@@ -81,15 +81,12 @@ var defaultModelPolicyPickerMessages = {
81
81
  }
82
82
  };
83
83
  var SLIDE_EASE = [0.22, 1, 0.36, 1];
84
- function OpenGeniMark(props) {
85
- return /* @__PURE__ */ jsx3("svg", { viewBox: "0 0 140 133", fill: "currentColor", "aria-hidden": "true", ...props, children: /* @__PURE__ */ jsx3("g", { transform: "translate(-17.5,-20.999893188476562) scale(1.75)", children: /* @__PURE__ */ jsx3("g", { transform: "translate(0,-952.36218)", children: /* @__PURE__ */ jsx3("path", { d: "m 60.7828,964.36215 27.1809,0.8834 -27.1809,25.9958 z m -1.9745,1.4513 0,26.7845 -25.2681,0 c 8.6166,-8.7334 16.8796,-17.8103 25.2681,-26.7845 z m 27.7053,3.628 3.4864,1.1989 -12.5877,7.4768 z m -68.1835,2.9656 5.5226,0 12.8654,14.0705 -5.9854,6.1204 -12.4026,0 c 9e-4,-6.7347 0,-13.4597 0,-20.1909 z m -1.9746,1.2304 0,5.8364 -6.3555,0 z m 3.363,20.9796 38.627,0 -10.7675,29.43465 z m 39.0898,4.54286 0,41.20229 -12.5878,-6.8775 c 4.1972,-11.443 8.3886,-22.879 12.5878,-34.32479 z" }) }) }) });
86
- }
87
84
  function ChatGptMark(props) {
88
85
  return /* @__PURE__ */ jsx3("svg", { viewBox: "0 0 24 24", fill: "currentColor", "aria-hidden": "true", ...props, children: /* @__PURE__ */ jsx3("path", { d: "M22.2819 9.8211a5.9847 5.9847 0 0 0-.5157-4.9108 6.0462 6.0462 0 0 0-6.5098-2.9A6.0651 6.0651 0 0 0 4.9807 4.1818a5.9847 5.9847 0 0 0-3.9977 2.9 6.0462 6.0462 0 0 0 .7427 7.0966 5.98 5.98 0 0 0 .511 4.9107 6.051 6.051 0 0 0 6.5146 2.9001A5.9847 5.9847 0 0 0 13.2599 24a6.0557 6.0557 0 0 0 5.7718-4.2058 5.9894 5.9894 0 0 0 3.9977-2.9001 6.0557 6.0557 0 0 0-.7475-7.0729zm-9.022 12.6081a4.4755 4.4755 0 0 1-2.8764-1.0408l.1419-.0804 4.7783-2.7582a.7948.7948 0 0 0 .3927-.6813v-6.7369l2.02 1.1686a.071.071 0 0 1 .038.052v5.5826a4.504 4.504 0 0 1-4.4945 4.4944zm-9.6607-4.1254a4.4708 4.4708 0 0 1-.5346-3.0137l.142.0852 4.783 2.7582a.7712.7712 0 0 0 .7806 0l5.8428-3.3685v2.3324a.0804.0804 0 0 1-.0332.0615L9.74 19.9502a4.4992 4.4992 0 0 1-6.1408-1.6464zM2.3408 7.8956a4.485 4.485 0 0 1 2.3653-1.9728V11.6a.7664.7664 0 0 0 .3879.6765l5.8414 3.3698-2.02 1.1685a.0757.0757 0 0 1-.071 0l-4.8303-2.7865A4.504 4.504 0 0 1 2.3408 7.872zm16.5963 3.8558L13.1038 8.364 15.1192 7.2a.0757.0757 0 0 1 .071 0l4.8303 2.7913a4.4944 4.4944 0 0 1-.6765 8.1042v-5.6772a.79.79 0 0 0-.407-.667zm2.0107-3.0231l-.142-.0852-4.783-2.7622a.7759.7759 0 0 0-.7854 0L9.409 9.2297V6.8974a.0662.0662 0 0 1 .0284-.0615l4.8303-2.7866a4.4992 4.4992 0 0 1 6.6802 4.66zM8.3065 12.863l-2.02-1.1638a.0804.0804 0 0 1-.038-.0567V6.0742a4.4992 4.4992 0 0 1 7.3757-3.4537l-.142.0805L8.704 5.459a.7948.7948 0 0 0-.3927.6813zm1.0976-2.3654l2.602-1.4998 2.6069 1.4998v2.9994l-2.5974 1.4997-2.6067-1.4997Z" }) });
89
86
  }
90
87
  function BillingClassMark(props) {
91
88
  const labels = {
92
- opengeni_credits: "Opengeni",
89
+ opengeni_credits: "Models",
93
90
  external: "External provider",
94
91
  codex_subscription: "Codex",
95
92
  supergrok_subscription: "SuperGrok",
@@ -111,7 +108,7 @@ function BillingClassMark(props) {
111
108
  className: shell,
112
109
  "data-testid": `billing-class-icon-${props.billingClass}`,
113
110
  ...accessibility,
114
- children: props.presentation?.icon !== void 0 ? props.presentation.icon : props.billingClass === "opengeni_credits" ? /* @__PURE__ */ jsx3(OpenGeniMark, { className: mark }) : props.billingClass === "external" ? /* @__PURE__ */ jsx3(Globe2Icon, { className: mark, "aria-hidden": true }) : props.billingClass === "codex_subscription" ? /* @__PURE__ */ jsx3(ChatGptMark, { className: mark }) : props.billingClass === "claude_subscription" ? /* @__PURE__ */ jsx3(ClaudeMark, { className: mark }) : props.billingClass === "supergrok_subscription" ? /* @__PURE__ */ jsx3(GrokMark, { className: mark }) : /* @__PURE__ */ jsx3(KeyRoundIcon, { className: mark, "aria-hidden": true })
111
+ children: props.presentation?.icon !== void 0 ? props.presentation.icon : props.billingClass === "opengeni_credits" ? /* @__PURE__ */ jsx3(SparklesIcon, { className: mark, "aria-hidden": true }) : props.billingClass === "external" ? /* @__PURE__ */ jsx3(Globe2Icon, { className: mark, "aria-hidden": true }) : props.billingClass === "codex_subscription" ? /* @__PURE__ */ jsx3(ChatGptMark, { className: mark }) : props.billingClass === "claude_subscription" ? /* @__PURE__ */ jsx3(ClaudeMark, { className: mark }) : props.billingClass === "supergrok_subscription" ? /* @__PURE__ */ jsx3(GrokMark, { className: mark }) : /* @__PURE__ */ jsx3(KeyRoundIcon, { className: mark, "aria-hidden": true })
115
112
  }
116
113
  );
117
114
  }
@@ -363,4 +360,4 @@ export {
363
360
  PickerAnimatedPage,
364
361
  ModelPolicyPicker
365
362
  };
366
- //# sourceMappingURL=chunk-UINDK6C3.js.map
363
+ //# sourceMappingURL=chunk-7CYYXWHU.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/claude-mark.tsx","../src/components/grok-mark.tsx","../src/components/model-policy-picker.tsx"],"sourcesContent":["import type { SVGProps } from \"react\";\n\n/** ClaudeMark: Simple Icons, CC0; https://github.com/simple-icons/simple-icons */\nexport function ClaudeMark(props: SVGProps<SVGSVGElement>) {\n return (\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden=\"true\" {...props}>\n <path d=\"m4.7144 15.9555 4.7174-2.6471.079-.2307-.079-.1275h-.2307l-.7893-.0486-2.6956-.0729-2.3375-.0971-2.2646-.1214-.5707-.1215-.5343-.7042.0546-.3522.4797-.3218.686.0608 1.5179.1032 2.2767.1578 1.6514.0972 2.4468.255h.3886l.0546-.1579-.1336-.0971-.1032-.0972L6.973 9.8356l-2.55-1.6879-1.3356-.9714-.7225-.4918-.3643-.4614-.1578-1.0078.6557-.7225.8803.0607.2246.0607.8925.686 1.9064 1.4754 2.4893 1.8336.3643.3035.1457-.1032.0182-.0728-.164-.2733-1.3539-2.4467-1.445-2.4893-.6435-1.032-.17-.6194c-.0607-.255-.1032-.4674-.1032-.7285L6.287.1335 6.6997 0l.9957.1336.419.3642.6192 1.4147 1.0018 2.2282 1.5543 3.0296.4553.8985.2429.8318.091.255h.1579v-.1457l.1275-1.706.2368-2.0947.2307-2.6957.0789-.7589.3764-.9107.7468-.4918.5828.2793.4797.686-.0668.4433-.2853 1.8517-.5586 2.9021-.3643 1.9429h.2125l.2429-.2429.9835-1.3053 1.6514-2.0643.7286-.8196.85-.9046.5464-.4311h1.0321l.759 1.1293-.34 1.1657-1.0625 1.3478-.8804 1.1414-1.2628 1.7-.7893 1.36.0729.1093.1882-.0183 2.8535-.607 1.5421-.2794 1.8396-.3157.8318.3886.091.3946-.3278.8075-1.967.4857-2.3072.4614-3.4364.8136-.0425.0304.0486.0607 1.5482.1457.6618.0364h1.621l3.0175.2247.7892.522.4736.6376-.079.4857-1.2142.6193-1.6393-.3886-3.825-.9107-1.3113-.3279h-.1822v.1093l1.0929 1.0686 2.0035 1.8092 2.5075 2.3314.1275.5768-.3218.4554-.34-.0486-2.2039-1.6575-.85-.7468-1.9246-1.621h-.1275v.17l.4432.6496 2.3436 3.5214.1214 1.0807-.17.3521-.6071.2125-.6679-.1214-1.3721-1.9246L14.38 17.959l-1.1414-1.9428-.1397.079-.674 7.2552-.3156.3703-.7286.2793-.6071-.4614-.3218-.7468.3218-1.4753.3886-1.9246.3157-1.53.2853-1.9004.17-.6314-.0121-.0425-.1397.0182-1.4328 1.9672-2.1796 2.9446-1.7243 1.8456-.4128.164-.7164-.3704.0667-.6618.4008-.5889 2.386-3.0357 1.4389-1.882.929-1.0868-.0062-.1579h-.0546l-6.3385 4.1164-1.1293.1457-.4857-.4554.0608-.7467.2307-.2429 1.9064-1.3114Z\" />\n </svg>\n );\n}\n","import type { SVGProps } from \"react\";\n\n/**\n * MIT License\n *\n * Copyright (c) 2023 LobeHub\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n * Source: https://raw.githubusercontent.com/lobehub/lobe-icons/master/src/Grok/components/Mono.tsx\n */\nexport function GrokMark(props: SVGProps<SVGSVGElement>) {\n return (\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden=\"true\" {...props}>\n <path d=\"M9.27 15.29l7.978-5.897c.391-.29.95-.177 1.137.272.98 2.369.542 5.215-1.41 7.169-1.951 1.954-4.667 2.382-7.149 1.406l-2.711 1.257c3.889 2.661 8.611 2.003 11.562-.953 2.341-2.344 3.066-5.539 2.388-8.42l.006.007c-.983-4.232.242-5.924 2.75-9.383.06-.082.12-.164.179-.248l-3.301 3.305v-.01L9.267 15.292M7.623 16.723c-2.792-2.67-2.31-6.801.071-9.184 1.761-1.763 4.647-2.483 7.166-1.425l2.705-1.25a7.808 7.808 0 00-1.829-1A8.975 8.975 0 005.984 5.83c-2.533 2.536-3.33 6.436-1.962 9.764 1.022 2.487-.653 4.246-2.34 6.022-.599.63-1.199 1.259-1.682 1.925l7.62-6.815\" />\n </svg>\n );\n}\n","import { ClaudeMark } from \"./claude-mark\";\nimport { GrokMark } from \"./grok-mark\";\nimport type { ClientModel, LatencyMode, ReasoningEffort } from \"@opengeni/sdk\";\nimport {\n ChevronDownIcon,\n ChevronLeftIcon,\n ChevronRightIcon,\n Globe2Icon,\n KeyRoundIcon,\n SparklesIcon,\n ZapIcon,\n} from \"lucide-react\";\nimport { motion, useReducedMotion } from \"motion/react\";\nimport {\n Suspense,\n lazy,\n useMemo,\n useId,\n useState,\n type CSSProperties,\n type ReactNode,\n type SVGProps,\n} from \"react\";\nimport { cn } from \"../lib/cn\";\nimport { MENU_CHEVRON_CLASS } from \"../lib/menu-styles\";\nimport { usePortalTokenSource, usePortalTokenStyle } from \"../lib/use-portal-token-style\";\nimport {\n effortOptionsForModel,\n findPickerRow,\n labelReasoningEffort,\n projectClientModelRows,\n type PickerBillingClass,\n type PickerModelRow,\n} from \"../model-policy\";\n\nconst LazyModelPolicyPickerMenu = lazy(() =>\n import(\"./model-policy-picker-menu\").then(({ ModelPolicyPickerPopover }) => ({\n default: ModelPolicyPickerPopover,\n })),\n);\n\ntype ClientPickerModelRow = PickerModelRow<ClientModel>;\n\n/** Presentation only; never changes model identity, billing or availability. */\nexport type ModelPolicyPickerGroupPresentation = Partial<\n Record<\n PickerBillingClass,\n {\n label?: string | undefined;\n /** Omit to preserve the default; null hides the supporting text. */\n description?: string | null | undefined;\n /** Decorative, non-interactive content. Omit for the default; null hides it. */\n icon?: ReactNode | undefined;\n }\n >\n>;\n\nexport type ModelPolicyPickerMessages = {\n label: string;\n loading: string;\n noModels: string;\n connectTitle: string;\n connectBody: string;\n connectAction: string;\n thinking: string;\n fast: string;\n fastRateHint: string;\n codexOnly: string;\n searchLabel?: string;\n searchPlaceholder?: string;\n currentModel?: string;\n noMatches?: string;\n unsupportedAttachments?: string;\n thinkingEffort?: string;\n selected?: string;\n free?: string;\n\n billingHints: Record<PickerBillingClass, string>;\n};\n\nexport const defaultModelPolicyPickerMessages: ModelPolicyPickerMessages = {\n label: \"Model and effort\",\n loading: \"Loading model catalog…\",\n noModels: \"No models available.\",\n connectTitle: \"Connect a model\",\n connectBody: \"Use a subscription or a provider key you already have.\",\n connectAction: \"Open Models\",\n thinking: \"Thinking\",\n fast: \"Fast\",\n fastRateHint: \"2× rate\",\n codexOnly: \"Codex-only session\",\n searchLabel: \"Search models or providers\",\n searchPlaceholder: \"Search models or providers…\",\n currentModel: \"Current model\",\n noMatches: \"No matching models. Try a model or provider name.\",\n unsupportedAttachments: \"This model cannot view the attached images.\",\n thinkingEffort: \"Thinking effort\",\n selected: \"Selected\",\n free: \"Free\",\n\n billingHints: {\n opengeni_credits: \"Provided by Opengeni\",\n external: \"Provider terms and limits apply\",\n codex_subscription: \"ChatGPT / Codex plan\",\n supergrok_subscription: \"SuperGrok / xAI plan\",\n claude_subscription: \"Claude plan\",\n byok: \"Billed to the workspace provider account\",\n organization_byok: \"Billed to the organization provider account\",\n },\n};\n\nexport type ModelPolicyPickerProps = {\n /** Host branding for payment-source groups, shared by menu and trigger. */\n groupPresentation?: ModelPolicyPickerGroupPresentation | undefined;\n /** Lightweight deployment models. Catalog rows take precedence when supplied. */\n models?: ClientModel[] | undefined;\n /** Warn only when the draft actually contains images this model cannot view. */\n hasImageAttachments?: boolean | undefined;\n /** Catalog-backed rows with availability and billing-class truth. */\n rows?: PickerModelRow[] | undefined;\n model: string;\n effort: ReasoningEffort;\n latencyMode: LatencyMode;\n disabled?: boolean | undefined;\n loading?: boolean | undefined;\n error?: string | null | undefined;\n /** Controlled menu state. Omit for the built-in uncontrolled behavior. */\n open?: boolean | undefined;\n /** Initial menu state when `open` is uncontrolled. */\n defaultOpen?: boolean | undefined;\n onOpenChange?: ((open: boolean) => void) | undefined;\n /** Non-Codex models stay visible but cannot be selected. */\n codexOnly?: boolean | undefined;\n /** Identity of the current session scope. */\n sessionKey?: string | undefined;\n /** Prefer bottom on new-chat surfaces and top for bottom-docked composers. */\n menuSide?: \"top\" | \"bottom\" | undefined;\n /** Hide latency controls on surfaces whose saved policy does not include latency. */\n allowLatencyMode?: boolean | undefined;\n /** Settings → Models. Shown when the catalog has no model that can run. */\n connectModelsHref?: string | undefined;\n /** Classes for the portalled menu surface. Prefer --og-* tokens for theming. */\n contentClassName?: string | undefined;\n /** Inline styles for the portalled menu, applied after inherited --og-* tokens. */\n contentStyle?: CSSProperties | undefined;\n className?: string | undefined;\n /**\n * \"pill\" (default) is the composer's quiet rounded trigger with the effort.\n * \"field\" is a settings control: a bordered rectangle with the model name\n * and `triggerMeta` (for example the payer) in muted text. The effort stays\n * in the menu.\n */\n triggerStyle?: \"pill\" | \"field\" | undefined;\n /** Muted text after the model name in the \"field\" trigger. */\n triggerMeta?: ReactNode;\n messages?: Partial<ModelPolicyPickerMessages> | undefined;\n onModelChange: (modelId: string) => void;\n onEffortChange: (effort: ReasoningEffort) => void;\n onLatencyModeChange: (latencyMode: LatencyMode) => void;\n};\n\nconst SLIDE_EASE = [0.22, 1, 0.36, 1] as const;\n\nfunction ChatGptMark(props: SVGProps<SVGSVGElement>) {\n return (\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden=\"true\" {...props}>\n <path d=\"M22.2819 9.8211a5.9847 5.9847 0 0 0-.5157-4.9108 6.0462 6.0462 0 0 0-6.5098-2.9A6.0651 6.0651 0 0 0 4.9807 4.1818a5.9847 5.9847 0 0 0-3.9977 2.9 6.0462 6.0462 0 0 0 .7427 7.0966 5.98 5.98 0 0 0 .511 4.9107 6.051 6.051 0 0 0 6.5146 2.9001A5.9847 5.9847 0 0 0 13.2599 24a6.0557 6.0557 0 0 0 5.7718-4.2058 5.9894 5.9894 0 0 0 3.9977-2.9001 6.0557 6.0557 0 0 0-.7475-7.0729zm-9.022 12.6081a4.4755 4.4755 0 0 1-2.8764-1.0408l.1419-.0804 4.7783-2.7582a.7948.7948 0 0 0 .3927-.6813v-6.7369l2.02 1.1686a.071.071 0 0 1 .038.052v5.5826a4.504 4.504 0 0 1-4.4945 4.4944zm-9.6607-4.1254a4.4708 4.4708 0 0 1-.5346-3.0137l.142.0852 4.783 2.7582a.7712.7712 0 0 0 .7806 0l5.8428-3.3685v2.3324a.0804.0804 0 0 1-.0332.0615L9.74 19.9502a4.4992 4.4992 0 0 1-6.1408-1.6464zM2.3408 7.8956a4.485 4.485 0 0 1 2.3653-1.9728V11.6a.7664.7664 0 0 0 .3879.6765l5.8414 3.3698-2.02 1.1685a.0757.0757 0 0 1-.071 0l-4.8303-2.7865A4.504 4.504 0 0 1 2.3408 7.872zm16.5963 3.8558L13.1038 8.364 15.1192 7.2a.0757.0757 0 0 1 .071 0l4.8303 2.7913a4.4944 4.4944 0 0 1-.6765 8.1042v-5.6772a.79.79 0 0 0-.407-.667zm2.0107-3.0231l-.142-.0852-4.783-2.7622a.7759.7759 0 0 0-.7854 0L9.409 9.2297V6.8974a.0662.0662 0 0 1 .0284-.0615l4.8303-2.7866a4.4992 4.4992 0 0 1 6.6802 4.66zM8.3065 12.863l-2.02-1.1638a.0804.0804 0 0 1-.038-.0567V6.0742a4.4992 4.4992 0 0 1 7.3757-3.4537l-.142.0805L8.704 5.459a.7948.7948 0 0 0-.3927.6813zm1.0976-2.3654l2.602-1.4998 2.6069 1.4998v2.9994l-2.5974 1.4997-2.6067-1.4997Z\" />\n </svg>\n );\n}\n\nexport function BillingClassMark(props: {\n billingClass: PickerBillingClass;\n presentation?: ModelPolicyPickerGroupPresentation[PickerBillingClass] | undefined;\n className?: string | undefined;\n \"aria-label\"?: string | undefined;\n}) {\n const labels: Record<PickerBillingClass, string> = {\n opengeni_credits: \"Models\",\n external: \"External provider\",\n codex_subscription: \"Codex\",\n supergrok_subscription: \"SuperGrok\",\n claude_subscription: \"Claude\",\n byok: \"Workspace provider account\",\n organization_byok: \"Organization provider account\",\n };\n if (props.presentation?.icon === null) return null;\n const label = props[\"aria-label\"] ?? props.presentation?.label ?? labels[props.billingClass];\n const accessibility =\n label.length === 0\n ? { \"aria-hidden\": true as const }\n : { role: \"img\" as const, \"aria-label\": label };\n const shell = cn(\n \"inline-flex size-3.5 shrink-0 items-center justify-center overflow-hidden text-og-fg-subtle [&>svg]:size-full [&>img]:size-full\",\n props.className,\n );\n const mark = \"size-3.5\";\n return (\n <span\n className={shell}\n data-testid={`billing-class-icon-${props.billingClass}`}\n {...accessibility}\n >\n {props.presentation?.icon !== undefined ? (\n props.presentation.icon\n ) : props.billingClass === \"opengeni_credits\" ? (\n <SparklesIcon className={mark} aria-hidden />\n ) : props.billingClass === \"external\" ? (\n <Globe2Icon className={mark} aria-hidden />\n ) : props.billingClass === \"codex_subscription\" ? (\n <ChatGptMark className={mark} />\n ) : props.billingClass === \"claude_subscription\" ? (\n <ClaudeMark className={mark} />\n ) : props.billingClass === \"supergrok_subscription\" ? (\n <GrokMark className={mark} />\n ) : (\n <KeyRoundIcon className={mark} aria-hidden />\n )}\n </span>\n );\n}\n\nfunction isCodexModel(model: ClientModel): boolean {\n return model.id.startsWith(\"codex/\") || model.source === \"codex\";\n}\n\nfunction billingClassForMissingSelection(modelId: string): PickerBillingClass {\n if (modelId.startsWith(\"workspace-claude-subscription/\")) return \"claude_subscription\";\n if (modelId.startsWith(\"workspace-anthropic/\")) return \"byok\";\n if (modelId.startsWith(\"organization-claude-subscription/\")) return \"claude_subscription\";\n if (modelId.startsWith(\"organization-anthropic/\")) return \"organization_byok\";\n if (modelId.startsWith(\"workspace-gateway/\")) return \"byok\";\n if (modelId.startsWith(\"workspace-openrouter/\")) return \"byok\";\n // A deployment OpenRouter ID does not encode its workspace-facing cost.\n // Missing rows therefore use the credits-safe rail instead of falsely\n // claiming that an unknown former selection was externally funded.\n if (modelId.startsWith(\"openrouter/\")) return \"opengeni_credits\";\n if (modelId.startsWith(\"codex/\")) return \"codex_subscription\";\n if (modelId.startsWith(\"supergrok/\")) return \"supergrok_subscription\";\n return \"opengeni_credits\";\n}\n\nfunction applyCodexOnly(\n rows: ClientPickerModelRow[],\n codexOnly: boolean,\n unavailableReason: string,\n): ClientPickerModelRow[] {\n if (!codexOnly) return rows;\n return rows.map((row) =>\n isCodexModel(row.catalog)\n ? row\n : {\n ...row,\n selectable: false,\n unavailableReason: row.unavailableReason ?? unavailableReason,\n },\n );\n}\n\nexport function effectiveRows(props: ModelPolicyPickerProps): ClientPickerModelRow[] {\n const rows = props.rows !== undefined ? props.rows : projectClientModelRows(props.models ?? []);\n const messages = { ...defaultModelPolicyPickerMessages, ...props.messages };\n return applyCodexOnly(rows, props.codexOnly === true, messages.codexOnly).map((row) => {\n const label = props.groupPresentation?.[row.billingClass]?.label;\n return label === undefined ? row : { ...row, billingClassLabel: label };\n });\n}\n\nexport function PickerNavRow(props: {\n label: string;\n hint?: string | undefined;\n icon?: ReactNode;\n trailing?: ReactNode;\n showChevron?: boolean | undefined;\n disabled?: boolean | undefined;\n title?: string | undefined;\n description?: string | undefined;\n active?: boolean | undefined;\n testId?: string | undefined;\n onClick: () => void;\n}) {\n return (\n <button\n type=\"button\"\n disabled={props.disabled}\n title={props.title}\n aria-description={props.description}\n onClick={props.onClick}\n data-testid={props.testId}\n className={cn(\n // The one menu row (lib/menu-styles.ts), with density tokens for embedders.\n \"flex min-h-8 w-full cursor-pointer items-center gap-2.5 rounded-og-md px-[var(--og-model-picker-row-padding-x)] py-[var(--og-model-picker-row-padding-y)] text-left text-og-fg outline-hidden transition-colors duration-[120ms] hover:bg-og-hover focus-visible:bg-og-hover focus-visible:outline-2 focus-visible:-outline-offset-2! focus-visible:outline-og-accent/55 pointer-coarse:min-h-11\",\n props.disabled && \"cursor-not-allowed opacity-50\",\n )}\n >\n {props.icon}\n <span className=\"min-w-0 flex-1\">\n <span className=\"block truncate text-og-menu\">{props.label}</span>\n {props.hint ? (\n <span className=\"mt-0.5 block truncate text-og-sm text-og-fg-muted\">{props.hint}</span>\n ) : null}\n </span>\n {props.trailing ? <span className=\"ml-auto shrink-0\">{props.trailing}</span> : null}\n {props.showChevron === false ? null : <ChevronRightIcon className={MENU_CHEVRON_CLASS} />}\n </button>\n );\n}\n\nexport function PickerBackHeader(props: {\n label: string;\n icon?: ReactNode;\n onBack: () => void;\n trailing?: ReactNode;\n}) {\n return (\n <div className=\"mb-1.5 flex min-h-9 items-center gap-1 border-b border-og-border pb-1.5\">\n <button\n type=\"button\"\n onClick={props.onBack}\n data-testid=\"model-picker-back\"\n className=\"flex min-h-8 min-w-0 flex-1 cursor-pointer items-center gap-1 rounded-og-md pr-2.5 text-left text-og-fg outline-hidden transition-colors duration-[120ms] hover:bg-og-hover focus-visible:outline-2 focus-visible:-outline-offset-2! focus-visible:outline-og-accent/55 pointer-coarse:min-h-11\"\n >\n <span className=\"flex size-8 shrink-0 items-center justify-center text-og-fg-muted\">\n <ChevronLeftIcon className=\"size-4\" />\n </span>\n {props.icon}\n <span className=\"min-w-0 flex-1 truncate text-og-menu font-medium\">{props.label}</span>\n </button>\n {props.trailing ? <div className=\"relative z-10 shrink-0\">{props.trailing}</div> : null}\n </div>\n );\n}\n\nexport function PickerAnimatedPage(props: {\n pageKey: string;\n direction: 1 | -1;\n children: ReactNode;\n}) {\n const reduceMotion = useReducedMotion();\n return (\n <motion.div\n key={props.pageKey}\n initial={reduceMotion ? false : { x: props.direction * 14, opacity: 0 }}\n animate={{ x: 0, opacity: 1 }}\n transition={{ duration: reduceMotion ? 0 : 0.18, ease: SLIDE_EASE }}\n className=\"w-full\"\n >\n {props.children}\n </motion.div>\n );\n}\n\n/** @internal Shared controlled/uncontrolled state seam. */\nexport function useModelPolicyPickerState(props: ModelPolicyPickerProps) {\n const [uncontrolledOpen, setUncontrolledOpen] = useState(props.defaultOpen ?? false);\n const open = props.open ?? uncontrolledOpen;\n const setOpen = (next: boolean) => {\n if (props.open === undefined) setUncontrolledOpen(next);\n props.onOpenChange?.(next);\n };\n return { open, setOpen, rows: effectiveRows(props) };\n}\n\nexport function ModelPolicyPicker(props: ModelPolicyPickerProps) {\n const contentId = useId();\n const trigger = usePortalTokenSource<HTMLButtonElement>();\n const portalStyle = usePortalTokenStyle(trigger.source);\n const messages = useMemo(\n () => ({ ...defaultModelPolicyPickerMessages, ...props.messages }),\n [props.messages],\n );\n const { open, setOpen, rows } = useModelPolicyPickerState(props);\n const selected = findPickerRow(rows, props.model);\n const needsModel =\n !rows.some((row) => row.selectable) && (rows.length > 0 || Boolean(props.connectModelsHref));\n\n if (props.loading) {\n return (\n <span\n className={cn(\n \"og-root inline-flex h-8 w-40 shrink-0 animate-pulse rounded-full bg-og-surface-2\",\n props.triggerStyle === \"field\" && \"w-[180px] rounded-og-md\",\n props.className,\n )}\n aria-label={messages.loading}\n data-testid=\"model-picker-loading\"\n />\n );\n }\n if (props.triggerStyle === \"field\") {\n return (\n <>\n <button\n ref={trigger.ref}\n type=\"button\"\n aria-haspopup=\"dialog\"\n aria-expanded={open}\n aria-controls={open ? contentId : undefined}\n data-state={open ? \"open\" : \"closed\"}\n data-trigger-style=\"field\"\n onClick={() => setOpen(!open)}\n disabled={props.disabled}\n aria-label={messages.label}\n className={cn(\n \"og-root inline-flex h-8 min-w-[180px] max-w-full items-center gap-2 rounded-og-md border border-og-border bg-og-surface px-2.5 text-sm text-og-fg outline-hidden transition-colors hover:bg-og-surface-2 focus-visible:ring-2 focus-visible:ring-og-accent/40 disabled:cursor-not-allowed disabled:opacity-50\",\n props.className,\n )}\n >\n {needsModel ? (\n <SparklesIcon className=\"size-3.5 shrink-0\" aria-hidden />\n ) : (\n <BillingClassMark\n billingClass={selected?.billingClass ?? billingClassForMissingSelection(props.model)}\n presentation={\n props.groupPresentation?.[\n selected?.billingClass ?? billingClassForMissingSelection(props.model)\n ]\n }\n className=\"text-og-fg\"\n />\n )}\n <span className=\"min-w-0 truncate font-medium\">\n {needsModel ? messages.connectTitle : (selected?.label ?? props.model)}\n </span>\n {props.triggerMeta && !needsModel ? (\n <span className=\"min-w-0 shrink-[9999] truncate text-og-fg-muted\">\n {props.triggerMeta}\n </span>\n ) : null}\n <ChevronDownIcon className=\"ml-auto size-3.5 shrink-0 text-og-fg-muted\" />\n </button>\n {open ? (\n <Suspense fallback={null}>\n <LazyModelPolicyPickerMenu\n {...props}\n anchor={trigger.currentRef}\n contentId={contentId}\n portalStyle={portalStyle}\n onOpenChange={setOpen}\n />\n </Suspense>\n ) : null}\n </>\n );\n }\n return (\n <>\n <button\n ref={trigger.ref}\n type=\"button\"\n aria-haspopup=\"dialog\"\n aria-expanded={open}\n aria-controls={open ? contentId : undefined}\n data-state={open ? \"open\" : \"closed\"}\n onClick={() => setOpen(!open)}\n disabled={props.disabled}\n aria-label={messages.label}\n className={cn(\n \"og-root og-model-policy-trigger inline-flex h-[var(--og-model-picker-trigger-height)] min-w-0 max-w-64 items-center gap-1 rounded-full border px-2.5 text-og-control outline-hidden transition-colors focus-visible:ring-2 focus-visible:ring-og-accent/40 disabled:cursor-not-allowed disabled:opacity-50 max-sm:h-11 max-sm:max-w-[7.5rem] max-sm:px-2\",\n // With no usable model the pill is the one thing that unblocks the\n // composer, so it takes the primary wash.\n needsModel\n ? \"border-og-primary-border bg-og-primary text-og-primary-fg hover:bg-og-primary-hover\"\n : \"border-transparent text-og-fg-muted hover:border-og-border hover:bg-og-surface-2 hover:text-og-fg\",\n props.className,\n )}\n >\n {needsModel ? (\n <SparklesIcon className=\"size-3.5 shrink-0\" aria-hidden />\n ) : (\n <BillingClassMark\n billingClass={selected?.billingClass ?? billingClassForMissingSelection(props.model)}\n presentation={\n props.groupPresentation?.[\n selected?.billingClass ?? billingClassForMissingSelection(props.model)\n ]\n }\n className=\"text-og-fg\"\n />\n )}\n <span className=\"og-model-policy-label-full min-w-0 truncate font-medium text-og-fg max-sm:hidden @max-[20rem]/model-controls:hidden\">\n {needsModel ? messages.connectTitle : (selected?.label ?? props.model)}\n </span>\n <span className=\"og-model-policy-label-short min-w-0 truncate font-medium text-og-fg sm:hidden @max-[20rem]/model-controls:block\">\n {needsModel\n ? messages.connectTitle\n : (selected?.shortLabel ?? selected?.label ?? props.model)}\n </span>\n {selected &&\n !needsModel &&\n effortOptionsForModel(selected.catalog).length > 1 &&\n selected.catalog.capabilities?.reasoning.runnable !== false ? (\n <span\n className=\"og-model-policy-effort min-w-0 shrink-[9999] truncate\"\n title={labelReasoningEffort(props.effort)}\n >\n {labelReasoningEffort(props.effort)}\n </span>\n ) : null}\n {props.latencyMode === \"fast\" && !needsModel ? (\n <ZapIcon\n className=\"size-3.5 shrink-0 fill-current stroke-current text-og-fg\"\n aria-label={messages.fast}\n data-testid=\"model-picker-fast-icon\"\n />\n ) : null}\n <ChevronDownIcon className=\"size-3 shrink-0\" />\n </button>\n\n {open ? (\n <Suspense fallback={null}>\n <LazyModelPolicyPickerMenu\n {...props}\n anchor={trigger.currentRef}\n contentId={contentId}\n portalStyle={portalStyle}\n onOpenChange={setOpen}\n />\n </Suspense>\n ) : null}\n </>\n );\n}\n"],"mappings":"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","names":["jsx","jsx"]}