@opengeni/react 3.1.0 → 3.1.2

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 (863) hide show
  1. package/README.md +769 -22
  2. package/dist/accounts.js +89 -11
  3. package/dist/accounts.js.map +1 -1
  4. package/dist/approvals.d.ts +2 -1
  5. package/dist/artifacts-document.js +5 -3
  6. package/dist/artifacts-presentation.js +5 -3
  7. package/dist/artifacts-spreadsheet.d.ts +1 -1
  8. package/dist/artifacts-spreadsheet.js +5 -3
  9. package/dist/artifacts.d.ts +5 -1
  10. package/dist/artifacts.js +536 -42
  11. package/dist/artifacts.js.map +1 -1
  12. package/dist/browser-viewer-ZWR6MWJ7.js +19 -0
  13. package/dist/capability-catalog-row.d.ts +20 -0
  14. package/dist/capability-logo-fallback.d.ts +3 -0
  15. package/dist/chat-interactive-block-BO2IWXVK.js +14 -0
  16. package/dist/chunk-2DDJ6YH6.js +41 -0
  17. package/dist/chunk-2DDJ6YH6.js.map +1 -0
  18. package/dist/chunk-2HVLQ26H.js +183 -0
  19. package/dist/chunk-2HVLQ26H.js.map +1 -0
  20. package/dist/{chunk-RGALCTWO.js → chunk-2I6R3GCZ.js} +4285 -3980
  21. package/dist/chunk-2I6R3GCZ.js.map +1 -0
  22. package/dist/{chunk-D3UIAJKY.js → chunk-2SFFYIH3.js} +1179 -166
  23. package/dist/chunk-2SFFYIH3.js.map +1 -0
  24. package/dist/chunk-3PVDYTTB.js +24 -0
  25. package/dist/chunk-3PVDYTTB.js.map +1 -0
  26. package/dist/chunk-3UZCWK46.js +298 -0
  27. package/dist/chunk-3UZCWK46.js.map +1 -0
  28. package/dist/chunk-47CKUXTW.js +293 -0
  29. package/dist/chunk-47CKUXTW.js.map +1 -0
  30. package/dist/chunk-4QYP6QUI.js +109 -0
  31. package/dist/chunk-4QYP6QUI.js.map +1 -0
  32. package/dist/chunk-5EY26VZ7.js +1053 -0
  33. package/dist/chunk-5EY26VZ7.js.map +1 -0
  34. package/dist/chunk-5I4VRWBB.js +56 -0
  35. package/dist/chunk-5I4VRWBB.js.map +1 -0
  36. package/dist/chunk-5WOR7UCL.js +191 -0
  37. package/dist/chunk-5WOR7UCL.js.map +1 -0
  38. package/dist/chunk-5YJLGOM5.js +51 -0
  39. package/dist/chunk-5YJLGOM5.js.map +1 -0
  40. package/dist/chunk-6JFN3OWG.js +386 -0
  41. package/dist/chunk-6JFN3OWG.js.map +1 -0
  42. package/dist/chunk-7QJT5O4S.js +35 -0
  43. package/dist/chunk-7QJT5O4S.js.map +1 -0
  44. package/dist/chunk-A55KV72M.js +402 -0
  45. package/dist/chunk-A55KV72M.js.map +1 -0
  46. package/dist/chunk-ADWCLI4G.js +2028 -0
  47. package/dist/chunk-ADWCLI4G.js.map +1 -0
  48. package/dist/chunk-B27E3V37.js +29 -0
  49. package/dist/chunk-B27E3V37.js.map +1 -0
  50. package/dist/chunk-B7TC2A33.js +83 -0
  51. package/dist/chunk-B7TC2A33.js.map +1 -0
  52. package/dist/chunk-BLL56F7R.js +385 -0
  53. package/dist/chunk-BLL56F7R.js.map +1 -0
  54. package/dist/chunk-BOFEQC6K.js +162 -0
  55. package/dist/chunk-BOFEQC6K.js.map +1 -0
  56. package/dist/chunk-CM7LVUKC.js +35 -0
  57. package/dist/chunk-CM7LVUKC.js.map +1 -0
  58. package/dist/chunk-CORUP6JB.js +122 -0
  59. package/dist/chunk-CORUP6JB.js.map +1 -0
  60. package/dist/chunk-CSX5FFKZ.js +35 -0
  61. package/dist/chunk-CSX5FFKZ.js.map +1 -0
  62. package/dist/chunk-EGVHJKGJ.js +3125 -0
  63. package/dist/chunk-EGVHJKGJ.js.map +1 -0
  64. package/dist/{chunk-NEXLLTP4.js → chunk-G76LSA76.js} +6 -5
  65. package/dist/chunk-G76LSA76.js.map +1 -0
  66. package/dist/{chunk-PEI6RANI.js → chunk-GQMRL52F.js} +311 -75
  67. package/dist/chunk-GQMRL52F.js.map +1 -0
  68. package/dist/{chunk-ELIYWBZR.js → chunk-GUUXOISA.js} +1113 -457
  69. package/dist/chunk-GUUXOISA.js.map +1 -0
  70. package/dist/{chunk-HUIKIDM5.js → chunk-I7X2P4FU.js} +225 -116
  71. package/dist/chunk-I7X2P4FU.js.map +1 -0
  72. package/dist/chunk-IGFZFLI2.js +1390 -0
  73. package/dist/chunk-IGFZFLI2.js.map +1 -0
  74. package/dist/{chunk-4MDLEHXL.js → chunk-IMSUVYQB.js} +26 -13
  75. package/dist/chunk-IMSUVYQB.js.map +1 -0
  76. package/dist/chunk-IOYHDEP3.js +38 -0
  77. package/dist/chunk-IOYHDEP3.js.map +1 -0
  78. package/dist/chunk-IZV5FTJC.js +55 -0
  79. package/dist/chunk-IZV5FTJC.js.map +1 -0
  80. package/dist/chunk-KF33GTWN.js +343 -0
  81. package/dist/chunk-KF33GTWN.js.map +1 -0
  82. package/dist/chunk-KSGQ5ODA.js +457 -0
  83. package/dist/chunk-KSGQ5ODA.js.map +1 -0
  84. package/dist/{chunk-OAM4WAAM.js → chunk-KZC6QRNR.js} +1513 -697
  85. package/dist/chunk-KZC6QRNR.js.map +1 -0
  86. package/dist/chunk-LJUMYUBO.js +218 -0
  87. package/dist/chunk-LJUMYUBO.js.map +1 -0
  88. package/dist/chunk-LSW2OJVV.js +380 -0
  89. package/dist/chunk-LSW2OJVV.js.map +1 -0
  90. package/dist/chunk-M357MHH3.js +2 -0
  91. package/dist/chunk-M357MHH3.js.map +1 -0
  92. package/dist/chunk-MK2TQO4Y.js +24 -0
  93. package/dist/chunk-MK2TQO4Y.js.map +1 -0
  94. package/dist/chunk-N7S72EXK.js +25 -0
  95. package/dist/chunk-N7S72EXK.js.map +1 -0
  96. package/dist/{chunk-XXWH2JLC.js → chunk-NKMYZFHA.js} +616 -621
  97. package/dist/chunk-NKMYZFHA.js.map +1 -0
  98. package/dist/chunk-NX4ADH73.js +14 -0
  99. package/dist/chunk-NX4ADH73.js.map +1 -0
  100. package/dist/chunk-O7F6UJO4.js +71 -0
  101. package/dist/chunk-O7F6UJO4.js.map +1 -0
  102. package/dist/chunk-OVB5WIG5.js +14064 -0
  103. package/dist/chunk-OVB5WIG5.js.map +1 -0
  104. package/dist/chunk-OYQQJL3J.js +16 -0
  105. package/dist/chunk-OYQQJL3J.js.map +1 -0
  106. package/dist/{chunk-H5YGYNXS.js → chunk-P4BNUO57.js} +60 -17
  107. package/dist/chunk-P4BNUO57.js.map +1 -0
  108. package/dist/{chunk-JVYQRRC4.js → chunk-PEHTX3V7.js} +21 -1
  109. package/dist/chunk-PEHTX3V7.js.map +1 -0
  110. package/dist/chunk-PMV53IMM.js +26 -0
  111. package/dist/chunk-PMV53IMM.js.map +1 -0
  112. package/dist/{chunk-KCGXPP5V.js → chunk-PYEOPA4M.js} +13 -7
  113. package/dist/chunk-PYEOPA4M.js.map +1 -0
  114. package/dist/{chunk-KZ73RL76.js → chunk-QHUE7E4N.js} +8 -3
  115. package/dist/chunk-QHUE7E4N.js.map +1 -0
  116. package/dist/chunk-QV3DJVRZ.js +11 -0
  117. package/dist/chunk-QV3DJVRZ.js.map +1 -0
  118. package/dist/chunk-R5SBNG7S.js +810 -0
  119. package/dist/chunk-R5SBNG7S.js.map +1 -0
  120. package/dist/chunk-RI42H5IU.js +326 -0
  121. package/dist/chunk-RI42H5IU.js.map +1 -0
  122. package/dist/chunk-S2QH6EZ5.js +211 -0
  123. package/dist/chunk-S2QH6EZ5.js.map +1 -0
  124. package/dist/chunk-SHLZMAJN.js +304 -0
  125. package/dist/chunk-SHLZMAJN.js.map +1 -0
  126. package/dist/chunk-TGXK4BAZ.js +293 -0
  127. package/dist/chunk-TGXK4BAZ.js.map +1 -0
  128. package/dist/{chunk-5YK2ZDIG.js → chunk-TNEZNMSN.js} +4 -10
  129. package/dist/chunk-TNEZNMSN.js.map +1 -0
  130. package/dist/{chunk-22KP6LR5.js → chunk-TXS65BB2.js} +3 -1
  131. package/dist/{chunk-22KP6LR5.js.map → chunk-TXS65BB2.js.map} +1 -1
  132. package/dist/chunk-UNJPZGNK.js +63 -0
  133. package/dist/chunk-UNJPZGNK.js.map +1 -0
  134. package/dist/{chunk-MZ2G2XBA.js → chunk-V5ZUJT2T.js} +205 -45
  135. package/dist/chunk-V5ZUJT2T.js.map +1 -0
  136. package/dist/chunk-VIUEOHXY.js +394 -0
  137. package/dist/chunk-VIUEOHXY.js.map +1 -0
  138. package/dist/chunk-WIUKB3LD.js +1911 -0
  139. package/dist/chunk-WIUKB3LD.js.map +1 -0
  140. package/dist/{chunk-ICA6R6TW.js → chunk-WNN7NO2N.js} +1451 -355
  141. package/dist/chunk-WNN7NO2N.js.map +1 -0
  142. package/dist/{chunk-YJFGAFBD.js → chunk-X5UVUIMF.js} +1892 -1223
  143. package/dist/chunk-X5UVUIMF.js.map +1 -0
  144. package/dist/chunk-XDA5QJE7.js +402 -0
  145. package/dist/chunk-XDA5QJE7.js.map +1 -0
  146. package/dist/{chunk-VZTQ73XT.js → chunk-XEA5BCMA.js} +3 -1
  147. package/dist/{chunk-VZTQ73XT.js.map → chunk-XEA5BCMA.js.map} +1 -1
  148. package/dist/chunk-XHF7OYAN.js +1150 -0
  149. package/dist/chunk-XHF7OYAN.js.map +1 -0
  150. package/dist/chunk-YSRBFJMQ.js +43 -0
  151. package/dist/chunk-YSRBFJMQ.js.map +1 -0
  152. package/dist/chunk-ZOZAPAUO.js +174 -0
  153. package/dist/chunk-ZOZAPAUO.js.map +1 -0
  154. package/dist/chunk-ZQV5W7YC.js +809 -0
  155. package/dist/chunk-ZQV5W7YC.js.map +1 -0
  156. package/dist/chunk-ZUWF4NF7.js +13 -0
  157. package/dist/chunk-ZUWF4NF7.js.map +1 -0
  158. package/dist/client.d.ts +16 -7
  159. package/dist/clipboard.js +3 -1
  160. package/dist/commands/types.d.ts +2 -0
  161. package/dist/components/anthropic-mark.d.ts +3 -0
  162. package/dist/components/approval-surface.d.ts +19 -6
  163. package/dist/components/artifacts/artifact-chrome.d.ts +120 -0
  164. package/dist/components/artifacts/artifact-sandbox.d.ts +30 -0
  165. package/dist/components/artifacts/artifact-surface.d.ts +4 -2
  166. package/dist/components/artifacts/chat-interactive-block.d.ts +29 -0
  167. package/dist/components/artifacts/deferred-chat-media.d.ts +15 -0
  168. package/dist/components/artifacts/document-editor.d.ts +4 -2
  169. package/dist/components/artifacts/editable-artifact-ui.d.ts +2 -1
  170. package/dist/components/artifacts/editable-artifact-view.d.ts +48 -0
  171. package/dist/components/artifacts/editable-document.d.ts +1 -1
  172. package/dist/components/artifacts/editable-presentation.d.ts +2 -2
  173. package/dist/components/artifacts/editable-spreadsheet.d.ts +8 -3
  174. package/dist/components/artifacts/index.d.ts +9 -2
  175. package/dist/components/artifacts/inline-html-document.d.ts +2 -0
  176. package/dist/components/artifacts/latest-task-runner.d.ts +15 -0
  177. package/dist/components/artifacts/presentation-editor.d.ts +6 -2
  178. package/dist/components/artifacts/published-html-artifact-frame.d.ts +23 -3
  179. package/dist/components/artifacts/session-artifact-viewer.d.ts +39 -0
  180. package/dist/components/artifacts/site-view.d.ts +26 -0
  181. package/dist/components/artifacts/spreadsheet-command-queue.d.ts +20 -0
  182. package/dist/components/artifacts/spreadsheet-download.d.ts +7 -0
  183. package/dist/components/artifacts/spreadsheet-general-display.d.ts +24 -0
  184. package/dist/components/artifacts/spreadsheet-grid.d.ts +10 -3
  185. package/dist/components/artifacts/spreadsheet-resize.d.ts +50 -0
  186. package/dist/components/artifacts/spreadsheet-submissions.d.ts +9 -0
  187. package/dist/components/artifacts/visualization-assets.gen.d.ts +2 -0
  188. package/dist/components/browser-select-control.d.ts +16 -0
  189. package/dist/components/browser-viewer.d.ts +11 -2
  190. package/dist/components/chat-composer.d.ts +21 -3
  191. package/dist/components/child-session-link.d.ts +9 -0
  192. package/dist/components/claude-mark.d.ts +3 -0
  193. package/dist/components/code-editor.d.ts +1 -4
  194. package/dist/components/composer-transcription-control.d.ts +7 -0
  195. package/dist/components/composer.d.ts +34 -67
  196. package/dist/components/computer-viewer.d.ts +1 -1
  197. package/dist/components/copy-button.d.ts +3 -1
  198. package/dist/components/desktop-viewer.d.ts +1 -1
  199. package/dist/components/fleet-tile.d.ts +2 -2
  200. package/dist/components/grok-mark.d.ts +26 -0
  201. package/dist/components/human-input-form.d.ts +28 -32
  202. package/dist/components/human-input-surface.d.ts +7 -2
  203. package/dist/components/linkified-text.d.ts +18 -0
  204. package/dist/components/machine-input-display.d.ts +22 -1
  205. package/dist/components/machines/agent-status-icon.d.ts +6 -0
  206. package/dist/components/machines/machine-detail.d.ts +7 -1
  207. package/dist/components/machines/machine-status.d.ts +48 -0
  208. package/dist/components/markdown-table-layout.d.ts +18 -0
  209. package/dist/components/markdown.d.ts +37 -4
  210. package/dist/components/message-timeline.d.ts +86 -7
  211. package/dist/components/model-mark.d.ts +29 -0
  212. package/dist/components/model-policy-picker-menu.d.ts +9 -0
  213. package/dist/components/model-policy-picker.d.ts +41 -25
  214. package/dist/components/new-conversation.d.ts +32 -0
  215. package/dist/components/open-geni-chat.d.ts +73 -0
  216. package/dist/components/open-geni-links.d.ts +68 -0
  217. package/dist/components/openrouter-mark.d.ts +6 -0
  218. package/dist/components/opper-mark.d.ts +7 -0
  219. package/dist/components/preview-loading.d.ts +2 -0
  220. package/dist/components/provider-recovery-notice.d.ts +16 -0
  221. package/dist/components/queue-item-content.d.ts +9 -0
  222. package/dist/components/rehype-secret-refs.d.ts +23 -0
  223. package/dist/components/remark-soft-line-breaks.d.ts +38 -0
  224. package/dist/components/sandbox-files.d.ts +3 -1
  225. package/dist/components/sandbox-workspace.d.ts +18 -0
  226. package/dist/components/secret-question-field.d.ts +31 -0
  227. package/dist/components/secret-ref-chip.d.ts +35 -0
  228. package/dist/components/session-capability-frame.d.ts +37 -0
  229. package/dist/components/session-chrome.d.ts +57 -8
  230. package/dist/components/session-commands-panel.d.ts +6 -0
  231. package/dist/components/session-commands.d.ts +6 -0
  232. package/dist/components/session-connection-request.d.ts +8 -0
  233. package/dist/components/session-conversation.d.ts +157 -0
  234. package/dist/components/session-list.d.ts +39 -0
  235. package/dist/components/session-mcp-capability-card.d.ts +41 -0
  236. package/dist/components/session-proxy-scope.d.ts +35 -0
  237. package/dist/components/session-status.d.ts +4 -1
  238. package/dist/components/session-usage-limit-notice.d.ts +39 -0
  239. package/dist/components/timeline-anchor.d.ts +24 -0
  240. package/dist/components/timeline-annotation-chrome.d.ts +25 -0
  241. package/dist/components/timeline-annotation-layout.d.ts +42 -0
  242. package/dist/components/timeline-annotation-markers.d.ts +8 -0
  243. package/dist/components/timeline-annotation-reveal-context.d.ts +4 -0
  244. package/dist/components/timeline-annotation-shared.d.ts +31 -0
  245. package/dist/components/timeline-annotations-dialog.d.ts +3 -2
  246. package/dist/components/timeline-annotations.d.ts +13 -3
  247. package/dist/components/timeline-reading-progress.d.ts +11 -0
  248. package/dist/components/timeline-search.d.ts +34 -0
  249. package/dist/components/timeline-settlement.d.ts +16 -0
  250. package/dist/components/tip-follow.d.ts +16 -0
  251. package/dist/components/tool-action-review.d.ts +47 -0
  252. package/dist/components/tool-review-history.d.ts +25 -0
  253. package/dist/components/usage-limit-notice.d.ts +49 -0
  254. package/dist/components/usage-member-list.d.ts +91 -0
  255. package/dist/components/usage-meter.d.ts +73 -0
  256. package/dist/components/use-viewer-menu-dismiss.d.ts +2 -0
  257. package/dist/components/user-message-body.d.ts +10 -1
  258. package/dist/composer-messages.d.ts +74 -0
  259. package/dist/composer-messages.js +9 -0
  260. package/dist/composer-messages.js.map +1 -0
  261. package/dist/composer-voice-events.d.ts +8 -0
  262. package/dist/composer.d.ts +5 -4
  263. package/dist/composer.js +26 -13
  264. package/dist/computer-viewer-GMLDXPON.js +20 -0
  265. package/dist/computer-viewer-GMLDXPON.js.map +1 -0
  266. package/dist/connect-account-identity.d.ts +8 -0
  267. package/dist/connect-accounts.d.ts +15 -0
  268. package/dist/connect-chooser.d.ts +18 -0
  269. package/dist/connect-panel.d.ts +18 -0
  270. package/dist/connect-setup.d.ts +18 -0
  271. package/dist/connect.d.ts +21 -0
  272. package/dist/connect.js +2149 -0
  273. package/dist/connect.js.map +1 -0
  274. package/dist/connection-catalog.d.ts +38 -0
  275. package/dist/connection-discovery.d.ts +12 -0
  276. package/dist/connection-installed.d.ts +17 -0
  277. package/dist/connection-logo.d.ts +9 -0
  278. package/dist/connection-service-logo.d.ts +8 -0
  279. package/dist/connection-service-presentation.d.ts +13 -0
  280. package/dist/connection-skeleton.d.ts +5 -0
  281. package/dist/connection-type-picker.d.ts +6 -0
  282. package/dist/conversation-timeline.d.ts +5 -0
  283. package/dist/desktop.d.ts +7 -0
  284. package/dist/desktop.js +27 -0
  285. package/dist/desktop.js.map +1 -0
  286. package/dist/device-authorization.d.ts +23 -0
  287. package/dist/diffs.d.ts +8 -0
  288. package/dist/diffs.js +15 -0
  289. package/dist/diffs.js.map +1 -0
  290. package/dist/discovery-cache.d.ts +5 -0
  291. package/dist/editor.d.ts +7 -0
  292. package/dist/editor.js +22 -0
  293. package/dist/editor.js.map +1 -0
  294. package/dist/embedded-new-voice-OCRNT6U5.js +18 -0
  295. package/dist/embedded-new-voice-OCRNT6U5.js.map +1 -0
  296. package/dist/embedded-voice-RPHPYVBT.js +18 -0
  297. package/dist/embedded-voice-RPHPYVBT.js.map +1 -0
  298. package/dist/{fleet-decision-row-GGCAT4E4.js → fleet-decision-row-SI63O5V4.js} +4 -1
  299. package/dist/fleet-decision-row-SI63O5V4.js.map +1 -0
  300. package/dist/hooks/latest-question.d.ts +25 -0
  301. package/dist/hooks/shared-machines-list.d.ts +4 -0
  302. package/dist/hooks/shared-query.d.ts +113 -0
  303. package/dist/hooks/use-attached-browsers.d.ts +1 -1
  304. package/dist/hooks/use-auth-runs.d.ts +1 -4
  305. package/dist/hooks/use-available-models.d.ts +1 -1
  306. package/dist/hooks/use-browser-frame-stream.d.ts +1 -1
  307. package/dist/hooks/use-browser-session.d.ts +12 -1
  308. package/dist/hooks/use-client-config-flags.d.ts +49 -0
  309. package/dist/hooks/use-codex-accounts.d.ts +59 -10
  310. package/dist/hooks/use-composer.d.ts +24 -2
  311. package/dist/hooks/use-computer-frame-stream.d.ts +1 -1
  312. package/dist/hooks/use-computer-input-posture.d.ts +13 -0
  313. package/dist/hooks/use-computer-session.d.ts +4 -0
  314. package/dist/hooks/use-connect.d.ts +23 -0
  315. package/dist/hooks/use-desktop-stream.d.ts +1 -1
  316. package/dist/hooks/use-file-attachments.d.ts +12 -0
  317. package/dist/hooks/use-goal.d.ts +2 -1
  318. package/dist/hooks/use-last-started-turn-policy.d.ts +5 -1
  319. package/dist/hooks/use-new-conversation.d.ts +56 -0
  320. package/dist/hooks/use-new-session-draft.d.ts +74 -0
  321. package/dist/hooks/use-realtime-voice-models.d.ts +7 -0
  322. package/dist/hooks/use-sandbox-files.d.ts +4 -1
  323. package/dist/hooks/use-session-conversation.d.ts +49 -0
  324. package/dist/hooks/use-session-events.d.ts +28 -7
  325. package/dist/hooks/use-session-mcp-approval-policy.d.ts +2 -2
  326. package/dist/hooks/use-session-model-account.d.ts +48 -0
  327. package/dist/hooks/use-supergrok-accounts.d.ts +7 -1
  328. package/dist/hooks/use-terminal-stream.d.ts +11 -5
  329. package/dist/hooks/use-usage.d.ts +40 -0
  330. package/dist/hooks/use-vaults.d.ts +53 -0
  331. package/dist/hooks/use-voice-input.d.ts +8 -1
  332. package/dist/hooks/use-workspace-edit.d.ts +4 -0
  333. package/dist/hooks/use-workspace-sessions.d.ts +22 -5
  334. package/dist/human-input-model.d.ts +122 -0
  335. package/dist/identity-link-accounts.d.ts +11 -0
  336. package/dist/identity-link-consent.d.ts +18 -0
  337. package/dist/index.d.ts +82 -20
  338. package/dist/index.js +2350 -6605
  339. package/dist/index.js.map +1 -1
  340. package/dist/interaction.d.ts +1 -1
  341. package/dist/interaction.js +14 -24
  342. package/dist/interaction.js.map +1 -1
  343. package/dist/latest-question-R77KWSUP.js +118 -0
  344. package/dist/latest-question-R77KWSUP.js.map +1 -0
  345. package/dist/lib/clipboard.d.ts +7 -0
  346. package/dist/lib/error-message.d.ts +7 -0
  347. package/dist/lib/format.d.ts +58 -4
  348. package/dist/lib/host-theme.d.ts +77 -0
  349. package/dist/lib/interaction-errors.d.ts +3 -0
  350. package/dist/lib/menu-styles.d.ts +22 -0
  351. package/dist/lib/notify-observer.d.ts +2 -0
  352. package/dist/lib/pierre-diffs-loader.d.ts +20 -0
  353. package/dist/lib/provider-recovery.d.ts +55 -0
  354. package/dist/lib/scrollbars.d.ts +11 -0
  355. package/dist/lib/terminal-input-readiness.d.ts +11 -0
  356. package/dist/lib/transient-retry.d.ts +25 -0
  357. package/dist/lib/workbench-peers.d.ts +36 -0
  358. package/dist/lib/xterm-theme.d.ts +7 -5
  359. package/dist/machines.js +9 -5
  360. package/dist/markdown-table-layout-3PV2UAAH.js +113 -0
  361. package/dist/markdown-table-layout-3PV2UAAH.js.map +1 -0
  362. package/dist/mcp-connection-status.d.ts +14 -0
  363. package/dist/model-mark-paths.d.ts +34 -0
  364. package/dist/model-mark-paths.js +16 -0
  365. package/dist/model-mark-paths.js.map +1 -0
  366. package/dist/model-picker-model.d.ts +111 -0
  367. package/dist/model-picker-model.js +25 -0
  368. package/dist/model-picker-model.js.map +1 -0
  369. package/dist/model-policy-picker-menu-7GJ5URPR.js +17 -0
  370. package/dist/model-policy-picker-menu-7GJ5URPR.js.map +1 -0
  371. package/dist/model-policy.d.ts +30 -3
  372. package/dist/model-policy.js +14 -1
  373. package/dist/native-previews.d.ts +28 -0
  374. package/dist/native-previews.js +82 -0
  375. package/dist/native-previews.js.map +1 -0
  376. package/dist/new-session-draft.d.ts +7 -0
  377. package/dist/new-session-draft.js +639 -0
  378. package/dist/new-session-draft.js.map +1 -0
  379. package/dist/notification-text.d.ts +27 -0
  380. package/dist/{noto-sans-arabic-loader-IA2T4X2A.js → noto-sans-arabic-loader-XSH2KYWJ.js} +3 -1
  381. package/dist/{noto-sans-arabic-loader-IA2T4X2A.js.map → noto-sans-arabic-loader-XSH2KYWJ.js.map} +1 -1
  382. package/dist/{noto-sans-jp-loader.generated-HFGLYBR3.js → noto-sans-jp-loader.generated-MR5L6V7K.js} +3 -1
  383. package/dist/{noto-sans-jp-loader.generated-HFGLYBR3.js.map → noto-sans-jp-loader.generated-MR5L6V7K.js.map} +1 -1
  384. package/dist/older-history.d.ts +3 -2
  385. package/dist/organization-model.d.ts +32 -0
  386. package/dist/organization-model.js +65 -0
  387. package/dist/organization-model.js.map +1 -0
  388. package/dist/{platform-activity-row-BJHUHXAT.js → platform-activity-row-5OCKOQWZ.js} +16 -78
  389. package/dist/platform-activity-row-5OCKOQWZ.js.map +1 -0
  390. package/dist/plugin-details.d.ts +14 -0
  391. package/dist/plugin-discovery.d.ts +25 -0
  392. package/dist/preview-loading-paint.d.ts +20 -0
  393. package/dist/provider.d.ts +25 -2
  394. package/dist/queue-presentation-model.d.ts +72 -0
  395. package/dist/queue-presentation-model.js +38 -0
  396. package/dist/queue-presentation-model.js.map +1 -0
  397. package/dist/{queue-surface-implementation-BSKUWHRI.js → queue-surface-implementation-GJBH7NKO.js} +65 -265
  398. package/dist/queue-surface-implementation-GJBH7NKO.js.map +1 -0
  399. package/dist/realtime/embedded-new-voice.d.ts +1 -0
  400. package/dist/realtime/embedded-voice.d.ts +1 -0
  401. package/dist/realtime/realtime-control.d.ts +4 -65
  402. package/dist/realtime/session-realtime.d.ts +78 -0
  403. package/dist/realtime.js +25 -1294
  404. package/dist/realtime.js.map +1 -1
  405. package/dist/sandbox-files-O27IPOZW.js +21 -0
  406. package/dist/sandbox-files-O27IPOZW.js.map +1 -0
  407. package/dist/sandbox-label-model.d.ts +30 -0
  408. package/dist/sandbox-label-model.js +20 -0
  409. package/dist/sandbox-label-model.js.map +1 -0
  410. package/dist/scrollbars.d.ts +1 -0
  411. package/dist/scrollbars.js +10 -0
  412. package/dist/scrollbars.js.map +1 -0
  413. package/dist/secret-reference-label.d.ts +14 -0
  414. package/dist/secrets-ui.d.ts +57 -0
  415. package/dist/session-agents-model.d.ts +10 -0
  416. package/dist/session-agents-model.js +25 -0
  417. package/dist/session-agents-model.js.map +1 -0
  418. package/dist/session-attention-model.d.ts +8 -0
  419. package/dist/session-attention-model.js +47 -0
  420. package/dist/session-attention-model.js.map +1 -0
  421. package/dist/session-auth-recommendation.d.ts +5 -0
  422. package/dist/session-capability-policy.d.ts +31 -0
  423. package/dist/session-feedback-model.d.ts +20 -0
  424. package/dist/session-feedback-model.js +56 -0
  425. package/dist/session-feedback-model.js.map +1 -0
  426. package/dist/session-list-model.d.ts +138 -0
  427. package/dist/session-list-model.js +274 -0
  428. package/dist/session-list-model.js.map +1 -0
  429. package/dist/session-realtime-7DJOIHQW.js +21 -0
  430. package/dist/session-realtime-7DJOIHQW.js.map +1 -0
  431. package/dist/session-realtime.d.ts +7 -0
  432. package/dist/session-realtime.js +19 -0
  433. package/dist/session-realtime.js.map +1 -0
  434. package/dist/session-status-model.d.ts +36 -0
  435. package/dist/session-ui.d.ts +39 -1
  436. package/dist/session-ui.js +126 -12
  437. package/dist/session-ui.js.map +1 -1
  438. package/dist/session.d.ts +8 -2
  439. package/dist/session.js +35 -20
  440. package/dist/site-snapshot.d.ts +14 -0
  441. package/dist/sites-ui.d.ts +24 -0
  442. package/dist/sites.d.ts +3 -0
  443. package/dist/sites.js +14 -0
  444. package/dist/sites.js.map +1 -0
  445. package/dist/skill-discovery.d.ts +47 -0
  446. package/dist/terminal.d.ts +8 -0
  447. package/dist/terminal.js +32 -0
  448. package/dist/terminal.js.map +1 -0
  449. package/dist/testing/session-scenarios.d.ts +10 -0
  450. package/dist/testing/session-scenarios.js +367 -0
  451. package/dist/testing/session-scenarios.js.map +1 -0
  452. package/dist/timeline/activity-rail.d.ts +11 -2
  453. package/dist/timeline/agent-identity.d.ts +30 -0
  454. package/dist/timeline/agent-row.d.ts +31 -0
  455. package/dist/timeline/allowance-exhausted-row.d.ts +24 -0
  456. package/dist/timeline/compaction-copy.d.ts +46 -0
  457. package/dist/timeline/entrance.d.ts +13 -1
  458. package/dist/timeline/focus-sequence.d.ts +9 -0
  459. package/dist/timeline/genie-copy.d.ts +3 -0
  460. package/dist/timeline/genie-loading.d.ts +47 -0
  461. package/dist/timeline/index.d.ts +10 -5
  462. package/dist/timeline/knowledge-receipt.d.ts +17 -0
  463. package/dist/timeline/message-sender.d.ts +19 -0
  464. package/dist/timeline/notice-presentation.d.ts +13 -0
  465. package/dist/timeline/parsers.d.ts +11 -0
  466. package/dist/timeline/patch-apply-command.d.ts +18 -0
  467. package/dist/timeline/platform-activity-presentation.d.ts +21 -0
  468. package/dist/timeline/platform-activity-row.d.ts +1 -2
  469. package/dist/timeline/presented-image.d.ts +11 -0
  470. package/dist/timeline/projection.d.ts +31 -2
  471. package/dist/timeline/provider-logo.d.ts +15 -0
  472. package/dist/timeline/question-nav-model.d.ts +23 -0
  473. package/dist/timeline/registry.d.ts +12 -1
  474. package/dist/timeline/retained-image.d.ts +18 -0
  475. package/dist/timeline/retained-loaders.d.ts +27 -0
  476. package/dist/timeline/rolling-activity.d.ts +11 -0
  477. package/dist/timeline/screenshot-lightbox.d.ts +23 -1
  478. package/dist/timeline/session-usage-limit-row.d.ts +11 -0
  479. package/dist/timeline/shared.d.ts +4 -1
  480. package/dist/timeline/startup-dispatch-details.d.ts +5 -0
  481. package/dist/timeline/startup-preference.d.ts +3 -0
  482. package/dist/timeline/startup-timings.d.ts +4 -0
  483. package/dist/timeline/tool-display-name.d.ts +5 -2
  484. package/dist/timeline/tool-presentation.d.ts +172 -0
  485. package/dist/timeline/turn-summary-model.d.ts +95 -0
  486. package/dist/timeline/turn-summary.d.ts +20 -54
  487. package/dist/timeline/types.d.ts +179 -7
  488. package/dist/timeline/work-presentation.d.ts +60 -0
  489. package/dist/timeline-annotation-markers-U3G66KUD.js +166 -0
  490. package/dist/timeline-annotation-markers-U3G66KUD.js.map +1 -0
  491. package/dist/timeline-annotation-selection-BI7QTPTZ.js +242 -0
  492. package/dist/timeline-annotation-selection-BI7QTPTZ.js.map +1 -0
  493. package/dist/timeline-annotations-dialog-FOMHSDTE.js +274 -0
  494. package/dist/timeline-annotations-dialog-FOMHSDTE.js.map +1 -0
  495. package/dist/timeline-model.d.ts +29 -0
  496. package/dist/timeline-model.js +254 -0
  497. package/dist/timeline-model.js.map +1 -0
  498. package/dist/usage/allowance-copy.d.ts +25 -0
  499. package/dist/usage/session-usage-limit.d.ts +88 -0
  500. package/dist/usage/summary.d.ts +35 -0
  501. package/dist/usage.d.ts +17 -0
  502. package/dist/usage.js +1187 -0
  503. package/dist/usage.js.map +1 -0
  504. package/dist/voice-recording-owner.d.ts +7 -0
  505. package/package.json +107 -7
  506. package/src/accounts.tsx +116 -14
  507. package/src/approvals.ts +8 -1
  508. package/src/artifacts-spreadsheet.ts +1 -0
  509. package/src/artifacts.ts +44 -0
  510. package/src/assets/README.md +8 -0
  511. package/src/assets/gmail.ico +0 -0
  512. package/src/assets/outlook.ico +0 -0
  513. package/src/capability-catalog-row.tsx +94 -0
  514. package/src/capability-logo-fallback.ts +22 -0
  515. package/src/client.ts +20 -31
  516. package/src/commands/registry.ts +18 -15
  517. package/src/commands/types.ts +2 -0
  518. package/src/components/anthropic-mark.tsx +10 -0
  519. package/src/components/approval-surface.tsx +401 -138
  520. package/src/components/artifacts/artifact-chrome.tsx +413 -0
  521. package/src/components/artifacts/artifact-sandbox.tsx +189 -0
  522. package/src/components/artifacts/artifact-surface.tsx +40 -20
  523. package/src/components/artifacts/chat-interactive-block.tsx +260 -0
  524. package/src/components/artifacts/deferred-chat-media.tsx +67 -0
  525. package/src/components/artifacts/document-editor.tsx +141 -16
  526. package/src/components/artifacts/editable-artifact-ui.tsx +4 -2
  527. package/src/components/artifacts/editable-artifact-view.tsx +197 -0
  528. package/src/components/artifacts/editable-artifact-workbench.tsx +5 -2
  529. package/src/components/artifacts/editable-document.tsx +37 -36
  530. package/src/components/artifacts/editable-presentation.tsx +36 -18
  531. package/src/components/artifacts/editable-spreadsheet.tsx +543 -103
  532. package/src/components/artifacts/index.ts +45 -0
  533. package/src/components/artifacts/inline-html-document.ts +24 -0
  534. package/src/components/artifacts/latest-task-runner.ts +49 -0
  535. package/src/components/artifacts/presentation-editor.tsx +323 -67
  536. package/src/components/artifacts/published-html-artifact-frame.tsx +122 -5
  537. package/src/components/artifacts/session-artifact-viewer.tsx +378 -0
  538. package/src/components/artifacts/site-view.tsx +121 -0
  539. package/src/components/artifacts/spreadsheet-canvas.ts +5 -10
  540. package/src/components/artifacts/spreadsheet-command-queue.ts +184 -0
  541. package/src/components/artifacts/spreadsheet-download.tsx +109 -0
  542. package/src/components/artifacts/spreadsheet-general-display.ts +43 -0
  543. package/src/components/artifacts/spreadsheet-grid.tsx +344 -144
  544. package/src/components/artifacts/spreadsheet-resize.tsx +421 -0
  545. package/src/components/artifacts/spreadsheet-submissions.tsx +46 -0
  546. package/src/components/artifacts/visualization-assets/base.css +1015 -0
  547. package/src/components/artifacts/visualization-assets/helpers.html +349 -0
  548. package/src/components/artifacts/visualization-assets.gen.ts +3 -0
  549. package/src/components/browser-select-control.tsx +312 -0
  550. package/src/components/browser-viewer.tsx +778 -318
  551. package/src/components/chat-composer.tsx +47 -5
  552. package/src/components/child-session-link.tsx +36 -0
  553. package/src/components/claude-mark.tsx +11 -0
  554. package/src/components/code-editor.tsx +13 -16
  555. package/src/components/composer-transcription-control.tsx +128 -30
  556. package/src/components/composer.tsx +404 -195
  557. package/src/components/computer-viewer.tsx +880 -253
  558. package/src/components/copy-button.tsx +13 -5
  559. package/src/components/desktop-viewer.tsx +1 -1
  560. package/src/components/enrollment-consent.tsx +1 -1
  561. package/src/components/enrollment-device-flow.tsx +1 -1
  562. package/src/components/file-browser.tsx +10 -14
  563. package/src/components/fleet-tile.tsx +9 -18
  564. package/src/components/generated-video-player.tsx +4 -2
  565. package/src/components/grok-mark.tsx +34 -0
  566. package/src/components/human-input-form.tsx +590 -283
  567. package/src/components/human-input-surface.tsx +11 -0
  568. package/src/components/interaction-intervention-banner.tsx +2 -2
  569. package/src/components/linkified-text.tsx +79 -0
  570. package/src/components/machine-card.tsx +35 -78
  571. package/src/components/machine-dock-bar.tsx +1 -1
  572. package/src/components/machine-input-display.ts +197 -3
  573. package/src/components/machines/agent-status-icon.tsx +31 -0
  574. package/src/components/machines/machine-detail.tsx +200 -31
  575. package/src/components/machines/machine-operation-policy.tsx +1 -1
  576. package/src/components/machines/machine-status.ts +241 -0
  577. package/src/components/machines-dashboard.tsx +2 -17
  578. package/src/components/markdown-table-layout.ts +143 -0
  579. package/src/components/markdown.tsx +466 -129
  580. package/src/components/message-timeline.tsx +2567 -728
  581. package/src/components/model-mark.tsx +102 -0
  582. package/src/components/model-picker.tsx +15 -4
  583. package/src/components/model-policy-picker-menu.tsx +371 -0
  584. package/src/components/model-policy-picker.tsx +256 -412
  585. package/src/components/new-conversation.tsx +221 -0
  586. package/src/components/open-geni-chat.tsx +309 -0
  587. package/src/components/open-geni-links.tsx +179 -0
  588. package/src/components/openrouter-mark.tsx +13 -0
  589. package/src/components/opper-mark.tsx +18 -0
  590. package/src/components/pierre-diff.tsx +41 -16
  591. package/src/components/pierre-file.tsx +35 -10
  592. package/src/components/preview-loading.tsx +109 -0
  593. package/src/components/provider-recovery-notice.tsx +49 -0
  594. package/src/components/queue-item-content.ts +14 -0
  595. package/src/components/queue-surface-implementation.tsx +51 -356
  596. package/src/components/queue-surface-state.tsx +3 -1
  597. package/src/components/rehype-secret-refs.ts +98 -0
  598. package/src/components/remark-soft-line-breaks.ts +166 -0
  599. package/src/components/sandbox-files.tsx +91 -15
  600. package/src/components/sandbox-terminal.tsx +84 -13
  601. package/src/components/sandbox-workspace.tsx +147 -51
  602. package/src/components/secret-question-field.tsx +324 -0
  603. package/src/components/secret-ref-chip.tsx +185 -0
  604. package/src/components/session-capability-frame.tsx +197 -0
  605. package/src/components/session-chrome.tsx +842 -251
  606. package/src/components/session-commands-panel.tsx +126 -0
  607. package/src/components/session-commands.tsx +18 -0
  608. package/src/components/session-connection-request.tsx +97 -0
  609. package/src/components/session-conversation.tsx +876 -0
  610. package/src/components/session-list.tsx +257 -0
  611. package/src/components/session-mcp-capability-card.tsx +680 -0
  612. package/src/components/session-proxy-scope.tsx +153 -0
  613. package/src/components/session-status.tsx +26 -17
  614. package/src/components/session-usage-limit-notice.tsx +174 -0
  615. package/src/components/timeline-anchor.tsx +119 -0
  616. package/src/components/timeline-annotation-chrome.tsx +196 -0
  617. package/src/components/timeline-annotation-layout.ts +268 -0
  618. package/src/components/timeline-annotation-markers.tsx +185 -0
  619. package/src/components/timeline-annotation-reveal-context.ts +9 -0
  620. package/src/components/timeline-annotation-selection.tsx +106 -54
  621. package/src/components/timeline-annotation-shared.ts +245 -0
  622. package/src/components/timeline-annotations-dialog.tsx +185 -128
  623. package/src/components/timeline-annotations.tsx +189 -45
  624. package/src/components/timeline-reading-progress.ts +80 -0
  625. package/src/components/timeline-search.tsx +168 -0
  626. package/src/components/timeline-settlement.ts +60 -0
  627. package/src/components/tip-follow.ts +52 -0
  628. package/src/components/tool-action-review.tsx +650 -0
  629. package/src/components/tool-review-history.tsx +88 -0
  630. package/src/components/tooltip.tsx +38 -5
  631. package/src/components/usage-limit-notice.tsx +179 -0
  632. package/src/components/usage-member-list.tsx +792 -0
  633. package/src/components/usage-meter.tsx +382 -0
  634. package/src/components/use-viewer-menu-dismiss.ts +33 -0
  635. package/src/components/user-message-body.tsx +27 -2
  636. package/src/components/workspace-dock.tsx +18 -1
  637. package/src/composer-messages.ts +150 -0
  638. package/src/composer-voice-events.ts +12 -0
  639. package/src/composer.ts +6 -1
  640. package/src/connect-account-identity.tsx +34 -0
  641. package/src/connect-accounts.tsx +233 -0
  642. package/src/connect-chooser.tsx +336 -0
  643. package/src/connect-panel.tsx +99 -0
  644. package/src/connect-setup.tsx +355 -0
  645. package/src/connect.ts +60 -0
  646. package/src/connection-assets.d.ts +4 -0
  647. package/src/connection-catalog.tsx +162 -0
  648. package/src/connection-discovery.tsx +238 -0
  649. package/src/connection-installed.tsx +51 -0
  650. package/src/connection-logo.tsx +37 -0
  651. package/src/connection-service-logo.tsx +55 -0
  652. package/src/connection-service-presentation.ts +46 -0
  653. package/src/connection-skeleton.tsx +16 -0
  654. package/src/connection-type-picker.tsx +36 -0
  655. package/src/conversation-timeline.ts +92 -0
  656. package/src/desktop.ts +24 -0
  657. package/src/device-authorization.tsx +98 -0
  658. package/src/diffs.ts +16 -0
  659. package/src/discovery-cache.ts +42 -0
  660. package/src/editor.ts +13 -0
  661. package/src/hooks/internal.ts +3 -2
  662. package/src/hooks/latest-question.ts +164 -0
  663. package/src/hooks/shared-machines-list.ts +34 -1
  664. package/src/hooks/shared-query.ts +721 -0
  665. package/src/hooks/use-attached-browsers.ts +1 -1
  666. package/src/hooks/use-auth-runs.ts +0 -27
  667. package/src/hooks/use-available-models.ts +21 -15
  668. package/src/hooks/use-browser-frame-stream.ts +19 -2
  669. package/src/hooks/use-browser-session.ts +680 -205
  670. package/src/hooks/use-browser-sessions.ts +32 -1
  671. package/src/hooks/use-client-config-flags.ts +118 -0
  672. package/src/hooks/use-codex-accounts.ts +247 -47
  673. package/src/hooks/use-composer.ts +276 -47
  674. package/src/hooks/use-computer-frame-stream.ts +25 -7
  675. package/src/hooks/use-computer-input-posture.ts +94 -0
  676. package/src/hooks/use-computer-session.ts +409 -95
  677. package/src/hooks/use-connect.ts +23 -0
  678. package/src/hooks/use-desktop-stream.ts +19 -28
  679. package/src/hooks/use-file-attachments.ts +80 -4
  680. package/src/hooks/use-goal.ts +107 -13
  681. package/src/hooks/use-last-started-turn-policy.ts +46 -14
  682. package/src/hooks/use-machines.ts +4 -0
  683. package/src/hooks/use-new-conversation.ts +374 -0
  684. package/src/hooks/use-new-session-draft.ts +813 -0
  685. package/src/hooks/use-realtime-voice-models.ts +46 -0
  686. package/src/hooks/use-sandbox-files.ts +68 -20
  687. package/src/hooks/use-session-background-commands.ts +22 -11
  688. package/src/hooks/use-session-capabilities.ts +3 -2
  689. package/src/hooks/use-session-conversation.ts +150 -0
  690. package/src/hooks/use-session-events.ts +703 -382
  691. package/src/hooks/use-session-lineage.ts +20 -16
  692. package/src/hooks/use-session-mcp-approval-policy.ts +13 -5
  693. package/src/hooks/use-session-model-account.ts +174 -0
  694. package/src/hooks/use-session.ts +53 -21
  695. package/src/hooks/use-slash-commands.ts +6 -11
  696. package/src/hooks/use-supergrok-accounts.ts +22 -8
  697. package/src/hooks/use-terminal-stream.ts +153 -27
  698. package/src/hooks/use-transcription.ts +6 -0
  699. package/src/hooks/use-turn-queue.ts +2 -1
  700. package/src/hooks/use-usage.ts +100 -0
  701. package/src/hooks/use-vaults.ts +153 -0
  702. package/src/hooks/use-video-artifact-playback.ts +1 -1
  703. package/src/hooks/use-voice-input.ts +127 -19
  704. package/src/hooks/use-workspace-capture.ts +3 -2
  705. package/src/hooks/use-workspace-edit.ts +23 -5
  706. package/src/hooks/use-workspace-sessions.ts +97 -32
  707. package/src/human-input-model.ts +359 -0
  708. package/src/identity-link-accounts.tsx +148 -0
  709. package/src/identity-link-consent.tsx +192 -0
  710. package/src/index.ts +262 -16
  711. package/src/interaction.ts +1 -0
  712. package/src/lib/clipboard.ts +29 -0
  713. package/src/lib/error-message.ts +37 -0
  714. package/src/lib/format.ts +213 -16
  715. package/src/lib/host-theme.ts +529 -0
  716. package/src/lib/interaction-errors.ts +15 -0
  717. package/src/lib/menu-styles.ts +44 -0
  718. package/src/lib/notify-observer.ts +15 -0
  719. package/src/lib/pierre-diffs-loader.ts +53 -0
  720. package/src/lib/provider-recovery.ts +243 -0
  721. package/src/lib/scrollbars.ts +30 -0
  722. package/src/lib/terminal-input-readiness.ts +51 -0
  723. package/src/lib/transient-retry.ts +99 -0
  724. package/src/lib/workbench-peers.ts +62 -0
  725. package/src/lib/xterm-theme.ts +23 -21
  726. package/src/mcp-connection-status.ts +35 -0
  727. package/src/model-mark-paths.ts +53 -0
  728. package/src/model-picker-model.ts +330 -0
  729. package/src/model-policy.ts +299 -74
  730. package/src/native-previews.ts +100 -0
  731. package/src/new-session-draft.ts +22 -0
  732. package/src/notification-text.ts +81 -0
  733. package/src/older-history.ts +22 -4
  734. package/src/organization-model.ts +118 -0
  735. package/src/plugin-details.tsx +185 -0
  736. package/src/plugin-discovery.tsx +196 -0
  737. package/src/preview-loading-paint.ts +68 -0
  738. package/src/provider.tsx +74 -15
  739. package/src/queue-presentation-model.ts +464 -0
  740. package/src/realtime/dropdown-menu.tsx +19 -12
  741. package/src/realtime/embedded-new-voice.tsx +1 -0
  742. package/src/realtime/embedded-voice.tsx +3 -0
  743. package/src/realtime/realtime-control.tsx +138 -501
  744. package/src/realtime/session-realtime.ts +566 -0
  745. package/src/sandbox-label-model.ts +53 -0
  746. package/src/scrollbars.ts +3 -0
  747. package/src/secret-reference-label.ts +43 -0
  748. package/src/secrets-ui.tsx +59 -0
  749. package/src/session-agents-model.ts +33 -0
  750. package/src/session-attention-model.ts +62 -0
  751. package/src/session-auth-recommendation.ts +48 -0
  752. package/src/session-capability-policy.ts +196 -0
  753. package/src/session-context.ts +3 -4
  754. package/src/session-feedback-model.ts +95 -0
  755. package/src/session-list-model.ts +434 -0
  756. package/src/session-realtime.ts +18 -0
  757. package/src/session-status-model.ts +99 -0
  758. package/src/session-ui.ts +98 -1
  759. package/src/session.ts +17 -1
  760. package/src/site-snapshot.ts +74 -0
  761. package/src/sites-ui.tsx +348 -0
  762. package/src/sites.ts +3 -0
  763. package/src/skill-discovery.tsx +208 -0
  764. package/src/terminal.ts +26 -0
  765. package/src/testing/session-scenarios.ts +404 -0
  766. package/src/timeline/activity-rail.tsx +242 -101
  767. package/src/timeline/agent-identity.tsx +84 -0
  768. package/src/timeline/agent-row.tsx +231 -0
  769. package/src/timeline/allowance-exhausted-row.tsx +86 -0
  770. package/src/timeline/compaction-copy.ts +115 -0
  771. package/src/timeline/entrance.tsx +28 -3
  772. package/src/timeline/fleet-decision-projection.ts +2 -1
  773. package/src/timeline/fleet-decision-row.tsx +1 -0
  774. package/src/timeline/focus-sequence.ts +44 -0
  775. package/src/timeline/genie-copy.ts +19 -0
  776. package/src/timeline/genie-loading.tsx +143 -0
  777. package/src/timeline/index.ts +30 -2
  778. package/src/timeline/knowledge-receipt.tsx +100 -0
  779. package/src/timeline/message-sender.tsx +71 -0
  780. package/src/timeline/notice-presentation.ts +48 -0
  781. package/src/timeline/parsers.ts +42 -2
  782. package/src/timeline/patch-apply-command.tsx +135 -0
  783. package/src/timeline/platform-activity-presentation.ts +166 -0
  784. package/src/timeline/platform-activity-row.tsx +15 -90
  785. package/src/timeline/presented-image.ts +63 -0
  786. package/src/timeline/projection.ts +1746 -76
  787. package/src/timeline/provider-logo.tsx +53 -0
  788. package/src/timeline/question-nav-model.ts +28 -0
  789. package/src/timeline/registry.ts +26 -4
  790. package/src/timeline/retained-image.ts +97 -0
  791. package/src/timeline/retained-loaders.ts +91 -0
  792. package/src/timeline/rolling-activity.tsx +80 -0
  793. package/src/timeline/screenshot-lightbox.tsx +228 -5
  794. package/src/timeline/session-usage-limit-row.tsx +42 -0
  795. package/src/timeline/shared.tsx +42 -15
  796. package/src/timeline/startup-dispatch-details.tsx +36 -0
  797. package/src/timeline/startup-preference.ts +33 -0
  798. package/src/timeline/startup-timings.tsx +145 -0
  799. package/src/timeline/tool-display-name.ts +19 -7
  800. package/src/timeline/tool-presentation.ts +1316 -0
  801. package/src/timeline/tool-renderers.tsx +835 -1138
  802. package/src/timeline/turn-summary-model.ts +343 -0
  803. package/src/timeline/turn-summary.tsx +272 -365
  804. package/src/timeline/types.ts +189 -6
  805. package/src/timeline/work-presentation.ts +189 -0
  806. package/src/timeline-model.ts +143 -0
  807. package/src/usage/allowance-copy.ts +64 -0
  808. package/src/usage/session-usage-limit.ts +266 -0
  809. package/src/usage/summary.ts +93 -0
  810. package/src/usage.ts +70 -0
  811. package/src/voice-recording-owner.ts +22 -0
  812. package/styles/compiled.css +2319 -748
  813. package/styles/connect.css +290 -0
  814. package/styles/connect.d.ts +1 -0
  815. package/styles/effective-tokens.css +1 -0
  816. package/styles/index.css +309 -9
  817. package/styles/responsive.css +99 -7
  818. package/styles/session-capability.css +44 -0
  819. package/styles/tokens.css +134 -66
  820. package/dist/browser-viewer-AEFHUYZK.js +0 -14
  821. package/dist/chunk-4MDLEHXL.js.map +0 -1
  822. package/dist/chunk-5YK2ZDIG.js.map +0 -1
  823. package/dist/chunk-D3UIAJKY.js.map +0 -1
  824. package/dist/chunk-ELIYWBZR.js.map +0 -1
  825. package/dist/chunk-H5YGYNXS.js.map +0 -1
  826. package/dist/chunk-HQVCKCLG.js +0 -9458
  827. package/dist/chunk-HQVCKCLG.js.map +0 -1
  828. package/dist/chunk-HUIKIDM5.js.map +0 -1
  829. package/dist/chunk-ICA6R6TW.js.map +0 -1
  830. package/dist/chunk-JVYQRRC4.js.map +0 -1
  831. package/dist/chunk-KCGXPP5V.js.map +0 -1
  832. package/dist/chunk-KZ73RL76.js.map +0 -1
  833. package/dist/chunk-LAKLF4PA.js +0 -141
  834. package/dist/chunk-LAKLF4PA.js.map +0 -1
  835. package/dist/chunk-MZ2G2XBA.js.map +0 -1
  836. package/dist/chunk-NEXLLTP4.js.map +0 -1
  837. package/dist/chunk-OAM4WAAM.js.map +0 -1
  838. package/dist/chunk-PEI6RANI.js.map +0 -1
  839. package/dist/chunk-RGALCTWO.js.map +0 -1
  840. package/dist/chunk-W6NFJXSA.js +0 -454
  841. package/dist/chunk-W6NFJXSA.js.map +0 -1
  842. package/dist/chunk-WSK7G5LE.js +0 -170
  843. package/dist/chunk-WSK7G5LE.js.map +0 -1
  844. package/dist/chunk-X4A66EWZ.js +0 -223
  845. package/dist/chunk-X4A66EWZ.js.map +0 -1
  846. package/dist/chunk-XXWH2JLC.js.map +0 -1
  847. package/dist/chunk-YFKJ7VZH.js +0 -268
  848. package/dist/chunk-YFKJ7VZH.js.map +0 -1
  849. package/dist/chunk-YJFGAFBD.js.map +0 -1
  850. package/dist/computer-viewer-FWEZISW4.js +0 -16
  851. package/dist/fleet-decision-row-GGCAT4E4.js.map +0 -1
  852. package/dist/hooks/use-environments.d.ts +0 -41
  853. package/dist/hooks/use-packs.d.ts +0 -32
  854. package/dist/platform-activity-row-BJHUHXAT.js.map +0 -1
  855. package/dist/queue-surface-implementation-BSKUWHRI.js.map +0 -1
  856. package/dist/timeline-annotation-selection-3L7LHGG2.js +0 -187
  857. package/dist/timeline-annotation-selection-3L7LHGG2.js.map +0 -1
  858. package/dist/timeline-annotations-dialog-U7EVLR75.js +0 -196
  859. package/dist/timeline-annotations-dialog-U7EVLR75.js.map +0 -1
  860. package/src/hooks/use-environments.ts +0 -182
  861. package/src/hooks/use-packs.ts +0 -157
  862. /package/dist/{browser-viewer-AEFHUYZK.js.map → browser-viewer-ZWR6MWJ7.js.map} +0 -0
  863. /package/dist/{computer-viewer-FWEZISW4.js.map → chat-interactive-block-BO2IWXVK.js.map} +0 -0
