@theoremjs/studio 0.0.0-stage → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +295 -2
- package/agreement.d.ts +14 -0
- package/agreement.js +80 -0
- package/asks.d.ts +47 -0
- package/asks.js +54 -0
- package/browser-connection.d.ts +49 -0
- package/browser-connection.js +215 -0
- package/browser-engine.d.ts +11 -0
- package/browser-engine.js +11 -0
- package/browser-execution.d.ts +6 -0
- package/browser-execution.js +18 -0
- package/browser-live.d.ts +4 -0
- package/browser-live.js +132 -0
- package/browser-transport.d.ts +33 -0
- package/browser-transport.js +229 -0
- package/browser.d.ts +4 -0
- package/browser.js +4 -0
- package/canonical.d.ts +10 -0
- package/canonical.js +25 -0
- package/compile-workspace.d.ts +28 -0
- package/compile-workspace.js +295 -0
- package/compile.d.ts +65 -0
- package/compile.js +1605 -0
- package/concierge-demo.d.ts +17 -0
- package/concierge-demo.js +1230 -0
- package/conversation-key.d.ts +5 -0
- package/conversation-key.js +10 -0
- package/decision-example-images.d.ts +30 -0
- package/decision-example-images.js +30 -0
- package/deno.json +3 -0
- package/draft.d.ts +407 -0
- package/draft.js +505 -0
- package/editors.d.ts +29 -0
- package/editors.js +51 -0
- package/example-embedding-files.d.ts +11 -0
- package/example-embedding-files.js +20 -0
- package/example.d.ts +36 -0
- package/example.js +357 -0
- package/guardrail-probe.d.ts +100 -0
- package/guardrail-probe.js +722 -0
- package/held-credentials.d.ts +28 -0
- package/held-credentials.js +87 -0
- package/installed.mjs +40 -0
- package/lent-keys.d.ts +122 -0
- package/lent-keys.js +47 -0
- package/line-diff.d.ts +15 -0
- package/line-diff.js +41 -0
- package/live-connection.d.ts +22 -0
- package/live-connection.js +27 -0
- package/live-session-bridge.d.ts +15 -0
- package/live-session-bridge.js +202 -0
- package/map-line.d.ts +19 -0
- package/map-line.js +42 -0
- package/map.d.ts +154 -0
- package/map.js +525 -0
- package/media-accept.d.ts +19 -0
- package/media-accept.js +65 -0
- package/mod.d.ts +39 -0
- package/mod.js +33 -0
- package/origins.d.ts +52 -0
- package/origins.js +165 -0
- package/package.json +85 -4
- package/page/assets/Banner-BISz3nXA.js +2 -0
- package/page/assets/BottomSheet-BwfBDtje.js +1 -0
- package/page/assets/Card-Lp-0P5eL.js +1 -0
- package/page/assets/CardWall-CBRLdDZW.js +1 -0
- package/page/assets/Center-nHS1JSux.js +1 -0
- package/page/assets/CheckboxInput-Cj5pk-KI.js +2 -0
- package/page/assets/CodeBlock-C7XJ4ioE.js +51 -0
- package/page/assets/CollapsibleGroup-N7_SOjbm.js +2 -0
- package/page/assets/ContextMenu-CBu9H-9H.js +2 -0
- package/page/assets/DateInput-BGrQ5tPC.js +1 -0
- package/page/assets/Dialog-DELWQo-v.js +1 -0
- package/page/assets/EmptyState-C8W4JKBZ.js +1 -0
- package/page/assets/HoverCard-D1Y1ltWQ.js +1 -0
- package/page/assets/Icon-JrysT8aU.js +3 -0
- package/page/assets/IconAlertTriangle-BqAEqqdU.js +1 -0
- package/page/assets/IconButton-DlOGzJIX.js +1 -0
- package/page/assets/IconEye-BB5aY-wQ.js +1 -0
- package/page/assets/IconFileText-6zOFKKrF.js +1 -0
- package/page/assets/IconSearch-BTx66a40.js +1 -0
- package/page/assets/IconShield-DDOh7Gr5.js +1 -0
- package/page/assets/ItemSwipeLayer-Ckn4X6h9.js +1 -0
- package/page/assets/PaneState-BvA2tLQg.js +1 -0
- package/page/assets/PaneState-eUzUkNE8.css +1 -0
- package/page/assets/ScrollableArea-Ckugdj1N.js +1 -0
- package/page/assets/Section-DJ97F7QE.js +1 -0
- package/page/assets/SegmentedControlItem-h-aaXzyS.js +1 -0
- package/page/assets/SidePanel-BL32abk8.js +1 -0
- package/page/assets/StackItem-CQviqAfM.js +1 -0
- package/page/assets/Text-bum6zWWx.js +2 -0
- package/page/assets/TimestampHoverCard-DQIG0RZF.js +1 -0
- package/page/assets/ToolResultCharts-CgshSv9Q.js +1 -0
- package/page/assets/Tooltip-BH9xiRMl.js +1 -0
- package/page/assets/TraceInspector-_yZiz05W.js +1 -0
- package/page/assets/TraceOverview-BPO-HIYK.js +57 -0
- package/page/assets/VStack-CkVMcNiK.js +1 -0
- package/page/assets/_virtual_studio-type-sources-ByxqQaOG.js +12936 -0
- package/page/assets/arrive-DvbqpeRS.js +1 -0
- package/page/assets/browser-engine-CYq9DQAM.js +9 -0
- package/page/assets/browser-transport-D-2jDYe7.js +47 -0
- package/page/assets/codicon-DF1abBS2.ttf +0 -0
- package/page/assets/compile-egress-BSxOdX4K.js +23 -0
- package/page/assets/container.stylex-BmOi-8DQ.js +1 -0
- package/page/assets/createReactComponent-CZwsv6DD.js +1 -0
- package/page/assets/decision-example-images-CZGr7YIT.js +1 -0
- package/page/assets/devWarning-DxuplmRl.js +1 -0
- package/page/assets/editor-DjpsE8to.css +1 -0
- package/page/assets/editor.api-Cd3ViPQa.js +908 -0
- package/page/assets/editor.worker-6GY8RhDc.js +1 -0
- package/page/assets/editor.worker-BmdWdrHZ.js +33 -0
- package/page/assets/editors-BJX_S59A.js +1 -0
- package/page/assets/egress-automata-B5ZGE1mT.js +1 -0
- package/page/assets/embedding-space-view-CfQBPDxD.js +140 -0
- package/page/assets/encode-files-Bc3HJyAh.js +1 -0
- package/page/assets/export-agent-C3yyzXH8.js +43 -0
- package/page/assets/figtree-latin-400-normal-BD4aNku5.woff +0 -0
- package/page/assets/figtree-latin-400-normal-g7Dtegnw.woff2 +0 -0
- package/page/assets/figtree-latin-500-normal-BWnGEVsr.woff2 +0 -0
- package/page/assets/figtree-latin-500-normal-B_yy1phn.woff +0 -0
- package/page/assets/figtree-latin-600-normal-BM_oTo4n.woff +0 -0
- package/page/assets/figtree-latin-600-normal-Cv_xCTDl.woff2 +0 -0
- package/page/assets/figtree-latin-700-normal-BCCt2T1q.woff +0 -0
- package/page/assets/figtree-latin-700-normal-th6qEP7c.woff2 +0 -0
- package/page/assets/focusOutline.stylex-BT0kfa4t.js +1 -0
- package/page/assets/focusableSelector-DXZeMU85.js +1 -0
- package/page/assets/groupStyles-C7Ter7zC.js +1 -0
- package/page/assets/guardrail-tester-Gut5xK4a.js +9 -0
- package/page/assets/host-patterns-C9RMP16Q.js +1 -0
- package/page/assets/index-CvvmFKgS.js +105 -0
- package/page/assets/index-DOaHlqBo.css +1 -0
- package/page/assets/isRtlElement-BG33-k_H.js +1 -0
- package/page/assets/labels-provider-4TIWDvsE.js +3 -0
- package/page/assets/lent-keys-C32ems-I.js +1 -0
- package/page/assets/live-ingress-lDUGPwth.js +1 -0
- package/page/assets/live-messages-CnkL4GWi.js +1 -0
- package/page/assets/mergeProps-ptS-gIMz.js +1 -0
- package/page/assets/padding.stylex-B76907Zf.js +1 -0
- package/page/assets/preload-helper-DpV6A1kQ.js +1 -0
- package/page/assets/reader-BOCCYaRp.js +7 -0
- package/page/assets/register-CDgivxvX.js +2 -0
- package/page/assets/rolldown-runtime-hePW80VL.js +1 -0
- package/page/assets/schemas-BQ9Jydzb.js +56 -0
- package/page/assets/shaped-data-BcarWqd5.js +16 -0
- package/page/assets/sharedResizeObserver-4U9Xq5Oq.js +1 -0
- package/page/assets/stub-DhdcU_Ew.js +471 -0
- package/page/assets/studio-code-pane-C_SAbcOa.js +8 -0
- package/page/assets/studio-console-DZwlEsvr.js +3 -0
- package/page/assets/studio-decision-B0FnCAXA.js +1 -0
- package/page/assets/studio-embedding-CmA51HVo.js +2 -0
- package/page/assets/studio-host-console-By7hqu2l.js +2 -0
- package/page/assets/studio-live-BrcVQcyV.js +1 -0
- package/page/assets/studio-map-B_xSia-z.js +1 -0
- package/page/assets/studio-map-Bb06Tw1F.css +1 -0
- package/page/assets/studio-monaco-CbKf90i6.css +1 -0
- package/page/assets/studio-monaco-xfyfezQS.js +34 -0
- package/page/assets/studio-ts.worker-B-EXG4Sv.js +67741 -0
- package/page/assets/studio-ts.worker-BXtW3z-O.js +1 -0
- package/page/assets/studio-type-checker-BOvxudki.js +23 -0
- package/page/assets/themeProps-3IqahpCr.js +1 -0
- package/page/assets/tokens.stylex-DkHf0P9C.js +1 -0
- package/page/assets/tool-schema-idaOe2nI.js +18 -0
- package/page/assets/trace-patterns-DnYJa0nI.js +1 -0
- package/page/assets/trace-record-C3zNksA_.js +1 -0
- package/page/assets/trace-schema-9CdEyG6Q.js +1 -0
- package/page/assets/tree-DqyAMsbI.js +3 -0
- package/page/assets/turn-client-Du3Um3Mg.js +2 -0
- package/page/assets/types-BhfXQCLx.js +1 -0
- package/page/assets/typescript-20GgZ8PJ.js +1 -0
- package/page/assets/use-one-call-Hcs8YBp1.js +1 -0
- package/page/assets/useAdaptivePresentation-BzmPCddb.js +1 -0
- package/page/assets/useClipboard-BgGRxRMJ.js +1 -0
- package/page/assets/useContainerReveal-BFy8N_QU.js +1 -0
- package/page/assets/useDevWarning-Z9SoixOP.js +1 -0
- package/page/assets/useLayerDismissal-B_G7IWpC.js +1 -0
- package/page/assets/useMediaQuery-BCT0NUeZ.js +1 -0
- package/page/assets/useScrollLock-Dyf6PHJt.js +1 -0
- package/page/assets/useScrollableArea-0NzdiBCq.js +1 -0
- package/page/assets/useTooltip-CJM_xhLB.js +1 -0
- package/page/assets/workspace-DZALqEDX.js +1 -0
- package/page/assets/zip-DTcEfps6.js +1 -0
- package/page/index.html +90 -0
- package/page.mjs +49 -0
- package/people.d.ts +87 -0
- package/people.js +110 -0
- package/policy.d.ts +43 -0
- package/policy.js +102 -0
- package/ports.d.mts +32 -0
- package/ports.mjs +85 -0
- package/probe-battery.d.ts +13 -0
- package/probe-battery.js +404 -0
- package/providers.d.ts +149 -0
- package/providers.js +306 -0
- package/read-source.d.ts +48 -0
- package/read-source.js +1301 -0
- package/read-steps.d.ts +23 -0
- package/read-steps.js +2 -0
- package/reader.d.ts +11 -0
- package/reader.js +11 -0
- package/registrations.d.ts +83 -0
- package/registrations.js +1 -0
- package/requirements.d.ts +22 -0
- package/requirements.js +38 -0
- package/run-payload-core.d.ts +28 -0
- package/run-payload-core.js +123 -0
- package/run-payload.d.ts +32 -0
- package/run-payload.js +26 -0
- package/runtime-scope.d.ts +84 -0
- package/runtime-scope.js +308 -0
- package/runtime.d.ts +84 -0
- package/runtime.js +387 -0
- package/section-notes.d.ts +33 -0
- package/section-notes.js +38 -0
- package/serve-page.mjs +96 -0
- package/server/draft-decide.d.ts +72 -0
- package/server/draft-decide.js +111 -0
- package/server/draft-embedding.d.ts +3 -0
- package/server/draft-embedding.js +35 -0
- package/server/draft-handler.d.ts +82 -0
- package/server/draft-handler.js +213 -0
- package/server/draft-probe.d.ts +14 -0
- package/server/draft-probe.js +61 -0
- package/server/draft-replies.d.ts +22 -0
- package/server/draft-replies.js +46 -0
- package/server/edited-session.d.ts +28 -0
- package/server/edited-session.js +83 -0
- package/server/edits.d.ts +38 -0
- package/server/edits.js +195 -0
- package/server/handler.d.ts +133 -0
- package/server/handler.js +598 -0
- package/server/lent-draft.d.ts +19 -0
- package/server/lent-draft.js +23 -0
- package/server/live.d.ts +15 -0
- package/server/live.js +96 -0
- package/server/open-editor.d.ts +63 -0
- package/server/open-editor.js +115 -0
- package/server/origins.d.ts +18 -0
- package/server/origins.js +330 -0
- package/server/project-source.d.ts +208 -0
- package/server/project-source.js +1042 -0
- package/server/project.d.ts +22 -0
- package/server/project.js +56 -0
- package/server/run-traces.d.ts +20 -0
- package/server/run-traces.js +96 -0
- package/server/save-new.d.ts +29 -0
- package/server/save-new.js +514 -0
- package/server/save-plan.d.ts +46 -0
- package/server/save-plan.js +1134 -0
- package/server/save-remove.d.ts +21 -0
- package/server/save-remove.js +528 -0
- package/server/save-session.d.ts +96 -0
- package/server/save-session.js +418 -0
- package/server/save-wire.d.ts +235 -0
- package/server/save-wire.js +8 -0
- package/server/save.d.ts +52 -0
- package/server/save.js +209 -0
- package/server/serve.d.ts +23 -0
- package/server/serve.js +413 -0
- package/server/test-connection.d.ts +17 -0
- package/server/test-connection.js +362 -0
- package/server/test-key.d.ts +2 -0
- package/server/test-key.js +83 -0
- package/server/watch.d.ts +28 -0
- package/server/watch.js +93 -0
- package/server/zod-edit.d.ts +74 -0
- package/server/zod-edit.js +558 -0
- package/server.d.ts +8 -0
- package/server.js +8 -0
- package/setups.mjs +170 -0
- package/shared-carry.d.ts +114 -0
- package/shared-carry.js +523 -0
- package/shared-settings.d.ts +34 -0
- package/shared-settings.js +70 -0
- package/source.d.ts +75 -0
- package/source.js +414 -0
- package/start.mjs +169 -0
- package/stream-lines.d.ts +9 -0
- package/stream-lines.js +27 -0
- package/stub.d.ts +6 -0
- package/stub.js +33 -0
- package/surface.d.ts +53 -0
- package/surface.js +631 -0
- package/system-markup.d.ts +20 -0
- package/system-markup.js +51 -0
- package/tool-schema.d.ts +23 -0
- package/tool-schema.js +69 -0
- package/tools.d.ts +16 -0
- package/tools.js +91 -0
- package/traces.d.ts +24 -0
- package/traces.js +29 -0
- package/transport.d.ts +57 -0
- package/transport.js +187 -0
- package/tree.d.ts +32 -0
- package/tree.js +83 -0
- package/types.d.ts +62 -0
- package/types.js +6 -0
- package/ui/acting-as-button.d.ts +2 -0
- package/ui/acting-as-button.js +16 -0
- package/ui/add-provider.d.ts +13 -0
- package/ui/add-provider.js +20 -0
- package/ui/boot-mark.css +53 -0
- package/ui/boot-mark.d.ts +19 -0
- package/ui/boot-mark.js +128 -0
- package/ui/boot-paint.d.ts +8 -0
- package/ui/boot-paint.js +8 -0
- package/ui/brand-icons.d.ts +57 -0
- package/ui/brand-icons.js +148 -0
- package/ui/built/theme.css +830 -0
- package/ui/built/theme.css.d.ts +9 -0
- package/ui/built/theorem-studio.d.ts +13 -0
- package/ui/built/theorem-studio.js +705 -0
- package/ui/built/theorem-studio.variants.d.ts +28 -0
- package/ui/code/monaco-contributions.d.ts +45 -0
- package/ui/code/studio-code.d.ts +7 -0
- package/ui/code/studio-code.js +253 -0
- package/ui/code/studio-monaco.d.ts +44 -0
- package/ui/code/studio-monaco.js +48 -0
- package/ui/code/studio-ts.worker.d.ts +1 -0
- package/ui/code/studio-ts.worker.js +16 -0
- package/ui/code/studio-type-checker.d.ts +12 -0
- package/ui/code/studio-type-checker.js +308 -0
- package/ui/code/studio-type-sources.d.ts +26 -0
- package/ui/confirm-write.d.ts +12 -0
- package/ui/confirm-write.js +45 -0
- package/ui/diff-block.d.ts +21 -0
- package/ui/diff-block.js +17 -0
- package/ui/figtree.css +59 -0
- package/ui/file-place.d.ts +4 -0
- package/ui/file-place.js +26 -0
- package/ui/guardrail-tester.d.ts +18 -0
- package/ui/guardrail-tester.js +248 -0
- package/ui/inspector-context.d.ts +119 -0
- package/ui/inspector-context.js +84 -0
- package/ui/inspector.d.ts +247 -0
- package/ui/inspector.js +284 -0
- package/ui/lib/acting-as.d.ts +25 -0
- package/ui/lib/acting-as.js +90 -0
- package/ui/lib/boot-sequence.d.ts +32 -0
- package/ui/lib/boot-sequence.js +57 -0
- package/ui/lib/export-agent.d.ts +11 -0
- package/ui/lib/export-agent.js +335 -0
- package/ui/lib/facet-icons.d.ts +20 -0
- package/ui/lib/facet-icons.js +21 -0
- package/ui/lib/panel-motion.d.ts +8 -0
- package/ui/lib/panel-motion.js +74 -0
- package/ui/lib/project-address.d.ts +14 -0
- package/ui/lib/project-address.js +24 -0
- package/ui/lib/project-starting.d.ts +13 -0
- package/ui/lib/project-starting.js +30 -0
- package/ui/lib/project-traces.d.ts +17 -0
- package/ui/lib/project-traces.js +54 -0
- package/ui/lib/read-map.d.ts +30 -0
- package/ui/lib/read-map.js +173 -0
- package/ui/lib/read-progress.d.ts +14 -0
- package/ui/lib/read-progress.js +12 -0
- package/ui/lib/refusal-lines.d.ts +3 -0
- package/ui/lib/refusal-lines.js +8 -0
- package/ui/lib/studio-activity.d.ts +5 -0
- package/ui/lib/studio-activity.js +17 -0
- package/ui/lib/studio-console.d.ts +27 -0
- package/ui/lib/studio-console.js +9 -0
- package/ui/lib/studio-conversation.d.ts +20 -0
- package/ui/lib/studio-conversation.js +130 -0
- package/ui/lib/studio-examples.d.ts +31 -0
- package/ui/lib/studio-examples.js +25 -0
- package/ui/lib/studio-labels.d.ts +6 -0
- package/ui/lib/studio-labels.js +13 -0
- package/ui/lib/studio-map-kept.d.ts +17 -0
- package/ui/lib/studio-map-kept.js +48 -0
- package/ui/lib/studio-open.d.ts +22 -0
- package/ui/lib/studio-open.js +54 -0
- package/ui/lib/studio-page.d.ts +33 -0
- package/ui/lib/studio-page.js +121 -0
- package/ui/lib/studio-prefs.d.ts +26 -0
- package/ui/lib/studio-prefs.js +87 -0
- package/ui/lib/studio-project.d.ts +106 -0
- package/ui/lib/studio-project.js +177 -0
- package/ui/lib/studio-restore.d.ts +49 -0
- package/ui/lib/studio-restore.js +251 -0
- package/ui/lib/studio-run-open.d.ts +15 -0
- package/ui/lib/studio-run-open.js +16 -0
- package/ui/lib/studio-session.d.ts +34 -0
- package/ui/lib/studio-session.js +17 -0
- package/ui/lib/studio-settings.d.ts +15 -0
- package/ui/lib/studio-settings.js +48 -0
- package/ui/lib/studio-store.d.ts +64 -0
- package/ui/lib/studio-store.js +391 -0
- package/ui/lib/studio-watch.d.ts +12 -0
- package/ui/lib/studio-watch.js +27 -0
- package/ui/lib/tab-fills.d.ts +6 -0
- package/ui/lib/tab-fills.js +14 -0
- package/ui/lib/tool-credentials.d.ts +3 -0
- package/ui/lib/tool-credentials.js +23 -0
- package/ui/lib/tool-probe.d.ts +19 -0
- package/ui/lib/tool-probe.js +104 -0
- package/ui/lib/type-icons.d.ts +35 -0
- package/ui/lib/type-icons.js +38 -0
- package/ui/lib/when-idle.d.ts +5 -0
- package/ui/lib/when-idle.js +14 -0
- package/ui/lib/zip.d.ts +5 -0
- package/ui/lib/zip.js +8 -0
- package/ui/map-token.css +11 -0
- package/ui/map-token.d.ts +17 -0
- package/ui/map-token.js +29 -0
- package/ui/mcp-icon.d.ts +6 -0
- package/ui/mcp-icon.js +8 -0
- package/ui/motion.css +113 -0
- package/ui/pan.d.ts +32 -0
- package/ui/pan.js +90 -0
- package/ui/profile-editor.d.ts +33 -0
- package/ui/profile-editor.js +2638 -0
- package/ui/provider-editor.d.ts +15 -0
- package/ui/provider-editor.js +92 -0
- package/ui/read-map.css +48 -0
- package/ui/read-map.d.ts +7 -0
- package/ui/read-map.js +163 -0
- package/ui/refusal-detail.d.ts +4 -0
- package/ui/refusal-detail.js +21 -0
- package/ui/shared-change.d.ts +9 -0
- package/ui/shared-change.js +28 -0
- package/ui/shell-motion.css +121 -0
- package/ui/shell-motion.d.ts +73 -0
- package/ui/shell-motion.js +194 -0
- package/ui/studio-code-pane.d.ts +19 -0
- package/ui/studio-code-pane.js +44 -0
- package/ui/studio-compare.d.ts +80 -0
- package/ui/studio-compare.js +326 -0
- package/ui/studio-conflicts.d.ts +17 -0
- package/ui/studio-conflicts.js +87 -0
- package/ui/studio-connection.d.ts +64 -0
- package/ui/studio-connection.js +286 -0
- package/ui/studio-decision.d.ts +6 -0
- package/ui/studio-decision.js +49 -0
- package/ui/studio-embedding.d.ts +6 -0
- package/ui/studio-embedding.js +30 -0
- package/ui/studio-host-console.d.ts +6 -0
- package/ui/studio-host-console.js +17 -0
- package/ui/studio-host.d.ts +73 -0
- package/ui/studio-host.js +12 -0
- package/ui/studio-live.d.ts +17 -0
- package/ui/studio-live.js +26 -0
- package/ui/studio-map.css +273 -0
- package/ui/studio-map.d.ts +17 -0
- package/ui/studio-map.js +397 -0
- package/ui/studio-nav.d.ts +24 -0
- package/ui/studio-nav.js +17 -0
- package/ui/studio-no-project.d.ts +5 -0
- package/ui/studio-no-project.js +9 -0
- package/ui/studio-run.css +76 -0
- package/ui/studio-run.d.ts +14 -0
- package/ui/studio-run.js +119 -0
- package/ui/studio-runner.d.ts +45 -0
- package/ui/studio-runner.js +187 -0
- package/ui/studio-save.d.ts +49 -0
- package/ui/studio-save.js +307 -0
- package/ui/studio-screen.d.ts +61 -0
- package/ui/studio-screen.js +2078 -0
- package/ui/studio-settings.d.ts +31 -0
- package/ui/studio-settings.js +288 -0
- package/ui/studio-shell.css +27 -0
- package/ui/studio-shell.d.ts +43 -0
- package/ui/studio-shell.js +87 -0
- package/ui/studio-theme.d.ts +7 -0
- package/ui/studio-theme.js +94 -0
- package/ui/studio.css +427 -0
- package/ui/theorem-mark.css +84 -0
- package/ui/theorem-mark.d.ts +22 -0
- package/ui/theorem-mark.js +21 -0
- package/vite.d.mts +30 -0
- package/vite.mjs +277 -0
- package/workspace.d.ts +230 -0
- package/workspace.js +1054 -0
package/draft.js
ADDED
|
@@ -0,0 +1,505 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Every section is always present so switching profile type keeps what the author typed.
|
|
3
|
+
* "Provider default" numbers are `null` and booleans hold the value the kernel would resolve,
|
|
4
|
+
* so compile emits a field only when it differs.
|
|
5
|
+
*/
|
|
6
|
+
import { liveIngressChannelDefault, profileAllowsInject, resolveGuardrailPolicy, } from '@theoremjs/agents';
|
|
7
|
+
import { BOUNDARIES, DETECTORS, detects, PATTERN_DETECTORS, recordOf, } from '@theoremjs/agents/guardrails';
|
|
8
|
+
import { CONTINUE_INSTRUCTION_TYPES, mimeAllowed, profileTypesForField, } from '@theoremjs/agents/kernel';
|
|
9
|
+
import { resolveObservabilityPolicy } from '@theoremjs/agents/observability';
|
|
10
|
+
import { IMAGE_ATTACHMENT_ACCEPT_MIMES, PROFILE_GRAPH, PROFILE_TYPES, TOOL_ACCESS, TOOL_LOAD_TIERS, TOOL_PERMISSION, } from '@theoremjs/agents/schema';
|
|
11
|
+
import { isGoogleRoute, STUDIO_TRACE_DESTINATION, startingBinding } from "./policy.js";
|
|
12
|
+
import { modelRoute, STUDIO_PROVIDERS, servesProfileType, } from "./providers.js";
|
|
13
|
+
import { keySlotUnset } from "./requirements.js";
|
|
14
|
+
import { DEFAULT_TOOL_INPUT_SCHEMA, DEFAULT_TOOL_OUTPUT_SCHEMA } from "./tool-schema.js";
|
|
15
|
+
export const STUDIO_PROFILE_TYPES = PROFILE_TYPES;
|
|
16
|
+
/** Where compaction starts when a builder turns it on; every number stays theirs to change. */
|
|
17
|
+
export const COMPACTION_DRAFT_DEFAULTS = {
|
|
18
|
+
compactMaxTokens: 32_000,
|
|
19
|
+
compactAt: 0.75,
|
|
20
|
+
compactKeep: 4,
|
|
21
|
+
};
|
|
22
|
+
/** Wording held beside the setting it words; each line has one value, so it edits that field. */
|
|
23
|
+
export const INLINE_LABELS = {
|
|
24
|
+
'continue.instruction': 'turnBehaviour',
|
|
25
|
+
'canary.bind_note': 'guardrails',
|
|
26
|
+
'quota.exhausted': 'guardrails',
|
|
27
|
+
'repair.default_guidance': 'outputs',
|
|
28
|
+
'egress.default_repair_guidance': 'guardrails',
|
|
29
|
+
'egress.refusal': 'guardrails',
|
|
30
|
+
};
|
|
31
|
+
export function draftKey(prefix) {
|
|
32
|
+
return `${prefix}-${crypto.randomUUID().slice(0, 8)}`;
|
|
33
|
+
}
|
|
34
|
+
export function defaultModelBinding(partial) {
|
|
35
|
+
return {
|
|
36
|
+
key: draftKey('model'),
|
|
37
|
+
modelId: 'fast',
|
|
38
|
+
protocol: 'openRouter',
|
|
39
|
+
provider: 'openrouter',
|
|
40
|
+
apiId: '',
|
|
41
|
+
options: {},
|
|
42
|
+
timeoutMs: null,
|
|
43
|
+
efforts: [],
|
|
44
|
+
defaultEffort: '',
|
|
45
|
+
allowEffortSelect: false,
|
|
46
|
+
summaries: null,
|
|
47
|
+
maxOutputTokens: null,
|
|
48
|
+
temperature: null,
|
|
49
|
+
builtInTools: [],
|
|
50
|
+
...partial,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
const STUB_TOOL_DESCRIPTION = 'Studio stub tool — returns a fixed result.';
|
|
54
|
+
export function defaultToolSpec(partial) {
|
|
55
|
+
return {
|
|
56
|
+
key: draftKey('tool'),
|
|
57
|
+
toolName: 'my_tool',
|
|
58
|
+
toolType: 'function',
|
|
59
|
+
description: STUB_TOOL_DESCRIPTION,
|
|
60
|
+
category: 'studio',
|
|
61
|
+
access: TOOL_ACCESS[0],
|
|
62
|
+
permission: TOOL_PERMISSION[0],
|
|
63
|
+
loadTier: TOOL_LOAD_TIERS[0],
|
|
64
|
+
paths: ['*'],
|
|
65
|
+
inputJson: DEFAULT_TOOL_INPUT_SCHEMA,
|
|
66
|
+
outputJson: DEFAULT_TOOL_OUTPUT_SCHEMA,
|
|
67
|
+
...partial,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* The change that points an agent tool at an agent. A description that is
|
|
72
|
+
* still the new tool's stub, or empty, comes to say what the tool now does.
|
|
73
|
+
*/
|
|
74
|
+
export function agentToolTarget(tool, agentKey, agentId) {
|
|
75
|
+
const isStub = !tool.description.trim() || tool.description === STUB_TOOL_DESCRIPTION;
|
|
76
|
+
return isStub && agentId
|
|
77
|
+
? { agentKey, description: `Asks ${agentId} and returns its answer.` }
|
|
78
|
+
: { agentKey };
|
|
79
|
+
}
|
|
80
|
+
/** A pattern to fill in. */
|
|
81
|
+
export function newPattern() {
|
|
82
|
+
return { name: '', kind: 'words', pattern: '', flags: '', words: [] };
|
|
83
|
+
}
|
|
84
|
+
/** A detector of the builder's own to fill in: it reads nowhere until a boundary is set. */
|
|
85
|
+
export function newOwnDetector() {
|
|
86
|
+
return {
|
|
87
|
+
key: '',
|
|
88
|
+
label: '',
|
|
89
|
+
at: recordOf(BOUNDARIES, () => 'ignore'),
|
|
90
|
+
patterns: [newPattern()],
|
|
91
|
+
hint: '',
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
function defaultGuardrails() {
|
|
95
|
+
const resolved = resolveGuardrailPolicy(undefined);
|
|
96
|
+
return {
|
|
97
|
+
canaryBindNote: '',
|
|
98
|
+
detect: recordOf(DETECTORS, (detector) => ({ ...resolved.detect[detector] })),
|
|
99
|
+
sources: Object.fromEntries(PATTERN_DETECTORS.map((detector) => [detector, { theorem: true, patterns: [], hint: '' }])),
|
|
100
|
+
own: [],
|
|
101
|
+
quotaEnabled: false,
|
|
102
|
+
quotaPerDay: null,
|
|
103
|
+
quotaMessage: '',
|
|
104
|
+
allow: {
|
|
105
|
+
ungiven_images: { hosts: [], fromTools: true },
|
|
106
|
+
ungiven_links: { hosts: [], fromTools: true },
|
|
107
|
+
},
|
|
108
|
+
innocentNames: [],
|
|
109
|
+
blockedReplyOnBlock: '',
|
|
110
|
+
blockedReplyMaxRetries: null,
|
|
111
|
+
egressRepairGuidance: '',
|
|
112
|
+
egressRefusal: '',
|
|
113
|
+
allowPrivateNetworks: false,
|
|
114
|
+
allowedHosts: [],
|
|
115
|
+
allowedSchemes: [],
|
|
116
|
+
taintAfterRemoteRead: '',
|
|
117
|
+
taintRemoteDestination: '',
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
function defaultObservability() {
|
|
121
|
+
// why: every draft writes this block, and the kernel reads one that is written with these.
|
|
122
|
+
const resolved = resolveObservabilityPolicy({});
|
|
123
|
+
return {
|
|
124
|
+
writeTo: STUDIO_TRACE_DESTINATION,
|
|
125
|
+
destination: STUDIO_TRACE_DESTINATION,
|
|
126
|
+
sampleRate: resolved.sampleRate,
|
|
127
|
+
include: { ...resolved.include },
|
|
128
|
+
scrub: {
|
|
129
|
+
sensitive: Boolean(resolved.scrub.sensitive),
|
|
130
|
+
injection: Boolean(resolved.scrub.injection),
|
|
131
|
+
canary: Boolean(resolved.scrub.canary),
|
|
132
|
+
},
|
|
133
|
+
retainForDays: null,
|
|
134
|
+
rotateAfterMiB: null,
|
|
135
|
+
resourceJson: '',
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
function criteria(entries) {
|
|
139
|
+
return entries.map(([label, text]) => ({ key: draftKey('criterion'), label, text }));
|
|
140
|
+
}
|
|
141
|
+
/** A guardrail on a tool call the agent is about to make: whether to let it run, and how much is at stake. */
|
|
142
|
+
export function exampleDecisionDraft() {
|
|
143
|
+
return {
|
|
144
|
+
contract: 'guardrails.tool_call.v1',
|
|
145
|
+
maxStateBytes: null,
|
|
146
|
+
questions: [
|
|
147
|
+
{
|
|
148
|
+
key: draftKey('question'),
|
|
149
|
+
id: 'verdict',
|
|
150
|
+
type: 'choice',
|
|
151
|
+
instructions: 'Given what the user asked for and what the call would do, should it run?',
|
|
152
|
+
criteria: criteria([
|
|
153
|
+
['allow', 'Safe, and what the user asked for.'],
|
|
154
|
+
['flag', 'Probably fine, but unusual or sensitive enough for a person to look first.'],
|
|
155
|
+
['block', 'Harmful, or clearly beyond what the user asked for.'],
|
|
156
|
+
]),
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
key: draftKey('question'),
|
|
160
|
+
id: 'risk',
|
|
161
|
+
type: 'score',
|
|
162
|
+
instructions: 'How much harm would this call do if it were wrong?',
|
|
163
|
+
criteria: criteria([
|
|
164
|
+
['', 'Low: reversible, and affects only the user.'],
|
|
165
|
+
['', 'High: hard to undo, or affects other people or money.'],
|
|
166
|
+
]),
|
|
167
|
+
},
|
|
168
|
+
],
|
|
169
|
+
images: [],
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
/** State the example's questions can be asked about: the field a decision preview starts with. */
|
|
173
|
+
export const EXAMPLE_DECISION_STATE = JSON.stringify({
|
|
174
|
+
context: 'The user asked the agent to tidy up old screenshots on their desktop.',
|
|
175
|
+
tool_call: { name: 'delete_files', path: '~/Documents', recursive: true },
|
|
176
|
+
outcome: 'Would delete 1,284 files, including tax_return_2025.pdf.',
|
|
177
|
+
}, null, 2);
|
|
178
|
+
/** Span accepts a JSON string state; the preview starts with that shape for Span models. */
|
|
179
|
+
export const EXAMPLE_SPAN_DECISION_STATE = JSON.stringify('The user asked to tidy screenshots. The proposed call recursively deletes 1,284 files, including a tax return.');
|
|
180
|
+
/** Documents an embedding preview starts with, one per paragraph: a small help centre in a few topics, with a couple that belong to none. */
|
|
181
|
+
export const EXAMPLE_EMBEDDING_TEXT = [
|
|
182
|
+
'To clear your desktop, select the screenshots and move them to the Trash. Empty the Trash to delete them for good.',
|
|
183
|
+
"Screen captures save to the desktop by default. You can change where they go in the Screenshot app's Options menu.",
|
|
184
|
+
'Press Command-Shift-5 to record the screen or capture a window. Recordings are saved as movie files next to your screenshots.',
|
|
185
|
+
'Stacks group desktop files by kind, date or tag, so a cluttered desktop folds into a few piles you can open one at a time.',
|
|
186
|
+
'Deleted files stay in the Trash for 30 days. Drag a file out of the Trash to put it back where it was.',
|
|
187
|
+
'When your disk is almost full, open Storage settings and review the largest files. Old downloads and installers are safe to remove.',
|
|
188
|
+
'Offloading unused apps frees space and keeps their documents. Reinstalling an app brings its data back.',
|
|
189
|
+
'Photos you have backed up can be optimised so the originals live in the cloud and smaller copies stay on the device.',
|
|
190
|
+
'Your plan renews on the same date each month. You can see the next charge under Billing, then Upcoming invoices.',
|
|
191
|
+
'To get a refund, open the invoice and choose Request refund. Charges from the last 14 days are refunded in full.',
|
|
192
|
+
'Update your card under Billing, then Payment methods. The new card is used for the next renewal, not for past invoices.',
|
|
193
|
+
'Annual plans cost two months less than paying monthly. Switching mid-term credits the unused months to the new plan.',
|
|
194
|
+
'Invoices are emailed as PDFs and list your company name and tax number. Edit those details before the invoice is issued.',
|
|
195
|
+
'Turn on two-step verification under Security. You will be asked for a code from your authenticator app each time you sign in on a new device.',
|
|
196
|
+
'If you forget your password, choose Forgot password on the sign-in page. The reset link expires after one hour.',
|
|
197
|
+
"Review signed-in devices under Security and sign out any you don't recognise. This ends their sessions immediately.",
|
|
198
|
+
'Passkeys replace your password with your fingerprint or face. Create one under Security, then Passkeys.',
|
|
199
|
+
'To close your account, export your data first. Closing deletes your workspace after a 30-day grace period.',
|
|
200
|
+
'Share a folder by choosing Share, then entering an email address. Viewers can read; editors can change and delete.',
|
|
201
|
+
'Public links work for anyone who has them. Set an expiry date, or turn the link off to stop sharing at once.',
|
|
202
|
+
'Transfer ownership of a folder before you leave a team, or its contents will be archived with your account.',
|
|
203
|
+
'Lisbon has mild, wet winters and warm, dry summers. Expect highs near 28 °C in August.',
|
|
204
|
+
'The best months for the Algarve coast are May, June and September, when the beaches are warm and the crowds are thin.',
|
|
205
|
+
'Trams in Lisbon climb the steep hills of Alfama and Graça. Line 28 is the famous one, and the busiest.',
|
|
206
|
+
'For a crisp pizza base, preheat the oven and the baking tray together at the highest setting for at least thirty minutes.',
|
|
207
|
+
'Rest steak for five minutes after cooking so the juices settle back into the meat instead of running onto the board.',
|
|
208
|
+
].join('\n\n');
|
|
209
|
+
/** The question an embedding preview starts with, nearest the first document. */
|
|
210
|
+
export const EXAMPLE_EMBEDDING_QUERY = 'How do I delete every screenshot on my desktop?';
|
|
211
|
+
/** A new question of `type`, with an id the draft doesn't use yet. */
|
|
212
|
+
export function newDecisionQuestion(draft, type = 'choice') {
|
|
213
|
+
const taken = draft.decision.questions.map((question) => question.id);
|
|
214
|
+
const id = freeName('question', taken, (n) => `question_${n}`);
|
|
215
|
+
return { key: draftKey('question'), id, type, instructions: '', criteria: newCriteria(type) };
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* A picture added from `file`, named after it in the way a reference is written: lowercase, with
|
|
219
|
+
* `_` for anything else, and `_2`, `_3` after a name the draft has.
|
|
220
|
+
*/
|
|
221
|
+
export function newDecisionImage(draft, file, image) {
|
|
222
|
+
const base = file
|
|
223
|
+
.replace(/\.[^.]*$/, '')
|
|
224
|
+
.toLowerCase()
|
|
225
|
+
.replace(/[^a-z0-9]+/g, '_')
|
|
226
|
+
.replace(/^_|_$/g, '') || 'image';
|
|
227
|
+
const taken = draft.decision.images.map((each) => each.name);
|
|
228
|
+
const name = freeName(base, taken, (n) => `${base}_${n}`);
|
|
229
|
+
return { key: draftKey('image'), name, ...image };
|
|
230
|
+
}
|
|
231
|
+
/** The rows a question of `type` starts with: two options, two levels, or none. */
|
|
232
|
+
export function newCriteria(type) {
|
|
233
|
+
if (type === 'noul' || type === 'box')
|
|
234
|
+
return [];
|
|
235
|
+
return criteria(type === 'choice'
|
|
236
|
+
? [
|
|
237
|
+
['yes', ''],
|
|
238
|
+
['no', ''],
|
|
239
|
+
]
|
|
240
|
+
: [
|
|
241
|
+
['', ''],
|
|
242
|
+
['', ''],
|
|
243
|
+
]);
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* An empty draft: no profile type chosen, every section at its kernel default
|
|
247
|
+
* except observability, which the studio includes and points at its own
|
|
248
|
+
* trace destination.
|
|
249
|
+
*/
|
|
250
|
+
export function createBlankDraft() {
|
|
251
|
+
return {
|
|
252
|
+
identity: { agentId: '', profileType: '', handle: '', system: '', systemByRoleJson: '' },
|
|
253
|
+
included: ['observability', 'labels'],
|
|
254
|
+
models: { defaultModel: '', allowModelSelect: false, maxSteps: null, key: '' },
|
|
255
|
+
modelBindings: [],
|
|
256
|
+
providers: [...STUDIO_PROVIDERS],
|
|
257
|
+
tools: { t2Loader: '', parallel: false },
|
|
258
|
+
toolSpecs: [],
|
|
259
|
+
inputs: {
|
|
260
|
+
text: true,
|
|
261
|
+
attachmentsAccept: [],
|
|
262
|
+
voiceAccept: [],
|
|
263
|
+
maxFiles: null,
|
|
264
|
+
maxBytes: null,
|
|
265
|
+
maxTurnBytes: null,
|
|
266
|
+
limitsByMimeJson: '',
|
|
267
|
+
slotsJson: '',
|
|
268
|
+
contextFrom: [],
|
|
269
|
+
contextMaxChars: null,
|
|
270
|
+
},
|
|
271
|
+
outputs: {
|
|
272
|
+
mode: 'text',
|
|
273
|
+
schemaId: '',
|
|
274
|
+
schemaJson: '',
|
|
275
|
+
streamMode: '',
|
|
276
|
+
streamThoughts: true,
|
|
277
|
+
validationEnabled: false,
|
|
278
|
+
maxRetries: null,
|
|
279
|
+
itemRules: {},
|
|
280
|
+
repairGuidance: '',
|
|
281
|
+
},
|
|
282
|
+
turnBehaviour: {
|
|
283
|
+
resumeEnabled: false,
|
|
284
|
+
allowContinue: [],
|
|
285
|
+
autoContinue: [],
|
|
286
|
+
maxContinues: null,
|
|
287
|
+
continueInstruction: '',
|
|
288
|
+
allowSteering: profileAllowsInject({ type: 'text' }),
|
|
289
|
+
atStepLimit: 'stop',
|
|
290
|
+
},
|
|
291
|
+
guardrails: defaultGuardrails(),
|
|
292
|
+
observability: defaultObservability(),
|
|
293
|
+
image: {
|
|
294
|
+
aspectRatio: '',
|
|
295
|
+
resolution: '',
|
|
296
|
+
mimeType: '',
|
|
297
|
+
quality: '',
|
|
298
|
+
background: '',
|
|
299
|
+
n: null,
|
|
300
|
+
seed: null,
|
|
301
|
+
outputCompression: null,
|
|
302
|
+
includeText: false,
|
|
303
|
+
references: [],
|
|
304
|
+
},
|
|
305
|
+
speech: { voice: '', style: '', speed: null, format: '' },
|
|
306
|
+
live: {
|
|
307
|
+
ingressAudio: liveIngressChannelDefault('audio'),
|
|
308
|
+
ingressVideo: liveIngressChannelDefault('video'),
|
|
309
|
+
ingressText: liveIngressChannelDefault('text'),
|
|
310
|
+
voice: '',
|
|
311
|
+
sessionResumption: false,
|
|
312
|
+
greeting: '',
|
|
313
|
+
resumedPrompt: '',
|
|
314
|
+
resumedAfterMs: null,
|
|
315
|
+
contextCompression: false,
|
|
316
|
+
compressionTriggerTokens: null,
|
|
317
|
+
compressionTargetTokens: null,
|
|
318
|
+
transcriptionInput: false,
|
|
319
|
+
transcriptionOutput: false,
|
|
320
|
+
vadActivityHandling: '',
|
|
321
|
+
vadStartSensitivity: '',
|
|
322
|
+
vadEndSensitivity: '',
|
|
323
|
+
vadPrefixPaddingMs: null,
|
|
324
|
+
vadSilenceDurationMs: null,
|
|
325
|
+
},
|
|
326
|
+
decision: exampleDecisionDraft(),
|
|
327
|
+
labels: {},
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* Facets a decision draft leaves out: its only guardrail is a host's disclosure
|
|
332
|
+
* hook, which a draft can't carry.
|
|
333
|
+
*/
|
|
334
|
+
const DECISION_HIDDEN_FACETS = new Set(['guardrails']);
|
|
335
|
+
function facetFits(facet, type) {
|
|
336
|
+
return (facet.profileTypes.includes(type) &&
|
|
337
|
+
!(type === 'decision' && DECISION_HIDDEN_FACETS.has(facet.id)));
|
|
338
|
+
}
|
|
339
|
+
/** Required facets for the type plus the included optional ones, in catalog order. */
|
|
340
|
+
export function draftFacets(draft) {
|
|
341
|
+
const type = draft.identity.profileType;
|
|
342
|
+
if (!type)
|
|
343
|
+
return ['identity'];
|
|
344
|
+
const included = new Set(draft.included);
|
|
345
|
+
return PROFILE_GRAPH.filter((facet) => facet.role !== 'branch' &&
|
|
346
|
+
facetFits(facet, type) &&
|
|
347
|
+
(!facet.optional || included.has(facet.id))).map((facet) => facet.id);
|
|
348
|
+
}
|
|
349
|
+
/** By the kernel's `PROFILE_FIELD_SCOPE`; false until a type is chosen. */
|
|
350
|
+
export function draftAllows(draft, path) {
|
|
351
|
+
const type = draft.identity.profileType;
|
|
352
|
+
return type !== '' && profileTypesForField(path).includes(type);
|
|
353
|
+
}
|
|
354
|
+
/** A canary is bound into a system prompt while `canary_leak` reads somewhere. */
|
|
355
|
+
export function plantsCanary(draft) {
|
|
356
|
+
return draftAllows(draft, 'identity.system') && detects(draft.guardrails.detect, 'canary_leak');
|
|
357
|
+
}
|
|
358
|
+
export function takesContinueInstruction(draft) {
|
|
359
|
+
const type = draft.identity.profileType;
|
|
360
|
+
return type !== '' && CONTINUE_INSTRUCTION_TYPES.includes(type);
|
|
361
|
+
}
|
|
362
|
+
export function includableFacets(draft) {
|
|
363
|
+
const type = draft.identity.profileType;
|
|
364
|
+
if (!type)
|
|
365
|
+
return [];
|
|
366
|
+
return PROFILE_GRAPH.filter((facet) => facet.role === 'spine' &&
|
|
367
|
+
facet.optional &&
|
|
368
|
+
facetFits(facet, type) &&
|
|
369
|
+
!draft.included.includes(facet.id)).map((facet) => facet.id);
|
|
370
|
+
}
|
|
371
|
+
/** Inputs an image profile can take: no voice, attachments within images, video, and PDF. */
|
|
372
|
+
function imageInputs(inputs) {
|
|
373
|
+
return {
|
|
374
|
+
...inputs,
|
|
375
|
+
attachmentsAccept: inputs.attachmentsAccept.filter((rule) => mimeAllowed(IMAGE_ATTACHMENT_ACCEPT_MIMES, rule)),
|
|
376
|
+
voiceAccept: [],
|
|
377
|
+
};
|
|
378
|
+
}
|
|
379
|
+
/** Updates a binding and keeps the default model attached to it through an id change. */
|
|
380
|
+
export function updateModelBinding(draft, bindingKey, change) {
|
|
381
|
+
const binding = draft.modelBindings.find((candidate) => candidate.key === bindingKey);
|
|
382
|
+
if (!binding)
|
|
383
|
+
return draft;
|
|
384
|
+
return {
|
|
385
|
+
...draft,
|
|
386
|
+
models: change.modelId !== undefined && draft.models.defaultModel === binding.modelId
|
|
387
|
+
? { ...draft.models, defaultModel: change.modelId }
|
|
388
|
+
: draft.models,
|
|
389
|
+
modelBindings: draft.modelBindings.map((candidate) => candidate.key === bindingKey ? { ...candidate, ...change } : candidate),
|
|
390
|
+
};
|
|
391
|
+
}
|
|
392
|
+
/**
|
|
393
|
+
* The default model once the bindings change: the one it was while that is still a model, and the
|
|
394
|
+
* only model when one is left, as the kernel reads a profile with one model.
|
|
395
|
+
*/
|
|
396
|
+
function defaultAmong(current, modelBindings) {
|
|
397
|
+
if (modelBindings.some((binding) => binding.modelId === current))
|
|
398
|
+
return current;
|
|
399
|
+
const [only, ...others] = modelBindings;
|
|
400
|
+
return only && !others.length ? only.modelId : '';
|
|
401
|
+
}
|
|
402
|
+
/**
|
|
403
|
+
* Drops a binding, and the default model with it when it was that one. Model select turns off
|
|
404
|
+
* below two bindings, as on a type switch.
|
|
405
|
+
*/
|
|
406
|
+
export function removeModelBinding(draft, bindingKey) {
|
|
407
|
+
const binding = draft.modelBindings.find((candidate) => candidate.key === bindingKey);
|
|
408
|
+
if (!binding)
|
|
409
|
+
return draft;
|
|
410
|
+
const modelBindings = draft.modelBindings.filter((candidate) => candidate.key !== bindingKey);
|
|
411
|
+
return {
|
|
412
|
+
...draft,
|
|
413
|
+
models: {
|
|
414
|
+
...draft.models,
|
|
415
|
+
defaultModel: defaultAmong(draft.models.defaultModel, modelBindings),
|
|
416
|
+
},
|
|
417
|
+
modelBindings,
|
|
418
|
+
};
|
|
419
|
+
}
|
|
420
|
+
/** A new model for the draft's type, starting where `start` puts it, or on no model yet. */
|
|
421
|
+
export function newModelBinding(draft, start) {
|
|
422
|
+
const chosen = draft.identity.profileType;
|
|
423
|
+
const type = chosen && chosen !== 'host' ? chosen : 'text';
|
|
424
|
+
const taken = draft.modelBindings.map((binding) => binding.modelId);
|
|
425
|
+
const seed = startingBinding(type, start);
|
|
426
|
+
const modelId = freeName(seed.modelId, taken, (n) => `${seed.modelId}${n}`);
|
|
427
|
+
return defaultModelBinding({ ...seed, modelId });
|
|
428
|
+
}
|
|
429
|
+
export function newToolSpec(draft) {
|
|
430
|
+
const taken = draft.toolSpecs.map((tool) => tool.toolName);
|
|
431
|
+
return defaultToolSpec({ toolName: freeName('my_tool', taken, (n) => `my_tool_${n}`) });
|
|
432
|
+
}
|
|
433
|
+
/** `first` if nothing has taken it, else the first `nth(2)`, `nth(3)`, … that is free. */
|
|
434
|
+
export function freeName(first, taken, nth) {
|
|
435
|
+
const used = new Set(taken);
|
|
436
|
+
let name = first;
|
|
437
|
+
for (let n = 2; used.has(name); n++)
|
|
438
|
+
name = nth(n);
|
|
439
|
+
return name;
|
|
440
|
+
}
|
|
441
|
+
/**
|
|
442
|
+
* Bindings whose model the kernel says can't serve the new type are dropped, and so are those
|
|
443
|
+
* `keys` list only for another type; if none remain, a new one starts where `keys` start one. Model select turns off below two bindings. Other sections and
|
|
444
|
+
* `included` are kept, so a facet the type lacks comes back when switching back. A host runs no
|
|
445
|
+
* model, so it keeps the bindings for the way back.
|
|
446
|
+
*/
|
|
447
|
+
export function setProfileType(draft, type, keys) {
|
|
448
|
+
if (type === 'host') {
|
|
449
|
+
return { ...draft, identity: { ...draft.identity, profileType: type } };
|
|
450
|
+
}
|
|
451
|
+
const kept = draft.modelBindings.filter((binding) => {
|
|
452
|
+
const route = modelRoute(draft.providers, type, binding);
|
|
453
|
+
const provider = draft.providers.find((each) => each.id === binding.provider);
|
|
454
|
+
return (servesProfileType(provider, type, binding.protocol) && !listedForOthers(keys, type, route));
|
|
455
|
+
});
|
|
456
|
+
const retyped = {
|
|
457
|
+
...draft,
|
|
458
|
+
identity: { ...draft.identity, profileType: type },
|
|
459
|
+
modelBindings: kept,
|
|
460
|
+
};
|
|
461
|
+
const modelBindings = kept.length ? kept : [newModelBinding(retyped, keys?.start)];
|
|
462
|
+
const needsKey = !draft.models.key && keySlotUnset({ ...retyped, modelBindings });
|
|
463
|
+
// why: Gemini speaks only in a named voice, so a speech agent on it starts with one.
|
|
464
|
+
const voiceless = type === 'speech' &&
|
|
465
|
+
!draft.speech.voice.trim() &&
|
|
466
|
+
modelBindings.some((binding) => isGoogleRoute(modelRoute(draft.providers, type, binding)));
|
|
467
|
+
return {
|
|
468
|
+
...retyped,
|
|
469
|
+
inputs: type === 'image' ? imageInputs(draft.inputs) : draft.inputs,
|
|
470
|
+
...(voiceless ? { speech: { ...draft.speech, voice: GOOGLE_STARTING_VOICE } } : {}),
|
|
471
|
+
models: {
|
|
472
|
+
...draft.models,
|
|
473
|
+
defaultModel: defaultAmong(draft.models.defaultModel, modelBindings),
|
|
474
|
+
key: needsKey ? DEFAULT_KEY_SLOT : draft.models.key,
|
|
475
|
+
},
|
|
476
|
+
modelBindings,
|
|
477
|
+
};
|
|
478
|
+
}
|
|
479
|
+
/** The voice a new Gemini speech agent starts with; Google's own examples read in it. */
|
|
480
|
+
const GOOGLE_STARTING_VOICE = 'Kore';
|
|
481
|
+
const MODEL_PROFILE_TYPES = [
|
|
482
|
+
'text',
|
|
483
|
+
'image',
|
|
484
|
+
'speech',
|
|
485
|
+
'live',
|
|
486
|
+
'decision',
|
|
487
|
+
];
|
|
488
|
+
/** Whether `keys` list the model for some other type, and not for `type`. */
|
|
489
|
+
function listedForOthers(keys, type, route) {
|
|
490
|
+
if (!keys)
|
|
491
|
+
return false;
|
|
492
|
+
const listed = (each) => keys.models(each, route.definition).some((model) => model.id === route.apiId.trim());
|
|
493
|
+
return !listed(type) && MODEL_PROFILE_TYPES.some((each) => each !== type && listed(each));
|
|
494
|
+
}
|
|
495
|
+
// The slot the studio's server fills; named slots in the editor replace this.
|
|
496
|
+
const DEFAULT_KEY_SLOT = 'slot_a';
|
|
497
|
+
export function includeFacet(draft, id) {
|
|
498
|
+
if (!includableFacets(draft).includes(id))
|
|
499
|
+
return draft;
|
|
500
|
+
return { ...draft, included: [...draft.included, id] };
|
|
501
|
+
}
|
|
502
|
+
/** Its values stay on the draft for when it comes back. */
|
|
503
|
+
export function excludeFacet(draft, id) {
|
|
504
|
+
return { ...draft, included: draft.included.filter((facet) => facet !== id) };
|
|
505
|
+
}
|
package/editors.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The editors the studio can start on a line of a file: the ones that open in a window of their
|
|
3
|
+
* own. One that runs in a terminal is not here, since the studio has no terminal to run it in.
|
|
4
|
+
*
|
|
5
|
+
* @module
|
|
6
|
+
*/
|
|
7
|
+
/** How an editor's command takes a file and a line: `-g file:line`, `file:line`, `--line n file`, or `-l n file`. */
|
|
8
|
+
export type EditorLineForm = 'goto' | 'colon' | 'line-flag' | 'l-flag';
|
|
9
|
+
/** An editor the studio can start, by the command that starts it. */
|
|
10
|
+
export interface StudioEditor {
|
|
11
|
+
command: string;
|
|
12
|
+
/** The editor's name, as the builder reads it. */
|
|
13
|
+
label: string;
|
|
14
|
+
form: EditorLineForm;
|
|
15
|
+
/** One the builder can choose in Settings. The others are started only when the studio command or the environment names them. */
|
|
16
|
+
choice?: true;
|
|
17
|
+
/**
|
|
18
|
+
* Where the macOS app keeps its command, from an Applications folder. The app is often installed
|
|
19
|
+
* without its command on the path, and the studio starts it from here then.
|
|
20
|
+
*/
|
|
21
|
+
macCommand?: string;
|
|
22
|
+
}
|
|
23
|
+
export declare const STUDIO_EDITORS: readonly StudioEditor[];
|
|
24
|
+
/** The editor a command names, or undefined when the studio cannot start it on a line. */
|
|
25
|
+
export declare function studioEditor(command: string): StudioEditor | undefined;
|
|
26
|
+
/** Whether a command is one the builder can choose in Settings, so one a page may name. */
|
|
27
|
+
export declare function isEditorChoice(command: string): boolean;
|
|
28
|
+
/** An editor's name as the builder reads it: `code` is VS Code. One the studio does not know keeps its command. */
|
|
29
|
+
export declare function editorLabel(command: string): string;
|
package/editors.js
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The editors the studio can start on a line of a file: the ones that open in a window of their
|
|
3
|
+
* own. One that runs in a terminal is not here, since the studio has no terminal to run it in.
|
|
4
|
+
*
|
|
5
|
+
* @module
|
|
6
|
+
*/
|
|
7
|
+
export const STUDIO_EDITORS = [
|
|
8
|
+
{
|
|
9
|
+
command: 'code',
|
|
10
|
+
label: 'VS Code',
|
|
11
|
+
form: 'goto',
|
|
12
|
+
choice: true,
|
|
13
|
+
macCommand: 'Visual Studio Code.app/Contents/Resources/app/bin/code',
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
command: 'cursor',
|
|
17
|
+
label: 'Cursor',
|
|
18
|
+
form: 'goto',
|
|
19
|
+
choice: true,
|
|
20
|
+
macCommand: 'Cursor.app/Contents/Resources/app/bin/cursor',
|
|
21
|
+
},
|
|
22
|
+
{ command: 'zed', label: 'Zed', form: 'colon' },
|
|
23
|
+
{ command: 'windsurf', label: 'Windsurf', form: 'goto' },
|
|
24
|
+
{ command: 'webstorm', label: 'WebStorm', form: 'line-flag' },
|
|
25
|
+
{ command: 'subl', label: 'Sublime Text', form: 'colon' },
|
|
26
|
+
{ command: 'code-insiders', label: 'VS Code Insiders', form: 'goto' },
|
|
27
|
+
{ command: 'codium', label: 'VSCodium', form: 'goto' },
|
|
28
|
+
{ command: 'positron', label: 'Positron', form: 'goto' },
|
|
29
|
+
{ command: 'zeditor', label: 'Zed (zeditor)', form: 'colon' },
|
|
30
|
+
{ command: 'idea', label: 'IntelliJ IDEA', form: 'line-flag' },
|
|
31
|
+
{ command: 'pycharm', label: 'PyCharm', form: 'line-flag' },
|
|
32
|
+
{ command: 'phpstorm', label: 'PhpStorm', form: 'line-flag' },
|
|
33
|
+
{ command: 'goland', label: 'GoLand', form: 'line-flag' },
|
|
34
|
+
{ command: 'rubymine', label: 'RubyMine', form: 'line-flag' },
|
|
35
|
+
{ command: 'clion', label: 'CLion', form: 'line-flag' },
|
|
36
|
+
{ command: 'rider', label: 'Rider', form: 'line-flag' },
|
|
37
|
+
{ command: 'fleet', label: 'Fleet', form: 'line-flag' },
|
|
38
|
+
{ command: 'mate', label: 'TextMate', form: 'l-flag' },
|
|
39
|
+
];
|
|
40
|
+
/** The editor a command names, or undefined when the studio cannot start it on a line. */
|
|
41
|
+
export function studioEditor(command) {
|
|
42
|
+
return STUDIO_EDITORS.find((editor) => editor.command === command);
|
|
43
|
+
}
|
|
44
|
+
/** Whether a command is one the builder can choose in Settings, so one a page may name. */
|
|
45
|
+
export function isEditorChoice(command) {
|
|
46
|
+
return studioEditor(command)?.choice === true;
|
|
47
|
+
}
|
|
48
|
+
/** An editor's name as the builder reads it: `code` is VS Code. One the studio does not know keeps its command. */
|
|
49
|
+
export function editorLabel(command) {
|
|
50
|
+
return studioEditor(command)?.label ?? command;
|
|
51
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { EmbeddingInput } from '@theoremjs/agents';
|
|
2
|
+
/** A document an embedding preview starts with, and the file it came from. */
|
|
3
|
+
export type ExampleEmbeddingFile = {
|
|
4
|
+
input: EmbeddingInput;
|
|
5
|
+
from: string;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* The files an embedding preview starts with, beside the example text: three pictures that
|
|
9
|
+
* belong to its topics, and a refund policy that adds three documents to billing.
|
|
10
|
+
*/
|
|
11
|
+
export declare const EXAMPLE_EMBEDDING_FILES: readonly ExampleEmbeddingFile[];
|