@theoremjs/studio 0.0.0-stage → 0.3.1

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 (473) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +294 -2
  3. package/agreement.d.ts +14 -0
  4. package/agreement.js +80 -0
  5. package/asks.d.ts +47 -0
  6. package/asks.js +54 -0
  7. package/browser-connection.d.ts +49 -0
  8. package/browser-connection.js +215 -0
  9. package/browser-engine.d.ts +11 -0
  10. package/browser-engine.js +11 -0
  11. package/browser-execution.d.ts +6 -0
  12. package/browser-execution.js +18 -0
  13. package/browser-live.d.ts +4 -0
  14. package/browser-live.js +132 -0
  15. package/browser-transport.d.ts +33 -0
  16. package/browser-transport.js +229 -0
  17. package/browser.d.ts +4 -0
  18. package/browser.js +4 -0
  19. package/canonical.d.ts +10 -0
  20. package/canonical.js +25 -0
  21. package/compile-workspace.d.ts +28 -0
  22. package/compile-workspace.js +295 -0
  23. package/compile.d.ts +65 -0
  24. package/compile.js +1605 -0
  25. package/concierge-demo.d.ts +17 -0
  26. package/concierge-demo.js +1230 -0
  27. package/conversation-key.d.ts +5 -0
  28. package/conversation-key.js +10 -0
  29. package/decision-example-images.d.ts +30 -0
  30. package/decision-example-images.js +30 -0
  31. package/deno.json +3 -0
  32. package/draft.d.ts +407 -0
  33. package/draft.js +505 -0
  34. package/editors.d.ts +29 -0
  35. package/editors.js +51 -0
  36. package/example-embedding-files.d.ts +11 -0
  37. package/example-embedding-files.js +20 -0
  38. package/example.d.ts +36 -0
  39. package/example.js +357 -0
  40. package/guardrail-probe.d.ts +100 -0
  41. package/guardrail-probe.js +722 -0
  42. package/held-credentials.d.ts +28 -0
  43. package/held-credentials.js +87 -0
  44. package/installed.mjs +40 -0
  45. package/lent-keys.d.ts +122 -0
  46. package/lent-keys.js +47 -0
  47. package/line-diff.d.ts +15 -0
  48. package/line-diff.js +41 -0
  49. package/live-connection.d.ts +22 -0
  50. package/live-connection.js +27 -0
  51. package/live-session-bridge.d.ts +15 -0
  52. package/live-session-bridge.js +202 -0
  53. package/map-line.d.ts +19 -0
  54. package/map-line.js +42 -0
  55. package/map.d.ts +154 -0
  56. package/map.js +525 -0
  57. package/media-accept.d.ts +19 -0
  58. package/media-accept.js +65 -0
  59. package/mod.d.ts +39 -0
  60. package/mod.js +33 -0
  61. package/origins.d.ts +52 -0
  62. package/origins.js +165 -0
  63. package/package.json +85 -4
  64. package/page/assets/Banner-ChigGVCM.js +2 -0
  65. package/page/assets/BottomSheet-BwfBDtje.js +1 -0
  66. package/page/assets/Card-Lp-0P5eL.js +1 -0
  67. package/page/assets/CardWall-CBRLdDZW.js +1 -0
  68. package/page/assets/Center-nHS1JSux.js +1 -0
  69. package/page/assets/CheckboxInput-Cj5pk-KI.js +2 -0
  70. package/page/assets/CodeBlock-C7XJ4ioE.js +51 -0
  71. package/page/assets/CollapsibleGroup-N7_SOjbm.js +2 -0
  72. package/page/assets/ContextMenu-BcXTDSnA.js +2 -0
  73. package/page/assets/DateInput-BGrQ5tPC.js +1 -0
  74. package/page/assets/Dialog-DELWQo-v.js +1 -0
  75. package/page/assets/EmptyState-C8W4JKBZ.js +1 -0
  76. package/page/assets/HoverCard-D1Y1ltWQ.js +1 -0
  77. package/page/assets/Icon-JrysT8aU.js +3 -0
  78. package/page/assets/IconAlertTriangle-BqAEqqdU.js +1 -0
  79. package/page/assets/IconButton-DlOGzJIX.js +1 -0
  80. package/page/assets/IconEye-BB5aY-wQ.js +1 -0
  81. package/page/assets/IconFileText-6zOFKKrF.js +1 -0
  82. package/page/assets/IconSearch-BTx66a40.js +1 -0
  83. package/page/assets/IconShield-DDOh7Gr5.js +1 -0
  84. package/page/assets/ItemSwipeLayer-Ckn4X6h9.js +1 -0
  85. package/page/assets/PaneState-BvA2tLQg.js +1 -0
  86. package/page/assets/PaneState-eUzUkNE8.css +1 -0
  87. package/page/assets/ScrollableArea-Ckugdj1N.js +1 -0
  88. package/page/assets/Section-DJ97F7QE.js +1 -0
  89. package/page/assets/SegmentedControlItem-h-aaXzyS.js +1 -0
  90. package/page/assets/SidePanel-BL32abk8.js +1 -0
  91. package/page/assets/StackItem-CQviqAfM.js +1 -0
  92. package/page/assets/Text-bum6zWWx.js +2 -0
  93. package/page/assets/TimestampHoverCard-DQIG0RZF.js +1 -0
  94. package/page/assets/ToolResultCharts-DsbzvrBK.js +1 -0
  95. package/page/assets/Tooltip-BH9xiRMl.js +1 -0
  96. package/page/assets/TraceInspector-B34qMQJH.js +1 -0
  97. package/page/assets/TraceOverview-Drp2Sl4p.js +57 -0
  98. package/page/assets/VStack-CkVMcNiK.js +1 -0
  99. package/page/assets/_virtual_studio-type-sources-B0u0_Vhq.js +12933 -0
  100. package/page/assets/arrive-DvbqpeRS.js +1 -0
  101. package/page/assets/browser-engine-rJc_aHJo.js +9 -0
  102. package/page/assets/browser-transport-Bn77Eq5d.js +47 -0
  103. package/page/assets/codicon-DF1abBS2.ttf +0 -0
  104. package/page/assets/compile-egress-CGwmX2BX.js +23 -0
  105. package/page/assets/container.stylex-BmOi-8DQ.js +1 -0
  106. package/page/assets/createReactComponent-CZwsv6DD.js +1 -0
  107. package/page/assets/decision-example-images-CZGr7YIT.js +1 -0
  108. package/page/assets/devWarning-DxuplmRl.js +1 -0
  109. package/page/assets/editor-DjpsE8to.css +1 -0
  110. package/page/assets/editor.api-Cd3ViPQa.js +908 -0
  111. package/page/assets/editor.worker-6GY8RhDc.js +1 -0
  112. package/page/assets/editor.worker-BmdWdrHZ.js +33 -0
  113. package/page/assets/editors-BJX_S59A.js +1 -0
  114. package/page/assets/egress-automata-B5ZGE1mT.js +1 -0
  115. package/page/assets/embedding-space-view-CfQBPDxD.js +140 -0
  116. package/page/assets/encode-files-Dq98bb-f.js +1 -0
  117. package/page/assets/export-agent-wlS68_dE.js +43 -0
  118. package/page/assets/figtree-latin-400-normal-BD4aNku5.woff +0 -0
  119. package/page/assets/figtree-latin-400-normal-g7Dtegnw.woff2 +0 -0
  120. package/page/assets/figtree-latin-500-normal-BWnGEVsr.woff2 +0 -0
  121. package/page/assets/figtree-latin-500-normal-B_yy1phn.woff +0 -0
  122. package/page/assets/figtree-latin-600-normal-BM_oTo4n.woff +0 -0
  123. package/page/assets/figtree-latin-600-normal-Cv_xCTDl.woff2 +0 -0
  124. package/page/assets/figtree-latin-700-normal-BCCt2T1q.woff +0 -0
  125. package/page/assets/figtree-latin-700-normal-th6qEP7c.woff2 +0 -0
  126. package/page/assets/focusOutline.stylex-BT0kfa4t.js +1 -0
  127. package/page/assets/focusableSelector-DXZeMU85.js +1 -0
  128. package/page/assets/groupStyles-C7Ter7zC.js +1 -0
  129. package/page/assets/guardrail-tester-BHcoZE5K.js +9 -0
  130. package/page/assets/host-patterns-DCz9Cmrt.js +1 -0
  131. package/page/assets/index-BmHkdZXS.js +105 -0
  132. package/page/assets/index-DOaHlqBo.css +1 -0
  133. package/page/assets/isRtlElement-BG33-k_H.js +1 -0
  134. package/page/assets/labels-provider-4TIWDvsE.js +3 -0
  135. package/page/assets/lent-keys-C32ems-I.js +1 -0
  136. package/page/assets/live-ingress-DsA4_80F.js +1 -0
  137. package/page/assets/live-messages-B19ZuTGI.js +1 -0
  138. package/page/assets/mergeProps-ptS-gIMz.js +1 -0
  139. package/page/assets/padding.stylex-B76907Zf.js +1 -0
  140. package/page/assets/preload-helper-DpV6A1kQ.js +1 -0
  141. package/page/assets/reader-CN15b9m8.js +7 -0
  142. package/page/assets/register-CDgivxvX.js +2 -0
  143. package/page/assets/rolldown-runtime-hePW80VL.js +1 -0
  144. package/page/assets/schemas-BQ9Jydzb.js +56 -0
  145. package/page/assets/shaped-data-BO_JTcQq.js +16 -0
  146. package/page/assets/sharedResizeObserver-4U9Xq5Oq.js +1 -0
  147. package/page/assets/stub-DDddt29Y.js +471 -0
  148. package/page/assets/studio-code-pane-BSXwNg0B.js +8 -0
  149. package/page/assets/studio-console-C1hyAfeb.js +3 -0
  150. package/page/assets/studio-decision-CZDF06ic.js +1 -0
  151. package/page/assets/studio-embedding-SqSYd_e1.js +2 -0
  152. package/page/assets/studio-host-console-BlbRUrR_.js +2 -0
  153. package/page/assets/studio-live-Dd0AEV_k.js +1 -0
  154. package/page/assets/studio-map-BIIZcltt.js +1 -0
  155. package/page/assets/studio-map-Bb06Tw1F.css +1 -0
  156. package/page/assets/studio-monaco-CbKf90i6.css +1 -0
  157. package/page/assets/studio-monaco-xfyfezQS.js +34 -0
  158. package/page/assets/studio-ts.worker-B-EXG4Sv.js +67741 -0
  159. package/page/assets/studio-ts.worker-BXtW3z-O.js +1 -0
  160. package/page/assets/studio-type-checker-Cp6IxLBp.js +23 -0
  161. package/page/assets/themeProps-3IqahpCr.js +1 -0
  162. package/page/assets/tokens.stylex-DkHf0P9C.js +1 -0
  163. package/page/assets/tool-schema-BF2BK9h8.js +18 -0
  164. package/page/assets/trace-patterns-DnYJa0nI.js +1 -0
  165. package/page/assets/trace-record-C-XxCjSg.js +1 -0
  166. package/page/assets/trace-schema-9CdEyG6Q.js +1 -0
  167. package/page/assets/tree-D1IYOD_9.js +3 -0
  168. package/page/assets/turn-client-BMBqw-ho.js +2 -0
  169. package/page/assets/types-CBmpjaet.js +1 -0
  170. package/page/assets/typescript-20GgZ8PJ.js +1 -0
  171. package/page/assets/use-one-call-BtrXMol7.js +1 -0
  172. package/page/assets/useAdaptivePresentation-BzmPCddb.js +1 -0
  173. package/page/assets/useClipboard-BgGRxRMJ.js +1 -0
  174. package/page/assets/useContainerReveal-BFy8N_QU.js +1 -0
  175. package/page/assets/useDevWarning-Z9SoixOP.js +1 -0
  176. package/page/assets/useLayerDismissal-B_G7IWpC.js +1 -0
  177. package/page/assets/useMediaQuery-BCT0NUeZ.js +1 -0
  178. package/page/assets/useScrollLock-Dyf6PHJt.js +1 -0
  179. package/page/assets/useScrollableArea-0NzdiBCq.js +1 -0
  180. package/page/assets/useTooltip-CJM_xhLB.js +1 -0
  181. package/page/assets/workspace-BMzjmPeQ.js +1 -0
  182. package/page/assets/zip-DTcEfps6.js +1 -0
  183. package/page/index.html +90 -0
  184. package/page.mjs +49 -0
  185. package/people.d.ts +87 -0
  186. package/people.js +110 -0
  187. package/policy.d.ts +43 -0
  188. package/policy.js +102 -0
  189. package/ports.d.mts +32 -0
  190. package/ports.mjs +85 -0
  191. package/probe-battery.d.ts +13 -0
  192. package/probe-battery.js +404 -0
  193. package/providers.d.ts +149 -0
  194. package/providers.js +306 -0
  195. package/read-source.d.ts +48 -0
  196. package/read-source.js +1301 -0
  197. package/read-steps.d.ts +23 -0
  198. package/read-steps.js +2 -0
  199. package/reader.d.ts +11 -0
  200. package/reader.js +11 -0
  201. package/registrations.d.ts +83 -0
  202. package/registrations.js +1 -0
  203. package/requirements.d.ts +22 -0
  204. package/requirements.js +38 -0
  205. package/run-payload-core.d.ts +28 -0
  206. package/run-payload-core.js +123 -0
  207. package/run-payload.d.ts +32 -0
  208. package/run-payload.js +26 -0
  209. package/runtime-scope.d.ts +84 -0
  210. package/runtime-scope.js +308 -0
  211. package/runtime.d.ts +84 -0
  212. package/runtime.js +387 -0
  213. package/section-notes.d.ts +33 -0
  214. package/section-notes.js +38 -0
  215. package/serve-page.mjs +96 -0
  216. package/server/draft-decide.d.ts +72 -0
  217. package/server/draft-decide.js +111 -0
  218. package/server/draft-embedding.d.ts +3 -0
  219. package/server/draft-embedding.js +35 -0
  220. package/server/draft-handler.d.ts +82 -0
  221. package/server/draft-handler.js +213 -0
  222. package/server/draft-probe.d.ts +14 -0
  223. package/server/draft-probe.js +61 -0
  224. package/server/draft-replies.d.ts +22 -0
  225. package/server/draft-replies.js +46 -0
  226. package/server/edited-session.d.ts +28 -0
  227. package/server/edited-session.js +83 -0
  228. package/server/edits.d.ts +38 -0
  229. package/server/edits.js +195 -0
  230. package/server/handler.d.ts +133 -0
  231. package/server/handler.js +598 -0
  232. package/server/lent-draft.d.ts +19 -0
  233. package/server/lent-draft.js +23 -0
  234. package/server/live.d.ts +15 -0
  235. package/server/live.js +96 -0
  236. package/server/open-editor.d.ts +63 -0
  237. package/server/open-editor.js +115 -0
  238. package/server/origins.d.ts +18 -0
  239. package/server/origins.js +330 -0
  240. package/server/project-source.d.ts +208 -0
  241. package/server/project-source.js +1042 -0
  242. package/server/project.d.ts +22 -0
  243. package/server/project.js +56 -0
  244. package/server/run-traces.d.ts +20 -0
  245. package/server/run-traces.js +96 -0
  246. package/server/save-new.d.ts +29 -0
  247. package/server/save-new.js +514 -0
  248. package/server/save-plan.d.ts +46 -0
  249. package/server/save-plan.js +1134 -0
  250. package/server/save-remove.d.ts +21 -0
  251. package/server/save-remove.js +528 -0
  252. package/server/save-session.d.ts +96 -0
  253. package/server/save-session.js +418 -0
  254. package/server/save-wire.d.ts +235 -0
  255. package/server/save-wire.js +8 -0
  256. package/server/save.d.ts +52 -0
  257. package/server/save.js +209 -0
  258. package/server/serve.d.ts +23 -0
  259. package/server/serve.js +413 -0
  260. package/server/test-connection.d.ts +17 -0
  261. package/server/test-connection.js +362 -0
  262. package/server/test-key.d.ts +2 -0
  263. package/server/test-key.js +83 -0
  264. package/server/watch.d.ts +28 -0
  265. package/server/watch.js +93 -0
  266. package/server/zod-edit.d.ts +74 -0
  267. package/server/zod-edit.js +558 -0
  268. package/server.d.ts +8 -0
  269. package/server.js +8 -0
  270. package/setups.mjs +170 -0
  271. package/shared-carry.d.ts +114 -0
  272. package/shared-carry.js +523 -0
  273. package/shared-settings.d.ts +34 -0
  274. package/shared-settings.js +70 -0
  275. package/source.d.ts +75 -0
  276. package/source.js +414 -0
  277. package/start.mjs +169 -0
  278. package/stream-lines.d.ts +9 -0
  279. package/stream-lines.js +27 -0
  280. package/stub.d.ts +6 -0
  281. package/stub.js +33 -0
  282. package/surface.d.ts +53 -0
  283. package/surface.js +631 -0
  284. package/system-markup.d.ts +20 -0
  285. package/system-markup.js +51 -0
  286. package/tool-schema.d.ts +23 -0
  287. package/tool-schema.js +69 -0
  288. package/tools.d.ts +16 -0
  289. package/tools.js +91 -0
  290. package/traces.d.ts +24 -0
  291. package/traces.js +29 -0
  292. package/transport.d.ts +57 -0
  293. package/transport.js +187 -0
  294. package/tree.d.ts +32 -0
  295. package/tree.js +83 -0
  296. package/types.d.ts +62 -0
  297. package/types.js +6 -0
  298. package/ui/acting-as-button.d.ts +2 -0
  299. package/ui/acting-as-button.js +16 -0
  300. package/ui/add-provider.d.ts +13 -0
  301. package/ui/add-provider.js +20 -0
  302. package/ui/boot-mark.css +53 -0
  303. package/ui/boot-mark.d.ts +19 -0
  304. package/ui/boot-mark.js +128 -0
  305. package/ui/boot-paint.d.ts +8 -0
  306. package/ui/boot-paint.js +8 -0
  307. package/ui/brand-icons.d.ts +57 -0
  308. package/ui/brand-icons.js +148 -0
  309. package/ui/built/theme.css +830 -0
  310. package/ui/built/theme.css.d.ts +9 -0
  311. package/ui/built/theorem-studio.d.ts +13 -0
  312. package/ui/built/theorem-studio.js +705 -0
  313. package/ui/built/theorem-studio.variants.d.ts +28 -0
  314. package/ui/code/monaco-contributions.d.ts +45 -0
  315. package/ui/code/studio-code.d.ts +7 -0
  316. package/ui/code/studio-code.js +253 -0
  317. package/ui/code/studio-monaco.d.ts +44 -0
  318. package/ui/code/studio-monaco.js +48 -0
  319. package/ui/code/studio-ts.worker.d.ts +1 -0
  320. package/ui/code/studio-ts.worker.js +16 -0
  321. package/ui/code/studio-type-checker.d.ts +12 -0
  322. package/ui/code/studio-type-checker.js +308 -0
  323. package/ui/code/studio-type-sources.d.ts +26 -0
  324. package/ui/confirm-write.d.ts +12 -0
  325. package/ui/confirm-write.js +45 -0
  326. package/ui/diff-block.d.ts +21 -0
  327. package/ui/diff-block.js +17 -0
  328. package/ui/figtree.css +59 -0
  329. package/ui/file-place.d.ts +4 -0
  330. package/ui/file-place.js +26 -0
  331. package/ui/guardrail-tester.d.ts +18 -0
  332. package/ui/guardrail-tester.js +248 -0
  333. package/ui/inspector-context.d.ts +119 -0
  334. package/ui/inspector-context.js +84 -0
  335. package/ui/inspector.d.ts +247 -0
  336. package/ui/inspector.js +284 -0
  337. package/ui/lib/acting-as.d.ts +25 -0
  338. package/ui/lib/acting-as.js +90 -0
  339. package/ui/lib/boot-sequence.d.ts +32 -0
  340. package/ui/lib/boot-sequence.js +57 -0
  341. package/ui/lib/export-agent.d.ts +11 -0
  342. package/ui/lib/export-agent.js +335 -0
  343. package/ui/lib/facet-icons.d.ts +20 -0
  344. package/ui/lib/facet-icons.js +21 -0
  345. package/ui/lib/panel-motion.d.ts +8 -0
  346. package/ui/lib/panel-motion.js +74 -0
  347. package/ui/lib/project-address.d.ts +14 -0
  348. package/ui/lib/project-address.js +24 -0
  349. package/ui/lib/project-starting.d.ts +13 -0
  350. package/ui/lib/project-starting.js +30 -0
  351. package/ui/lib/project-traces.d.ts +17 -0
  352. package/ui/lib/project-traces.js +54 -0
  353. package/ui/lib/read-map.d.ts +30 -0
  354. package/ui/lib/read-map.js +173 -0
  355. package/ui/lib/read-progress.d.ts +14 -0
  356. package/ui/lib/read-progress.js +12 -0
  357. package/ui/lib/refusal-lines.d.ts +3 -0
  358. package/ui/lib/refusal-lines.js +8 -0
  359. package/ui/lib/studio-activity.d.ts +5 -0
  360. package/ui/lib/studio-activity.js +17 -0
  361. package/ui/lib/studio-console.d.ts +27 -0
  362. package/ui/lib/studio-console.js +9 -0
  363. package/ui/lib/studio-conversation.d.ts +20 -0
  364. package/ui/lib/studio-conversation.js +130 -0
  365. package/ui/lib/studio-examples.d.ts +31 -0
  366. package/ui/lib/studio-examples.js +25 -0
  367. package/ui/lib/studio-labels.d.ts +6 -0
  368. package/ui/lib/studio-labels.js +13 -0
  369. package/ui/lib/studio-map-kept.d.ts +17 -0
  370. package/ui/lib/studio-map-kept.js +48 -0
  371. package/ui/lib/studio-open.d.ts +22 -0
  372. package/ui/lib/studio-open.js +54 -0
  373. package/ui/lib/studio-page.d.ts +33 -0
  374. package/ui/lib/studio-page.js +121 -0
  375. package/ui/lib/studio-prefs.d.ts +26 -0
  376. package/ui/lib/studio-prefs.js +87 -0
  377. package/ui/lib/studio-project.d.ts +106 -0
  378. package/ui/lib/studio-project.js +177 -0
  379. package/ui/lib/studio-restore.d.ts +49 -0
  380. package/ui/lib/studio-restore.js +251 -0
  381. package/ui/lib/studio-run-open.d.ts +15 -0
  382. package/ui/lib/studio-run-open.js +16 -0
  383. package/ui/lib/studio-session.d.ts +34 -0
  384. package/ui/lib/studio-session.js +17 -0
  385. package/ui/lib/studio-settings.d.ts +15 -0
  386. package/ui/lib/studio-settings.js +48 -0
  387. package/ui/lib/studio-store.d.ts +64 -0
  388. package/ui/lib/studio-store.js +391 -0
  389. package/ui/lib/studio-watch.d.ts +12 -0
  390. package/ui/lib/studio-watch.js +27 -0
  391. package/ui/lib/tab-fills.d.ts +6 -0
  392. package/ui/lib/tab-fills.js +14 -0
  393. package/ui/lib/tool-credentials.d.ts +3 -0
  394. package/ui/lib/tool-credentials.js +23 -0
  395. package/ui/lib/tool-probe.d.ts +19 -0
  396. package/ui/lib/tool-probe.js +104 -0
  397. package/ui/lib/type-icons.d.ts +35 -0
  398. package/ui/lib/type-icons.js +38 -0
  399. package/ui/lib/when-idle.d.ts +5 -0
  400. package/ui/lib/when-idle.js +14 -0
  401. package/ui/lib/zip.d.ts +5 -0
  402. package/ui/lib/zip.js +8 -0
  403. package/ui/map-token.css +11 -0
  404. package/ui/map-token.d.ts +17 -0
  405. package/ui/map-token.js +29 -0
  406. package/ui/mcp-icon.d.ts +6 -0
  407. package/ui/mcp-icon.js +8 -0
  408. package/ui/motion.css +113 -0
  409. package/ui/pan.d.ts +32 -0
  410. package/ui/pan.js +90 -0
  411. package/ui/profile-editor.d.ts +33 -0
  412. package/ui/profile-editor.js +2638 -0
  413. package/ui/provider-editor.d.ts +15 -0
  414. package/ui/provider-editor.js +92 -0
  415. package/ui/read-map.css +48 -0
  416. package/ui/read-map.d.ts +7 -0
  417. package/ui/read-map.js +163 -0
  418. package/ui/refusal-detail.d.ts +4 -0
  419. package/ui/refusal-detail.js +21 -0
  420. package/ui/shared-change.d.ts +9 -0
  421. package/ui/shared-change.js +28 -0
  422. package/ui/shell-motion.css +121 -0
  423. package/ui/shell-motion.d.ts +73 -0
  424. package/ui/shell-motion.js +194 -0
  425. package/ui/studio-code-pane.d.ts +19 -0
  426. package/ui/studio-code-pane.js +44 -0
  427. package/ui/studio-compare.d.ts +80 -0
  428. package/ui/studio-compare.js +326 -0
  429. package/ui/studio-conflicts.d.ts +17 -0
  430. package/ui/studio-conflicts.js +87 -0
  431. package/ui/studio-connection.d.ts +64 -0
  432. package/ui/studio-connection.js +286 -0
  433. package/ui/studio-decision.d.ts +6 -0
  434. package/ui/studio-decision.js +49 -0
  435. package/ui/studio-embedding.d.ts +6 -0
  436. package/ui/studio-embedding.js +30 -0
  437. package/ui/studio-host-console.d.ts +6 -0
  438. package/ui/studio-host-console.js +17 -0
  439. package/ui/studio-host.d.ts +73 -0
  440. package/ui/studio-host.js +12 -0
  441. package/ui/studio-live.d.ts +17 -0
  442. package/ui/studio-live.js +26 -0
  443. package/ui/studio-map.css +273 -0
  444. package/ui/studio-map.d.ts +17 -0
  445. package/ui/studio-map.js +397 -0
  446. package/ui/studio-nav.d.ts +24 -0
  447. package/ui/studio-nav.js +17 -0
  448. package/ui/studio-no-project.d.ts +5 -0
  449. package/ui/studio-no-project.js +9 -0
  450. package/ui/studio-run.css +76 -0
  451. package/ui/studio-run.d.ts +14 -0
  452. package/ui/studio-run.js +119 -0
  453. package/ui/studio-runner.d.ts +45 -0
  454. package/ui/studio-runner.js +187 -0
  455. package/ui/studio-save.d.ts +49 -0
  456. package/ui/studio-save.js +307 -0
  457. package/ui/studio-screen.d.ts +61 -0
  458. package/ui/studio-screen.js +2078 -0
  459. package/ui/studio-settings.d.ts +31 -0
  460. package/ui/studio-settings.js +288 -0
  461. package/ui/studio-shell.css +27 -0
  462. package/ui/studio-shell.d.ts +43 -0
  463. package/ui/studio-shell.js +87 -0
  464. package/ui/studio-theme.d.ts +7 -0
  465. package/ui/studio-theme.js +94 -0
  466. package/ui/studio.css +427 -0
  467. package/ui/theorem-mark.css +84 -0
  468. package/ui/theorem-mark.d.ts +22 -0
  469. package/ui/theorem-mark.js +21 -0
  470. package/vite.d.mts +30 -0
  471. package/vite.mjs +277 -0
  472. package/workspace.d.ts +230 -0
  473. package/workspace.js +1054 -0