@@ -1,79 +1,68 @@
1
+ import { ClaudeMark } from "./claude-mark";
2
+ import { GrokMark } from "./grok-mark";
3
+ import { ChatGptMark, ModelMark, modelHasMark } from "./model-mark";
4
+ import { modelDisplayName, modelLogoUrl } from "@opengeni/sdk/model-display";
1
5
  import type { ClientModel, LatencyMode, ReasoningEffort } from "@opengeni/sdk";
2
6
  import {
3
- CheckIcon,
4
7
  ChevronDownIcon,
5
8
  ChevronLeftIcon,
6
9
  ChevronRightIcon,
7
10
  Globe2Icon,
8
11
  KeyRoundIcon,
12
+ SparklesIcon,
9
13
  ZapIcon,
10
14
  } from "lucide-react";
11
15
  import { motion, useReducedMotion } from "motion/react";
12
- import { DropdownMenu } from "radix-ui";
13
16
  import {
14
- useEffect,
17
+ Suspense,
18
+ lazy,
15
19
  useMemo,
20
+ useId,
16
21
  useState,
17
22
  type CSSProperties,
18
23
  type ReactNode,
19
- type SVGProps,
20
24
  } from "react";
21
25
  import { cn } from "../lib/cn";
26
+ import {
27
+ billingClassForMissingSelection,
28
+ defaultModelPolicyPickerMessages,
29
+ effectiveRows as sharedEffectiveRows,
30
+ groupPresentationFor,
31
+ SCOPED_BILLING_HINTS,
32
+ type ModelPickerGroupPresentation,
33
+ type ModelPolicyPickerMessages,
34
+ } from "../model-picker-model";
35
+ import { MENU_CHEVRON_CLASS } from "../lib/menu-styles";
22
36
  import { usePortalTokenSource, usePortalTokenStyle } from "../lib/use-portal-token-style";
