@opengeni/react 3.3.2-canary.1 → 3.4.0

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