@@ -0,0 +1,215 @@
1
+ import { TheoremError, z } from '@theoremjs/agents';
2
+ import { GEMINI_MODELS_URL } from '@theoremjs/agents/presets/google';
3
+ /** Which service a pasted key belongs to, from its published prefix; `undefined` when unknown. */
4
+ export function keyKind(secret) {
5
+ const key = secret?.trim() ?? '';
6
+ if (key.startsWith('AIza'))
7
+ return 'gemini';
8
+ if (key.startsWith('sk-or-'))
9
+ return 'openrouter';
10
+ return undefined;
11
+ }
12
+ export function localStudioConfig(local) {
13
+ let url;
14
+ try {
15
+ url = new URL(local.baseUrl);
16
+ }
17
+ catch {
18
+ throw new TheoremError('config', 'Enter a valid localhost URL.');
19
+ } // labels-exempt: builder diagnostic
20
+ if (!['http:', 'https:'].includes(url.protocol) ||
21
+ !['localhost', '127.0.0.1', '[::1]'].includes(url.hostname) ||
22
+ url.username ||
23
+ url.password ||
24
+ url.search ||
25
+ url.hash) {
26
+ throw new TheoremError('config', 'Use a localhost URL without credentials, query parameters or a fragment.'); // labels-exempt: builder diagnostic
27
+ }
28
+ return {
29
+ baseUrl: url.href.replace(/\/$/, ''),
30
+ // A token, when the model names a slot, comes from the vault through the adapter.
31
+ fetch: (input, init) => {
32
+ const target = new URL(input instanceof Request ? input.url : String(input));
33
+ if (target.origin !== url.origin) {
34
+ return Promise.reject(new TheoremError('blocked', 'Local requests must stay on the configured origin.')); // labels-exempt: builder diagnostic
35
+ }
36
+ return fetch(input, {
37
+ ...init,
38
+ redirect: 'error',
39
+ credentials: 'omit',
40
+ });
41
+ },
42
+ };
43
+ }
44
+ export const STUDIO_KEY_SLOT_CAP = 32;
45
+ const localModelList = z.object({ data: z.array(z.object({ id: z.string().min(1) })) });
46
+ /** The same localhost origin and transport used for inference; never a site proxy. */
47
+ export async function listLocalStudioModels(local, signal) {
48
+ const config = localStudioConfig(local);
49
+ if (!config?.fetch)
50
+ throw new TheoremError('config', 'Enter a local endpoint.'); // labels-exempt: builder diagnostic
51
+ const response = await config.fetch(`${config.baseUrl}/v1/models`, {
52
+ signal,
53
+ headers: { Accept: 'application/json' },
54
+ });
55
+ if (!response.ok)
56
+ throw new TheoremError('network', `Local model list returned HTTP ${response.status}.`); // labels-exempt: builder diagnostic
57
+ const parsed = localModelList.safeParse(await response.json());
58
+ if (!parsed.success)
59
+ throw new TheoremError('request', 'The endpoint returned an invalid model list.'); // labels-exempt: builder diagnostic
60
+ return [...new Set(parsed.data.data.map((model) => model.id))];
61
+ }
62
+ const OPENROUTER_MODELS_URL = 'https://openrouter.ai/api/v1/models';
63
+ const OPENROUTER_EMBEDDING_MODELS_URL = 'https://openrouter.ai/api/v1/embeddings/models';
64
+ export const KNOWN_GEMINI_EMBEDDING_MODELS = [
65
+ { id: 'gemini-embedding-2-preview', label: 'Gemini Embeddings 2 (preview)' },
66
+ { id: 'gemini-embedding-001', label: 'Gemini Embedding 001' },
67
+ ];
68
+ export const KNOWN_OPENROUTER_EMBEDDING_MODELS = [
69
+ { id: 'liquid/lfm-2.5-embedding-350m:free', label: 'Liquid LFM 2.5 Embedding 350M (free)' },
70
+ { id: 'nvidia/nemotron-3-embed-1b:free', label: 'NVIDIA Nemotron 3 Embed 1B (free)' },
71
+ {
72
+ id: 'nvidia/llama-nemotron-embed-vl-1b-v2:free',
73
+ label: 'NVIDIA Llama Nemotron Embed VL 1B v2 (free)',
74
+ },
75
+ ];
76
+ /**
77
+ * OpenRouter's `output_modalities` for each profile type: chat models for text, `/images` models
78
+ * for image, `/audio/speech` models for speech. OpenRouter has no live models.
79
+ */
80
+ const OPENROUTER_OUTPUT = {
81
+ text: 'text',
82
+ image: 'image',
83
+ speech: 'speech',
84
+ live: undefined,
85
+ embedding: undefined,
86
+ };
87
+ const openRouterModelList = z.object({
88
+ data: z.array(z.object({
89
+ id: z.string().min(1),
90
+ name: z.string().optional(),
91
+ architecture: z.object({ output_modalities: z.array(z.string()).optional() }).optional(),
92
+ })),
93
+ });
94
+ const openRouterEmbeddingModelList = z.object({
95
+ data: z.array(z.object({ id: z.string().min(1), name: z.string().optional() })),
96
+ });
97
+ const geminiModelList = z.object({
98
+ models: z
99
+ .array(z.object({
100
+ name: z.string().min(1),
101
+ displayName: z.string().optional(),
102
+ supportedGenerationMethods: z.array(z.string()).optional(),
103
+ }))
104
+ .optional(),
105
+ nextPageToken: z.string().optional(),
106
+ });
107
+ /** Enough pages for every model a Gemini project lists; a runaway token stops here. */
108
+ const GEMINI_MODEL_PAGES = 5;
109
+ async function listedJson(provider, url, init) {
110
+ const response = await fetch(url, { ...init, redirect: 'error', credentials: 'omit' });
111
+ // Gemini answers a key it doesn't know with 400; the list's own query never earns one.
112
+ if (response.status === 400 || response.status === 401 || response.status === 403) {
113
+ throw new TheoremError('auth', `${provider} refused the key.`); // labels-exempt: builder diagnostic
114
+ }
115
+ if (!response.ok) {
116
+ throw new TheoremError('network', `${provider} model list returned HTTP ${response.status}.`); // labels-exempt: builder diagnostic
117
+ }
118
+ return await response.json();
119
+ }
120
+ /**
121
+ * The models a provider offers for a profile type, fetched from the browser with the key in this
122
+ * tab, never through the site. OpenRouter lists without a key and says what each model returns, so
123
+ * its list keeps only models of the profile's kind. Gemini needs the key and says only which calls
124
+ * a model takes, so its list keeps the models that answer a turn (live models for live).
125
+ */
126
+ export async function listProviderModels(provider, profileType, key, signal) {
127
+ const secret = key?.trim();
128
+ if (profileType === 'embedding' && !secret) {
129
+ return [
130
+ ...(provider === 'openrouter'
131
+ ? KNOWN_OPENROUTER_EMBEDDING_MODELS
132
+ : KNOWN_GEMINI_EMBEDDING_MODELS),
133
+ ];
134
+ }
135
+ if (provider === 'openrouter')
136
+ return await listOpenRouterModels(profileType, secret, signal);
137
+ if (!secret)
138
+ throw new TheoremError('auth', 'Choose a key to list Gemini models.'); // labels-exempt: builder diagnostic
139
+ return await listGeminiModels(profileType, secret, signal);
140
+ }
141
+ /** OpenRouter's models of the profile's kind; the key is optional. */
142
+ async function listOpenRouterModels(profileType, secret, signal) {
143
+ const init = {
144
+ signal,
145
+ headers: {
146
+ Accept: 'application/json',
147
+ ...(secret ? { Authorization: ['Bearer', secret].join(' ') } : {}),
148
+ },
149
+ };
150
+ if (profileType === 'embedding') {
151
+ const parsed = openRouterEmbeddingModelList.safeParse(await listedJson('OpenRouter', OPENROUTER_EMBEDDING_MODELS_URL, init));
152
+ if (!parsed.success)
153
+ throw new TheoremError('bad_response', 'OpenRouter returned an invalid embedding model list.'); // labels-exempt: builder diagnostic
154
+ return parsed.data.data.map((model) => ({ id: model.id, label: model.name ?? model.id }));
155
+ }
156
+ const output = OPENROUTER_OUTPUT[profileType];
157
+ if (!output)
158
+ return [];
159
+ const parsed = openRouterModelList.safeParse(await listedJson('OpenRouter', `${OPENROUTER_MODELS_URL}?output_modalities=${output}`, init));
160
+ if (!parsed.success)
161
+ throw new TheoremError('bad_response', 'OpenRouter returned an invalid model list.'); // labels-exempt: builder diagnostic
162
+ return parsed.data.data
163
+ .filter((model) => model.architecture?.output_modalities?.includes(output) ?? true)
164
+ .map((model) => ({ id: model.id, label: model.name ?? model.id }));
165
+ }
166
+ /** The Gemini method a profile type's models must take. */
167
+ const GEMINI_METHOD = {
168
+ live: 'bidiGenerateContent',
169
+ embedding: 'embedContent',
170
+ };
171
+ /** The key's Gemini models that take the profile type's method, page by page. */
172
+ async function listGeminiModels(profileType, secret, signal) {
173
+ const method = GEMINI_METHOD[profileType] ?? 'generateContent';
174
+ const models = [];
175
+ let pageToken;
176
+ for (let page = 0; page < GEMINI_MODEL_PAGES; page++) {
177
+ const url = new URL(GEMINI_MODELS_URL);
178
+ url.searchParams.set('pageSize', '1000');
179
+ if (pageToken)
180
+ url.searchParams.set('pageToken', pageToken);
181
+ const parsed = geminiModelList.safeParse(await listedJson('Google', url.href, {
182
+ signal,
183
+ headers: { Accept: 'application/json', 'x-goog-api-key': secret },
184
+ }));
185
+ if (!parsed.success)
186
+ throw new TheoremError('bad_response', 'Google returned an invalid model list.'); // labels-exempt: builder diagnostic
187
+ for (const model of parsed.data.models ?? []) {
188
+ if (!model.supportedGenerationMethods?.includes(method))
189
+ continue;
190
+ const id = model.name.replace(/^models\//, '');
191
+ models.push({ id, label: model.displayName ?? id });
192
+ }
193
+ pageToken = parsed.data.nextPageToken;
194
+ if (!pageToken)
195
+ break;
196
+ }
197
+ return models;
198
+ }
199
+ /** Slot references come from the compiled contract, including each model's overrides. */
200
+ export function studioKeySlots(profile) {
201
+ return [
202
+ ...new Set([
203
+ profile.key,
204
+ profile.fallbackKey,
205
+ ...Object.values(profile.models ?? {}).flatMap((model) => [
206
+ model.keySlot,
207
+ model.fallbackKeySlot,
208
+ ]),
209
+ ].filter((slot) => Boolean(slot))),
210
+ ];
211
+ }
212
+ /** Defines even empty referenced slots, so names such as `constructor` never read inherited values. */
213
+ export function studioVault(slots, vault) {
214
+ return Object.fromEntries(slots.map((slot) => [slot, Object.hasOwn(vault, slot) ? vault[slot] : undefined]));
215
+ }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * What a run in the page runs on: the kernel's engine and the session machinery around it. The
3
+ * page's transports load it on their first call, so a studio that never runs in the page never
4
+ * downloads it.
5
+ *
6
+ * @module
7
+ */
8
+ export { createMemorySteerInbox, createSealedConversationStore, liveSessionOpen, parseLiveOpenMessage, steerUnitOf, } from '@theoremjs/react/server';
9
+ export { browserExecution } from './browser-execution.ts';
10
+ export { attachStudioLiveSession } from './live-session-bridge.ts';
11
+ export { rewindStudio, runStudioDecision, runStudioEmbedding, streamStudioCall, streamStudioHostInvoke, streamStudioInvoke, streamStudioTurn, studioConversation, studioScope, studioTraces, } from './runtime.ts';
@@ -0,0 +1,11 @@
1
+ /**
2
+ * What a run in the page runs on: the kernel's engine and the session machinery around it. The
3
+ * page's transports load it on their first call, so a studio that never runs in the page never
4
+ * downloads it.
5
+ *
6
+ * @module
7
+ */
8
+ export { createMemorySteerInbox, createSealedConversationStore, liveSessionOpen, parseLiveOpenMessage, steerUnitOf, } from '@theoremjs/react/server';
9
+ export { browserExecution } from "./browser-execution.js";
10
+ export { attachStudioLiveSession } from "./live-session-bridge.js";
11
+ export { rewindStudio, runStudioDecision, runStudioEmbedding, streamStudioCall, streamStudioHostInvoke, streamStudioInvoke, streamStudioTurn, studioConversation, studioScope, studioTraces, } from "./runtime.js";
@@ -0,0 +1,6 @@
1
+ export declare function browserExecution(): {
2
+ boundary: Promise<import("@theoremjs/react/server").TheoremSessionBoundary>;
3
+ execution: import("../mod").ToolExecutionCoordinator;
4
+ pageExecution: import("../mod").PageToolExecution;
5
+ pageResult: (result: import("@theoremjs/react/server").PageToolResult) => Promise<boolean>;
6
+ };
@@ -0,0 +1,18 @@
1
+ import { createMemoryPageToolBroker, createMemorySessionStore, createTheoremSessionBoundary, DEFAULT_OPERATION_RETENTION_MS, resolveSessionLimits, sessionPageDispatch, sessionStateStore, sessionToolCoordinator, } from '@theoremjs/react/server';
2
+ export function browserExecution() {
3
+ const id = crypto.randomUUID();
4
+ const memory = createMemorySessionStore();
5
+ const boundary = createTheoremSessionBoundary({
6
+ request: new Request('https://studio.local'),
7
+ session: () => id,
8
+ sessionStore: memory,
9
+ });
10
+ const store = sessionStateStore(memory, 30 * 60_000, DEFAULT_OPERATION_RETENTION_MS, resolveSessionLimits());
11
+ const page = sessionPageDispatch(store, id, createMemoryPageToolBroker());
12
+ return {
13
+ boundary,
14
+ execution: sessionToolCoordinator(store, id),
15
+ pageExecution: page.execution,
16
+ pageResult: page.answer,
17
+ };
18
+ }
@@ -0,0 +1,4 @@
1
+ import type { LiveConnection } from '@theoremjs/react/client';
2
+ import { type StudioBrowserRuntime } from './browser-transport.ts';
3
+ import type { StudioRunPayload } from './run-payload.ts';
4
+ export declare function browserStudioLiveConnection(payload: StudioRunPayload, runtime: StudioBrowserRuntime): LiveConnection;
@@ -0,0 +1,132 @@
1
+ import { TheoremError } from '@theoremjs/agents';
2
+ import { clientError } from '@theoremjs/agents/host';
3
+ import { browserEngine } from "./browser-transport.js";
4
+ import { STUDIO_READER } from "./reader.js";
5
+ /** The Live UI's existing relay protocol, carried in memory instead of over a site socket. */
6
+ class BrowserLiveSocket {
7
+ readyState = 0;
8
+ binaryType = 'arraybuffer';
9
+ onopen = null;
10
+ onmessage = null;
11
+ onclose = null;
12
+ onerror = null;
13
+ outbound = new EventTarget();
14
+ closeSession;
15
+ queued = [];
16
+ listening = false;
17
+ constructor(payload, runtime, local) {
18
+ // Install the UI's handlers before the first ready/error message.
19
+ queueMicrotask(() => {
20
+ void this.open(payload, runtime, local);
21
+ });
22
+ }
23
+ send(data) {
24
+ if (this.readyState !== 1) {
25
+ throw new TheoremError('network', 'Live connection is closed'); // labels-exempt: internal diagnostic
26
+ }
27
+ if (!this.listening)
28
+ this.queued.push(data);
29
+ else
30
+ this.outbound.dispatchEvent(new MessageEvent('message', { data }));
31
+ }
32
+ close() {
33
+ if (this.readyState === 3)
34
+ return;
35
+ this.readyState = 3;
36
+ this.queued = [];
37
+ this.outbound.dispatchEvent(new Event('close'));
38
+ void this.closeSession?.();
39
+ this.emit('onclose', new CloseEvent('close'));
40
+ }
41
+ emit(kind, event) {
42
+ // Native socket callbacks carry a WebSocket `this`; these callbacks only read the event.
43
+ const callback = this[kind];
44
+ callback?.(event);
45
+ }
46
+ async open(payload, runtime, local) {
47
+ if (this.readyState === 3)
48
+ return;
49
+ this.readyState = 1;
50
+ this.emit('onopen', new Event('open'));
51
+ let traces;
52
+ try {
53
+ const run = await browserEngine();
54
+ const page = local?.(run);
55
+ traces = run.studioTraces.route((record) => this.receive({ type: 'trace', record }));
56
+ const { scope, profile } = await run.studioScope(payload.profile, payload.customTools, payload.structured, runtime);
57
+ if (!runtime.providers?.vault) {
58
+ throw new TheoremError('auth', 'Fill the vault slot this model names.'); // labels-exempt: builder diagnostic
59
+ }
60
+ // The client sends its open message as the socket opens: the call's slots, context, and resume.
61
+ const [first] = this.queued.splice(0, 1);
62
+ if (typeof first !== 'string') {
63
+ throw new TheoremError('request', 'A live call must open with its open message'); // labels-exempt: internal diagnostic
64
+ }
65
+ const session = await scope.runSession({
66
+ ...(await (page
67
+ ? (await page.boundary).prepareLiveOpen(run.parseLiveOpenMessage(first))
68
+ : Promise.resolve(run.liveSessionOpen(run.parseLiveOpenMessage(first))))),
69
+ profile: profile.id,
70
+ metadata: traces.metadata,
71
+ signal: runtime.signal,
72
+ }, {
73
+ execution: runtime.execution ?? page?.execution,
74
+ pageExecution: runtime.pageExecution ?? page?.pageExecution,
75
+ vault: runtime.providers.vault,
76
+ fetch: runtime.providers.fetch,
77
+ wait: runtime.providers.wait,
78
+ openWebSocket: runtime.providers.openWebSocket,
79
+ });
80
+ this.closeSession = () => session.close('client disconnected');
81
+ if (this.readyState !== 1) {
82
+ await this.closeSession();
83
+ traces.close();
84
+ return;
85
+ }
86
+ await this.attach(run.attachStudioLiveSession, session, profile.id, traces, profile.labels, page
87
+ ? {
88
+ pageResult: page.pageResult,
89
+ beforeEvent: async (event) => {
90
+ if ((event.type === 'done' || event.type === 'provider_checkpoint') &&
91
+ event.providerState)
92
+ await (await page.boundary).recordCheckpoint(event.providerState);
93
+ },
94
+ }
95
+ : {});
96
+ }
97
+ catch (err) {
98
+ traces?.close();
99
+ this.receive({ type: 'error', ...clientError(err, payload.profile.labels, STUDIO_READER) });
100
+ this.close();
101
+ }
102
+ }
103
+ async attach(attachStudioLiveSession, session, profileId, traces, labels, options = {}) {
104
+ const socket = {
105
+ send: (data) => {
106
+ if (typeof data === 'string')
107
+ this.receive(JSON.parse(data));
108
+ },
109
+ close: () => this.close(),
110
+ addEventListener: this.outbound.addEventListener.bind(this.outbound),
111
+ };
112
+ const ended = attachStudioLiveSession(socket, session, profileId, crypto.randomUUID(), traces, labels, { ...options, clientEvents: STUDIO_READER });
113
+ this.closeSession = undefined;
114
+ this.listening = true;
115
+ for (const data of this.queued.splice(0)) {
116
+ this.outbound.dispatchEvent(new MessageEvent('message', { data }));
117
+ }
118
+ await ended;
119
+ }
120
+ receive(message) {
121
+ if (this.readyState === 1) {
122
+ this.emit('onmessage', new MessageEvent('message', { data: JSON.stringify(message) }));
123
+ }
124
+ }
125
+ }
126
+ export function browserStudioLiveConnection(payload, runtime) {
127
+ // The in-process connection knows its draft, so its open message carries none.
128
+ // The page's sessions are made once, by the first call, from the engine that call loaded.
129
+ let page;
130
+ const local = runtime.execution ? undefined : (run) => (page ??= run.browserExecution());
131
+ return { createSocket: () => new BrowserLiveSocket(payload, runtime, local) };
132
+ }
@@ -0,0 +1,33 @@
1
+ import type { RunDecisionOptions } from '@theoremjs/agents/kernel';
2
+ import { type DecisionTransport, type EmbeddingTransport, type HostTransport, type TheoremTransport, type TraceFeed } from '@theoremjs/react/client';
3
+ import type { StudioRunPayload } from './run-payload.ts';
4
+ import type { StudioRuntimeBase } from './runtime-scope.ts';
5
+ /**
6
+ * The engine a run in the page runs on, loaded once. A connection asks for it as it is made, so
7
+ * the first run waits on nothing; a studio that never runs in the page never downloads it.
8
+ */
9
+ export declare const browserEngine: () => Promise<typeof import("./browser-engine.ts")>;
10
+ /** A run in the page: on the builder's own keys or machine, never on lent keys. */
11
+ export interface StudioBrowserRuntime extends StudioRuntimeBase {
12
+ mode: 'byok' | 'local';
13
+ decision?: Pick<RunDecisionOptions, 'vault' | 'fetch'>;
14
+ /** Disconnecting aborts active requests, without retaining the vault in a saved payload. */
15
+ signal?: AbortSignal;
16
+ }
17
+ /**
18
+ * A chat run in the page. Its conversation is sealed with `conversationKey`,
19
+ * a key the tab keeps, so every transport of the tab opens the same refs.
20
+ */
21
+ export declare function createBrowserStudioTransport(payload: StudioRunPayload, runtime: StudioBrowserRuntime, options: {
22
+ conversationKey: string;
23
+ traces?: TraceFeed;
24
+ }): TheoremTransport;
25
+ export declare function createBrowserStudioHostTransport(payload: StudioRunPayload, runtime: StudioBrowserRuntime, options?: {
26
+ traces?: TraceFeed;
27
+ }): HostTransport;
28
+ export declare function createBrowserStudioDecisionTransport(payload: StudioRunPayload, runtime: StudioBrowserRuntime, options?: {
29
+ traces?: TraceFeed;
30
+ }): DecisionTransport;
31
+ export declare function createBrowserStudioEmbeddingTransport(payload: StudioRunPayload, runtime: StudioBrowserRuntime, options?: {
32
+ traces?: TraceFeed;
33
+ }): EmbeddingTransport;
@@ -0,0 +1,229 @@
1
+ import { defineProfile, TheoremError } from '@theoremjs/agents';
2
+ import { clientError, forClient } from '@theoremjs/agents/host';
3
+ import { createTraceFeed, decisionInterface, embeddingInterface, failedTraces, hostError, hostInterface, isTheoremStreamError, withFailedTraces, } from '@theoremjs/react/client';
4
+ import { STUDIO_READER } from "./reader.js";
5
+ import { hostCallLines, routeStudioLines, studioInterface, } from "./transport.js";
6
+ let engine;
7
+ /**
8
+ * The engine a run in the page runs on, loaded once. A connection asks for it as it is made, so
9
+ * the first run waits on nothing; a studio that never runs in the page never downloads it.
10
+ */
11
+ export const browserEngine = () => (engine ??= import("./browser-engine.js"));
12
+ /** The lines `open` streams once `ready` settles: a run's lines wait for the engine it runs on. */
13
+ async function* after(ready, open) {
14
+ yield* open(await ready);
15
+ }
16
+ /** The run's signal: the disconnect's and the request's, either of which aborts it. */
17
+ function runSignal(runtime, signal) {
18
+ return AbortSignal.any([runtime.signal, signal].filter((each) => each !== undefined));
19
+ }
20
+ /** A failure of a run made in the page, as the studio's reader has it. */
21
+ function failed(error, payload) {
22
+ return hostError(clientError(error, payload.profile.labels, STUDIO_READER), 'internal');
23
+ }
24
+ /** Direct streams use the same event and trace routing as the HTTP transport. */
25
+ async function deliver(source, payload, sink) {
26
+ try {
27
+ for await (const line of source) {
28
+ const read = line.type === 'trace' || line.type === 'steer_inbox' || line.type === 'conversation'
29
+ ? line
30
+ : forClient(line, STUDIO_READER);
31
+ if (read.type === 'error')
32
+ throw hostError(read, 'internal');
33
+ sink(read);
34
+ }
35
+ }
36
+ catch (error) {
37
+ throw isTheoremStreamError(error) ? error : failed(error, payload);
38
+ }
39
+ }
40
+ /** A page tool's answer goes to the page's own sessions, once the engine they live in has loaded. */
41
+ function localPageResult(runtime, local) {
42
+ return runtime.execution
43
+ ? undefined
44
+ : async (result) => {
45
+ await (await local())?.pageResult(result);
46
+ };
47
+ }
48
+ function withBrowserExecution(runtime, run) {
49
+ const local = runtime.execution ? undefined : run.browserExecution();
50
+ if (local) {
51
+ const original = runtime;
52
+ runtime = {
53
+ mode: original.mode,
54
+ providers: original.providers,
55
+ providerDefinitions: original.providerDefinitions,
56
+ decision: original.decision,
57
+ signal: original.signal,
58
+ resolveHost: original.resolveHost?.bind(original),
59
+ remoteTools: original.remoteTools,
60
+ hostOptions: original.hostOptions?.bind(original),
61
+ provider: original.provider?.bind(original),
62
+ onAgentCall: original.onAgentCall?.bind(original),
63
+ execution: local.execution,
64
+ pageExecution: local.pageExecution,
65
+ };
66
+ }
67
+ return { runtime, local };
68
+ }
69
+ /** The one session a page's conversations open in: the tab holds the key, so only its refs open. */
70
+ const PAGE_SESSION = 'studio-page';
71
+ /**
72
+ * A chat run in the page. Its conversation is sealed with `conversationKey`,
73
+ * a key the tab keeps, so every transport of the tab opens the same refs.
74
+ */
75
+ export function createBrowserStudioTransport(payload, runtime, options) {
76
+ const traces = options.traces ?? createTraceFeed();
77
+ // The engine starts loading as the transport is made, when the builder connects.
78
+ const session = browserEngine().then((run) => ({
79
+ run,
80
+ ...withBrowserExecution(runtime, run),
81
+ steer: run.createMemorySteerInbox(),
82
+ conversations: {
83
+ sessionId: PAGE_SESSION,
84
+ store: run.createSealedConversationStore({
85
+ keys: { 1: options.conversationKey },
86
+ keyVersion: 1,
87
+ }),
88
+ },
89
+ }));
90
+ // why: a failed load surfaces on the run that awaits it, not as an unhandled rejection.
91
+ session.catch(() => { });
92
+ const inboxes = new Map();
93
+ const compiled = {
94
+ profile: payload.profile,
95
+ customTools: payload.customTools,
96
+ structured: payload.structured,
97
+ dependencies: payload.dependencies,
98
+ };
99
+ const route = (onLine, onInbox = (_inbox) => { }) => routeStudioLines(onLine, traces, onInbox);
100
+ /** A request the page answers at once: its failure as the studio's reader has it. */
101
+ const answered = async (answer) => {
102
+ try {
103
+ return await answer();
104
+ }
105
+ catch (error) {
106
+ throw failed(error, payload);
107
+ }
108
+ };
109
+ return {
110
+ pageResult: localPageResult(runtime, async () => (await session).local),
111
+ describe: () => Promise.resolve(studioInterface(payload)),
112
+ async turn(request, onEvent, signal) {
113
+ try {
114
+ await deliver(after(session, ({ run, runtime: inPage, conversations, steer }) => run.streamStudioTurn({
115
+ ...compiled,
116
+ runtime: inPage,
117
+ request,
118
+ conversations,
119
+ signal: runSignal(runtime, signal),
120
+ steer,
121
+ })), payload, route(onEvent, (inbox) => {
122
+ if (request.turnId)
123
+ inboxes.set(request.turnId, inbox);
124
+ }));
125
+ }
126
+ finally {
127
+ if (request.turnId)
128
+ inboxes.delete(request.turnId);
129
+ }
130
+ },
131
+ invoke: (answer, onEvent, signal) => deliver(after(session, ({ run, runtime: inPage, conversations }) => run.streamStudioInvoke({
132
+ ...compiled,
133
+ runtime: inPage,
134
+ answer,
135
+ conversations,
136
+ signal: runSignal(runtime, signal),
137
+ })), payload, route(onEvent)),
138
+ conversation: (request) => answered(async () => {
139
+ const { run, runtime: inPage, conversations } = await session;
140
+ return run.studioConversation({ ...compiled, runtime: inPage }, conversations, request);
141
+ }),
142
+ rewind: (request, signal) => answered(async () => {
143
+ const { run, runtime: inPage, conversations } = await session;
144
+ return run.rewindStudio({ ...compiled, runtime: inPage }, conversations, request, runSignal(runtime, signal));
145
+ }),
146
+ async steer(request) {
147
+ const inbox = inboxes.get(request.turnId);
148
+ const { run, steer } = await session;
149
+ if (!inbox || !(await steer.enqueue(inbox, run.steerUnitOf(request)))) {
150
+ throw new TheoremError('request', 'The turn has ended', {
151
+ copy: { key: 'session.turn_ended' },
152
+ }); // labels-exempt: internal diagnostic
153
+ }
154
+ },
155
+ traces,
156
+ };
157
+ }
158
+ export function createBrowserStudioHostTransport(payload, runtime, options = {}) {
159
+ const traces = options.traces ?? createTraceFeed();
160
+ let sessionPermissions = [];
161
+ let prepared;
162
+ /** The engine and the page's sessions, made on the first call and kept for the rest. */
163
+ const prepare = () => (prepared ??= browserEngine().then((run) => ({ run, ...withBrowserExecution(runtime, run) })));
164
+ const compiled = {
165
+ profile: payload.profile,
166
+ customTools: payload.customTools,
167
+ dependencies: payload.dependencies,
168
+ };
169
+ const route = (onEvent) => routeStudioLines(hostCallLines(onEvent), traces, () => { });
170
+ return {
171
+ pageResult: localPageResult(runtime, async () => (await prepare()).local),
172
+ describe: () => Promise.resolve(hostInterface(defineProfile(payload.profile), (name) => payload.customTools.find((tool) => tool.name === name))),
173
+ call: (call, onEvent, signal) => deliver(after(prepare(), ({ run, runtime: inPage }) => run.streamStudioCall({
174
+ ...compiled,
175
+ runtime: inPage,
176
+ call,
177
+ sessionPermissions,
178
+ signal: runSignal(runtime, signal),
179
+ })), payload, route(onEvent)),
180
+ invoke(answer, onEvent, signal) {
181
+ sessionPermissions = answer.replay?.sessionPermissions ?? sessionPermissions;
182
+ return deliver(after(prepare(), ({ run, runtime: inPage }) => run.streamStudioHostInvoke({
183
+ ...compiled,
184
+ runtime: inPage,
185
+ answer,
186
+ signal: runSignal(runtime, signal),
187
+ })), payload, route(onEvent));
188
+ },
189
+ traces,
190
+ };
191
+ }
192
+ export function createBrowserStudioDecisionTransport(payload, runtime, options = {}) {
193
+ const traces = options.traces ?? createTraceFeed();
194
+ return {
195
+ describe: () => Promise.resolve(decisionInterface(defineProfile(payload.profile), payload.questions ?? {}, payload.images)),
196
+ decide: async (state, signal, assets) => {
197
+ try {
198
+ const run = await browserEngine();
199
+ return await run.runStudioDecision(payload, state, runtime.decision ?? {}, runSignal(runtime, signal), assets);
200
+ }
201
+ catch (err) {
202
+ // The failure keeps the trace the kernel left.
203
+ throw withFailedTraces(failed(err, payload), failedTraces(err));
204
+ }
205
+ },
206
+ traces,
207
+ };
208
+ }
209
+ export function createBrowserStudioEmbeddingTransport(payload, runtime, options = {}) {
210
+ const traces = options.traces ?? createTraceFeed();
211
+ return {
212
+ describe: () => Promise.resolve(embeddingInterface(defineProfile(payload.profile))),
213
+ embed: async (input, embed, signal) => {
214
+ try {
215
+ const run = await browserEngine();
216
+ const response = await run.runStudioEmbedding(payload, {
217
+ input,
218
+ ...embed,
219
+ signal: runSignal(runtime, signal),
220
+ }, withBrowserExecution(runtime, run).runtime);
221
+ return { result: response.result, traces: response.traces };
222
+ }
223
+ catch (error) {
224
+ throw withFailedTraces(failed(error, payload), failedTraces(error));
225
+ }
226
+ },
227
+ traces,
228
+ };
229
+ }
package/browser.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ export { KNOWN_GEMINI_EMBEDDING_MODELS, KNOWN_OPENROUTER_EMBEDDING_MODELS, keyKind, type ListedProfileType, type ListedProvider, listLocalStudioModels, listProviderModels, localStudioConfig, type ProviderModel, STUDIO_KEY_SLOT_CAP, type StudioBrowserConnection, studioKeySlots, studioVault, } from './browser-connection.ts';
2
+ export { browserStudioLiveConnection } from './browser-live.ts';
3
+ export { createBrowserStudioDecisionTransport, createBrowserStudioEmbeddingTransport, createBrowserStudioHostTransport, createBrowserStudioTransport, type StudioBrowserRuntime, } from './browser-transport.ts';
4
+ export { attachStudioLiveSession } from './live-session-bridge.ts';