23
37
  import {
24
- effortOptionsForModel,
25
38
  findPickerRow,
26
- groupPickerRowsByBillingClass,
27
39
  labelReasoningEffort,
28
- projectClientModelRows,
29
- runnableLatencyModesForModel,
40
+ modelOffersEffortChoice,
30
41
  type PickerBillingClass,
31
42
  type PickerModelRow,
32
43
  } from "../model-policy";
33
44
 
34
- type ClientPickerModelRow = PickerModelRow<ClientModel>;
35
-
36
- type NavLevel = "providers" | "models" | "thinking";
45
+ const LazyModelPolicyPickerMenu = lazy(() =>
46
+ import("./model-policy-picker-menu").then(({ ModelPolicyPickerPopover }) => ({
47
+ default: ModelPolicyPickerPopover,
48
+ })),
49
+ );
37
50
 
38
- type PickerNavState = {
39
- level: NavLevel;
40
- rail: PickerBillingClass | null;
41
- modelId: string | null;
42
- };
43
-
44
- type NavUpdater = PickerNavState | ((previous: PickerNavState) => PickerNavState);
51
+ type ClientPickerModelRow = PickerModelRow<ClientModel>;
45
52
 
46
- export type ModelPolicyPickerMessages = {
47
- label: string;
48
- loading: string;
49
- noModels: string;
50
- thinking: string;
51
- fast: string;
52
- fastRateHint: string;
53
- codexOnly: string;
54
- billingHints: Record<PickerBillingClass, string>;
55
- };
53
+ /** Presentation only; never changes model identity, billing or availability. */
54
+ export type ModelPolicyPickerGroupPresentation = ModelPickerGroupPresentation<ReactNode>;
56
55
 
