@kitn.ai/ui 0.28.0 → 0.30.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -7
- package/dist/{Icon-DObhsRtm.js → Icon-BzBET3E-.js} +1 -1
- package/dist/{action-icons-CcgNN2oT.js → action-icons-DaW2pU6m.js} +1 -1
- package/dist/agent-tooling/construct/public.d.ts +15 -0
- package/dist/agent-tooling/construct/schema.d.ts +111 -0
- package/dist/arrow-down-D783iMJj.js +1 -0
- package/dist/arrow-left-0VLM5kyg.js +1 -0
- package/dist/artifact-DGjzHYUT.js +1 -0
- package/dist/{attachments-Qr4kg-2b.js → attachments-YvXHlg88.js} +1 -1
- package/dist/{audio-visualizer-DToYdfSc.js → audio-visualizer-9lz5IHsL.js} +1 -1
- package/dist/{badge-CdEu_jn2.js → badge-Dh_vp8A5.js} +1 -1
- package/dist/{bell-DQAAOpDz.js → bell-CT7_WUwS.js} +1 -1
- package/dist/{button-DkuOnGLy.js → button-C_3te6fm.js} +1 -1
- package/dist/{card-renderer-Jx70m6_l.js → card-renderer-DZVaGH2e.js} +1 -1
- package/dist/check-CiEOVnEN.js +1 -0
- package/dist/{checkbox-D7iRB3nL.js → checkbox-Bu2T2e0U.js} +1 -1
- package/dist/{checkbox-group-B2_rpoPM.js → checkbox-group-BiryEXPQ.js} +1 -1
- package/dist/chevron-down-CSobuZRG.js +1 -0
- package/dist/chevron-right-DR9ZAP-2.js +1 -0
- package/dist/{choice-card-m0BYqqOK.js → choice-card-CM6IjkmL.js} +1 -1
- package/dist/circle-BC66EYF7.js +1 -0
- package/dist/circle-check-BqmahW0O.js +1 -0
- package/dist/{circle-x-BPG0iPst.js → circle-x-Bk-dA5Wf.js} +1 -1
- package/dist/{code-block-ClMLKb7C.js → code-block-B26t-Q7q.js} +1 -1
- package/dist/{collapsible-B4DlWicL.js → collapsible-Bhc636Cf.js} +1 -1
- package/dist/components/builder-composer-triggers.d.ts +62 -0
- package/dist/components/builder-layout.d.ts +54 -0
- package/dist/components/builder-message-actions.d.ts +72 -0
- package/dist/components/builder-panel.d.ts +189 -0
- package/dist/components/builder-preview.d.ts +11 -0
- package/dist/components/builder-shell-controls.d.ts +69 -0
- package/dist/components/builder-skeleton.d.ts +58 -0
- package/dist/components/builder-start.d.ts +75 -0
- package/dist/components/builder-workspace-variants.d.ts +23 -0
- package/dist/components/captions.d.ts +66 -0
- package/dist/{composer-sQ0HcvyG.js → composer-DMI85B6j.js} +1 -1
- package/dist/{confirm-card-rQWDQsnC.js → confirm-card-B0YIAwXp.js} +1 -1
- package/dist/construct-cli.es.js +3 -3
- package/dist/construct.d.ts +5 -0
- package/dist/construct.js +327 -0
- package/dist/{context-0kg4ZX1J.js → context-DWgfhqWp.js} +1 -1
- package/dist/controllable-BagRpyHv.js +1 -0
- package/dist/{conversation-item-BxwQLaFJ.js → conversation-item-BsOsVGmT.js} +1 -1
- package/dist/{conversation-list-BCfGN1JU.js → conversation-list-aX3Vtc7L.js} +1 -1
- package/dist/{copy-n9u9rqpi.js → copy-BmEwsNhJ.js} +1 -1
- package/dist/core-C8fzo39E.js +1 -12
- package/dist/{create-tween-uPkArjIG.js → create-tween-CNOAU3Fx.js} +1 -1
- package/dist/{create-tween-C-q-JCM-.js → create-tween-WfqiENls.js} +1 -1
- package/dist/{create-tween-CRrJXxBd.js → create-tween-wlFtW9Kh.js} +1 -1
- package/dist/{create-tween-DZ3RRDHD.js → create-tween-zt79ba32.js} +1 -1
- package/dist/{default-input-CaMrJkgH.js → default-input-DMV5Eaze.js} +1 -1
- package/dist/define-CI0y3eE4.js +1 -0
- package/dist/define.js +40 -40
- package/dist/define.server.js +45 -45
- package/dist/{disclosure-WUImBbDv.js → disclosure-NnACBxsC.js} +1 -1
- package/dist/{dropdown-wZVeJOMd.js → dropdown-DT7G0RGR.js} +1 -1
- package/dist/elements/agent-card.js +1 -1
- package/dist/elements/artifact.js +1 -1
- package/dist/elements/attachments.js +1 -1
- package/dist/elements/audio-visualizer.js +1 -1
- package/dist/elements/avatar.js +1 -1
- package/dist/elements/badge.js +1 -1
- package/dist/elements/button.js +1 -1
- package/dist/elements/card.js +1 -1
- package/dist/elements/cards.js +1 -1
- package/dist/elements/chain-of-thought.js +1 -1
- package/dist/elements/chat-scope-picker.js +1 -1
- package/dist/elements/chat-workspace.js +1 -1
- package/dist/elements/chat.js +1 -1
- package/dist/elements/checkbox-group.js +1 -1
- package/dist/elements/checkbox.js +1 -1
- package/dist/elements/checkpoint.js +1 -1
- package/dist/elements/choice.js +1 -1
- package/dist/elements/coachmark.js +1 -1
- package/dist/elements/code-block.js +1 -1
- package/dist/elements/command.js +1 -1
- package/dist/elements/compare.js +1 -1
- package/dist/elements/composer.js +1 -1
- package/dist/elements/confirm-card.js +1 -1
- package/dist/elements/context-meter.js +1 -1
- package/dist/elements/conversation-item.js +1 -1
- package/dist/elements/conversation-list.js +1 -1
- package/dist/elements/dialog.js +1 -1
- package/dist/elements/dock.js +1 -1
- package/dist/elements/dropdown.js +1 -1
- package/dist/elements/editable-label.js +1 -1
- package/dist/elements/embed.js +1 -1
- package/dist/elements/empty.js +1 -1
- package/dist/elements/feedback-bar.js +1 -1
- package/dist/elements/file-tree.js +1 -1
- package/dist/elements/file-upload.js +1 -1
- package/dist/elements/form.js +1 -1
- package/dist/elements/hover-card.js +1 -1
- package/dist/elements/icon.js +1 -1
- package/dist/elements/image.js +1 -1
- package/dist/elements/input.js +1 -1
- package/dist/elements/kbd.js +1 -1
- package/dist/elements/link-preview.js +1 -1
- package/dist/elements/loader.js +1 -1
- package/dist/elements/markdown.js +1 -1
- package/dist/elements/menu.js +1 -1
- package/dist/elements/message-skills.js +1 -1
- package/dist/elements/message.js +1 -1
- package/dist/elements/model-switcher.js +1 -1
- package/dist/elements/nav.js +1 -1
- package/dist/elements/notice.js +1 -1
- package/dist/elements/pane-grid.js +1 -1
- package/dist/elements/pane-group.js +1 -1
- package/dist/elements/pane.js +1 -1
- package/dist/elements/popover.js +1 -1
- package/dist/elements/progress-bar.js +1 -1
- package/dist/elements/prompt-dock.js +1 -1
- package/dist/elements/prompt-input.js +1 -1
- package/dist/elements/prompt-suggestions.js +1 -1
- package/dist/elements/radio-group.js +1 -1
- package/dist/elements/reasoning.js +1 -1
- package/dist/elements/remote.js +1 -1
- package/dist/elements/resizable.js +1 -1
- package/dist/elements/response-stream.js +1 -1
- package/dist/elements/screen.js +1 -1
- package/dist/elements/scroll-area.js +1 -1
- package/dist/elements/scroll-button.js +1 -1
- package/dist/elements/search.js +1 -1
- package/dist/elements/segmented.js +1 -1
- package/dist/elements/select.js +1 -1
- package/dist/elements/separator.js +1 -1
- package/dist/elements/setting-item.js +1 -1
- package/dist/elements/settings-group.js +1 -1
- package/dist/elements/skeleton.js +1 -1
- package/dist/elements/slider.js +1 -1
- package/dist/elements/source.js +1 -1
- package/dist/elements/status.js +1 -1
- package/dist/elements/switch.js +1 -1
- package/dist/elements/tabs.js +1 -1
- package/dist/elements/tasks.js +1 -1
- package/dist/elements/text-shimmer.js +1 -1
- package/dist/elements/thinking-bar.js +1 -1
- package/dist/elements/thread.js +1 -1
- package/dist/elements/toast.js +1 -1
- package/dist/elements/tool.js +1 -1
- package/dist/elements/tooltip.js +1 -1
- package/dist/elements/voice-input.js +1 -1
- package/dist/elements/voice-output.js +1 -1
- package/dist/{ellipsis-CbOpJnU3.js → ellipsis-6pJ7SxYT.js} +1 -1
- package/dist/{embed-CrfjkbUG.js → embed-BMje-nxj.js} +1 -1
- package/dist/engine-javascript-C1x7zo1_.js +1 -141
- package/dist/{external-link-ByXAwBBQ.js → external-link-Beh9DKeR.js} +1 -1
- package/dist/{file-text-DMib2qwt.js → file-text-D1GPfZ8Q.js} +1 -1
- package/dist/{file-tree-CJqM2aP7.js → file-tree-Dwj2lqg-.js} +1 -1
- package/dist/{folder-_BAb929C.js → folder-b6D8x1DY.js} +1 -1
- package/dist/{form-DSZgZQZk.js → form-DWgdxDXu.js} +1 -1
- package/dist/{hover-card-BQbul9eq.js → hover-card-CWRkqm40.js} +1 -1
- package/dist/{icon-CdcfRhYI.js → icon-CL0jdhsf.js} +1 -1
- package/dist/index.js +1741 -1725
- package/dist/index.server.js +1582 -1566
- package/dist/{info-DsFjGuI_.js → info-0cOUherQ.js} +1 -1
- package/dist/{input-DKbmkMos.js → input-BH6Ru91Q.js} +1 -1
- package/dist/kai.es.js +1 -1
- package/dist/{kbd-PvdGhX4s.js → kbd-DRAnVtNX.js} +1 -1
- package/dist/{link-zF8PzWfF.js → link-Dlr0vssB.js} +1 -1
- package/dist/{link-preview-DbM1866N.js → link-preview-DODgRyV9.js} +1 -1
- package/dist/loader-KvJB6NrT.js +1 -0
- package/dist/{markdown-LMvmAyBk.js → markdown-DX9tuJVj.js} +1 -1
- package/dist/mcp.es.js +9 -5
- package/dist/{message-BYZECyek.js → message-BqQ7Ot5q.js} +1 -1
- package/dist/{message-BSsgvHvf.js → message-DkaGfBd8.js} +1 -1
- package/dist/message-circle-BPpp5QKv.js +1 -0
- package/dist/message-square-BLbsd9BJ.js +1 -0
- package/dist/{minimize-2-BQRoBV1V.js → minimize-2-CyOHJwcN.js} +1 -1
- package/dist/{model-switcher-CMpCOYcB.js → model-switcher-0hrKDiK2.js} +1 -1
- package/dist/{overlay-Cb-MkyDa.js → overlay-DBMFXie6.js} +1 -1
- package/dist/{panel-right-i8warFxT.js → panel-right-t8SWJL6e.js} +1 -1
- package/dist/{paperclip-ByY3UVO6.js → paperclip-CdzuOjbU.js} +1 -1
- package/dist/play-BXy1u7rW.js +1 -0
- package/dist/primitives/use-auto-resize.d.ts +11 -0
- package/dist/{progress-bar-jVAHvMUf.js → progress-bar-CiBtxMWT.js} +1 -1
- package/dist/{prompt-suggestion-CD-qtNgC.js → prompt-suggestion-I_DHP21i.js} +1 -1
- package/dist/{radio-BsoBMhkF.js → radio-C_p3n39l.js} +1 -1
- package/dist/{reasoning-4kBPtlTx.js → reasoning-BDwy_tIe.js} +1 -1
- package/dist/register-impl-DvEnhIxx.js +424 -0
- package/dist/{resizable-uPmY9VY-.js → resizable-SYC-fStM.js} +1 -1
- package/dist/{rotate-ccw-B2xn93py.js → rotate-ccw-B1nwmwuY.js} +1 -1
- package/dist/{rotate-cw-CMVLoCyH.js → rotate-cw-CLAnBcm1.js} +1 -1
- package/dist/{scroll-area-BqLUo8ZZ.js → scroll-area-zRyXoLhI.js} +1 -1
- package/dist/{scroll-button-DslXiJyL.js → scroll-button-jzrbYCG9.js} +1 -1
- package/dist/{select-2cLRtPGT.js → select-DM-0nEe0.js} +1 -1
- package/dist/{separator-BWQtNJcM.js → separator-BToOOoOt.js} +1 -1
- package/dist/{settings-BBR63jLg.js → settings-PaGo_S4U.js} +1 -1
- package/dist/{settings-group-B2ciy-Iw.js → settings-group-BFXGIfXq.js} +1 -1
- package/dist/{skeleton-CkHI-HgC.js → skeleton-DYpmFnnm.js} +1 -1
- package/dist/{slider-DDR9U-i0.js → slider-ebutAmkQ.js} +1 -1
- package/dist/{solid-DruVOXnf.js → solid-15v_3WVL.js} +3563 -3412
- package/dist/{solid-BzCFdL25.js → solid-5P-otgdi.js} +4502 -4296
- package/dist/solid.d.ts +6 -0
- package/dist/solid.js +259 -254
- package/dist/solid.server.js +259 -254
- package/dist/{source-GEnFF528.js → source-c1gpRl9h.js} +1 -1
- package/dist/{star-CilHq8GP.js → star-pcV_3LqF.js} +1 -1
- package/dist/{store-Ciyk6eZG.js → store-CSgbFFCg.js} +1 -1
- package/dist/{switch-KkeQIbuH.js → switch-Bh2OdLV2.js} +1 -1
- package/dist/{tasks-card-BrN4bggJ.js → tasks-card-CbqQAn2S.js} +1 -1
- package/dist/text-shimmer-BSzgEnDH.js +1 -0
- package/dist/textarea-DrYNt_0z.js +1 -0
- package/dist/theme.tokens.css +22 -21
- package/dist/{thumbs-up-CsT9Wzb9.js → thumbs-up-BL3-NenK.js} +1 -1
- package/dist/{toast-store-tgK6MuMv.js → toast-store-DkOlYczt.js} +1 -1
- package/dist/{tool-DzUjIBT8.js → tool-CeIWUVUe.js} +1 -1
- package/dist/{tooltip-Bkkg_4t0.js → tooltip-GA-nmg06.js} +1 -1
- package/dist/{trash-2-jBKxjGGQ.js → trash-2-CT66QWlm.js} +1 -1
- package/dist/{triangle-alert-DlQ68ppf.js → triangle-alert-CeHLWxhD.js} +1 -1
- package/dist/ui/color-field.d.ts +48 -0
- package/dist/ui/textarea.d.ts +4 -0
- package/dist/ui/toggle-chip.d.ts +40 -0
- package/dist/{upload-TcAHXv9W.js → upload-9Csb0F0J.js} +1 -1
- package/dist/{use-card-resolution-DaZqAdWf.js → use-card-resolution-Zg0a08Z-.js} +1 -1
- package/dist/{variant-aurora-DbW_OWL2.js → variant-aurora-4VBQHIKV.js} +1 -1
- package/dist/{variant-aurora-CNmfHhcx.js → variant-aurora-DBeCAQNk.js} +2 -2
- package/dist/{variant-aurora-D6GsdTPA.js → variant-aurora-FzHVXHby.js} +2 -2
- package/dist/{variant-aurora-BhLuYxJR.js → variant-aurora-LE3fqxgw.js} +1 -1
- package/dist/{variant-custom-BvYHR62b.js → variant-custom-AFRGcOBS.js} +1 -1
- package/dist/{variant-custom-DV2x254s.js → variant-custom-BQkNuPpE.js} +2 -2
- package/dist/{variant-custom-BRvaNHSi.js → variant-custom-DI5R0rln.js} +1 -1
- package/dist/{variant-custom-DMTrEO5w.js → variant-custom-WWnrrRHS.js} +2 -2
- package/dist/{variant-wave-CyBueXj9.js → variant-wave-DUCbH5oI.js} +2 -2
- package/dist/{variant-wave-BNMGrDfj.js → variant-wave-DuQV7DhQ.js} +2 -2
- package/dist/{variant-wave-BpDd8t3Z.js → variant-wave-nSI2sfII.js} +1 -1
- package/dist/{variant-wave-sp-qwsdI.js → variant-wave-wTP5v_jU.js} +1 -1
- package/dist/x-eiO9V6J6.js +1 -0
- package/{src/elements/styles.css → kit-base.css} +27 -44
- package/package.json +32 -17
- package/solid.css +33 -0
- package/theme.css +39 -23
- package/bin/route.test.js +0 -58
- package/dist/arrow-down-CjRU3JgV.js +0 -1
- package/dist/arrow-left-Bnpb1UEW.js +0 -1
- package/dist/artifact-Bwt7OgcR.js +0 -1
- package/dist/check-njkVdZu2.js +0 -1
- package/dist/chevron-down-B72s6PXR.js +0 -1
- package/dist/chevron-right-BatuHzUm.js +0 -1
- package/dist/circle-check-B62pODB3.js +0 -1
- package/dist/circle-zx0ByzY9.js +0 -1
- package/dist/controllable-CnGpMF6r.js +0 -1
- package/dist/define-By-uL588.js +0 -1
- package/dist/loader-BM4CEz4G.js +0 -1
- package/dist/message-circle-DruwObfX.js +0 -1
- package/dist/message-square-BG6q6mlm.js +0 -1
- package/dist/play-BvKKq3fX.js +0 -1
- package/dist/register-impl-B1hLkrI8.js +0 -424
- package/dist/text-shimmer-Dcj1MHuq.js +0 -1
- package/dist/textarea-Dpvbngbg.js +0 -1
- package/dist/x-Z5UntkIJ.js +0 -1
- package/src/agent-tooling/README.md +0 -192
- package/src/agent-tooling/archetypes.ts +0 -205
- package/src/agent-tooling/catalog/README.md +0 -676
- package/src/agent-tooling/catalog/catalog-types.ts +0 -231
- package/src/agent-tooling/catalog/fabrications.ts +0 -96
- package/src/agent-tooling/catalog/invariants.ts +0 -284
- package/src/agent-tooling/catalog/labs-titles.ts +0 -114
- package/src/agent-tooling/catalog/scenarios.ts +0 -87
- package/src/agent-tooling/catalog/surfaces.ts +0 -347
- package/src/agent-tooling/construct/cli-entry.ts +0 -8
- package/src/agent-tooling/construct/cli.ts +0 -147
- package/src/agent-tooling/construct/codegen.ts +0 -1635
- package/src/agent-tooling/construct/construct.v1.schema.json +0 -319
- package/src/agent-tooling/construct/dev.ts +0 -148
- package/src/agent-tooling/construct/fixtures/demo-widget.construct.json +0 -7
- package/src/agent-tooling/construct/fixtures/ops-console.construct.json +0 -44
- package/src/agent-tooling/construct/fixtures/owner-widget.construct.json +0 -32
- package/src/agent-tooling/construct/schema.ts +0 -452
- package/src/agent-tooling/integrations/anthropic.ts +0 -442
- package/src/agent-tooling/integrations/cloudflare.ts +0 -218
- package/src/agent-tooling/integrations/langgraph.ts +0 -133
- package/src/agent-tooling/integrations/mastra.ts +0 -182
- package/src/agent-tooling/integrations/mock.ts +0 -148
- package/src/agent-tooling/integrations/ollama.ts +0 -97
- package/src/agent-tooling/integrations/openai.ts +0 -95
- package/src/agent-tooling/integrations/openrouter.ts +0 -82
- package/src/agent-tooling/integrations/pi.ts +0 -176
- package/src/agent-tooling/integrations/pydantic-ai.ts +0 -108
- package/src/agent-tooling/integrations/vercel-ai-sdk.ts +0 -398
- package/src/agent-tooling/mcp/css-raw.d.ts +0 -12
- package/src/agent-tooling/mcp/manifest.ts +0 -422
- package/src/agent-tooling/mcp/server.ts +0 -116
- package/src/agent-tooling/mcp/stdio.ts +0 -18
- package/src/agent-tooling/mcp/tools/construct.ts +0 -130
- package/src/agent-tooling/mcp/tools/debug.ts +0 -621
- package/src/agent-tooling/mcp/tools/reference.ts +0 -980
- package/src/agent-tooling/mcp/tools/scaffold.ts +0 -6708
- package/src/agent-tooling/mcp/tools/theme.ts +0 -456
- package/src/agent-tooling/mcp/tools/types.ts +0 -14
- package/src/agent-tooling/mcp/validate-args.ts +0 -141
- package/src/agent-tooling/recipes/composed-thread.ts +0 -714
- package/src/agent-tooling/recipes/index.ts +0 -22
- package/src/agent-tooling/recipes/types.ts +0 -32
- package/src/agent-tooling/registry.ts +0 -132
- package/src/agent-tooling/route-emit.ts +0 -305
- package/src/agent-tooling/types.ts +0 -390
- package/src/components/artifact-card.tsx +0 -120
- package/src/components/artifact.tsx +0 -914
- package/src/components/attachment-types.ts +0 -66
- package/src/components/attachments.tsx +0 -536
- package/src/components/audio-visualizer/audio-visualizer.voice-fixture.ts +0 -257
- package/src/components/audio-visualizer/aurora.glsl.ts +0 -330
- package/src/components/audio-visualizer/fit-scale.ts +0 -112
- package/src/components/audio-visualizer/index.tsx +0 -528
- package/src/components/audio-visualizer/labs/lab-choreography.ts +0 -187
- package/src/components/audio-visualizer/labs/lab-shaders.ts +0 -363
- package/src/components/audio-visualizer/labs/lab-visualizer.tsx +0 -102
- package/src/components/audio-visualizer/shader-canvas.tsx +0 -876
- package/src/components/audio-visualizer/sizes.ts +0 -54
- package/src/components/audio-visualizer/variant-aurora.tsx +0 -305
- package/src/components/audio-visualizer/variant-bar.tsx +0 -175
- package/src/components/audio-visualizer/variant-custom.tsx +0 -344
- package/src/components/audio-visualizer/variant-grid.tsx +0 -175
- package/src/components/audio-visualizer/variant-radial.tsx +0 -163
- package/src/components/audio-visualizer/variant-wave.tsx +0 -130
- package/src/components/audio-visualizer/wave.glsl.ts +0 -130
- package/src/components/card-fallback.tsx +0 -60
- package/src/components/card-renderer.tsx +0 -220
- package/src/components/card.tsx +0 -212
- package/src/components/chain-of-thought.tsx +0 -348
- package/src/components/chat-container.tsx +0 -89
- package/src/components/chat-scope-picker.tsx +0 -57
- package/src/components/chat-thread.tsx +0 -1014
- package/src/components/checkpoint.tsx +0 -88
- package/src/components/choice-card.tsx +0 -743
- package/src/components/coachmark.tsx +0 -249
- package/src/components/code-block.tsx +0 -181
- package/src/components/composer-dom.ts +0 -159
- package/src/components/composer-highlight.ts +0 -242
- package/src/components/composer-history.ts +0 -82
- package/src/components/composer.tsx +0 -1075
- package/src/components/confirm-card.tsx +0 -402
- package/src/components/context.tsx +0 -377
- package/src/components/conversation-item.tsx +0 -241
- package/src/components/conversation-list.tsx +0 -429
- package/src/components/conversation-panel.tsx +0 -118
- package/src/components/dismissed-stub.tsx +0 -80
- package/src/components/embed.tsx +0 -200
- package/src/components/empty.tsx +0 -177
- package/src/components/feedback-bar.tsx +0 -166
- package/src/components/file-tree.tsx +0 -530
- package/src/components/file-upload.tsx +0 -167
- package/src/components/form-widgets.tsx +0 -525
- package/src/components/form.tsx +0 -1296
- package/src/components/home-panel.tsx +0 -159
- package/src/components/image.tsx +0 -65
- package/src/components/link-preview.tsx +0 -195
- package/src/components/loader.tsx +0 -367
- package/src/components/markdown.tsx +0 -162
- package/src/components/message-skills.tsx +0 -40
- package/src/components/message.tsx +0 -765
- package/src/components/model-switcher.tsx +0 -132
- package/src/components/prompt-input.tsx +0 -188
- package/src/components/prompt-suggestion.tsx +0 -150
- package/src/components/reasoning.tsx +0 -293
- package/src/components/response-compare-types.ts +0 -152
- package/src/components/response-compare.tsx +0 -455
- package/src/components/response-stream.tsx +0 -109
- package/src/components/screen.tsx +0 -181
- package/src/components/scroll-button.tsx +0 -93
- package/src/components/source.tsx +0 -192
- package/src/components/tasks-card.tsx +0 -801
- package/src/components/text-shimmer.tsx +0 -37
- package/src/components/thinking-bar.tsx +0 -50
- package/src/components/thread.tsx +0 -228
- package/src/components/toast.tsx +0 -503
- package/src/components/tool-classify.ts +0 -26
- package/src/components/tool-types.ts +0 -49
- package/src/components/tool.tsx +0 -190
- package/src/components/use-card-resolution.ts +0 -44
- package/src/components/voice-input.tsx +0 -222
- package/src/components/voice-output.tsx +0 -242
- package/src/components/widget-tab-bar.tsx +0 -73
- package/src/components/workspace-shell.tsx +0 -285
- package/src/diagnostics/hook.ts +0 -352
- package/src/diagnostics/index.ts +0 -82
- package/src/diagnostics/report-request.ts +0 -296
- package/src/elements/agent-card.tsx +0 -67
- package/src/elements/artifact.tsx +0 -194
- package/src/elements/attachments.tsx +0 -140
- package/src/elements/audio-visualizer.tsx +0 -227
- package/src/elements/autoloader.ts +0 -89
- package/src/elements/avatar.tsx +0 -33
- package/src/elements/badge.tsx +0 -32
- package/src/elements/button.tsx +0 -149
- package/src/elements/card.tsx +0 -133
- package/src/elements/cards.tsx +0 -266
- package/src/elements/chain-of-thought.tsx +0 -141
- package/src/elements/chat-scope-picker.tsx +0 -65
- package/src/elements/chat-types.ts +0 -102
- package/src/elements/chat-workspace.tsx +0 -188
- package/src/elements/chat.tsx +0 -304
- package/src/elements/checkbox-group.tsx +0 -164
- package/src/elements/checkbox.tsx +0 -134
- package/src/elements/checkpoint.tsx +0 -47
- package/src/elements/choice.tsx +0 -100
- package/src/elements/coachmark.tsx +0 -90
- package/src/elements/code-block.tsx +0 -60
- package/src/elements/command.tsx +0 -197
- package/src/elements/compare.tsx +0 -111
- package/src/elements/compiled.css +0 -2
- package/src/elements/composer.tsx +0 -162
- package/src/elements/confirm-card.tsx +0 -76
- package/src/elements/context-meter.tsx +0 -107
- package/src/elements/conversation-item.tsx +0 -120
- package/src/elements/conversation-list.tsx +0 -203
- package/src/elements/css.ts +0 -5
- package/src/elements/default-input.tsx +0 -392
- package/src/elements/define-entry.ts +0 -12
- package/src/elements/define.tsx +0 -563
- package/src/elements/diagnostic-events.ts +0 -114
- package/src/elements/dialog.tsx +0 -145
- package/src/elements/disclosure.ts +0 -95
- package/src/elements/dock.tsx +0 -215
- package/src/elements/dropdown.tsx +0 -123
- package/src/elements/editable-label.tsx +0 -140
- package/src/elements/element-data-types.ts +0 -152
- package/src/elements/element-diagnostics.ts +0 -392
- package/src/elements/element-manifest.json +0 -354
- package/src/elements/element-nonscalar.json +0 -187
- package/src/elements/element-types.d.ts +0 -4353
- package/src/elements/embed.tsx +0 -35
- package/src/elements/empty.tsx +0 -29
- package/src/elements/feedback-bar.tsx +0 -66
- package/src/elements/file-tree.tsx +0 -62
- package/src/elements/file-upload.tsx +0 -44
- package/src/elements/form.tsx +0 -94
- package/src/elements/hover-card.tsx +0 -80
- package/src/elements/icon.tsx +0 -41
- package/src/elements/image.tsx +0 -32
- package/src/elements/input.tsx +0 -492
- package/src/elements/kbd.tsx +0 -45
- package/src/elements/link-preview.tsx +0 -34
- package/src/elements/loader.tsx +0 -25
- package/src/elements/markdown.tsx +0 -38
- package/src/elements/menu.tsx +0 -241
- package/src/elements/message-skills.tsx +0 -83
- package/src/elements/message.tsx +0 -361
- package/src/elements/model-switcher.tsx +0 -121
- package/src/elements/nav.tsx +0 -87
- package/src/elements/notice.tsx +0 -53
- package/src/elements/pane-grid.tsx +0 -111
- package/src/elements/pane-group.tsx +0 -119
- package/src/elements/pane.tsx +0 -129
- package/src/elements/popover.tsx +0 -81
- package/src/elements/progress-bar.tsx +0 -39
- package/src/elements/prompt-dock.tsx +0 -82
- package/src/elements/prompt-input.tsx +0 -240
- package/src/elements/prompt-suggestions.tsx +0 -113
- package/src/elements/radio-group.tsx +0 -129
- package/src/elements/reasoning.tsx +0 -71
- package/src/elements/register-impl.ts +0 -148
- package/src/elements/register.ts +0 -76
- package/src/elements/remote.tsx +0 -225
- package/src/elements/resizable.globals.d.ts +0 -36
- package/src/elements/resizable.tsx +0 -704
- package/src/elements/response-stream.tsx +0 -40
- package/src/elements/screen.tsx +0 -90
- package/src/elements/scroll-area.tsx +0 -33
- package/src/elements/scroll-button.tsx +0 -179
- package/src/elements/search.tsx +0 -185
- package/src/elements/segmented.tsx +0 -129
- package/src/elements/select.tsx +0 -165
- package/src/elements/separator.tsx +0 -36
- package/src/elements/setting-item.tsx +0 -50
- package/src/elements/settings-group.tsx +0 -37
- package/src/elements/skeleton.tsx +0 -45
- package/src/elements/slider.tsx +0 -171
- package/src/elements/slot-text.ts +0 -73
- package/src/elements/slots.ts +0 -787
- package/src/elements/source.tsx +0 -126
- package/src/elements/status.tsx +0 -42
- package/src/elements/switch.tsx +0 -118
- package/src/elements/tabs.tsx +0 -95
- package/src/elements/tasks.tsx +0 -103
- package/src/elements/text-shimmer.tsx +0 -28
- package/src/elements/thinking-bar.tsx +0 -43
- package/src/elements/thread.tsx +0 -139
- package/src/elements/toast.tsx +0 -106
- package/src/elements/tool.tsx +0 -78
- package/src/elements/tooltip.tsx +0 -85
- package/src/elements/validate-messages.ts +0 -76
- package/src/elements/voice-input.tsx +0 -100
- package/src/elements/voice-output.tsx +0 -82
- package/src/index.ts +0 -430
- package/src/primitives/audio-bands.ts +0 -174
- package/src/primitives/card-component-types.ts +0 -63
- package/src/primitives/card-contract.ts +0 -80
- package/src/primitives/card-data-types.ts +0 -361
- package/src/primitives/card-host.tsx +0 -37
- package/src/primitives/card-recovery.ts +0 -160
- package/src/primitives/card-registry.tsx +0 -78
- package/src/primitives/card-resolution.ts +0 -36
- package/src/primitives/card-routing.ts +0 -85
- package/src/primitives/card-schemas/artifact.schema.json +0 -92
- package/src/primitives/card-schemas/card-envelope.schema.json +0 -14
- package/src/primitives/card-schemas/card-event.schema.json +0 -12
- package/src/primitives/card-schemas/choice.schema.json +0 -75
- package/src/primitives/card-schemas/confirm.schema.json +0 -65
- package/src/primitives/card-schemas/embed.schema.json +0 -63
- package/src/primitives/card-schemas/form.result.schema.json +0 -7
- package/src/primitives/card-schemas/form.schema.json +0 -53
- package/src/primitives/card-schemas/link.schema.json +0 -54
- package/src/primitives/card-schemas/tasks.result.schema.json +0 -16
- package/src/primitives/card-schemas/tasks.schema.json +0 -83
- package/src/primitives/card-tags.ts +0 -61
- package/src/primitives/card-validate-cards.ts +0 -255
- package/src/primitives/card-validate-schemas.ts +0 -58
- package/src/primitives/card-validate.ts +0 -131
- package/src/primitives/chat-config.tsx +0 -103
- package/src/primitives/composer-model.ts +0 -49
- package/src/primitives/composer-triggers.ts +0 -35
- package/src/primitives/controllable.ts +0 -21
- package/src/primitives/conversation-store.ts +0 -248
- package/src/primitives/create-kai-chat.ts +0 -66
- package/src/primitives/create-tween.ts +0 -266
- package/src/primitives/embed-providers.ts +0 -254
- package/src/primitives/field-mask.ts +0 -256
- package/src/primitives/field-semantics.ts +0 -115
- package/src/primitives/highlighter.ts +0 -157
- package/src/primitives/input-mask.ts +0 -853
- package/src/primitives/link-preview.ts +0 -87
- package/src/primitives/message-feedback.ts +0 -124
- package/src/primitives/pdf-preview.ts +0 -121
- package/src/primitives/toast-store.ts +0 -338
- package/src/primitives/url-scheme-policy.ts +0 -70
- package/src/primitives/use-audio-analysis.ts +0 -340
- package/src/primitives/use-auto-resize.ts +0 -31
- package/src/primitives/use-resize-observer.ts +0 -45
- package/src/primitives/use-sequencer.ts +0 -72
- package/src/primitives/use-speech-recognition.ts +0 -146
- package/src/primitives/use-stick-to-bottom.ts +0 -75
- package/src/primitives/use-text-stream.ts +0 -143
- package/src/primitives/use-voice-recorder.ts +0 -62
- package/src/primitives/visualizer-sequences.ts +0 -350
- package/src/remote/host-embed.ts +0 -345
- package/src/remote/index.ts +0 -2
- package/src/remote/origin.ts +0 -30
- package/src/remote/provider-runtime.ts +0 -262
- package/src/remote/provider.ts +0 -2
- package/src/remote/validate.ts +0 -22
- package/src/remote/version.ts +0 -12
- package/src/remote/wire.ts +0 -48
- package/src/schemas/from-tool-call.ts +0 -151
- package/src/schemas/index.ts +0 -341
- package/src/schemas/provider-subsets.ts +0 -538
- package/src/schemas/registry.ts +0 -355
- package/src/schemas/tool-defs.ts +0 -793
- package/src/solid.ts +0 -173
- package/src/state/index.ts +0 -44
- package/src/state/messages.ts +0 -53
- package/src/state/mock.ts +0 -297
- package/src/state/parts.ts +0 -295
- package/src/state/persistence.ts +0 -180
- package/src/state/stream.ts +0 -246
- package/src/state/suggestions.ts +0 -9
- package/src/state/threads.ts +0 -142
- package/src/test-utils/fake-clock.ts +0 -88
- package/src/types.ts +0 -95
- package/src/ui/action-icons.ts +0 -53
- package/src/ui/agent-card.tsx +0 -218
- package/src/ui/avatar.tsx +0 -23
- package/src/ui/badge.tsx +0 -21
- package/src/ui/button.tsx +0 -49
- package/src/ui/card.tsx +0 -245
- package/src/ui/checkbox-group.tsx +0 -153
- package/src/ui/checkbox.tsx +0 -63
- package/src/ui/collapsible.tsx +0 -163
- package/src/ui/command.tsx +0 -103
- package/src/ui/dialog.tsx +0 -223
- package/src/ui/dock.tsx +0 -630
- package/src/ui/dropdown.tsx +0 -636
- package/src/ui/editable-label.tsx +0 -112
- package/src/ui/hover-card.tsx +0 -345
- package/src/ui/icon.tsx +0 -167
- package/src/ui/input.tsx +0 -391
- package/src/ui/kbd.tsx +0 -118
- package/src/ui/nav.tsx +0 -282
- package/src/ui/notice.tsx +0 -84
- package/src/ui/overlay.tsx +0 -277
- package/src/ui/pane-grid.tsx +0 -117
- package/src/ui/pane-group.tsx +0 -291
- package/src/ui/pane.tsx +0 -193
- package/src/ui/popover.tsx +0 -106
- package/src/ui/progress-bar.tsx +0 -83
- package/src/ui/prompt-dock.tsx +0 -145
- package/src/ui/radio.tsx +0 -150
- package/src/ui/resizable.tsx +0 -693
- package/src/ui/scroll-area.tsx +0 -26
- package/src/ui/segmented.tsx +0 -109
- package/src/ui/select.tsx +0 -168
- package/src/ui/separator.tsx +0 -10
- package/src/ui/settings-group.tsx +0 -67
- package/src/ui/skeleton.tsx +0 -73
- package/src/ui/slider.tsx +0 -178
- package/src/ui/status.tsx +0 -48
- package/src/ui/switch.tsx +0 -119
- package/src/ui/tabs.tsx +0 -168
- package/src/ui/textarea.tsx +0 -21
- package/src/ui/tooltip.tsx +0 -118
- package/src/utils/cn.ts +0 -30
- package/src/wire/chunk.ts +0 -248
- package/src/wire/consume.ts +0 -599
- package/src/wire/diagnostics.ts +0 -727
- package/src/wire/encode-probe.ts +0 -214
- package/src/wire/encode.ts +0 -947
- package/src/wire/files.ts +0 -342
- package/src/wire/formats/anthropic.ts +0 -274
- package/src/wire/formats/openai.ts +0 -228
- package/src/wire/index.ts +0 -95
- package/src/wire/media-types.ts +0 -344
- package/src/wire/read.ts +0 -396
- package/src/wire/sink-helpers.ts +0 -50
- package/src/wire/sse.ts +0 -153
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
import type { Integration } from '../types';
|
|
2
|
-
|
|
3
|
-
const openrouter: Integration = {
|
|
4
|
-
id: 'openrouter',
|
|
5
|
-
title: 'OpenRouter',
|
|
6
|
-
category: 'gateway',
|
|
7
|
-
language: 'ts',
|
|
8
|
-
streamFormat: 'openai-sse',
|
|
9
|
-
envVars: ['OPENROUTER_API_KEY'],
|
|
10
|
-
// No per-framework templates: the handler below is web-standard, so the
|
|
11
|
-
// scaffolder wraps it in whatever the target framework routes with. This used
|
|
12
|
-
// to be a `next`-only entry that every other framework inherited verbatim.
|
|
13
|
-
routeTemplates: {},
|
|
14
|
-
webRoute: `async function chatHandler(request: Request): Promise<Response> {
|
|
15
|
-
// tools is undefined unless the front end sent one; JSON.stringify drops it,
|
|
16
|
-
// so the same handler serves a tool archetype and a plain chat.
|
|
17
|
-
let chatBody: ChatRequestBody;
|
|
18
|
-
try {
|
|
19
|
-
chatBody = await readChatRequest(request);
|
|
20
|
-
} catch (error) {
|
|
21
|
-
return toChatErrorResponse(error);
|
|
22
|
-
}
|
|
23
|
-
const { model, messages, tools } = chatBody;
|
|
24
|
-
|
|
25
|
-
const upstream = await fetch('https://openrouter.ai/api/v1/chat/completions', {
|
|
26
|
-
method: 'POST',
|
|
27
|
-
headers: {
|
|
28
|
-
Authorization: \`Bearer \${process.env.OPENROUTER_API_KEY}\`,
|
|
29
|
-
'Content-Type': 'application/json',
|
|
30
|
-
},
|
|
31
|
-
body: JSON.stringify({ model, messages, tools, stream: true }),
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
// FORWARD THE STATUS. Returning 200 here is how a missing key turns into
|
|
35
|
-
// silence: the 401 body is JSON, it goes out labelled text/event-stream, the
|
|
36
|
-
// SSE reader finds no frame, and the turn resolves empty with nothing logged
|
|
37
|
-
// and no bubble. With the status intact readOpenAIStream throws a WireError
|
|
38
|
-
// carrying the provider's own message.
|
|
39
|
-
if (!upstream.ok) {
|
|
40
|
-
return new Response(await upstream.text(), {
|
|
41
|
-
status: upstream.status,
|
|
42
|
-
headers: {
|
|
43
|
-
'Content-Type': upstream.headers.get('content-type') ?? 'application/json',
|
|
44
|
-
},
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
if (!upstream.body) {
|
|
48
|
-
return new Response(JSON.stringify({ error: { message: 'The provider returned no body to stream.' } }), {
|
|
49
|
-
status: 502,
|
|
50
|
-
headers: { 'Content-Type': 'application/json' },
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
return new Response(upstream.body, {
|
|
55
|
-
status: 200,
|
|
56
|
-
headers: {
|
|
57
|
-
'Content-Type': 'text/event-stream; charset=utf-8',
|
|
58
|
-
// no-transform stops a proxy buffering the stream into one blob.
|
|
59
|
-
'Cache-Control': 'no-cache, no-transform',
|
|
60
|
-
Connection: 'keep-alive',
|
|
61
|
-
},
|
|
62
|
-
});
|
|
63
|
-
}`,
|
|
64
|
-
streamMapping:
|
|
65
|
-
'OpenRouter returns OpenAI-format SSE. Pipe upstream.body straight to the browser; readOpenAIStream from @kitn.ai/ui/wire parses it, including tool calls and reasoning.',
|
|
66
|
-
runNote: 'Set OPENROUTER_API_KEY. Model ids are vendor/model, e.g. openai/gpt-4o.',
|
|
67
|
-
docsSlug: 'integrations/connect-any-model',
|
|
68
|
-
// The route forwards both, so a scaffold's editable consts reach the gateway.
|
|
69
|
-
forwardsFromClient: ['model', 'tools'],
|
|
70
|
-
// The handler puts the client's `tools` straight into an OpenAI-compatible
|
|
71
|
-
// /chat/completions body, unconverted — so the client must send OpenAI's own
|
|
72
|
-
// `{ type: 'function', function: { parameters } }` envelope.
|
|
73
|
-
clientToolFormat: 'openai',
|
|
74
|
-
// Nothing to install. The route is global `fetch` and imports no module.
|
|
75
|
-
deps: { npm: [], pip: [] },
|
|
76
|
-
// The route reads OPENROUTER_API_KEY into an `Authorization: Bearer` header.
|
|
77
|
-
keyExposure: 'needs-proxy',
|
|
78
|
-
// A remote HTTPS endpoint and a key. Nothing to install, nothing to start.
|
|
79
|
-
outOfBand: 'none',
|
|
80
|
-
};
|
|
81
|
-
|
|
82
|
-
export default openrouter;
|
|
@@ -1,176 +0,0 @@
|
|
|
1
|
-
import type { Integration } from '../types';
|
|
2
|
-
|
|
3
|
-
const pi: Integration = {
|
|
4
|
-
id: 'pi',
|
|
5
|
-
title: 'Pi',
|
|
6
|
-
category: 'harness',
|
|
7
|
-
language: 'ts',
|
|
8
|
-
streamFormat: 'native',
|
|
9
|
-
envVars: [],
|
|
10
|
-
routeTemplates: {
|
|
11
|
-
// Express only, and genuinely so: the bridge spawns a local process, which a
|
|
12
|
-
// Worker or an edge runtime cannot do. Every other framework gets this under
|
|
13
|
-
// the scaffolder's "cannot host" warning, the same way pydantic-ai emits a
|
|
14
|
-
// whole FastAPI service.
|
|
15
|
-
express: `// server.ts
|
|
16
|
-
import express from 'express';
|
|
17
|
-
import { spawn } from 'node:child_process';
|
|
18
|
-
import type { OpenAIWireMessage } from '@kitn.ai/ui/wire';
|
|
19
|
-
|
|
20
|
-
const app = express();
|
|
21
|
-
app.use(express.json());
|
|
22
|
-
|
|
23
|
-
class ChatRequestError extends Error {
|
|
24
|
-
constructor(readonly status: number, message: string) { super(message); }
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/** Narrow the JSON body once, at the edge. A bare GET or a missing messages
|
|
28
|
-
* array is a ChatRequestError with a status — NEVER an unhandled throw
|
|
29
|
-
* (findings F-10). Malformed JSON is rejected upstream by express.json(),
|
|
30
|
-
* which the error handler below turns into a JSON 400. */
|
|
31
|
-
function readChatRequest(req: express.Request): { messages: OpenAIWireMessage[] } {
|
|
32
|
-
if (req.method !== 'POST') {
|
|
33
|
-
throw new ChatRequestError(405, \`Method \${req.method} not allowed — POST /api/chat.\`);
|
|
34
|
-
}
|
|
35
|
-
const body = (req.body ?? {}) as { messages?: OpenAIWireMessage[] };
|
|
36
|
-
if (!Array.isArray(body.messages)) {
|
|
37
|
-
throw new ChatRequestError(400, 'Request body must carry a messages array.');
|
|
38
|
-
}
|
|
39
|
-
return body as { messages: OpenAIWireMessage[] };
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/** Map a guard rejection to the response its status demands; rethrow anything
|
|
43
|
-
* else — an unexpected error should be loud, not laundered into a 400. */
|
|
44
|
-
function toChatErrorResponse(error: unknown, res: express.Response): void {
|
|
45
|
-
if (error instanceof ChatRequestError) {
|
|
46
|
-
res.status(error.status).json({ error: { message: error.message } });
|
|
47
|
-
return;
|
|
48
|
-
}
|
|
49
|
-
throw error;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// express.json() rejects a malformed body at the MIDDLEWARE level, before any
|
|
53
|
-
// handler runs — without this it surfaces as Express's default HTML error page.
|
|
54
|
-
app.use(
|
|
55
|
-
(
|
|
56
|
-
err: { status?: number; message?: string },
|
|
57
|
-
_req: express.Request,
|
|
58
|
-
res: express.Response,
|
|
59
|
-
_next: express.NextFunction,
|
|
60
|
-
) => {
|
|
61
|
-
res.status(err?.status ?? 500).json({ error: { message: err?.message ?? 'Request failed.' } });
|
|
62
|
-
},
|
|
63
|
-
);
|
|
64
|
-
|
|
65
|
-
// A bare GET is a 405 with the method named, not Express's default 404 —
|
|
66
|
-
// the resource exists, the verb is wrong.
|
|
67
|
-
app.get('/api/chat', (_req, res) => {
|
|
68
|
-
res.status(405).json({ error: { message: 'Method not allowed — POST /api/chat.' } });
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
// POST /api/chat: bridge a Pi RPC session to the browser as SSE.
|
|
72
|
-
app.post('/api/chat', (req, res) => {
|
|
73
|
-
let chatBody: { messages: OpenAIWireMessage[] };
|
|
74
|
-
try {
|
|
75
|
-
chatBody = readChatRequest(req);
|
|
76
|
-
} catch (error) {
|
|
77
|
-
toChatErrorResponse(error, res);
|
|
78
|
-
return;
|
|
79
|
-
}
|
|
80
|
-
const { messages } = chatBody;
|
|
81
|
-
const last = messages.at(-1)?.content;
|
|
82
|
-
// \`content\` is a plain string until the turn carries an attachment, at which
|
|
83
|
-
// point it is an ARRAY of content parts. Pi's RPC mode takes a TEXT prompt and
|
|
84
|
-
// has no channel for a file, so an attachment is REFUSED here. Passing the
|
|
85
|
-
// array straight through would JSON.stringify an object graph into the prompt
|
|
86
|
-
// — no type error, no crash, just a model reading serialised noise.
|
|
87
|
-
if (Array.isArray(last) && last.some((part) => part.type !== 'text')) {
|
|
88
|
-
res.status(400).json({
|
|
89
|
-
error: {
|
|
90
|
-
message:
|
|
91
|
-
'This Pi bridge forwards a text prompt only and has no channel for an attachment. Extract the file content into the message text, or send it through a tool.',
|
|
92
|
-
},
|
|
93
|
-
});
|
|
94
|
-
return;
|
|
95
|
-
}
|
|
96
|
-
const prompt =
|
|
97
|
-
typeof last === 'string'
|
|
98
|
-
? last
|
|
99
|
-
: (last ?? []).map((part) => (part.type === 'text' ? part.text : '')).join('');
|
|
100
|
-
|
|
101
|
-
// Headers before the first frame: without text/event-stream the browser
|
|
102
|
-
// buffers the body and readOpenAIStream never sees a frame.
|
|
103
|
-
res.setHeader('Content-Type', 'text/event-stream; charset=utf-8');
|
|
104
|
-
// no-transform stops a proxy buffering the stream into one blob.
|
|
105
|
-
res.setHeader('Cache-Control', 'no-cache, no-transform');
|
|
106
|
-
res.setHeader('Connection', 'keep-alive');
|
|
107
|
-
|
|
108
|
-
// ONE PROCESS PER REQUEST. Pi in RPC mode holds conversation state, so a
|
|
109
|
-
// module-level process would leak one caller's turns into the next caller's
|
|
110
|
-
// reply and serialise every request behind a single stdin.
|
|
111
|
-
const pi = spawn('pi', ['--mode', 'rpc', '--no-session']);
|
|
112
|
-
|
|
113
|
-
// A spawn failure (pi not on PATH) arrives asynchronously, by which point the
|
|
114
|
-
// SSE headers are out and the status is spent, so report IN BAND:
|
|
115
|
-
// readOpenAIStream lands this on turn.error instead of leaving a blank bubble.
|
|
116
|
-
pi.on('error', (err) => {
|
|
117
|
-
res.write(\`data: \${JSON.stringify({ error: { message: err.message } })}\\n\\n\`);
|
|
118
|
-
res.write('data: [DONE]\\n\\n');
|
|
119
|
-
res.end();
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
// Send the user's turn. Pi commands are { type, message }.
|
|
123
|
-
pi.stdin.write(JSON.stringify({ type: 'prompt', message: prompt }) + '\\n');
|
|
124
|
-
|
|
125
|
-
let buffer = '';
|
|
126
|
-
pi.stdout.on('data', (chunk: Buffer) => {
|
|
127
|
-
buffer += chunk.toString();
|
|
128
|
-
// Split on \\n rather than readline: readline also breaks on the Unicode
|
|
129
|
-
// separators U+2028/U+2029, which appear inside model output.
|
|
130
|
-
const lines = buffer.split('\\n');
|
|
131
|
-
// pop() is \`string | undefined\`, and the buffer has to stay a string.
|
|
132
|
-
buffer = lines.pop() ?? ''; // hold the partial line for the next chunk
|
|
133
|
-
for (const line of lines) {
|
|
134
|
-
if (!line) continue;
|
|
135
|
-
const event = JSON.parse(line);
|
|
136
|
-
const part = event.assistantMessageEvent;
|
|
137
|
-
if (event.type === 'message_update' && part?.type === 'text_delta') {
|
|
138
|
-
res.write(\`data: \${JSON.stringify({ choices: [{ delta: { content: part.delta } }] })}\\n\\n\`);
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
});
|
|
142
|
-
pi.on('close', () => { res.write('data: [DONE]\\n\\n'); res.end(); });
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
app.listen(3001, () => console.log('chat api: http://localhost:3001/api/chat'));
|
|
146
|
-
// The front end fetches a RELATIVE /api/chat, so proxy that path to this port
|
|
147
|
-
// from your dev server, or serve both from one origin.`,
|
|
148
|
-
},
|
|
149
|
-
streamMapping: "Pi runs as a local stdio process in RPC mode (pi --mode rpc --no-session). It emits newline-delimited JSON events on stdout. Map message_update events where assistantMessageEvent.type === 'text_delta' to data: {choices:[{delta:{content:part.delta}}]} SSE frames; send data: [DONE] on close. Split stdout on \\n (not readline, which breaks on Unicode separators U+2028/U+2029). Pi also emits thinking_delta and toolcall_* events; re-frame them onto delta.reasoning and delta.tool_calls in the same frames. readOpenAIStream from @kitn.ai/ui/wire parses it, including tool calls and reasoning.",
|
|
150
|
-
runNote: "Pi must be installed locally and available on PATH as 'pi'. No API key is required by the bridge itself; Pi uses its own credentials. Pi runs with full user permissions, so sandbox it before exposing to a public endpoint. See the RPC reference: https://github.com/earendil-works/pi/blob/main/packages/coding-agent/docs/rpc.md",
|
|
151
|
-
docsSlug: 'integrations/harnesses',
|
|
152
|
-
// Nothing. Pi runs with its own credentials, model and tools; the bridge
|
|
153
|
-
// forwards a prompt, not a model id.
|
|
154
|
-
forwardsFromClient: [],
|
|
155
|
-
// `express` only. The bridge's other two imports are excluded by the rule:
|
|
156
|
-
// `node:child_process` is a builtin and '@kitn.ai/ui/wire' is the kit. Pi
|
|
157
|
-
// itself is NOT an npm dep of the app — runNote requires it on PATH, and the
|
|
158
|
-
// route reaches it with spawn('pi'), not an import.
|
|
159
|
-
deps: { npm: ['express'], pip: [] },
|
|
160
|
-
// No key anywhere: envVars is empty and Pi uses its own credentials on disk.
|
|
161
|
-
// This is 'needs-proxy' for the OTHER reason the flag covers — a server-only
|
|
162
|
-
// capability. The bridge calls spawn(), which no browser can do, and runNote
|
|
163
|
-
// warns that Pi runs with full user permissions and wants sandboxing before it
|
|
164
|
-
// is exposed. "No key" is not the same fact as "safe in the browser", and
|
|
165
|
-
// collapsing the two is exactly how this flag would be got wrong.
|
|
166
|
-
keyExposure: 'needs-proxy',
|
|
167
|
-
// Not 'local-server': nothing is listening in advance. The bridge spawns
|
|
168
|
-
// `pi --mode rpc` per request, so what the developer supplies is an EXECUTABLE
|
|
169
|
-
// on PATH ("Pi must be installed locally and available on PATH as 'pi'"), and
|
|
170
|
-
// "start the server first" would be the wrong instruction to print. Pi is not
|
|
171
|
-
// in `deps` for the same reason — the route reaches it with spawn(), not an
|
|
172
|
-
// import. The schema's SPAWNS_PROCESS net catches this one independently.
|
|
173
|
-
outOfBand: 'local-binary',
|
|
174
|
-
};
|
|
175
|
-
|
|
176
|
-
export default pi;
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
import type { Integration } from '../types';
|
|
2
|
-
|
|
3
|
-
const pydanticAi: Integration = {
|
|
4
|
-
id: 'pydantic-ai',
|
|
5
|
-
title: 'Pydantic AI',
|
|
6
|
-
category: 'framework',
|
|
7
|
-
language: 'python',
|
|
8
|
-
streamFormat: 'openai-sse',
|
|
9
|
-
envVars: ['OPENAI_API_KEY'],
|
|
10
|
-
routeTemplates: {
|
|
11
|
-
fastapi: `# main.py
|
|
12
|
-
import json
|
|
13
|
-
from fastapi import FastAPI, HTTPException
|
|
14
|
-
from fastapi.middleware.cors import CORSMiddleware
|
|
15
|
-
from fastapi.responses import StreamingResponse
|
|
16
|
-
from pydantic import BaseModel
|
|
17
|
-
from pydantic_ai import Agent
|
|
18
|
-
|
|
19
|
-
agent = Agent('openai:gpt-4o')
|
|
20
|
-
|
|
21
|
-
app = FastAPI()
|
|
22
|
-
app.add_middleware(
|
|
23
|
-
CORSMiddleware, allow_origins=['*'], allow_methods=['*'], allow_headers=['*']
|
|
24
|
-
)
|
|
25
|
-
|
|
26
|
-
class ContentPart(BaseModel):
|
|
27
|
-
type: str
|
|
28
|
-
text: str | None = None
|
|
29
|
-
|
|
30
|
-
class Message(BaseModel):
|
|
31
|
-
role: str
|
|
32
|
-
# A plain string until the turn carries an attachment, at which point the
|
|
33
|
-
# wire sends an ARRAY of content parts. Declaring this \`str\` alone made a
|
|
34
|
-
# message with a file a 422 that named pydantic rather than the cause.
|
|
35
|
-
content: str | list[ContentPart] | None = None
|
|
36
|
-
|
|
37
|
-
class ChatRequest(BaseModel):
|
|
38
|
-
messages: list[Message]
|
|
39
|
-
|
|
40
|
-
def prompt_text(message: Message) -> str:
|
|
41
|
-
"""The text of a turn, refusing what this route cannot carry.
|
|
42
|
-
|
|
43
|
-
agent.run_stream() takes a TEXT prompt, so an image or a document has no
|
|
44
|
-
channel here. Dropping it would send the model a turn that silently lost the
|
|
45
|
-
user's file; a 400 that names the reason is the honest failure.
|
|
46
|
-
"""
|
|
47
|
-
if message.content is None:
|
|
48
|
-
return ''
|
|
49
|
-
if isinstance(message.content, str):
|
|
50
|
-
return message.content
|
|
51
|
-
if any(part.type != 'text' for part in message.content):
|
|
52
|
-
raise HTTPException(
|
|
53
|
-
status_code=400,
|
|
54
|
-
detail='This route forwards a text prompt only and has no channel for an attachment. '
|
|
55
|
-
'Extract the file content into the message text, or send it through a tool.',
|
|
56
|
-
)
|
|
57
|
-
return ''.join(part.text or '' for part in message.content)
|
|
58
|
-
|
|
59
|
-
async def openai_sse(messages: list[Message]):
|
|
60
|
-
prompt = prompt_text(messages[-1]) if messages else ''
|
|
61
|
-
async with agent.run_stream(prompt) as result:
|
|
62
|
-
async for delta in result.stream_text(delta=True):
|
|
63
|
-
chunk = {'choices': [{'delta': {'content': delta}}]}
|
|
64
|
-
yield f'data: {json.dumps(chunk)}\\n\\n'
|
|
65
|
-
yield 'data: [DONE]\\n\\n'
|
|
66
|
-
|
|
67
|
-
@app.post('/api/chat')
|
|
68
|
-
async def chat(req: ChatRequest):
|
|
69
|
-
return StreamingResponse(openai_sse(req.messages), media_type='text/event-stream')`,
|
|
70
|
-
},
|
|
71
|
-
streamMapping:
|
|
72
|
-
"Pydantic AI's agent.run_stream() yields text deltas via result.stream_text(delta=True). Each delta is re-framed as a data: {choices:[{delta:{content}}]} SSE line and the stream closes with data: [DONE]. readOpenAIStream from @kitn.ai/ui/wire parses tool calls and reasoning too, but stream_text() yields text only: iterate the run's events instead and re-frame its tool-call events onto delta.tool_calls to fill kai-tool.",
|
|
73
|
-
// No install list here: `deps` below is the one, and the scaffolder emits it.
|
|
74
|
-
// This sentence used to open "Install: pip install pydantic-ai fastapi
|
|
75
|
-
// uvicorn." — three of the four packages, missing the `pydantic` its own route
|
|
76
|
-
// imports on the next line.
|
|
77
|
-
runNote:
|
|
78
|
-
'Set OPENAI_API_KEY. Run: uvicorn main:app --reload (default port 8000). Point kai-chat at http://localhost:8000/api/chat.',
|
|
79
|
-
docsSlug: 'integrations/pydantic-ai',
|
|
80
|
-
// Nothing. Agent('openai:gpt-4o') pins the model and the agent registers its
|
|
81
|
-
// own tools, both server-side.
|
|
82
|
-
forwardsFromClient: [],
|
|
83
|
-
// The only python integration, so the only non-empty `pip`. Three of the four
|
|
84
|
-
// are the route's own imports (`pydantic_ai` is imported under its module
|
|
85
|
-
// name and installed under its hyphenated one); `uvicorn` is the ASGI server
|
|
86
|
-
// the run note starts, which nothing imports and without which the app cannot
|
|
87
|
-
// run. That asymmetry is why the pip guard checks imports ⊆ declared and not
|
|
88
|
-
// the reverse.
|
|
89
|
-
deps: { npm: [], pip: ['pydantic-ai', 'fastapi', 'pydantic', 'uvicorn'] },
|
|
90
|
-
// Agent('openai:gpt-4o') reads OPENAI_API_KEY inside the python process.
|
|
91
|
-
//
|
|
92
|
-
// Worth being precise about, because this one looks like an exception: the
|
|
93
|
-
// FastAPI app sets CORS to allow_origins=['*'] and the browser fetches it
|
|
94
|
-
// DIRECTLY on :8000, with no JS proxy in front. That still is not
|
|
95
|
-
// 'frontend-safe' — the flag asks where the SECRET lives, and it lives in the
|
|
96
|
-
// python process. The FastAPI service IS the server hop.
|
|
97
|
-
keyExposure: 'needs-proxy',
|
|
98
|
-
// The emitted backend is a FastAPI service: a python interpreter, the four
|
|
99
|
-
// `deps.pip` packages, and `uvicorn main:app` on its own port — none of which a
|
|
100
|
-
// node toolchain provides or starts. It also needs OPENAI_API_KEY, so this is
|
|
101
|
-
// the entry that proves the groups are not mutually exclusive: a runtime
|
|
102
|
-
// prerequisite and a key at once. The prompt should lead with the runtime,
|
|
103
|
-
// because a key is useless until the service runs. The schema's `language ===
|
|
104
|
-
// 'python'` net catches this one independently.
|
|
105
|
-
outOfBand: 'language-runtime',
|
|
106
|
-
};
|
|
107
|
-
|
|
108
|
-
export default pydanticAi;
|