@marimo-team/frontend 0.15.5 → 0.16.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/dist/assets/{ConnectedDataExplorerComponent-Cn5-l2X1.js → ConnectedDataExplorerComponent-BErMbWvG.js} +1 -1
- package/dist/assets/{ImageComparisonComponent-CEXMKKA4.js → ImageComparisonComponent-fTHv1Ih0.js} +1 -1
- package/dist/assets/{VegaLite-Bt14Ds9k.js → VegaLite-Bdi-TyfY.js} +6 -6
- package/dist/assets/_baseEach-CNBxBxvS.js +1 -0
- package/dist/assets/_baseMap-D1WHjKrd.js +1 -0
- package/dist/assets/_baseUniq-CCgDNtZb.js +1 -0
- package/dist/assets/_createAggregator-DcD0kTA5.js +1 -0
- package/dist/assets/agent-panel-Crv430aI.js +268 -0
- package/dist/assets/agent-panel-D92Mfy1i.css +1 -0
- package/dist/assets/{any-language-editor-DiwNT6zp.js → any-language-editor-CQh552Wu.js} +1 -1
- package/dist/assets/architectureDiagram-W76B3OCA-BAJeBxzt.js +36 -0
- package/dist/assets/{between-horizontal-start-FyewyCGn.js → between-horizontal-start-Boxgxbt_.js} +1 -1
- package/dist/assets/{blockDiagram-QIGZ2CNN-BrOkAf_c.js → blockDiagram-QIGZ2CNN-CL-1svEK.js} +1 -1
- package/dist/assets/{c4Diagram-FPNF74CW-BHPzDxE2.js → c4Diagram-FPNF74CW-BbEqbCTl.js} +5 -5
- package/dist/assets/channel-_2eNSz0n.js +1 -0
- package/dist/assets/chat-panel-CXh5Wl6C.js +3 -0
- package/dist/assets/{chunk-4BX2VUAB-DLxaCNYh.js → chunk-4BX2VUAB-C--8TXeE.js} +1 -1
- package/dist/assets/{chunk-55IACEB6-DdzvO3HR.js → chunk-55IACEB6-Bj00HDqq.js} +1 -1
- package/dist/assets/{chunk-FMBD7UC4-R5o-nSiG.js → chunk-FMBD7UC4-C-lhB6hN.js} +1 -1
- package/dist/assets/{chunk-K7UQS3LO-DxaMrGgG.js → chunk-K7UQS3LO-B-pGTXPt.js} +1 -1
- package/dist/assets/{chunk-QN33PNHL-DqS9-FYm.js → chunk-QN33PNHL-DqUzGhvm.js} +1 -1
- package/dist/assets/{chunk-QZHKN3VN-BZ-TzajS.js → chunk-QZHKN3VN-TntJHfSk.js} +1 -1
- package/dist/assets/{chunk-TVAH2DTR-BsgP2dyv.js → chunk-TVAH2DTR-HUJb1psV.js} +1 -1
- package/dist/assets/{chunk-TZMSLE5B-D-h3ahXI.js → chunk-TZMSLE5B-BK3C__t3.js} +1 -1
- package/dist/assets/{circle-play-CQtRZ-rT.js → circle-play-DBLOv1Yu.js} +1 -1
- package/dist/assets/classDiagram-KNZD7YFC-BGmh9POF.js +1 -0
- package/dist/assets/classDiagram-v2-RKCZMP56-BGmh9POF.js +1 -0
- package/dist/assets/{clear-button-BY6Z_ViL.js → clear-button-BeoFbEKH.js} +1 -1
- package/dist/assets/clone-BFDSPAj3.js +1 -0
- package/dist/assets/command-palette-CXZiSv0I.js +1 -0
- package/dist/assets/common-C7oJcmCT.js +1 -0
- package/dist/assets/{compile-Ct_jzdKr.js → compile-7L0MwhyI.js} +1 -1
- package/dist/assets/cose-bilkent-S5V4N54A-BMkGLcVC.js +1 -0
- package/dist/assets/dagre-5GWH7T2D-BJtRienS.js +4 -0
- package/dist/assets/{data-grid-overlay-editor-BN_wulc3.js → data-grid-overlay-editor-DBkmGtNs.js} +1 -1
- package/dist/assets/datasources-panel-B7FbYLiy.js +1 -0
- package/dist/assets/{dependency-graph-panel-BOmSCZf7.js → dependency-graph-panel-DEdOxp2X.js} +4 -4
- package/dist/assets/diagram-N5W7TBWH-CmECY3nb.js +24 -0
- package/dist/assets/diagram-QEK2KX5R-DMOVSNKD.js +43 -0
- package/dist/assets/diagram-S2PKOQOG-BiJ96PNQ.js +24 -0
- package/dist/assets/{documentation-panel-BxjJO_Gw.js → documentation-panel-xULhaEv3.js} +1 -1
- package/dist/assets/edit-page-BrYda9VE.js +129 -0
- package/dist/assets/{ellipsis-vertical-UHbmjI2n.js → ellipsis-vertical-BBqXIlc2.js} +1 -1
- package/dist/assets/{empty-state-BIBXzY_0.js → empty-state-B3dA3G5P.js} +1 -1
- package/dist/assets/{erDiagram-AWTI2OKA-E84mAle_.js → erDiagram-AWTI2OKA-MP1DiFRo.js} +1 -1
- package/dist/assets/{error-panel-MEvQ6K7h.js → error-panel-Cc1sv-Ag.js} +1 -1
- package/dist/assets/file-explorer-panel-Bw59Kva1.js +1 -0
- package/dist/assets/{flowDiagram-PVAE7QVJ-DfbIRSAW.js → flowDiagram-PVAE7QVJ-BX7caPp7.js} +1 -1
- package/dist/assets/{ganttDiagram-OWAHRB6G-DR4HZ1z_.js → ganttDiagram-OWAHRB6G-B462g4Yf.js} +3 -3
- package/dist/assets/gitGraphDiagram-NY62KEGX-CGgvZ9-9.js +65 -0
- package/dist/assets/{glide-data-editor-nNmo1lPq.js → glide-data-editor-C0gUFZON.js} +4 -4
- package/dist/assets/graph-CHRVBzY5.js +1 -0
- package/dist/assets/{home-page-9eW6qida.js → home-page-Fb2osjys.js} +3 -3
- package/dist/assets/{index-DMomwMcN.js → index-BVgAenPd.js} +1 -1
- package/dist/assets/{index-B8llrTSo.js → index-BY93Ejhl.js} +1 -1
- package/dist/assets/{index-BFSnz7iM.js → index-C-8WADat.js} +1 -1
- package/dist/assets/{index-CPN7TRA1.js → index-C-GhZ7ti.js} +1 -1
- package/dist/assets/{index-DyLSuOH1.js → index-C1v_Z9et.js} +1 -1
- package/dist/assets/{index-VPWqq2Pg.js → index-C4Tn5NvJ.js} +1 -1
- package/dist/assets/{index-BAH034Ue.js → index-C77h_TXN.js} +1 -1
- package/dist/assets/{index-Dt9UWeWn.js → index-CQDrxQ0j.js} +1 -1
- package/dist/assets/{index-DWOaniGT.js → index-CWMgowgL.js} +1 -1
- package/dist/assets/{index-B1_GXGaP.js → index-Clbi_Yaq.js} +1 -1
- package/dist/assets/{index-B7yXbrLa.js → index-CpTPJo4k.js} +1 -1
- package/dist/assets/{index-CknhX2Vy.css → index-Cx0bsY1w.css} +1 -1
- package/dist/assets/{index-DqzMPAC8.js → index-D1vmG6DS.js} +2 -2
- package/dist/assets/{index-c6If577Q.js → index-D9UKkrr2.js} +1 -1
- package/dist/assets/{index-CB2pnVQG.js → index-DEQvTChO.js} +1 -1
- package/dist/assets/{index-OC46250R.js → index-DKEudB02.js} +205 -197
- package/dist/assets/{index-CSgxTUzD.js → index-DRMm6SNo.js} +1 -1
- package/dist/assets/{index-Bq516OmX.js → index-DoRmcrKM.js} +1 -1
- package/dist/assets/{index-DSU75csX.js → index-lYa_leQE.js} +1 -1
- package/dist/assets/{index-BLu5CX6z.js → index-vmICa5KN.js} +1 -1
- package/dist/assets/{index-uacyUula.js → index-z9bohSQJ.js} +1 -1
- package/dist/assets/infoDiagram-STP46IZ2-CVyrdLc8.js +2 -0
- package/dist/assets/isEmpty-DU_ogP_D.js +1 -0
- package/dist/assets/{journeyDiagram-BIP6EPQ6-BBiFyygf.js → journeyDiagram-BIP6EPQ6-C6EgLP_Q.js} +1 -1
- package/dist/assets/{kanban-definition-6OIFK2YF-DhgA6Nt6.js → kanban-definition-6OIFK2YF-BXzYO1yj.js} +4 -4
- package/dist/assets/layout-jihVw5-i.js +1 -0
- package/dist/assets/linear-C4blANlC.js +1 -0
- package/dist/assets/{links-CbvGxbsJ.js → links-D59GIweI.js} +3 -3
- package/dist/assets/{logs-panel-B9SmTZAW.js → logs-panel-D401qzZh.js} +1 -1
- package/dist/assets/markdown-renderer-Cd9eYyaL.js +263 -0
- package/dist/assets/{agent-panel-DpQ6muj-.css → markdown-renderer-ClyzDMmG.css} +1 -1
- package/dist/assets/mermaid-BEVuRz_O.js +1 -0
- package/dist/assets/{mermaid.core-4nVOEVX3.js → mermaid.core-CaSnaLH0.js} +41 -41
- package/dist/assets/min-DUMu_zeK.js +1 -0
- package/dist/assets/{mindmap-definition-Q6HEUPPD-CVLQNn1q.js → mindmap-definition-Q6HEUPPD-BXUM5MT2.js} +2 -2
- package/dist/assets/{number-overlay-editor-CzRzXLcd.js → number-overlay-editor-4uWXGlPG.js} +1 -1
- package/dist/assets/{outline-panel-uvsS-YEQ.js → outline-panel-DIzkvm2I.js} +1 -1
- package/dist/assets/packages-panel-CJL0MVlj.js +1 -0
- package/dist/assets/{pieDiagram-ADFJNKIX-C5IQ5DBZ.js → pieDiagram-ADFJNKIX-Dxt5PVNo.js} +3 -3
- package/dist/assets/{quadrantDiagram-LMRXKWRM-CFXFnQxx.js → quadrantDiagram-LMRXKWRM-D4pUaA31.js} +1 -1
- package/dist/assets/{react-plotly-mzdv02_Y.js → react-plotly-cJZ0VWBq.js} +1 -1
- package/dist/assets/{requirementDiagram-4UW4RH46-D9bPC89T.js → requirementDiagram-4UW4RH46-DVRTjgas.js} +1 -1
- package/dist/assets/run-page-BUEnMC9w.js +1 -0
- package/dist/assets/sankeyDiagram-GR3RE2ED-CVFnD9C-.js +10 -0
- package/dist/assets/scratchpad-panel-BIgRENkI.js +1 -0
- package/dist/assets/secrets-panel-xY5-V_BD.js +1 -0
- package/dist/assets/{sequenceDiagram-C3RYC4MD-6N7_hY4k.js → sequenceDiagram-C3RYC4MD-_lY4ZN_S.js} +4 -4
- package/dist/assets/{slides-component-EcjC8sDK.js → slides-component-Xjymwj7X.js} +1 -1
- package/dist/assets/snippets-panel-CTPYW41n.js +1 -0
- package/dist/assets/sortBy-BNZKwiq_.js +1 -0
- package/dist/assets/state-C4NiC9tO.js +1 -0
- package/dist/assets/stateDiagram-KXAO66HF-Da0JQWCn.js +1 -0
- package/dist/assets/stateDiagram-v2-UMBNRL4Z-D5lYZOOt.js +1 -0
- package/dist/assets/storage-CMdLzB_c.js +26 -0
- package/dist/assets/terminal-BPwTkXae.js +10 -0
- package/dist/assets/time-Dv5_Ouz_.js +1 -0
- package/dist/assets/{timeline-definition-XQNQX7LJ-BEaynAiY.js → timeline-definition-XQNQX7LJ-Dxh5Zu2e.js} +1 -1
- package/dist/assets/tracing-BCIurUfa.js +2 -0
- package/dist/assets/{tracing-panel-BmuHLPrY.js → tracing-panel-DAzrzNmm.js} +2 -2
- package/dist/assets/{trash-UBqfK4mR.js → trash-Dc6DSjz_.js} +1 -1
- package/dist/assets/{tree-XiEycetl.js → tree-jheoerAX.js} +1 -1
- package/dist/assets/{treemap-75Q7IDZK-CnuVFbBG.js → treemap-75Q7IDZK-IgpxeGaf.js} +21 -21
- package/dist/assets/{ts-tags-CloPe9IY.js → ts-tags-DxCDHihD.js} +1 -1
- package/dist/assets/variable-panel-DYAiLBmF.js +1 -0
- package/dist/assets/{vega-component-DsTH4tuX.js → vega-component-BpfpiPKI.js} +1 -1
- package/dist/assets/{xychartDiagram-6GGTOJPD-Dcz3O-A3.js → xychartDiagram-6GGTOJPD-CmNigJ31.js} +1 -1
- package/dist/index.html +2 -2
- package/package.json +8 -4
- package/src/__tests__/mocks.ts +43 -0
- package/src/components/app-config/user-config-form.tsx +32 -0
- package/src/components/chat/acp/__tests__/__snapshots__/prompt.test.ts.snap +55 -23
- package/src/components/chat/acp/__tests__/context-utils.test.ts +222 -0
- package/src/components/chat/acp/__tests__/prompt.test.ts +1 -1
- package/src/components/chat/acp/__tests__/state.test.ts +2 -6
- package/src/components/chat/acp/agent-docs.tsx +33 -6
- package/src/components/chat/acp/agent-panel.css +0 -18
- package/src/components/chat/acp/agent-panel.tsx +397 -72
- package/src/components/chat/acp/agent-selector.tsx +7 -1
- package/src/components/chat/acp/blocks.tsx +40 -10
- package/src/components/chat/acp/common.tsx +10 -2
- package/src/components/chat/acp/context-utils.ts +127 -0
- package/src/components/chat/acp/prompt.ts +34 -10
- package/src/components/chat/acp/state.ts +1 -1
- package/src/components/chat/acp/types.ts +8 -0
- package/src/components/chat/chat-panel.tsx +23 -88
- package/src/components/chat/chat-utils.ts +127 -1
- package/src/components/chat/markdown-renderer.css +39 -0
- package/src/components/chat/markdown-renderer.tsx +7 -38
- package/src/components/chat/tool-call-accordion.tsx +113 -23
- package/src/components/editor/Cell.tsx +6 -0
- package/src/components/editor/actions/name-cell-input.tsx +6 -1
- package/src/components/editor/actions/useCellActionButton.tsx +3 -1
- package/src/components/editor/ai/__tests__/completion-utils.test.ts +178 -1
- package/src/components/editor/ai/add-cell-with-ai.tsx +68 -66
- package/src/components/editor/ai/ai-completion-editor.tsx +29 -26
- package/src/components/editor/ai/completion-handlers.tsx +44 -6
- package/src/components/editor/ai/completion-utils.ts +92 -0
- package/src/components/editor/ai/transport/chat-transport.tsx +36 -0
- package/src/components/editor/cell/StagedAICell.tsx +51 -0
- package/src/components/editor/cell/cell-actions.tsx +2 -1
- package/src/components/terminal/__tests__/state.test.ts +207 -0
- package/src/components/terminal/hooks.ts +41 -0
- package/src/components/terminal/state.ts +75 -0
- package/src/components/terminal/terminal.tsx +334 -13
- package/src/components/terminal/theme.tsx +56 -0
- package/src/core/ai/__tests__/staged-cells.test.ts +356 -0
- package/src/core/ai/staged-cells.ts +208 -0
- package/src/core/cells/cells.ts +1 -1
- package/src/core/codemirror/lsp/federated-lsp.ts +1 -1
- package/src/core/islands/main.ts +2 -2
- package/src/core/kernel/messages.ts +8 -12
- package/src/core/saving/__tests__/filename.test.ts +37 -0
- package/src/core/static/__tests__/download-html.test.ts +43 -1
- package/src/core/websocket/useMarimoWebSocket.tsx +2 -2
- package/src/css/app/Cell.css +11 -0
- package/src/plugins/core/RenderHTML.tsx +36 -2
- package/src/plugins/core/__test__/RenderHTML.test.ts +72 -0
- package/src/plugins/core/registerReactComponent.tsx +28 -0
- package/src/plugins/impl/FileBrowserPlugin.tsx +8 -2
- package/src/stories/cell.stories.tsx +1 -1
- package/src/stories/layout/vertical/one-column.stories.tsx +1 -1
- package/src/utils/__tests__/cell-urls.test.ts +29 -0
- package/src/utils/__tests__/filenames.test.ts +18 -0
- package/src/utils/__tests__/path.test.ts +38 -0
- package/src/utils/__tests__/urls.test.ts +56 -1
- package/src/utils/errors.ts +9 -0
- package/dist/assets/_baseEach-C1FLm7WW.js +0 -1
- package/dist/assets/_baseMap-DBVArUYD.js +0 -1
- package/dist/assets/_baseUniq-Dk7ZPJ3N.js +0 -1
- package/dist/assets/_createAggregator-Bn38fDd3.js +0 -1
- package/dist/assets/agent-panel-COUYnuIK.js +0 -475
- package/dist/assets/architectureDiagram-W76B3OCA-DBzWQKKu.js +0 -36
- package/dist/assets/channel-CjhbjOv4.js +0 -1
- package/dist/assets/chat-panel-BPXKoTnZ.js +0 -7
- package/dist/assets/chat-panel-Brrs_eeH.css +0 -1
- package/dist/assets/classDiagram-KNZD7YFC-DHs5cFzy.js +0 -1
- package/dist/assets/classDiagram-v2-RKCZMP56-DHs5cFzy.js +0 -1
- package/dist/assets/clone-DM1YNjEn.js +0 -1
- package/dist/assets/command-palette-S0bzQp7v.js +0 -1
- package/dist/assets/common-B8U9k2Ly.js +0 -1
- package/dist/assets/cose-bilkent-S5V4N54A-wz1Sfx7j.js +0 -1
- package/dist/assets/dagre-5GWH7T2D-BfpcVBgq.js +0 -4
- package/dist/assets/datasources-panel-DfuURLJw.js +0 -1
- package/dist/assets/diagram-N5W7TBWH-Bf0oqqQh.js +0 -24
- package/dist/assets/diagram-QEK2KX5R-ZTc3qikh.js +0 -43
- package/dist/assets/diagram-S2PKOQOG-tLScBy7Z.js +0 -24
- package/dist/assets/edit-page-DJ8kJZ9w.js +0 -129
- package/dist/assets/file-explorer-panel-CzNUJ63G.js +0 -1
- package/dist/assets/gitGraphDiagram-NY62KEGX-C1t6QtVa.js +0 -65
- package/dist/assets/graph-CssCVWIq.js +0 -1
- package/dist/assets/index-DcCIe7np.js +0 -28
- package/dist/assets/infoDiagram-STP46IZ2-CwiAoz9f.js +0 -2
- package/dist/assets/layout-DpQrxGW-.js +0 -1
- package/dist/assets/linear-NsreOeBF.js +0 -1
- package/dist/assets/mermaid-DSt0r6IQ.js +0 -1
- package/dist/assets/min-D259kI3t.js +0 -1
- package/dist/assets/packages-panel-xMz9W2hW.js +0 -1
- package/dist/assets/run-page-Bb68qdhQ.js +0 -1
- package/dist/assets/sankeyDiagram-GR3RE2ED-BSJOau8E.js +0 -10
- package/dist/assets/scratchpad-panel-BF4BO-U4.js +0 -1
- package/dist/assets/secrets-panel-CdIX44dQ.js +0 -1
- package/dist/assets/snippets-panel-Dco9h0rb.js +0 -1
- package/dist/assets/sortBy-aLGA-PGK.js +0 -1
- package/dist/assets/stateDiagram-KXAO66HF-Bd68WT3b.js +0 -1
- package/dist/assets/stateDiagram-v2-UMBNRL4Z-BXz_GSwb.js +0 -1
- package/dist/assets/storage-CGlP4lCF.js +0 -26
- package/dist/assets/terminal-CxkHubcu.js +0 -9
- package/dist/assets/time-D2nr1UgQ.js +0 -1
- package/dist/assets/tracing-kTqHxa7q.js +0 -2
- package/dist/assets/variable-panel-noTnH-AQ.js +0 -1
|
@@ -20,7 +20,6 @@ import {
|
|
|
20
20
|
XIcon,
|
|
21
21
|
} from "lucide-react";
|
|
22
22
|
import React from "react";
|
|
23
|
-
import { Streamdown } from "streamdown";
|
|
24
23
|
import { mergeToolCalls } from "use-acp";
|
|
25
24
|
import { JsonOutput } from "@/components/editor/output/JsonOutput";
|
|
26
25
|
import { Button } from "@/components/ui/button";
|
|
@@ -33,12 +32,14 @@ import { logNever } from "@/utils/assertNever";
|
|
|
33
32
|
import { cn } from "@/utils/cn";
|
|
34
33
|
import { type Base64String, base64ToDataURL } from "@/utils/json/base64";
|
|
35
34
|
import { Strings } from "@/utils/strings";
|
|
35
|
+
import { MarkdownRenderer } from "../markdown-renderer";
|
|
36
36
|
import { SimpleAccordion } from "./common";
|
|
37
37
|
import type {
|
|
38
38
|
AgentNotificationEvent,
|
|
39
39
|
AgentThoughtNotificationEvent,
|
|
40
40
|
ConnectionChangeNotificationEvent,
|
|
41
41
|
ContentBlockOf,
|
|
42
|
+
CurrentModeUpdateNotificationEvent,
|
|
42
43
|
ErrorNotificationEvent,
|
|
43
44
|
PlanNotificationEvent,
|
|
44
45
|
SessionNotificationEventData,
|
|
@@ -307,7 +308,7 @@ export const AgentMessagesBlock = (props: {
|
|
|
307
308
|
export const ContentBlocks = (props: { data: ContentBlock[] }) => {
|
|
308
309
|
const renderBlock = (block: ContentBlock) => {
|
|
309
310
|
if (block.type === "text") {
|
|
310
|
-
return <
|
|
311
|
+
return <MarkdownRenderer content={block.text} />;
|
|
311
312
|
}
|
|
312
313
|
if (block.type === "image") {
|
|
313
314
|
return <ImageBlock data={block} />;
|
|
@@ -371,7 +372,7 @@ export const ResourceBlock = (props: { data: ContentBlockOf<"resource"> }) => {
|
|
|
371
372
|
</span>
|
|
372
373
|
</PopoverTrigger>
|
|
373
374
|
<PopoverContent className="max-h-96 overflow-y-auto scrollbar-thin">
|
|
374
|
-
<
|
|
375
|
+
<MarkdownRenderer content={props.data.resource.text} />
|
|
375
376
|
</PopoverContent>
|
|
376
377
|
</Popover>
|
|
377
378
|
);
|
|
@@ -495,6 +496,18 @@ export const SessionNotificationsBlock = <
|
|
|
495
496
|
return <PlansBlock data={items} />;
|
|
496
497
|
}
|
|
497
498
|
|
|
499
|
+
if (kind === "available_commands_update") {
|
|
500
|
+
return null; // nothing to show
|
|
501
|
+
}
|
|
502
|
+
if (kind === "current_mode_update") {
|
|
503
|
+
const lastItem = items.at(-1);
|
|
504
|
+
if (lastItem?.sessionUpdate !== "current_mode_update") {
|
|
505
|
+
return null;
|
|
506
|
+
} else {
|
|
507
|
+
return <CurrentModeBlock data={lastItem} />;
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
|
|
498
511
|
return (
|
|
499
512
|
<SimpleAccordion title={items[0].sessionUpdate}>
|
|
500
513
|
<JsonOutput data={items} format="tree" className="max-h-64" />
|
|
@@ -509,6 +522,13 @@ export const SessionNotificationsBlock = <
|
|
|
509
522
|
);
|
|
510
523
|
};
|
|
511
524
|
|
|
525
|
+
export const CurrentModeBlock = (props: {
|
|
526
|
+
data: CurrentModeUpdateNotificationEvent;
|
|
527
|
+
}) => {
|
|
528
|
+
const { currentModeId } = props.data;
|
|
529
|
+
return <div>Mode: {currentModeId}</div>;
|
|
530
|
+
};
|
|
531
|
+
|
|
512
532
|
export const ToolNotificationsBlock = (props: {
|
|
513
533
|
data: Array<ToolCallNotificationEvent | ToolCallUpdateNotificationEvent>;
|
|
514
534
|
}) => {
|
|
@@ -635,19 +655,29 @@ export const ToolBodyBlock = (props: {
|
|
|
635
655
|
| Omit<ToolCallNotificationEvent, "sessionUpdate">
|
|
636
656
|
| Omit<ToolCallUpdateNotificationEvent, "sessionUpdate">;
|
|
637
657
|
}) => {
|
|
638
|
-
const content = props.data
|
|
658
|
+
const { content, locations, status, kind, rawInput } = props.data;
|
|
659
|
+
const textContent = content
|
|
639
660
|
?.filter((item) => item.type === "content")
|
|
640
661
|
.map((item) => item.content);
|
|
641
|
-
const diffs =
|
|
642
|
-
const
|
|
643
|
-
const isFailed = props.data.status === "failed";
|
|
662
|
+
const diffs = content?.filter((item) => item.type === "diff");
|
|
663
|
+
const isFailed = status === "failed";
|
|
644
664
|
const hasLocations = locations && locations.length > 0;
|
|
645
665
|
|
|
646
|
-
|
|
666
|
+
// Completely empty
|
|
667
|
+
if (!content && !hasLocations && rawInput) {
|
|
668
|
+
// Show rawInput
|
|
669
|
+
return (
|
|
670
|
+
<pre className="bg-[var(--slate-2)] p-1 text-muted-foreground border border-[var(--slate-4)] rounded text-xs overflow-auto scrollbar-thin max-h-64">
|
|
671
|
+
<JsonOutput data={rawInput} format="tree" />
|
|
672
|
+
</pre>
|
|
673
|
+
);
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
if (content?.length && hasLocations) {
|
|
647
677
|
return (
|
|
648
678
|
<div className="flex flex-col gap-2 pr-2">
|
|
649
679
|
<span className="text-xs text-muted-foreground">
|
|
650
|
-
{capitalize(
|
|
680
|
+
{capitalize(kind || "")}{" "}
|
|
651
681
|
{locations?.map((item) => item.path).join(", ")}
|
|
652
682
|
</span>
|
|
653
683
|
</div>
|
|
@@ -657,7 +687,7 @@ export const ToolBodyBlock = (props: {
|
|
|
657
687
|
return (
|
|
658
688
|
<div className="flex flex-col gap-2 pr-2">
|
|
659
689
|
{locations && <LocationsBlock data={locations} />}
|
|
660
|
-
{
|
|
690
|
+
{textContent && <ContentBlocks data={textContent} />}
|
|
661
691
|
{diffs && !isFailed && <DiffBlocks data={diffs} />}
|
|
662
692
|
</div>
|
|
663
693
|
);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/* Copyright 2024 Marimo. All rights reserved. */
|
|
2
2
|
|
|
3
|
+
import type { RequestPermissionResponse } from "@zed-industries/agent-client-protocol";
|
|
3
4
|
import {
|
|
4
5
|
CheckCircleIcon,
|
|
5
6
|
Loader2,
|
|
@@ -151,7 +152,7 @@ ConnectionStatus.displayName = "ConnectionStatus";
|
|
|
151
152
|
|
|
152
153
|
interface PermissionRequestProps {
|
|
153
154
|
permission: NonNullable<AgentPendingPermission>;
|
|
154
|
-
onResolve: (option:
|
|
155
|
+
onResolve: (option: RequestPermissionResponse) => void;
|
|
155
156
|
}
|
|
156
157
|
|
|
157
158
|
export const PermissionRequest: React.FC<PermissionRequestProps> = memo(
|
|
@@ -179,7 +180,14 @@ export const PermissionRequest: React.FC<PermissionRequestProps> = memo(
|
|
|
179
180
|
? "text-[var(--blue-10)]"
|
|
180
181
|
: "text-[var(--red-10)]"
|
|
181
182
|
}
|
|
182
|
-
onClick={() =>
|
|
183
|
+
onClick={() =>
|
|
184
|
+
onResolve({
|
|
185
|
+
outcome: {
|
|
186
|
+
outcome: "selected",
|
|
187
|
+
optionId: option.optionId,
|
|
188
|
+
},
|
|
189
|
+
})
|
|
190
|
+
}
|
|
183
191
|
>
|
|
184
192
|
{option.kind.startsWith("allow") && (
|
|
185
193
|
<CheckCircleIcon className="h-3 w-3 mr-1" />
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/* Copyright 2024 Marimo. All rights reserved. */
|
|
2
|
+
|
|
3
|
+
import type { ContentBlock } from "@zed-industries/agent-client-protocol";
|
|
4
|
+
import type { FileUIPart } from "ai";
|
|
5
|
+
import { getAIContextRegistry } from "@/core/ai/context/context";
|
|
6
|
+
import { store } from "@/core/state/jotai";
|
|
7
|
+
import { blobToString } from "@/utils/fileToBase64";
|
|
8
|
+
import { Logger } from "@/utils/Logger";
|
|
9
|
+
|
|
10
|
+
export interface ContextParseResult {
|
|
11
|
+
contextBlocks: ContentBlock[];
|
|
12
|
+
attachmentBlocks: ContentBlock[];
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Converts File objects to agent protocol resource_link content blocks
|
|
17
|
+
*/
|
|
18
|
+
export async function convertFilesToResourceLinks(
|
|
19
|
+
files: File[],
|
|
20
|
+
): Promise<ContentBlock[]> {
|
|
21
|
+
const resourceLinks: ContentBlock[] = [];
|
|
22
|
+
|
|
23
|
+
for (const file of files) {
|
|
24
|
+
try {
|
|
25
|
+
const dataUrl = await blobToString(file, "dataUrl");
|
|
26
|
+
resourceLinks.push({
|
|
27
|
+
type: "resource_link",
|
|
28
|
+
uri: dataUrl,
|
|
29
|
+
mimeType: file.type,
|
|
30
|
+
name: file.name,
|
|
31
|
+
});
|
|
32
|
+
} catch (error) {
|
|
33
|
+
Logger.error("Error converting file to resource link", {
|
|
34
|
+
fileName: file.name,
|
|
35
|
+
error,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return resourceLinks;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Converts AI context registry attachments to agent protocol resource_link content blocks
|
|
45
|
+
*/
|
|
46
|
+
async function convertAiAttachmentsToResourceLinks(
|
|
47
|
+
attachments: FileUIPart[],
|
|
48
|
+
): Promise<ContentBlock[]> {
|
|
49
|
+
const resourceLinks: ContentBlock[] = [];
|
|
50
|
+
|
|
51
|
+
for (const attachment of attachments) {
|
|
52
|
+
resourceLinks.push({
|
|
53
|
+
type: "resource_link",
|
|
54
|
+
uri: attachment.url,
|
|
55
|
+
mimeType: attachment.mediaType,
|
|
56
|
+
name: attachment.filename ?? attachment.url,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return resourceLinks;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Parses context from the prompt value and returns content blocks for agent prompts.
|
|
65
|
+
* Extracts context references using @ notation and converts them to resource blocks.
|
|
66
|
+
* Also handles attachments from the AI context registry.
|
|
67
|
+
*/
|
|
68
|
+
export async function parseContextFromPrompt(
|
|
69
|
+
promptValue: string,
|
|
70
|
+
): Promise<ContextParseResult> {
|
|
71
|
+
const contextBlocks: ContentBlock[] = [];
|
|
72
|
+
const attachmentBlocks: ContentBlock[] = [];
|
|
73
|
+
|
|
74
|
+
// Skip if no '@' in the input
|
|
75
|
+
if (!promptValue.includes("@")) {
|
|
76
|
+
return { contextBlocks, attachmentBlocks };
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
try {
|
|
80
|
+
const registry = getAIContextRegistry(store);
|
|
81
|
+
const contextIds = registry.parseAllContextIds(promptValue);
|
|
82
|
+
|
|
83
|
+
if (contextIds.length === 0) {
|
|
84
|
+
return { contextBlocks, attachmentBlocks };
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Get context string for the registry
|
|
88
|
+
const contextString = registry.formatContextForAI(contextIds);
|
|
89
|
+
|
|
90
|
+
if (contextString.trim()) {
|
|
91
|
+
// Create a resource block with the context information
|
|
92
|
+
contextBlocks.push({
|
|
93
|
+
type: "resource",
|
|
94
|
+
resource: {
|
|
95
|
+
uri: "context.md",
|
|
96
|
+
mimeType: "text/markdown",
|
|
97
|
+
text: contextString,
|
|
98
|
+
},
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Get attachments from the AI context registry
|
|
103
|
+
try {
|
|
104
|
+
const aiAttachments = await registry.getAttachmentsForContext(contextIds);
|
|
105
|
+
if (aiAttachments.length > 0) {
|
|
106
|
+
const resourceLinks =
|
|
107
|
+
await convertAiAttachmentsToResourceLinks(aiAttachments);
|
|
108
|
+
attachmentBlocks.push(...resourceLinks);
|
|
109
|
+
Logger.debug("Added AI context attachments", {
|
|
110
|
+
count: aiAttachments.length,
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
} catch (error) {
|
|
114
|
+
Logger.error("Error getting AI context attachments", { error });
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
Logger.debug("Parsed context for agent", {
|
|
118
|
+
contextIds,
|
|
119
|
+
contextLength: contextString.length,
|
|
120
|
+
attachmentCount: attachmentBlocks.length,
|
|
121
|
+
});
|
|
122
|
+
} catch (error) {
|
|
123
|
+
Logger.error("Error parsing context for agent", { error });
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return { contextBlocks, attachmentBlocks };
|
|
127
|
+
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
export function getAgentPrompt(filename: string) {
|
|
4
4
|
return `
|
|
5
5
|
I am currently editing a marimo notebook.
|
|
6
|
-
You can read or write to the notebook at
|
|
6
|
+
You can read or write to the notebook at ${filename}
|
|
7
7
|
|
|
8
8
|
If you make edits to the notebook, only edit the contents inside the function decorator with @app.cell.
|
|
9
9
|
marimo will automatically handle adding the parameters and return statement of the function. For example,
|
|
@@ -11,7 +11,7 @@ export function getAgentPrompt(filename: string) {
|
|
|
11
11
|
|
|
12
12
|
\`\`\`
|
|
13
13
|
@app.cell
|
|
14
|
-
def
|
|
14
|
+
def _():
|
|
15
15
|
<your code here>
|
|
16
16
|
return
|
|
17
17
|
\`\`\`
|
|
@@ -37,6 +37,7 @@ export function getAgentPrompt(filename: string) {
|
|
|
37
37
|
7. The last expression in a cell is automatically displayed, just like in Jupyter notebooks.
|
|
38
38
|
8. Don't include comments in markdown cells
|
|
39
39
|
9. Don't include comments in SQL cells
|
|
40
|
+
10. Never define anything using \`global\`.
|
|
40
41
|
|
|
41
42
|
## Reactivity
|
|
42
43
|
|
|
@@ -46,6 +47,7 @@ export function getAgentPrompt(filename: string) {
|
|
|
46
47
|
- UI elements trigger updates when their values change without explicit callbacks
|
|
47
48
|
- UI element values are accessed through \`.value\` attribute
|
|
48
49
|
- You cannot access a UI element's value in the same cell where it's defined
|
|
50
|
+
- Cells prefixed with an underscore (e.g. _my_var) are local to the cell and cannot be accessed by other cells
|
|
49
51
|
|
|
50
52
|
## Best Practices
|
|
51
53
|
|
|
@@ -115,14 +117,29 @@ export function getAgentPrompt(filename: string) {
|
|
|
115
117
|
|
|
116
118
|
- \`mo.md(text)\` - display markdown
|
|
117
119
|
- \`mo.stop(predicate, output=None)\` - stop execution conditionally
|
|
120
|
+
- \`mo.output.append(value)\` - append to the output when it is not the last expression
|
|
121
|
+
- \`mo.output.replace(value)\` - replace the output when it is not the last expression
|
|
118
122
|
- \`mo.Html(html)\` - display HTML
|
|
119
123
|
- \`mo.image(image)\` - display an image
|
|
120
124
|
- \`mo.hstack(elements)\` - stack elements horizontally
|
|
121
125
|
- \`mo.vstack(elements)\` - stack elements vertically
|
|
122
126
|
- \`mo.tabs(elements)\` - create a tabbed interface
|
|
123
127
|
|
|
128
|
+
|
|
129
|
+
|
|
124
130
|
## Examples
|
|
125
131
|
|
|
132
|
+
<example title="Markdown ccell">
|
|
133
|
+
${formatCells([
|
|
134
|
+
`
|
|
135
|
+
mo.md("""
|
|
136
|
+
# Hello world
|
|
137
|
+
This is a _markdown_ **cell**.
|
|
138
|
+
""")
|
|
139
|
+
`,
|
|
140
|
+
])}
|
|
141
|
+
</example>
|
|
142
|
+
|
|
126
143
|
<example title="Basic UI with reactivity">
|
|
127
144
|
${formatCells([
|
|
128
145
|
`
|
|
@@ -207,6 +224,19 @@ export function getAgentPrompt(filename: string) {
|
|
|
207
224
|
])}
|
|
208
225
|
</example>
|
|
209
226
|
|
|
227
|
+
<example title="Conditional Outputs">
|
|
228
|
+
${formatCells([
|
|
229
|
+
`
|
|
230
|
+
mo.stop(not data.value, mo.md("No data to display"))
|
|
231
|
+
|
|
232
|
+
if mode.value == "scatter":
|
|
233
|
+
mo.output.replace(render_scatter(data.value))
|
|
234
|
+
else:
|
|
235
|
+
mo.output.replace(render_bar_chart(data.value))
|
|
236
|
+
`,
|
|
237
|
+
])}
|
|
238
|
+
</example>
|
|
239
|
+
|
|
210
240
|
<example title="Interactive chart with Altair">
|
|
211
241
|
${formatCells([
|
|
212
242
|
`
|
|
@@ -256,25 +286,19 @@ export function getAgentPrompt(filename: string) {
|
|
|
256
286
|
}
|
|
257
287
|
|
|
258
288
|
function formatCells(cells: string[]) {
|
|
259
|
-
// Option 1:
|
|
260
|
-
// return cells.map((cell) => {
|
|
261
|
-
// return `# Cell ${cell}`;
|
|
262
|
-
// });
|
|
263
|
-
|
|
264
289
|
const indent = " ";
|
|
265
290
|
const indentCode = (code: string) => {
|
|
266
291
|
return code
|
|
267
292
|
.trim()
|
|
268
293
|
.split("\n")
|
|
269
|
-
.map((line) => indent + line)
|
|
294
|
+
.map((line) => (indent + line).trimEnd())
|
|
270
295
|
.join("\n");
|
|
271
296
|
};
|
|
272
297
|
|
|
273
|
-
// Option 2:
|
|
274
298
|
const formatCell = (cell: string) => {
|
|
275
299
|
return `
|
|
276
300
|
@app.cell
|
|
277
|
-
def
|
|
301
|
+
def _():
|
|
278
302
|
${indentCode(cell)}
|
|
279
303
|
return
|
|
280
304
|
`;
|
|
@@ -259,5 +259,5 @@ export function getAgentSessionSupport(
|
|
|
259
259
|
export function getAgentConnectionCommand(agentId: ExternalAgentId): string {
|
|
260
260
|
const port = AGENT_CONFIG[agentId].port;
|
|
261
261
|
const command = AGENT_CONFIG[agentId].command;
|
|
262
|
-
return `npx
|
|
262
|
+
return `npx stdio-to-ws "${command}" --port ${port}`;
|
|
263
263
|
}
|
|
@@ -2,10 +2,16 @@
|
|
|
2
2
|
import type { ContentBlock } from "@zed-industries/agent-client-protocol";
|
|
3
3
|
import type { groupNotifications, useAcpClient } from "use-acp";
|
|
4
4
|
|
|
5
|
+
export type SessionMode = ReturnType<typeof useAcpClient>["sessionMode"];
|
|
6
|
+
|
|
5
7
|
export type NotificationEvent = Awaited<
|
|
6
8
|
ReturnType<typeof groupNotifications>
|
|
7
9
|
>[number][number];
|
|
8
10
|
|
|
11
|
+
export type AvailableCommands = ReturnType<
|
|
12
|
+
typeof useAcpClient
|
|
13
|
+
>["availableCommands"];
|
|
14
|
+
|
|
9
15
|
export type AgentConnectionState = ReturnType<
|
|
10
16
|
typeof useAcpClient
|
|
11
17
|
>["connectionState"];
|
|
@@ -49,6 +55,8 @@ export type ToolCallNotificationEvent = NotificationDataOf<"tool_call">;
|
|
|
49
55
|
export type ToolCallUpdateNotificationEvent =
|
|
50
56
|
NotificationDataOf<"tool_call_update">;
|
|
51
57
|
export type PlanNotificationEvent = NotificationDataOf<"plan">;
|
|
58
|
+
export type CurrentModeUpdateNotificationEvent =
|
|
59
|
+
NotificationDataOf<"current_mode_update">;
|
|
52
60
|
|
|
53
61
|
export type ContentBlockType = ContentBlock["type"];
|
|
54
62
|
export type ContentBlockOf<T extends ContentBlockType> = Extract<
|
|
@@ -48,7 +48,6 @@ import { DEFAULT_AI_MODEL } from "@/core/config/config-schema";
|
|
|
48
48
|
import { FeatureFlagged } from "@/core/config/feature-flag";
|
|
49
49
|
import { useRequestClient } from "@/core/network/requests";
|
|
50
50
|
import { useRuntimeManager } from "@/core/runtime/config";
|
|
51
|
-
import type { ChatMessage } from "@/plugins/impl/chat/types";
|
|
52
51
|
import { ErrorBanner } from "@/plugins/impl/common/error-banner";
|
|
53
52
|
import { cn } from "@/utils/cn";
|
|
54
53
|
import { timeAgo } from "@/utils/dates";
|
|
@@ -59,7 +58,6 @@ import { PromptInput } from "../editor/ai/add-cell-with-ai";
|
|
|
59
58
|
import {
|
|
60
59
|
addContextCompletion,
|
|
61
60
|
CONTEXT_TRIGGER,
|
|
62
|
-
getAICompletionBodyWithAttachments,
|
|
63
61
|
} from "../editor/ai/completion-utils";
|
|
64
62
|
import { PanelEmptyState } from "../editor/chrome/panels/empty-state";
|
|
65
63
|
import { CopyClipboardIcon } from "../icons/copy-icon";
|
|
@@ -68,8 +66,11 @@ import { Tooltip, TooltipProvider } from "../ui/tooltip";
|
|
|
68
66
|
import { toast } from "../ui/use-toast";
|
|
69
67
|
import { AttachmentRenderer, FileAttachmentPill } from "./chat-components";
|
|
70
68
|
import {
|
|
69
|
+
buildCompletionRequestBody,
|
|
71
70
|
convertToFileUIPart,
|
|
72
71
|
generateChatTitle,
|
|
72
|
+
handleToolCall,
|
|
73
|
+
hasPendingToolCalls,
|
|
73
74
|
isLastMessageReasoning,
|
|
74
75
|
} from "./chat-utils";
|
|
75
76
|
import { MarkdownRenderer } from "./markdown-renderer";
|
|
@@ -233,6 +234,7 @@ const ChatMessageDisplay: React.FC<ChatMessageProps> = memo(
|
|
|
233
234
|
index={i}
|
|
234
235
|
toolName={part.type}
|
|
235
236
|
result={part.output}
|
|
237
|
+
className="my-2"
|
|
236
238
|
state={part.state}
|
|
237
239
|
/>
|
|
238
240
|
);
|
|
@@ -265,6 +267,7 @@ const ChatMessageDisplay: React.FC<ChatMessageProps> = memo(
|
|
|
265
267
|
toolName={part.type}
|
|
266
268
|
result={part.output}
|
|
267
269
|
state={part.state}
|
|
270
|
+
className="my-2"
|
|
268
271
|
/>
|
|
269
272
|
);
|
|
270
273
|
|
|
@@ -282,10 +285,11 @@ const ChatMessageDisplay: React.FC<ChatMessageProps> = memo(
|
|
|
282
285
|
Logger.error("Unhandled part type:", part.type);
|
|
283
286
|
try {
|
|
284
287
|
return (
|
|
285
|
-
<
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
288
|
+
<div className="text-xs text-muted-foreground" key={i}>
|
|
289
|
+
<MarkdownRenderer
|
|
290
|
+
content={JSON.stringify(part, null, 2)}
|
|
291
|
+
/>
|
|
292
|
+
</div>
|
|
289
293
|
);
|
|
290
294
|
} catch (error) {
|
|
291
295
|
Logger.error("Error rendering part:", part.type, error);
|
|
@@ -429,7 +433,7 @@ const ChatInputFooter: React.FC<ChatInputFooterProps> = memo(
|
|
|
429
433
|
</>
|
|
430
434
|
)}
|
|
431
435
|
|
|
432
|
-
<Tooltip content="Submit">
|
|
436
|
+
<Tooltip content={isLoading ? "Stop" : "Submit"}>
|
|
433
437
|
<Button
|
|
434
438
|
variant="text"
|
|
435
439
|
size="sm"
|
|
@@ -565,80 +569,20 @@ const ChatPanelBody = () => {
|
|
|
565
569
|
id: chatId,
|
|
566
570
|
} = useChat({
|
|
567
571
|
id: activeChatId,
|
|
568
|
-
|
|
569
|
-
sendAutomaticallyWhen: ({ messages }) => {
|
|
570
|
-
if (messages.length === 0) {
|
|
571
|
-
return false;
|
|
572
|
-
}
|
|
573
|
-
|
|
574
|
-
const lastMessage = messages[messages.length - 1];
|
|
575
|
-
const parts = lastMessage.parts;
|
|
576
|
-
|
|
577
|
-
if (parts.length === 0) {
|
|
578
|
-
return false;
|
|
579
|
-
}
|
|
580
|
-
|
|
581
|
-
// Only auto-send if the last message is an assistant message
|
|
582
|
-
// Because assistant messages are the ones that can have tool calls
|
|
583
|
-
if (lastMessage.role !== "assistant") {
|
|
584
|
-
return false;
|
|
585
|
-
}
|
|
586
|
-
|
|
587
|
-
const toolParts = parts.filter((part) =>
|
|
588
|
-
part.type.startsWith("tool-"),
|
|
589
|
-
) as ToolUIPart[];
|
|
590
|
-
|
|
591
|
-
const hasCompletedToolCalls = toolParts.some(
|
|
592
|
-
(part) => part.state === "output-available",
|
|
593
|
-
);
|
|
594
|
-
|
|
595
|
-
// Check if the last part has any text content
|
|
596
|
-
const lastPart = parts[parts.length - 1];
|
|
597
|
-
const hasTextContent =
|
|
598
|
-
lastPart.type === "text" && lastPart.text?.trim().length > 0;
|
|
599
|
-
|
|
600
|
-
// Only auto-send if we have completed tool calls and there is no reply yet
|
|
601
|
-
return hasCompletedToolCalls && !hasTextContent;
|
|
602
|
-
},
|
|
572
|
+
sendAutomaticallyWhen: ({ messages }) => hasPendingToolCalls(messages),
|
|
603
573
|
messages: activeChat?.messages || [], // initial messages
|
|
604
574
|
transport: new DefaultChatTransport({
|
|
605
575
|
api: runtimeManager.getAiURL("chat").toString(),
|
|
606
576
|
headers: runtimeManager.headers(),
|
|
607
577
|
prepareSendMessagesRequest: async (options) => {
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
.map((part) => (part.type === "text" ? part.text : ""))
|
|
612
|
-
.join("\n");
|
|
613
|
-
}
|
|
614
|
-
|
|
615
|
-
const input = toContent(options.messages.flatMap((m) => m.parts));
|
|
616
|
-
const completionBody = await getAICompletionBodyWithAttachments({
|
|
617
|
-
input,
|
|
618
|
-
});
|
|
619
|
-
|
|
620
|
-
// Map from UIMessage to our ChatMessage type
|
|
621
|
-
// If it's the last message, add the attachments from the completion body
|
|
622
|
-
function mapMessage(m: UIMessage, isLastMessage: boolean): ChatMessage {
|
|
623
|
-
const parts = m.parts;
|
|
624
|
-
if (isLastMessage) {
|
|
625
|
-
parts.push(...completionBody.attachments);
|
|
626
|
-
}
|
|
627
|
-
return {
|
|
628
|
-
role: m.role,
|
|
629
|
-
content: toContent(m.parts),
|
|
630
|
-
parts: parts,
|
|
631
|
-
};
|
|
632
|
-
}
|
|
578
|
+
const completionBody = await buildCompletionRequestBody(
|
|
579
|
+
options.messages,
|
|
580
|
+
);
|
|
633
581
|
|
|
634
582
|
return {
|
|
635
583
|
body: {
|
|
636
584
|
...options,
|
|
637
|
-
...completionBody
|
|
638
|
-
messages: options.messages.map((m, idx) => ({
|
|
639
|
-
...m,
|
|
640
|
-
...mapMessage(m, idx === options.messages.length - 1),
|
|
641
|
-
})),
|
|
585
|
+
...completionBody,
|
|
642
586
|
},
|
|
643
587
|
};
|
|
644
588
|
},
|
|
@@ -653,24 +597,15 @@ const ChatPanelBody = () => {
|
|
|
653
597
|
});
|
|
654
598
|
},
|
|
655
599
|
onToolCall: async ({ toolCall }) => {
|
|
656
|
-
|
|
657
|
-
|
|
600
|
+
await handleToolCall({
|
|
601
|
+
invokeAiTool,
|
|
602
|
+
addToolResult,
|
|
603
|
+
toolCall: {
|
|
658
604
|
toolName: toolCall.toolName,
|
|
659
|
-
arguments: toolCall.input as Record<string, never>,
|
|
660
|
-
});
|
|
661
|
-
addToolResult({
|
|
662
|
-
tool: toolCall.toolName,
|
|
663
605
|
toolCallId: toolCall.toolCallId,
|
|
664
|
-
|
|
665
|
-
}
|
|
666
|
-
}
|
|
667
|
-
Logger.error("Tool call failed:", error);
|
|
668
|
-
addToolResult({
|
|
669
|
-
tool: toolCall.toolName,
|
|
670
|
-
toolCallId: toolCall.toolCallId,
|
|
671
|
-
output: `Error: ${error instanceof Error ? error.message : String(error)}`,
|
|
672
|
-
});
|
|
673
|
-
}
|
|
606
|
+
input: toolCall.input as Record<string, never>,
|
|
607
|
+
},
|
|
608
|
+
});
|
|
674
609
|
},
|
|
675
610
|
onError: (error) => {
|
|
676
611
|
Logger.error("An error occurred:", error);
|