57
- export const defaultModelPolicyPickerMessages: ModelPolicyPickerMessages = {
58
- label: "Model and effort",
59
- loading: "Loading model catalog…",
60
- noModels: "No models available.",
61
- thinking: "Thinking",
62
- fast: "Fast",
63
- fastRateHint: "2× rate",
64
- codexOnly: "Codex-only session",
65
- billingHints: {
66
- opengeni_credits: "Will use credits",
67
- external: "Provider terms and limits apply",
68
- codex_subscription: "ChatGPT / Codex plan",
69
- supergrok_subscription: "SuperGrok / xAI plan",
70
- byok: "Billed to your AI Gateway",
71
- },
72
- };
56
+ export { defaultModelPolicyPickerMessages, groupPresentationFor, SCOPED_BILLING_HINTS };
57
+ export type { ModelPolicyPickerMessages };
73
58
 
74
59
  export type ModelPolicyPickerProps = {
60
+ /** Host branding for payment-source groups, shared by menu and trigger. */
61
+ groupPresentation?: ModelPolicyPickerGroupPresentation | undefined;
75
62
  /** Lightweight deployment models. Catalog rows take precedence when supplied. */
76
63
  models?: ClientModel[] | undefined;
64
+ /** Warn only when the draft actually contains images this model cannot view. */
65
+ hasImageAttachments?: boolean | undefined;
77
66
  /** Catalog-backed rows with availability and billing-class truth. */
78
67
  rows?: PickerModelRow[] | undefined;
79
68
  model: string;
@@ -89,17 +78,37 @@ export type ModelPolicyPickerProps = {
89
78
  onOpenChange?: ((open: boolean) => void) | undefined;
90
79
  /** Non-Codex models stay visible but cannot be selected. */
91
80
  codexOnly?: boolean | undefined;
92
- /** Resets drill-down navigation when the session scope changes. */
81
+ /** Identity of the current session scope. */
93
82
  sessionKey?: string | undefined;
94
83
  /** Prefer bottom on new-chat surfaces and top for bottom-docked composers. */
95
84
  menuSide?: "top" | "bottom" | undefined;
85
+ /**
86
+ * Default true: show models the way people choose them, with clean names,
87
+ * maker marks, one "API keys" group for organization- and workspace-connected
88
+ * keys, and one row for identical copies. Models settings passes false to
89
+ * keep its scope-aware presentation (raw catalog labels, scoped groups).
90
+ */
91
+ collapseScopes?: boolean | undefined;
96
92
  /** Hide latency controls on surfaces whose saved policy does not include latency. */
97
93
  allowLatencyMode?: boolean | undefined;
94
+ /** Hide effort and latency controls when the saved policy chooses only a model identity. */
95
+ allowModelOptions?: boolean | undefined;
96
+ /** Settings → Models. Shown when the catalog has no model that can run. */
97
+ connectModelsHref?: string | undefined;
98
98
  /** Classes for the portalled menu surface. Prefer --og-* tokens for theming. */
99
99
  contentClassName?: string | undefined;
100
100
  /** Inline styles for the portalled menu, applied after inherited --og-* tokens. */
101
101
  contentStyle?: CSSProperties | undefined;
102
102
  className?: string | undefined;
103
+ /**
104
+ * "pill" (default) is the composer's quiet rounded trigger with the effort.
105
+ * "field" is a settings control: a bordered rectangle with the model name
106
+ * and `triggerMeta` (for example the payer) in muted text. The effort stays
107
+ * in the menu.
108
+ */
109
+ triggerStyle?: "pill" | "field" | undefined;
110
+ /** Muted text after the model name in the "field" trigger. */
111
+ triggerMeta?: ReactNode;
103
112
  messages?: Partial<ModelPolicyPickerMessages> | undefined;
104
113
  onModelChange: (modelId: string) => void;
105
114
  onEffortChange: (effort: ReasoningEffort) => void;
@@ -108,64 +117,29 @@ export type ModelPolicyPickerProps = {
108
117
 
109
118
  const SLIDE_EASE = [0.22, 1, 0.36, 1] as const;
110
119
 
111
- function OpenGeniMark(props: SVGProps<SVGSVGElement>) {
112
- return (
113
- <svg
114
- viewBox="0 0 140 133"
115
- fill="none"
116
- stroke="currentColor"
117
- strokeWidth={1.2}
118
- strokeLinejoin="round"
119
- aria-hidden="true"
120
- {...props}
121
- >
122
- <g transform="translate(-17.5,-20.999893188476562) scale(1.75)">
123
- <g transform="translate(0,-952.36218)">
124
- <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" />
125
- </g>
126
- </g>
127
- </svg>
128
- );
129
- }
130
-
131
- function ChatGptMark(props: SVGProps<SVGSVGElement>) {
132
- return (
133
- <svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true" {...props}>
134
- <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" />
135
- </svg>
136
- );
137
- }
138
-
139
- function XaiMark(props: SVGProps<SVGSVGElement>) {
140
- return (
141
- <svg viewBox="0 0 466.04 516.93" fill="currentColor" aria-hidden="true" {...props}>
142
- <polygon points="0.12 182.71 234.14 516.92 338.15 516.92 104.13 182.71 0.12 182.71" />
143
- <polygon points="0 516.92 104.08 516.92 156.08 442.67 104.04 368.34 0 516.92" />
144
- <polygon points="466.04 0 361.96 0 182.1 256.86 234.15 331.18 466.04 0" />
145
- <polygon points="380.78 516.92 466.04 516.92 466.04 37.16 380.78 158.92 380.78 516.92" />
146
- </svg>
147
- );
148
- }
149
-
150
120
  export function BillingClassMark(props: {
151
121
  billingClass: PickerBillingClass;
122
+ presentation?: ModelPolicyPickerGroupPresentation[PickerBillingClass] | undefined;
152
123
  className?: string | undefined;
153
124
  "aria-label"?: string | undefined;
154
125
  }) {
155
126
  const labels: Record<PickerBillingClass, string> = {
156
- opengeni_credits: "OpenGeni",
127
+ opengeni_credits: "Models",
157
128
  external: "External provider",
158
129
  codex_subscription: "Codex",
159
130
  supergrok_subscription: "SuperGrok",
160
- byok: "Bring your own key",
131
+ claude_subscription: "Claude",
132
+ byok: "API key",
133
+ organization_byok: "API key",
161
134
  };
162
- const label = props["aria-label"] ?? labels[props.billingClass];
135
+ if (props.presentation?.icon === null) return null;
136
+ const label = props["aria-label"] ?? props.presentation?.label ?? labels[props.billingClass];
163
137
  const accessibility =
164
138
  label.length === 0
165
139
  ? { "aria-hidden": true as const }
166
140
  : { role: "img" as const, "aria-label": label };
167
141
  const shell = cn(
168
- "inline-flex size-3.5 shrink-0 items-center justify-center overflow-hidden text-og-fg-subtle",
142
+ "inline-flex size-3.5 shrink-0 items-center justify-center overflow-hidden text-og-fg-subtle [&>svg]:size-full [&>img]:size-full",
169
143
  props.className,
170
144
  );
171
145
  const mark = "size-3.5";
@@ -175,14 +149,18 @@ export function BillingClassMark(props: {
175
149
  data-testid={`billing-class-icon-${props.billingClass}`}
176
150
  {...accessibility}
177
151
  >
178
- {props.billingClass === "opengeni_credits" ? (
179
- <OpenGeniMark className={mark} />
152
+ {props.presentation?.icon !== undefined ? (
153
+ props.presentation.icon
154
+ ) : props.billingClass === "opengeni_credits" ? (
155
+ <SparklesIcon className={mark} aria-hidden />
180
156
  ) : props.billingClass === "external" ? (
181
157
  <Globe2Icon className={mark} aria-hidden />
182
158
  ) : props.billingClass === "codex_subscription" ? (
183
159
  <ChatGptMark className={mark} />
160
+ ) : props.billingClass === "claude_subscription" ? (
161
+ <ClaudeMark className={mark} />
184
162
  ) : props.billingClass === "supergrok_subscription" ? (
185
- <XaiMark className={mark} />
163
+ <GrokMark className={mark} />
186
164
  ) : (
187
165
  <KeyRoundIcon className={mark} aria-hidden />
188
166
  )}
@@ -190,57 +168,67 @@ export function BillingClassMark(props: {
190
168
  );
191
169
  }
192
170
 
193
- function isCodexModel(model: ClientModel): boolean {
194
- return model.id.startsWith("codex/") || model.source === "codex";
171
+ /**
172
+ * The trigger shows who makes the chosen model. Subscription rails already
173
+ * carry their maker's mark (ChatGPT, Claude, Grok). Configured catalog logos win
174
+ * in collapsed model presentation; otherwise explicit host branding wins and models show
175
+ * the maker's logo instead of a generic key, falling back to the group mark.
176
+ */
177
+ function SelectedModelMark(input: {
178
+ props: ModelPolicyPickerProps;
179
+ selected: ClientPickerModelRow | null;
180
+ }) {
181
+ const billingClass =
182
+ input.selected?.billingClass ?? billingClassForMissingSelection(input.props.model);
183
+ const presentation = groupPresentationFor(input.props, billingClass);
184
+ const model = input.selected?.catalog ?? input.props.model;
185
+ if (input.props.collapseScopes === false) {
186
+ return (
187
+ <BillingClassMark
188
+ billingClass={billingClass}
189
+ presentation={presentation}
190
+ aria-label={presentation?.label ?? SCOPED_MARK_LABELS[billingClass]}
191
+ className="text-og-fg"
192
+ />
193
+ );
194
+ }
195
+ if (modelLogoUrl(model)) {
196
+ return <ModelMark model={model} className="text-og-fg" />;
197
+ }
198
+ if (
199
+ presentation?.icon !== undefined ||
200
+ BRANDED_BILLING_CLASSES.has(billingClass) ||
201
+ !modelHasMark(model)
202
+ ) {
203
+ return (
204
+ <BillingClassMark
205
+ billingClass={billingClass}
206
+ presentation={presentation}
207
+ className="text-og-fg"
208
+ />
209
+ );
210
+ }
211
+ return <ModelMark model={model} className="text-og-fg" />;
195
212
  }
196
213
 
197
- function applyCodexOnly(
198
- rows: ClientPickerModelRow[],
199
- codexOnly: boolean,
200
- unavailableReason: string,
201
- ): ClientPickerModelRow[] {
202
- if (!codexOnly) return rows;
203
- return rows.map((row) =>
204
- isCodexModel(row.catalog)
205
- ? row
206
- : {
207
- ...row,
208
- selectable: false,
209
- unavailableReason: row.unavailableReason ?? unavailableReason,
210
- },
211
- );
212
- }
214
+ const SCOPED_MARK_LABELS: Partial<Record<PickerBillingClass, string>> = {
215
+ byok: "Workspace provider account",
216
+ organization_byok: "Organization provider account",
217
+ };
213
218
 
214
- function effectiveRows(props: ModelPolicyPickerProps): ClientPickerModelRow[] {
215
- const rows = props.rows !== undefined ? props.rows : projectClientModelRows(props.models ?? []);
216
- const messages = { ...defaultModelPolicyPickerMessages, ...props.messages };
217
- return applyCodexOnly(rows, props.codexOnly === true, messages.codexOnly);
219
+ /** A selection the catalog no longer lists: its clean name (settings keep the id). */
220
+ function fallbackName(props: ModelPolicyPickerProps): string {
221
+ return props.collapseScopes === false ? props.model : modelDisplayName(props.model);
218
222
  }
219
223
 
220
- function defaultNavState(rows: ClientPickerModelRow[], modelId: string): PickerNavState {
221
- const selected = findPickerRow(rows, modelId);
222
- if (!selected) {
223
- const rails = new Set(rows.map((row) => row.billingClass));
224
- const onlyRail = rails.size === 1 ? rows[0]?.billingClass : null;
225
- return onlyRail
226
- ? { level: "models", rail: onlyRail, modelId: null }
227
- : { level: "providers", rail: null, modelId: null };
228
- }
229
- return { level: "thinking", rail: selected.billingClass, modelId: selected.id };
230
- }
224
+ const BRANDED_BILLING_CLASSES: ReadonlySet<PickerBillingClass> = new Set([
225
+ "codex_subscription",
226
+ "claude_subscription",
227
+ "supergrok_subscription",
228
+ ]);
231
229
 
232
- function usePickerNavState(
233
- sessionKey: string | undefined,
234
- rows: ClientPickerModelRow[],
235
- model: string,
236
- ): [PickerNavState, (next: NavUpdater) => void] {
237
- const [state, setState] = useState<PickerNavState>(() => defaultNavState(rows, model));
238
- useEffect(() => {
239
- setState(defaultNavState(rows, model));
240
- // The menu deliberately preserves its drill-down while the same session is mounted.
241
- // eslint-disable-next-line react-hooks/exhaustive-deps
242
- }, [sessionKey]);
243
- return [state, setState];
230
+ export function effectiveRows(props: ModelPolicyPickerProps): ClientPickerModelRow[] {
231
+ return sharedEffectiveRows(props);
244
232
  }
245
233
 
246
234
  export function PickerNavRow(props: {
@@ -251,6 +239,7 @@ export function PickerNavRow(props: {
251
239
  showChevron?: boolean | undefined;
252
240
  disabled?: boolean | undefined;
253
241
  title?: string | undefined;
242
+ description?: string | undefined;
254
243
  active?: boolean | undefined;
255
244
  testId?: string | undefined;
256
245
  onClick: () => void;
@@ -260,28 +249,24 @@ export function PickerNavRow(props: {
260
249
  type="button"
261
250
  disabled={props.disabled}
262
251
  title={props.title}
252
+ aria-description={props.description}
263
253
  onClick={props.onClick}
264
254
  data-testid={props.testId}
265
255
  className={cn(
266
- "flex w-full cursor-pointer items-center gap-2 rounded-og-sm 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 hover:bg-og-surface-2 focus-visible:ring-2 focus-visible:ring-og-accent/40",
256
+ // The one menu row (lib/menu-styles.ts), with density tokens for embedders.
257
+ "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",
267
258
  props.disabled && "cursor-not-allowed opacity-50",
268
259
  )}
269
260
  >
270
261
  {props.icon}
271
262
  <span className="min-w-0 flex-1">
272
- <span className={cn("block truncate text-og-menu", props.active && "font-medium")}>
273
- {props.label}
274
- </span>
263
+ <span className="block truncate text-og-menu">{props.label}</span>
275
264
  {props.hint ? (
276
- <span className="mt-0.5 block truncate text-og-control text-og-fg-subtle">
277
- {props.hint}
278
- </span>
265
+ <span className="mt-0.5 block truncate text-og-sm text-og-fg-muted">{props.hint}</span>
279
266
  ) : null}
280
267
  </span>
281
268
  {props.trailing ? <span className="ml-auto shrink-0">{props.trailing}</span> : null}
282
- {props.showChevron === false ? null : (
283
- <ChevronRightIcon className="size-3.5 shrink-0 text-og-fg-subtle" />
284
- )}
269
+ {props.showChevron === false ? null : <ChevronRightIcon className={MENU_CHEVRON_CLASS} />}
285
270
  </button>
286
271
  );
287
272
  }
@@ -293,14 +278,16 @@ export function PickerBackHeader(props: {
293
278
  trailing?: ReactNode;
294
279
  }) {
295
280
  return (
296
- <div className="mb-1 flex items-center gap-0.5 border-b border-og-border/70 px-0.5 pb-1.5">
281
+ <div className="mb-1.5 flex min-h-9 items-center gap-1 border-b border-og-border pb-1.5">
297
282
  <button
298
283
  type="button"
299
284
  onClick={props.onBack}
300
285
  data-testid="model-picker-back"
301
- className="flex min-w-0 flex-1 cursor-pointer items-center gap-1.5 rounded-og-sm px-1.5 py-1.5 text-left text-og-fg outline-hidden transition-colors hover:bg-og-surface-2 focus-visible:ring-2 focus-visible:ring-og-accent/40"
286
+ 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"
302
287
  >
303
- <ChevronLeftIcon className="size-3.5 shrink-0 text-og-fg-subtle" />
288
+ <span className="flex size-8 shrink-0 items-center justify-center text-og-fg-muted">
289
+ <ChevronLeftIcon className="size-4" />
290
+ </span>
304
291
  {props.icon}
305
292
  <span className="min-w-0 flex-1 truncate text-og-menu font-medium">{props.label}</span>
306
293
  </button>
@@ -328,241 +315,39 @@ export function PickerAnimatedPage(props: {
328
315
  );
329
316
  }
330
317
 
331
- export function ModelPolicyPickerMenu(
332
- props: ModelPolicyPickerProps & {
333
- nav?: PickerNavState | undefined;
334
- onNavChange?: ((next: NavUpdater) => void) | undefined;
335
- },
336
- ) {
337
- const messages = useMemo(
338
- () => ({ ...defaultModelPolicyPickerMessages, ...props.messages }),
339
- [props.messages],
340
- );
341
- const rows = effectiveRows(props);
342
- const groups = useMemo(() => groupPickerRowsByBillingClass(rows), [rows]);
343
- const [localNav, setLocalNav] = usePickerNavState(
344
- props.nav === undefined ? props.sessionKey : undefined,
345
- rows,
346
- props.model,
347
- );
348
- const nav = props.nav ?? localNav;
349
- const setNav = props.onNavChange ?? setLocalNav;
350
- const [direction, setDirection] = useState<1 | -1>(1);
351
-
352
- const effectiveNav =
353
- nav.level === "providers" && groups.length === 1
354
- ? { level: "models" as const, rail: groups[0]!.billingClass, modelId: null }
355
- : nav;
356
- const activeGroup =
357
- effectiveNav.rail === null
358
- ? undefined
359
- : groups.find((group) => group.billingClass === effectiveNav.rail);
360
- const focusModel =
361
- effectiveNav.modelId === null ? undefined : findPickerRow(rows, effectiveNav.modelId);
362
- const selectedRow = findPickerRow(rows, props.model);
363
-
364
- const go = (next: PickerNavState, nextDirection: 1 | -1) => {
365
- setDirection(nextDirection);
366
- setNav(next);
367
- };
368
-
369
- const selectEffort = (row: ClientPickerModelRow, effort: ReasoningEffort) => {
370
- if (!row.selectable) return;
371
- if (row.id !== props.model) props.onModelChange(row.id);
372
- props.onEffortChange(effort);
373
- };
374
-
375
- const pageKey =
376
- effectiveNav.level === "providers"
377
- ? "providers"
378
- : effectiveNav.level === "models"
379
- ? `models:${effectiveNav.rail ?? ""}`
380
- : `thinking:${effectiveNav.modelId ?? ""}`;
381
-
382
- let body: ReactNode;
383
- if (props.loading) {
384
- body = <p className="px-2 py-3 text-og-control text-og-fg-subtle">{messages.loading}</p>;
385
- } else if (groups.length === 0) {
386
- body = <p className="px-2 py-3 text-og-control text-og-fg-subtle">{messages.noModels}</p>;
387
- } else if (effectiveNav.level === "providers") {
388
- body = (
389
- <div className="flex flex-col gap-0.5" data-testid="model-picker-providers">
390
- {groups.map((group) => (
391
- <PickerNavRow
392
- key={group.billingClass}
393
- label={group.label}
394
- hint={messages.billingHints[group.billingClass]}
395
- icon={<BillingClassMark billingClass={group.billingClass} />}
396
- active={selectedRow?.billingClass === group.billingClass}
397
- testId={`model-picker-rail-${group.billingClass}`}
398
- onClick={() => go({ level: "models", rail: group.billingClass, modelId: null }, 1)}
399
- />
400
- ))}
401
- </div>
402
- );
403
- } else if (effectiveNav.level === "models" && activeGroup) {
404
- body = (
405
- <div data-testid="model-picker-models">
406
- {groups.length > 1 ? (
407
- <PickerBackHeader
408
- label={activeGroup.label}
409
- icon={<BillingClassMark billingClass={activeGroup.billingClass} />}
410
- onBack={() => go({ level: "providers", rail: null, modelId: null }, -1)}
411
- />
412
- ) : null}
413
- <div className="flex flex-col gap-0.5">
414
- {activeGroup.rows.map((row) => (
415
- <PickerNavRow
416
- key={`${row.billingClass}:${row.id}`}
417
- label={row.label}
418
- hint={row.unavailableReason ?? undefined}
419
- disabled={!row.selectable}
420
- title={row.unavailableReason ?? undefined}
421
- active={row.id === props.model}
422
- testId={`model-picker-choice-${row.id}`}
423
- onClick={() => {
424
- if (row.selectable) {
425
- go({ level: "thinking", rail: row.billingClass, modelId: row.id }, 1);
426
- }
427
- }}
428
- />
429
- ))}
430
- </div>
431
- </div>
432
- );
433
- } else if (effectiveNav.level === "thinking" && focusModel) {
434
- const activeModel = focusModel.id === props.model;
435
- const supportsFast = runnableLatencyModesForModel(focusModel.catalog).includes("fast");
436
- body = (
437
- <div data-testid="model-picker-reasoning">
438
- <PickerBackHeader
439
- label={focusModel.label}
440
- icon={<BillingClassMark billingClass={focusModel.billingClass} />}
441
- onBack={() => go({ level: "models", rail: focusModel.billingClass, modelId: null }, -1)}
442
- trailing={
443
- supportsFast && props.allowLatencyMode !== false ? (
444
- <button
445
- type="button"
446
- disabled={!focusModel.selectable}
447
- aria-pressed={activeModel && props.latencyMode === "fast"}
448
- aria-label={
449
- activeModel && props.latencyMode === "fast"
450
- ? `Disable ${messages.fast}`
451
- : `Enable ${messages.fast}`
452
- }
453
- title={`${messages.fast} · ${messages.fastRateHint}`}
454
- data-testid="model-picker-fast"
455
- onClick={() => {
456
- if (!activeModel) {
457
- props.onModelChange(focusModel.id);
458
- }
459
- props.onLatencyModeChange(
460
- activeModel && props.latencyMode === "fast" ? "standard" : "fast",
461
- );
462
- }}
463
- className={cn(
464
- "flex size-8 shrink-0 cursor-pointer items-center justify-center rounded-og-sm text-og-fg-subtle 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",
465
- activeModel && props.latencyMode === "fast" && "text-og-fg",
466
- )}
467
- >
468
- <ZapIcon
469
- className={cn(
470
- "size-3.5",
471
- activeModel && props.latencyMode === "fast" && "fill-current",
472
- )}
473
- />
474
- </button>
475
- ) : null
476
- }
477
- />
478
- <p className="px-2.5 pt-1 pb-1 text-og-control font-medium tracking-wide text-og-fg-subtle uppercase">
479
- {messages.thinking}
480
- </p>
481
- {focusModel.catalog.capabilities?.inputModalities.includes("image") === false ? (
482
- <p className="px-2.5 pb-1.5 text-og-control leading-relaxed text-og-fg-subtle">
483
- Unsupported attachments stay in the session but are hidden from this model.
484
- </p>
485
- ) : null}
486
- <div className="flex flex-col gap-0.5">
487
- {effortOptionsForModel(focusModel.catalog).map((effort) => {
488
- const selected = activeModel && effort === props.effort;
489
- return (
490
- <button
491
- key={effort}
492
- type="button"
493
- disabled={!focusModel.selectable}
494
- onClick={() => selectEffort(focusModel, effort)}
495
- className={cn(
496
- "flex h-[var(--og-model-picker-effort-height)] w-full cursor-pointer items-center rounded-og-sm px-[var(--og-model-picker-row-padding-x)] text-left text-og-menu 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",
497
- selected && "bg-og-surface-2",
498
- )}
499
- >
500
- <span className="min-w-0 flex-1 truncate">{labelReasoningEffort(effort)}</span>
501
- {selected ? (
502
- <CheckIcon
503
- className="ml-auto size-3.5 shrink-0"
504
- data-testid="model-picker-effort-check"
505
- />
506
- ) : null}
507
- </button>
508
- );
509
- })}
510
- </div>
511
- </div>
512
- );
513
- } else {
514
- body = (
515
- <div className="flex flex-col gap-0.5" data-testid="model-picker-providers">
516
- {groups.map((group) => (
517
- <PickerNavRow
518
- key={group.billingClass}
519
- label={group.label}
520
- hint={messages.billingHints[group.billingClass]}
521
- icon={<BillingClassMark billingClass={group.billingClass} />}
522
- testId={`model-picker-rail-${group.billingClass}`}
523
- onClick={() => go({ level: "models", rail: group.billingClass, modelId: null }, 1)}
524
- />
525
- ))}
526
- </div>
527
- );
528
- }
529
-
530
- return (
531
- <div data-testid="model-picker-menu" className="relative overflow-hidden">
532
- {props.error ? (
533
- <p className="px-2 py-1 text-og-control text-og-status-failed" role="alert">
534
- {props.error}
535
- </p>
536
- ) : null}
537
- <PickerAnimatedPage pageKey={pageKey} direction={direction}>
538
- {body}
539
- </PickerAnimatedPage>
540
- </div>
541
- );
542
- }
543
-
544
- export function ModelPolicyPicker(props: ModelPolicyPickerProps) {
318
+ /** @internal Shared controlled/uncontrolled state seam. */
319
+ export function useModelPolicyPickerState(props: ModelPolicyPickerProps) {
545
320
  const [uncontrolledOpen, setUncontrolledOpen] = useState(props.defaultOpen ?? false);
546
321
  const open = props.open ?? uncontrolledOpen;
547
322
  const setOpen = (next: boolean) => {
548
323
  if (props.open === undefined) setUncontrolledOpen(next);
549
324
  props.onOpenChange?.(next);
550
325
  };
326
+ return { open, setOpen, rows: effectiveRows(props) };
327
+ }
328
+
329
+ export function ModelPolicyPicker(props: ModelPolicyPickerProps) {
330
+ const contentId = useId();
551
331
  const trigger = usePortalTokenSource<HTMLButtonElement>();
552
332
  const portalStyle = usePortalTokenStyle(trigger.source);
553
333
  const messages = useMemo(
554
334
  () => ({ ...defaultModelPolicyPickerMessages, ...props.messages }),
555
335
  [props.messages],
556
336
  );
557
- const rows = effectiveRows(props);
558
- const [nav, setNav] = usePickerNavState(props.sessionKey, rows, props.model);
337
+ const { open, setOpen, rows } = useModelPolicyPickerState(props);
559
338
  const selected = findPickerRow(rows, props.model);
339
+ const needsModel =
340
+ !rows.some((row) => row.selectable) && (rows.length > 0 || Boolean(props.connectModelsHref));
341
+ const selectedDescription = needsModel
342
+ ? messages.connectTitle
343
+ : [selected?.label ?? fallbackName(props), labelReasoningEffort(props.effort)].join(" · ");
560
344
 
561
345
  if (props.loading) {
562
346
  return (
563
347
  <span
564
348
  className={cn(
565
349
  "og-root inline-flex h-8 w-40 shrink-0 animate-pulse rounded-full bg-og-surface-2",
350
+ props.triggerStyle === "field" && "w-[180px] rounded-og-md",
566
351
  props.className,
567
352
  )}
568
353
  aria-label={messages.loading}
@@ -570,64 +355,123 @@ export function ModelPolicyPicker(props: ModelPolicyPickerProps) {
570
355
  />
571
356
  );
572
357
  }
573
- return (
574
- <DropdownMenu.Root open={open} onOpenChange={setOpen}>
575
- <DropdownMenu.Trigger asChild>
358
+ if (props.triggerStyle === "field") {
359
+ return (
360
+ <>
576
361
  <button
577
362
  ref={trigger.ref}
578
363
  type="button"
364
+ aria-haspopup="dialog"
365
+ aria-expanded={open}
366
+ aria-controls={open ? contentId : undefined}
367
+ data-state={open ? "open" : "closed"}
368
+ data-trigger-style="field"
369
+ onClick={() => setOpen(!open)}
579
370
  disabled={props.disabled}
580
371
  aria-label={messages.label}
372
+ aria-description={selectedDescription}
581
373
  className={cn(
582
- "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 border-transparent px-2.5 text-og-control text-og-fg-muted outline-hidden transition-colors hover:border-og-border hover:bg-og-surface-2 hover:text-og-fg 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",
374
+ "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",
583
375
  props.className,
584
376
  )}
585
377
  >
586
- <BillingClassMark
587
- billingClass={
588
- selected?.billingClass ??
589
- (props.model.startsWith("codex/") ? "codex_subscription" : "opengeni_credits")
590
- }
591
- className="text-og-fg"
592
- />
593
- <span className="og-model-policy-label-full min-w-0 truncate font-medium text-og-fg max-sm:hidden">
594
- {selected?.label ?? props.model}
595
- </span>
596
- <span className="og-model-policy-label-short min-w-0 truncate font-medium text-og-fg sm:hidden">
597
- {selected?.shortLabel ?? selected?.label ?? props.model}
598
- </span>
599
- <span className="og-model-policy-effort max-sm:hidden">
600
- {labelReasoningEffort(props.effort)}
378
+ {needsModel ? (
379
+ <SparklesIcon className="size-3.5 shrink-0" aria-hidden />
380
+ ) : (
381
+ <SelectedModelMark props={props} selected={selected} />
382
+ )}
383
+ <span className="min-w-0 truncate font-medium">
384
+ {needsModel ? messages.connectTitle : (selected?.label ?? fallbackName(props))}
601
385
  </span>
602
- {props.latencyMode === "fast" ? (
603
- <ZapIcon
604
- className="size-3.5 shrink-0 fill-current stroke-current text-og-fg"
605
- aria-label={messages.fast}
606
- data-testid="model-picker-fast-icon"
607
- />
386
+ {props.triggerMeta && !needsModel ? (
387
+ <span className="min-w-0 shrink-[9999] truncate text-og-fg-muted">
388
+ {props.triggerMeta}
389
+ </span>
608
390
  ) : null}
609
- <ChevronDownIcon className="size-3 shrink-0" />
391
+ <ChevronDownIcon className="ml-auto size-3.5 shrink-0 text-og-fg-muted" />
610
392
  </button>
611
- </DropdownMenu.Trigger>
612
- <DropdownMenu.Portal>
613
- <DropdownMenu.Content
614
- align="start"
615
- side={props.menuSide ?? "bottom"}
616
- sideOffset={8}
617
- collisionPadding={12}
618
- onCloseAutoFocus={(event) => event.preventDefault()}
619
- className={cn(
620
- "og-root og-model-policy-menu z-50 flex max-h-[min(20rem,var(--radix-dropdown-menu-content-available-height))] w-[var(--og-model-picker-menu-width)] 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",
621
- props.contentClassName,
622
- )}
623
- style={{ ...portalStyle, ...props.contentStyle }}
624
- data-testid="model-picker-content"
625
- >
626
- <div className="min-h-0 flex-1 overflow-y-auto overscroll-contain">
627
- <ModelPolicyPickerMenu {...props} nav={nav} onNavChange={setNav} />
628
- </div>
629
- </DropdownMenu.Content>
630
- </DropdownMenu.Portal>
631
- </DropdownMenu.Root>
393
+ {open ? (
394
+ <Suspense fallback={null}>
395
+ <LazyModelPolicyPickerMenu
396
+ {...props}
397
+ anchor={trigger.currentRef}
398
+ contentId={contentId}
399
+ portalStyle={portalStyle}
400
+ onOpenChange={setOpen}
401
+ />
402
+ </Suspense>
403
+ ) : null}
404
+ </>
405
+ );
406
+ }
407
+ return (
408
+ <>
409
+ <button
410
+ ref={trigger.ref}
411
+ type="button"
412
+ aria-haspopup="dialog"
413
+ aria-expanded={open}
414
+ aria-controls={open ? contentId : undefined}
415
+ data-state={open ? "open" : "closed"}
416
+ onClick={() => setOpen(!open)}
417
+ disabled={props.disabled}
418
+ aria-label={messages.label}
419
+ aria-description={selectedDescription}
420
+ className={cn(
421
+ // Phone: the composer row also carries attach, dictate, voice, pause
422
+ // and send, so the pill drops its chevron and tightens its padding
423
+ // to keep the model's short name readable.
424
+ "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:gap-0.5 max-sm:px-1.5",
425
+ // With no usable model the pill is the one thing that unblocks the
426
+ // composer, so it takes the primary wash.
427
+ needsModel
428
+ ? "border-og-primary-border bg-og-primary text-og-primary-fg hover:bg-og-primary-hover"
429
+ : "border-transparent text-og-fg-muted hover:border-og-border hover:bg-og-surface-2 hover:text-og-fg",
430
+ props.className,
431
+ )}
432
+ >
433
+ {needsModel ? (
434
+ <SparklesIcon className="size-3.5 shrink-0" aria-hidden />
435
+ ) : (
436
+ <SelectedModelMark props={props} selected={selected} />
437
+ )}
438
+ <span className="og-model-policy-label-full min-w-0 truncate font-medium text-og-fg max-sm:hidden @max-[20rem]/model-controls:hidden">
439
+ {needsModel ? messages.connectTitle : (selected?.label ?? fallbackName(props))}
440
+ </span>
441
+ <span className="og-model-policy-label-short min-w-0 truncate font-medium text-og-fg sm:hidden @max-[20rem]/model-controls:block">
442
+ {needsModel
443
+ ? messages.connectTitle
444
+ : (selected?.shortLabel ?? selected?.label ?? fallbackName(props))}
445
+ </span>
446
+ {selected && !needsModel && modelOffersEffortChoice(selected.catalog) ? (
447
+ <span
448
+ className="og-model-policy-effort min-w-0 shrink-[9999] truncate"
449
+ title={labelReasoningEffort(props.effort)}
450
+ >
451
+ {labelReasoningEffort(props.effort)}
452
+ </span>
453
+ ) : null}
454
+ {props.latencyMode === "fast" && !needsModel ? (
455
+ <ZapIcon
456
+ className="size-3.5 shrink-0 fill-current stroke-current text-og-fg"
457
+ aria-label={messages.fast}
458
+ data-testid="model-picker-fast-icon"
459
+ />
460
+ ) : null}
461
+ <ChevronDownIcon className="og-model-policy-chevron size-3 shrink-0 max-sm:hidden" />
462
+ </button>
463
+
464
+ {open ? (
465
+ <Suspense fallback={null}>
466
+ <LazyModelPolicyPickerMenu
467
+ {...props}
468
+ anchor={trigger.currentRef}
469
+ contentId={contentId}
470
+ portalStyle={portalStyle}
471
+ onOpenChange={setOpen}
472
+ />
473
+ </Suspense>
474
+ ) : null}
475
+ </>
632
476
  );
633
477
  }