@zythum02/fello-server 0.1.51 → 0.1.53
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/out/renderer/assets/{_baseUniq-DdWCC-Go.js → _baseUniq-CJr3HkLS.js} +1 -1
- package/out/renderer/assets/_baseUniq-CJr3HkLS.js.br +0 -0
- package/out/renderer/assets/_baseUniq-CJr3HkLS.js.gz +0 -0
- package/out/renderer/assets/{arc-B_en4gJt.js → arc-POsBroTF.js} +1 -1
- package/out/renderer/assets/arc-POsBroTF.js.br +0 -0
- package/out/renderer/assets/arc-POsBroTF.js.gz +0 -0
- package/out/renderer/assets/{architectureDiagram-Q4EWVU46-W-l3dTvZ.js → architectureDiagram-Q4EWVU46-CmToUhDb.js} +6 -6
- package/out/renderer/assets/architectureDiagram-Q4EWVU46-CmToUhDb.js.br +0 -0
- package/out/renderer/assets/architectureDiagram-Q4EWVU46-CmToUhDb.js.gz +0 -0
- package/out/renderer/assets/{arrow-left-BwbOF_G_.js → arrow-left-CxS1t3f7.js} +1 -1
- package/out/renderer/assets/{automation--izxbhlj.js → automation-Cyz3eLWp.js} +7 -8
- package/out/renderer/assets/automation-Cyz3eLWp.js.br +0 -0
- package/out/renderer/assets/automation-Cyz3eLWp.js.gz +0 -0
- package/out/renderer/assets/{blockDiagram-DXYQGD6D-BdxXOr8Y.js → blockDiagram-DXYQGD6D-M2nnTg9f.js} +7 -7
- package/out/renderer/assets/blockDiagram-DXYQGD6D-M2nnTg9f.js.br +0 -0
- package/out/renderer/assets/blockDiagram-DXYQGD6D-M2nnTg9f.js.gz +0 -0
- package/out/renderer/assets/{c4Diagram-AHTNJAMY-C_8XgPtT.js → c4Diagram-AHTNJAMY-CwLtsy_0.js} +3 -3
- package/out/renderer/assets/c4Diagram-AHTNJAMY-CwLtsy_0.js.br +0 -0
- package/out/renderer/assets/c4Diagram-AHTNJAMY-CwLtsy_0.js.gz +0 -0
- package/out/renderer/assets/{channel-BsSLbHzl.js → channel-BUNDMqpH.js} +1 -1
- package/out/renderer/assets/{chunk-4BX2VUAB-CADGLBio.js → chunk-4BX2VUAB-B2qXmkDT.js} +1 -1
- package/out/renderer/assets/{chunk-4TB4RGXK-C7h57GNs.js → chunk-4TB4RGXK-DXLZpPY5.js} +5 -5
- package/out/renderer/assets/chunk-4TB4RGXK-DXLZpPY5.js.br +0 -0
- package/out/renderer/assets/chunk-4TB4RGXK-DXLZpPY5.js.gz +0 -0
- package/out/renderer/assets/{chunk-55IACEB6-Cw-dv2b3.js → chunk-55IACEB6-CJeyefxI.js} +1 -1
- package/out/renderer/assets/{chunk-EDXVE4YY-BPjYyS5o.js → chunk-EDXVE4YY-CNjJEQfY.js} +1 -1
- package/out/renderer/assets/chunk-EDXVE4YY-CNjJEQfY.js.br +0 -0
- package/out/renderer/assets/chunk-EDXVE4YY-CNjJEQfY.js.gz +0 -0
- package/out/renderer/assets/{chunk-FMBD7UC4-DhJ5Z89u.js → chunk-FMBD7UC4-DOAOsjRu.js} +1 -1
- package/out/renderer/assets/{chunk-OYMX7WX6-D5Q5ZCl0.js → chunk-OYMX7WX6-BG4B1VQ7.js} +3 -3
- package/out/renderer/assets/chunk-OYMX7WX6-BG4B1VQ7.js.br +0 -0
- package/out/renderer/assets/chunk-OYMX7WX6-BG4B1VQ7.js.gz +0 -0
- package/out/renderer/assets/{chunk-QZHKN3VN-SsM-5KS-.js → chunk-QZHKN3VN-B9zfXYIQ.js} +1 -1
- package/out/renderer/assets/{chunk-YZCP3GAM-AbfctYy8.js → chunk-YZCP3GAM-jeoI2tsD.js} +1 -1
- package/out/renderer/assets/chunk-YZCP3GAM-jeoI2tsD.js.br +0 -0
- package/out/renderer/assets/chunk-YZCP3GAM-jeoI2tsD.js.gz +0 -0
- package/out/renderer/assets/{circle-x-CxFDvVH_.js → circle-x-B1kBsMlS.js} +1 -1
- package/out/renderer/assets/{classDiagram-v2-HSJHXN6E-7ZGV_42k.js → classDiagram-6PBFFD2Q-DWPFF3Yt.js} +7 -7
- package/out/renderer/assets/{classDiagram-6PBFFD2Q-7ZGV_42k.js → classDiagram-v2-HSJHXN6E-DWPFF3Yt.js} +7 -7
- package/out/renderer/assets/{clone-D2_BL2Tz.js → clone-Dcvr9oKv.js} +1 -1
- package/out/renderer/assets/{code-editor-cp9haQUT.js → code-editor-CEXlC4aV.js} +2 -2
- package/out/renderer/assets/code-editor-CEXlC4aV.js.br +0 -0
- package/out/renderer/assets/code-editor-CEXlC4aV.js.gz +0 -0
- package/out/renderer/assets/{collapsible-BHMUDZxc.js → collapsible-CMuCJUWG.js} +1 -1
- package/out/renderer/assets/collapsible-CMuCJUWG.js.br +0 -0
- package/out/renderer/assets/collapsible-CMuCJUWG.js.gz +0 -0
- package/out/renderer/assets/{cose-bilkent-S5V4N54A-CVcE9aWV.js → cose-bilkent-S5V4N54A-B3bgImVS.js} +2 -2
- package/out/renderer/assets/cose-bilkent-S5V4N54A-B3bgImVS.js.br +0 -0
- package/out/renderer/assets/cose-bilkent-S5V4N54A-B3bgImVS.js.gz +0 -0
- package/out/renderer/assets/{dagre-KV5264BT-zrX-TFsi.js → dagre-KV5264BT-DTbumBA_.js} +7 -7
- package/out/renderer/assets/dagre-KV5264BT-DTbumBA_.js.br +0 -0
- package/out/renderer/assets/dagre-KV5264BT-DTbumBA_.js.gz +0 -0
- package/out/renderer/assets/{diagram-5BDNPKRD-Ct9NrJP9.js → diagram-5BDNPKRD-B34Y6e8q.js} +7 -7
- package/out/renderer/assets/diagram-5BDNPKRD-B34Y6e8q.js.br +0 -0
- package/out/renderer/assets/diagram-5BDNPKRD-B34Y6e8q.js.gz +0 -0
- package/out/renderer/assets/{diagram-G4DWMVQ6-tTGWcCd_.js → diagram-G4DWMVQ6-BBiBmFR4.js} +7 -7
- package/out/renderer/assets/diagram-G4DWMVQ6-BBiBmFR4.js.br +0 -0
- package/out/renderer/assets/diagram-G4DWMVQ6-BBiBmFR4.js.gz +0 -0
- package/out/renderer/assets/{diagram-MMDJMWI5-CpmcnN2B.js → diagram-MMDJMWI5-P-YslDjG.js} +6 -6
- package/out/renderer/assets/diagram-MMDJMWI5-P-YslDjG.js.br +0 -0
- package/out/renderer/assets/diagram-MMDJMWI5-P-YslDjG.js.gz +0 -0
- package/out/renderer/assets/{diagram-TYMM5635-DKTR2xS9.js → diagram-TYMM5635-D_cLard_.js} +6 -6
- package/out/renderer/assets/diagram-TYMM5635-D_cLard_.js.br +0 -0
- package/out/renderer/assets/diagram-TYMM5635-D_cLard_.js.gz +0 -0
- package/out/renderer/assets/{ellipsis-8708fodN.js → ellipsis-D1agTYu1.js} +1 -1
- package/out/renderer/assets/{erDiagram-SMLLAGMA-BW13EXAs.js → erDiagram-SMLLAGMA-C1MHqKvC.js} +5 -5
- package/out/renderer/assets/erDiagram-SMLLAGMA-C1MHqKvC.js.br +0 -0
- package/out/renderer/assets/erDiagram-SMLLAGMA-C1MHqKvC.js.gz +0 -0
- package/out/renderer/assets/{field-Be86bgEh.js → field-DR3J0r9e.js} +1 -1
- package/out/renderer/assets/field-DR3J0r9e.js.br +0 -0
- package/out/renderer/assets/field-DR3J0r9e.js.gz +0 -0
- package/out/renderer/assets/{file-text-CMw1QH-C.js → file-text-nGCW6zu1.js} +1 -1
- package/out/renderer/assets/{flowDiagram-DWJPFMVM-C3oZAKxX.js → flowDiagram-DWJPFMVM-DprlEc3Z.js} +7 -7
- package/out/renderer/assets/flowDiagram-DWJPFMVM-DprlEc3Z.js.br +0 -0
- package/out/renderer/assets/flowDiagram-DWJPFMVM-DprlEc3Z.js.gz +0 -0
- package/out/renderer/assets/{ganttDiagram-T4ZO3ILL-BARJrpDB.js → ganttDiagram-T4ZO3ILL-CbTdumBm.js} +3 -3
- package/out/renderer/assets/ganttDiagram-T4ZO3ILL-CbTdumBm.js.br +0 -0
- package/out/renderer/assets/ganttDiagram-T4ZO3ILL-CbTdumBm.js.gz +0 -0
- package/out/renderer/assets/{gitGraphDiagram-UUTBAWPF-D0gl3Row.js → gitGraphDiagram-UUTBAWPF-06bme-w8.js} +7 -7
- package/out/renderer/assets/gitGraphDiagram-UUTBAWPF-06bme-w8.js.br +0 -0
- package/out/renderer/assets/gitGraphDiagram-UUTBAWPF-06bme-w8.js.gz +0 -0
- package/out/renderer/assets/{graph-DB7hnlLW.js → graph-BZhxluo9.js} +2 -2
- package/out/renderer/assets/graph-BZhxluo9.js.br +0 -0
- package/out/renderer/assets/graph-BZhxluo9.js.gz +0 -0
- package/out/renderer/assets/{highlighted-body-OFNGDK62-J87DvYBX.js → highlighted-body-OFNGDK62-CvDMJtXf.js} +2 -2
- package/out/renderer/assets/{index-Co8mzhyV.js → index-LmYTNvdF.js} +913 -453
- package/out/renderer/assets/index-LmYTNvdF.js.br +0 -0
- package/out/renderer/assets/index-LmYTNvdF.js.gz +0 -0
- package/out/renderer/assets/index-aGJ_yZib.css +382 -0
- package/out/renderer/assets/index-aGJ_yZib.css.br +0 -0
- package/out/renderer/assets/index-aGJ_yZib.css.gz +0 -0
- package/out/renderer/assets/{infoDiagram-42DDH7IO-BrfLG_LC.js → infoDiagram-42DDH7IO-DqivEzWL.js} +5 -5
- package/out/renderer/assets/infoDiagram-42DDH7IO-DqivEzWL.js.br +0 -0
- package/out/renderer/assets/infoDiagram-42DDH7IO-DqivEzWL.js.gz +0 -0
- package/out/renderer/assets/{ishikawaDiagram-UXIWVN3A-CO0cyvTq.js → ishikawaDiagram-UXIWVN3A-BKcg_z4w.js} +2 -2
- package/out/renderer/assets/ishikawaDiagram-UXIWVN3A-BKcg_z4w.js.br +0 -0
- package/out/renderer/assets/ishikawaDiagram-UXIWVN3A-BKcg_z4w.js.gz +0 -0
- package/out/renderer/assets/{item-CvcokSWl.js → item-BHEUMM9H.js} +1 -1
- package/out/renderer/assets/item-BHEUMM9H.js.br +0 -0
- package/out/renderer/assets/item-BHEUMM9H.js.gz +0 -0
- package/out/renderer/assets/{journeyDiagram-VCZTEJTY-D3F2Iu5P.js → journeyDiagram-VCZTEJTY-Bvv8xuxQ.js} +5 -5
- package/out/renderer/assets/journeyDiagram-VCZTEJTY-Bvv8xuxQ.js.br +0 -0
- package/out/renderer/assets/journeyDiagram-VCZTEJTY-Bvv8xuxQ.js.gz +0 -0
- package/out/renderer/assets/{kanban-definition-6JOO6SKY-CC_drlaB.js → kanban-definition-6JOO6SKY-C-gRMpeM.js} +3 -3
- package/out/renderer/assets/kanban-definition-6JOO6SKY-C-gRMpeM.js.br +0 -0
- package/out/renderer/assets/kanban-definition-6JOO6SKY-C-gRMpeM.js.gz +0 -0
- package/out/renderer/assets/{layout-B_3n1To1.js → layout-B4dSyItA.js} +4 -4
- package/out/renderer/assets/layout-B4dSyItA.js.br +0 -0
- package/out/renderer/assets/layout-B4dSyItA.js.gz +0 -0
- package/out/renderer/assets/{linear-AxwRZ_jw.js → linear-CoVhuer7.js} +1 -1
- package/out/renderer/assets/linear-CoVhuer7.js.br +0 -0
- package/out/renderer/assets/linear-CoVhuer7.js.gz +0 -0
- package/out/renderer/assets/{link-2-4A51Gs15.js → link-2-DHUPzNSt.js} +1 -1
- package/out/renderer/assets/{mermaid-GHXKKRXX-DFOJYe_t.js → mermaid-GHXKKRXX-CZqkhGx7.js} +54 -54
- package/out/renderer/assets/mermaid-GHXKKRXX-CZqkhGx7.js.br +0 -0
- package/out/renderer/assets/mermaid-GHXKKRXX-CZqkhGx7.js.gz +0 -0
- package/out/renderer/assets/mic-BgSvicCB.js +22 -0
- package/out/renderer/assets/{min-Dip7FmOo.js → min-emzuJjmk.js} +2 -2
- package/out/renderer/assets/min-emzuJjmk.js.br +0 -0
- package/out/renderer/assets/min-emzuJjmk.js.gz +0 -0
- package/out/renderer/assets/{mindmap-definition-QFDTVHPH-D9aiLrpe.js → mindmap-definition-QFDTVHPH-DQ4JNECm.js} +4 -4
- package/out/renderer/assets/mindmap-definition-QFDTVHPH-DQ4JNECm.js.br +0 -0
- package/out/renderer/assets/mindmap-definition-QFDTVHPH-DQ4JNECm.js.gz +0 -0
- package/out/renderer/assets/{open-guide-KaWHLGYU.js → open-guide-CfLO-Sdk.js} +1 -1
- package/out/renderer/assets/{package-search-CNALSYvi.js → package-search-CrF2Iegl.js} +1 -1
- package/out/renderer/assets/{pieDiagram-DEJITSTG-BX_34lAP.js → pieDiagram-DEJITSTG-0H6CGQQt.js} +7 -7
- package/out/renderer/assets/pieDiagram-DEJITSTG-0H6CGQQt.js.br +0 -0
- package/out/renderer/assets/pieDiagram-DEJITSTG-0H6CGQQt.js.gz +0 -0
- package/out/renderer/assets/{plus-DOVKq0d7.js → plus-YNCXW-GD.js} +1 -1
- package/out/renderer/assets/{quadrantDiagram-34T5L4WZ-G09qfNO8.js → quadrantDiagram-34T5L4WZ-D0aPKp5z.js} +3 -3
- package/out/renderer/assets/quadrantDiagram-34T5L4WZ-D0aPKp5z.js.br +0 -0
- package/out/renderer/assets/quadrantDiagram-34T5L4WZ-D0aPKp5z.js.gz +0 -0
- package/out/renderer/assets/{refresh-cw-DGB7KSZ3.js → refresh-cw-Bvm578nW.js} +1 -1
- package/out/renderer/assets/{requirementDiagram-MS252O5E-sJPY8r9J.js → requirementDiagram-MS252O5E-BkzwapW_.js} +4 -4
- package/out/renderer/assets/requirementDiagram-MS252O5E-BkzwapW_.js.br +0 -0
- package/out/renderer/assets/requirementDiagram-MS252O5E-BkzwapW_.js.gz +0 -0
- package/out/renderer/assets/{resizable-C5jomC3Y.js → resizable-cStzNJ8V.js} +1 -1
- package/out/renderer/assets/resizable-cStzNJ8V.js.br +0 -0
- package/out/renderer/assets/resizable-cStzNJ8V.js.gz +0 -0
- package/out/renderer/assets/{sankeyDiagram-XADWPNL6-DHIS2ISZ.js → sankeyDiagram-XADWPNL6-Dbde7usj.js} +2 -2
- package/out/renderer/assets/sankeyDiagram-XADWPNL6-Dbde7usj.js.br +0 -0
- package/out/renderer/assets/sankeyDiagram-XADWPNL6-Dbde7usj.js.gz +0 -0
- package/out/renderer/assets/{schedule-BoqPUAOI.js → schedule-DNMCsk-G.js} +9 -10
- package/out/renderer/assets/schedule-DNMCsk-G.js.br +0 -0
- package/out/renderer/assets/schedule-DNMCsk-G.js.gz +0 -0
- package/out/renderer/assets/{search-DdqhQVGJ.js → search-BEY9yGF_.js} +1 -1
- package/out/renderer/assets/{sequenceDiagram-FGHM5R23-Boc12Em2.js → sequenceDiagram-FGHM5R23-DI8l1pSL.js} +4 -4
- package/out/renderer/assets/sequenceDiagram-FGHM5R23-DI8l1pSL.js.br +0 -0
- package/out/renderer/assets/sequenceDiagram-FGHM5R23-DI8l1pSL.js.gz +0 -0
- package/out/renderer/assets/{session-DgU3TDDV.js → session-Bn5k9ScR.js} +1540 -182
- package/out/renderer/assets/session-Bn5k9ScR.js.br +0 -0
- package/out/renderer/assets/session-Bn5k9ScR.js.gz +0 -0
- package/out/renderer/assets/{setting-dialog-4pmkQ7WP.js → setting-dialog-sqfPfGsy.js} +3 -3
- package/out/renderer/assets/setting-dialog-sqfPfGsy.js.br +0 -0
- package/out/renderer/assets/setting-dialog-sqfPfGsy.js.gz +0 -0
- package/out/renderer/assets/{settings-2-CI8inOtS.js → settings-2-DRhoXOO8.js} +1 -1
- package/out/renderer/assets/{settings-agents-C4u0s-iR.js → settings-agents-Bntc31Nn.js} +10 -11
- package/out/renderer/assets/settings-agents-Bntc31Nn.js.br +0 -0
- package/out/renderer/assets/settings-agents-Bntc31Nn.js.gz +0 -0
- package/out/renderer/assets/{settings-general-BkLSJoHB.js → settings-general-DhbLb9cP.js} +2 -2
- package/out/renderer/assets/settings-general-DhbLb9cP.js.br +0 -0
- package/out/renderer/assets/settings-general-DhbLb9cP.js.gz +0 -0
- package/out/renderer/assets/{settings-ilink-6ZrgPpeO.js → settings-ilink-C7nGGjwT.js} +3 -3
- package/out/renderer/assets/settings-ilink-C7nGGjwT.js.br +0 -0
- package/out/renderer/assets/settings-ilink-C7nGGjwT.js.gz +0 -0
- package/out/renderer/assets/{settings-image-generation-B6YIO6o_.js → settings-image-generation-H2dgqG7Y.js} +6 -7
- package/out/renderer/assets/settings-image-generation-H2dgqG7Y.js.br +0 -0
- package/out/renderer/assets/settings-image-generation-H2dgqG7Y.js.gz +0 -0
- package/out/renderer/assets/{settings-layout-Cf7GMXFZ.js → settings-layout-ATto1xpJ.js} +9 -3
- package/out/renderer/assets/settings-layout-ATto1xpJ.js.br +0 -0
- package/out/renderer/assets/settings-layout-ATto1xpJ.js.gz +0 -0
- package/out/renderer/assets/{settings-mcp-CJvL5Siz.js → settings-mcp-DUdMuoJ-.js} +7 -8
- package/out/renderer/assets/settings-mcp-DUdMuoJ-.js.br +0 -0
- package/out/renderer/assets/settings-mcp-DUdMuoJ-.js.gz +0 -0
- package/out/renderer/assets/{settings-memory-CvkppfHy.js → settings-memory-CJLG4aHW.js} +3 -3
- package/out/renderer/assets/settings-memory-CJLG4aHW.js.br +0 -0
- package/out/renderer/assets/settings-memory-CJLG4aHW.js.gz +0 -0
- package/out/renderer/assets/{settings-snippets-CO_jL3O3.js → settings-snippets-B4VcnD5Z.js} +6 -7
- package/out/renderer/assets/settings-snippets-B4VcnD5Z.js.br +0 -0
- package/out/renderer/assets/settings-snippets-B4VcnD5Z.js.gz +0 -0
- package/out/renderer/assets/settings-speech-to-text-DQ7lfkTu.js +1054 -0
- package/out/renderer/assets/settings-speech-to-text-DQ7lfkTu.js.br +0 -0
- package/out/renderer/assets/settings-speech-to-text-DQ7lfkTu.js.gz +0 -0
- package/out/renderer/assets/{settings-webui-5n5mI55N.js → settings-webui-DZf9O-6j.js} +2 -2
- package/out/renderer/assets/settings-webui-DZf9O-6j.js.br +0 -0
- package/out/renderer/assets/settings-webui-DZf9O-6j.js.gz +0 -0
- package/out/renderer/assets/{skills-installed-BqjN4mEl.js → skills-installed-Dp0r_4I-.js} +4 -4
- package/out/renderer/assets/skills-installed-Dp0r_4I-.js.br +0 -0
- package/out/renderer/assets/skills-installed-Dp0r_4I-.js.gz +0 -0
- package/out/renderer/assets/{skills-layout-C8b-pe9X.js → skills-layout-D-5rlY38.js} +2 -2
- package/out/renderer/assets/skills-layout-D-5rlY38.js.br +0 -0
- package/out/renderer/assets/skills-layout-D-5rlY38.js.gz +0 -0
- package/out/renderer/assets/{skills-skills-sh-Bh8KQ3PF.js → skills-skills-sh-CcLoIrSw.js} +4 -4
- package/out/renderer/assets/skills-skills-sh-CcLoIrSw.js.br +0 -0
- package/out/renderer/assets/skills-skills-sh-CcLoIrSw.js.gz +0 -0
- package/out/renderer/assets/{sortable.esm-DARmP-Qe.js → sortable.esm-knFxDx0Y.js} +1 -1
- package/out/renderer/assets/sortable.esm-knFxDx0Y.js.br +0 -0
- package/out/renderer/assets/sortable.esm-knFxDx0Y.js.gz +0 -0
- package/out/renderer/assets/{standard-schema-CtFhVVG9.js → standard-schema-dKXoCekr.js} +1 -1
- package/out/renderer/assets/standard-schema-dKXoCekr.js.br +0 -0
- package/out/renderer/assets/standard-schema-dKXoCekr.js.gz +0 -0
- package/out/renderer/assets/{stateDiagram-FHFEXIEX-Da2gV_KD.js → stateDiagram-FHFEXIEX-DWWz4PMv.js} +9 -9
- package/out/renderer/assets/stateDiagram-FHFEXIEX-DWWz4PMv.js.br +0 -0
- package/out/renderer/assets/stateDiagram-FHFEXIEX-DWWz4PMv.js.gz +0 -0
- package/out/renderer/assets/{stateDiagram-v2-QKLJ7IA2-D44mYiaY.js → stateDiagram-v2-QKLJ7IA2-Dm2qD5bg.js} +5 -5
- package/out/renderer/assets/{task-Ca7ur8ku.js → task-C5dyYbfn.js} +11 -12
- package/out/renderer/assets/task-C5dyYbfn.js.br +0 -0
- package/out/renderer/assets/task-C5dyYbfn.js.gz +0 -0
- package/out/renderer/assets/{textarea-BCC4Oh3S.js → textarea-DTqKlQbL.js} +1 -1
- package/out/renderer/assets/{timeline-definition-GMOUNBTQ-egFv4rLM.js → timeline-definition-GMOUNBTQ-A1tEoL9d.js} +3 -3
- package/out/renderer/assets/timeline-definition-GMOUNBTQ-A1tEoL9d.js.br +0 -0
- package/out/renderer/assets/timeline-definition-GMOUNBTQ-A1tEoL9d.js.gz +0 -0
- package/out/renderer/assets/{vennDiagram-DHZGUBPP-CnOs99wX.js → vennDiagram-DHZGUBPP-tNdYrJi_.js} +2 -2
- package/out/renderer/assets/vennDiagram-DHZGUBPP-tNdYrJi_.js.br +0 -0
- package/out/renderer/assets/vennDiagram-DHZGUBPP-tNdYrJi_.js.gz +0 -0
- package/out/renderer/assets/{wardley-RL74JXVD-Bb1llXhX.js → wardley-RL74JXVD-BxN5_Sp6.js} +4 -4
- package/out/renderer/assets/wardley-RL74JXVD-BxN5_Sp6.js.br +0 -0
- package/out/renderer/assets/wardley-RL74JXVD-BxN5_Sp6.js.gz +0 -0
- package/out/renderer/assets/{wardleyDiagram-NUSXRM2D-BupfUxsI.js → wardleyDiagram-NUSXRM2D-B_3jA8zU.js} +6 -6
- package/out/renderer/assets/wardleyDiagram-NUSXRM2D-B_3jA8zU.js.br +0 -0
- package/out/renderer/assets/wardleyDiagram-NUSXRM2D-B_3jA8zU.js.gz +0 -0
- package/out/renderer/assets/{wrench-Dj1S5dhM.js → wrench-7r-g9MUq.js} +1 -1
- package/out/renderer/assets/wrench-7r-g9MUq.js.br +0 -0
- package/out/renderer/assets/wrench-7r-g9MUq.js.gz +0 -0
- package/out/renderer/assets/{xlsx-view-DIarHecR.js → xlsx-view-Bv0YhA5m.js} +10 -10
- package/out/renderer/assets/xlsx-view-Bv0YhA5m.js.br +0 -0
- package/out/renderer/assets/xlsx-view-Bv0YhA5m.js.gz +0 -0
- package/out/renderer/assets/{xychartDiagram-5P7HB3ND-CtPNxvT_.js → xychartDiagram-5P7HB3ND-NNVuzC4j.js} +3 -3
- package/out/renderer/assets/xychartDiagram-5P7HB3ND-NNVuzC4j.js.br +0 -0
- package/out/renderer/assets/xychartDiagram-5P7HB3ND-NNVuzC4j.js.gz +0 -0
- package/out/renderer/index.html +2 -2
- package/out/renderer/index.html.br +0 -0
- package/out/renderer/index.html.gz +0 -0
- package/out/server/main.js +602 -68
- package/package.json +3 -1
- package/resources/tree-sitter-wasm/tree-sitter-dart.wasm +0 -0
- package/out/renderer/assets/_baseUniq-DdWCC-Go.js.br +0 -0
- package/out/renderer/assets/_baseUniq-DdWCC-Go.js.gz +0 -0
- package/out/renderer/assets/arc-B_en4gJt.js.br +0 -0
- package/out/renderer/assets/arc-B_en4gJt.js.gz +0 -0
- package/out/renderer/assets/architectureDiagram-Q4EWVU46-W-l3dTvZ.js.br +0 -0
- package/out/renderer/assets/architectureDiagram-Q4EWVU46-W-l3dTvZ.js.gz +0 -0
- package/out/renderer/assets/automation--izxbhlj.js.br +0 -0
- package/out/renderer/assets/automation--izxbhlj.js.gz +0 -0
- package/out/renderer/assets/blockDiagram-DXYQGD6D-BdxXOr8Y.js.br +0 -0
- package/out/renderer/assets/blockDiagram-DXYQGD6D-BdxXOr8Y.js.gz +0 -0
- package/out/renderer/assets/c4Diagram-AHTNJAMY-C_8XgPtT.js.br +0 -0
- package/out/renderer/assets/c4Diagram-AHTNJAMY-C_8XgPtT.js.gz +0 -0
- package/out/renderer/assets/chunk-4TB4RGXK-C7h57GNs.js.br +0 -0
- package/out/renderer/assets/chunk-4TB4RGXK-C7h57GNs.js.gz +0 -0
- package/out/renderer/assets/chunk-EDXVE4YY-BPjYyS5o.js.br +0 -0
- package/out/renderer/assets/chunk-EDXVE4YY-BPjYyS5o.js.gz +0 -0
- package/out/renderer/assets/chunk-OYMX7WX6-D5Q5ZCl0.js.br +0 -0
- package/out/renderer/assets/chunk-OYMX7WX6-D5Q5ZCl0.js.gz +0 -0
- package/out/renderer/assets/chunk-YZCP3GAM-AbfctYy8.js.br +0 -0
- package/out/renderer/assets/chunk-YZCP3GAM-AbfctYy8.js.gz +0 -0
- package/out/renderer/assets/clipboard-D6ZpW5GH.js +0 -15
- package/out/renderer/assets/code-editor-cp9haQUT.js.br +0 -0
- package/out/renderer/assets/code-editor-cp9haQUT.js.gz +0 -0
- package/out/renderer/assets/collapsible-BHMUDZxc.js.br +0 -0
- package/out/renderer/assets/collapsible-BHMUDZxc.js.gz +0 -0
- package/out/renderer/assets/context-menu-K6z5uSmg.js +0 -282
- package/out/renderer/assets/context-menu-K6z5uSmg.js.br +0 -0
- package/out/renderer/assets/context-menu-K6z5uSmg.js.gz +0 -0
- package/out/renderer/assets/cose-bilkent-S5V4N54A-CVcE9aWV.js.br +0 -0
- package/out/renderer/assets/cose-bilkent-S5V4N54A-CVcE9aWV.js.gz +0 -0
- package/out/renderer/assets/dagre-KV5264BT-zrX-TFsi.js.br +0 -0
- package/out/renderer/assets/dagre-KV5264BT-zrX-TFsi.js.gz +0 -0
- package/out/renderer/assets/diagram-5BDNPKRD-Ct9NrJP9.js.br +0 -0
- package/out/renderer/assets/diagram-5BDNPKRD-Ct9NrJP9.js.gz +0 -0
- package/out/renderer/assets/diagram-G4DWMVQ6-tTGWcCd_.js.br +0 -0
- package/out/renderer/assets/diagram-G4DWMVQ6-tTGWcCd_.js.gz +0 -0
- package/out/renderer/assets/diagram-MMDJMWI5-CpmcnN2B.js.br +0 -0
- package/out/renderer/assets/diagram-MMDJMWI5-CpmcnN2B.js.gz +0 -0
- package/out/renderer/assets/diagram-TYMM5635-DKTR2xS9.js.br +0 -0
- package/out/renderer/assets/diagram-TYMM5635-DKTR2xS9.js.gz +0 -0
- package/out/renderer/assets/erDiagram-SMLLAGMA-BW13EXAs.js.br +0 -0
- package/out/renderer/assets/erDiagram-SMLLAGMA-BW13EXAs.js.gz +0 -0
- package/out/renderer/assets/field-Be86bgEh.js.br +0 -0
- package/out/renderer/assets/field-Be86bgEh.js.gz +0 -0
- package/out/renderer/assets/flowDiagram-DWJPFMVM-C3oZAKxX.js.br +0 -0
- package/out/renderer/assets/flowDiagram-DWJPFMVM-C3oZAKxX.js.gz +0 -0
- package/out/renderer/assets/ganttDiagram-T4ZO3ILL-BARJrpDB.js.br +0 -0
- package/out/renderer/assets/ganttDiagram-T4ZO3ILL-BARJrpDB.js.gz +0 -0
- package/out/renderer/assets/gitGraphDiagram-UUTBAWPF-D0gl3Row.js.br +0 -0
- package/out/renderer/assets/gitGraphDiagram-UUTBAWPF-D0gl3Row.js.gz +0 -0
- package/out/renderer/assets/graph-DB7hnlLW.js.br +0 -0
- package/out/renderer/assets/graph-DB7hnlLW.js.gz +0 -0
- package/out/renderer/assets/index-Co8mzhyV.js.br +0 -0
- package/out/renderer/assets/index-Co8mzhyV.js.gz +0 -0
- package/out/renderer/assets/index-iHYS74sQ.css +0 -382
- package/out/renderer/assets/index-iHYS74sQ.css.br +0 -0
- package/out/renderer/assets/index-iHYS74sQ.css.gz +0 -0
- package/out/renderer/assets/infoDiagram-42DDH7IO-BrfLG_LC.js.br +0 -0
- package/out/renderer/assets/infoDiagram-42DDH7IO-BrfLG_LC.js.gz +0 -0
- package/out/renderer/assets/ishikawaDiagram-UXIWVN3A-CO0cyvTq.js.br +0 -0
- package/out/renderer/assets/ishikawaDiagram-UXIWVN3A-CO0cyvTq.js.gz +0 -0
- package/out/renderer/assets/item-CvcokSWl.js.br +0 -0
- package/out/renderer/assets/item-CvcokSWl.js.gz +0 -0
- package/out/renderer/assets/journeyDiagram-VCZTEJTY-D3F2Iu5P.js.br +0 -0
- package/out/renderer/assets/journeyDiagram-VCZTEJTY-D3F2Iu5P.js.gz +0 -0
- package/out/renderer/assets/kanban-definition-6JOO6SKY-CC_drlaB.js.br +0 -0
- package/out/renderer/assets/kanban-definition-6JOO6SKY-CC_drlaB.js.gz +0 -0
- package/out/renderer/assets/layout-B_3n1To1.js.br +0 -0
- package/out/renderer/assets/layout-B_3n1To1.js.gz +0 -0
- package/out/renderer/assets/linear-AxwRZ_jw.js.br +0 -0
- package/out/renderer/assets/linear-AxwRZ_jw.js.gz +0 -0
- package/out/renderer/assets/mermaid-GHXKKRXX-DFOJYe_t.js.br +0 -0
- package/out/renderer/assets/mermaid-GHXKKRXX-DFOJYe_t.js.gz +0 -0
- package/out/renderer/assets/min-Dip7FmOo.js.br +0 -0
- package/out/renderer/assets/min-Dip7FmOo.js.gz +0 -0
- package/out/renderer/assets/mindmap-definition-QFDTVHPH-D9aiLrpe.js.br +0 -0
- package/out/renderer/assets/mindmap-definition-QFDTVHPH-D9aiLrpe.js.gz +0 -0
- package/out/renderer/assets/pieDiagram-DEJITSTG-BX_34lAP.js.br +0 -0
- package/out/renderer/assets/pieDiagram-DEJITSTG-BX_34lAP.js.gz +0 -0
- package/out/renderer/assets/quadrantDiagram-34T5L4WZ-G09qfNO8.js.br +0 -0
- package/out/renderer/assets/quadrantDiagram-34T5L4WZ-G09qfNO8.js.gz +0 -0
- package/out/renderer/assets/requirementDiagram-MS252O5E-sJPY8r9J.js.br +0 -0
- package/out/renderer/assets/requirementDiagram-MS252O5E-sJPY8r9J.js.gz +0 -0
- package/out/renderer/assets/resizable-C5jomC3Y.js.br +0 -0
- package/out/renderer/assets/resizable-C5jomC3Y.js.gz +0 -0
- package/out/renderer/assets/sankeyDiagram-XADWPNL6-DHIS2ISZ.js.br +0 -0
- package/out/renderer/assets/sankeyDiagram-XADWPNL6-DHIS2ISZ.js.gz +0 -0
- package/out/renderer/assets/schedule-BoqPUAOI.js.br +0 -0
- package/out/renderer/assets/schedule-BoqPUAOI.js.gz +0 -0
- package/out/renderer/assets/sequenceDiagram-FGHM5R23-Boc12Em2.js.br +0 -0
- package/out/renderer/assets/sequenceDiagram-FGHM5R23-Boc12Em2.js.gz +0 -0
- package/out/renderer/assets/session-DgU3TDDV.js.br +0 -0
- package/out/renderer/assets/session-DgU3TDDV.js.gz +0 -0
- package/out/renderer/assets/setting-dialog-4pmkQ7WP.js.br +0 -0
- package/out/renderer/assets/setting-dialog-4pmkQ7WP.js.gz +0 -0
- package/out/renderer/assets/settings-agents-C4u0s-iR.js.br +0 -0
- package/out/renderer/assets/settings-agents-C4u0s-iR.js.gz +0 -0
- package/out/renderer/assets/settings-general-BkLSJoHB.js.br +0 -0
- package/out/renderer/assets/settings-general-BkLSJoHB.js.gz +0 -0
- package/out/renderer/assets/settings-ilink-6ZrgPpeO.js.br +0 -0
- package/out/renderer/assets/settings-ilink-6ZrgPpeO.js.gz +0 -0
- package/out/renderer/assets/settings-image-generation-B6YIO6o_.js.br +0 -0
- package/out/renderer/assets/settings-image-generation-B6YIO6o_.js.gz +0 -0
- package/out/renderer/assets/settings-layout-Cf7GMXFZ.js.br +0 -0
- package/out/renderer/assets/settings-layout-Cf7GMXFZ.js.gz +0 -0
- package/out/renderer/assets/settings-mcp-CJvL5Siz.js.br +0 -0
- package/out/renderer/assets/settings-mcp-CJvL5Siz.js.gz +0 -0
- package/out/renderer/assets/settings-memory-CvkppfHy.js.br +0 -0
- package/out/renderer/assets/settings-memory-CvkppfHy.js.gz +0 -0
- package/out/renderer/assets/settings-snippets-CO_jL3O3.js.br +0 -0
- package/out/renderer/assets/settings-snippets-CO_jL3O3.js.gz +0 -0
- package/out/renderer/assets/settings-webui-5n5mI55N.js.br +0 -0
- package/out/renderer/assets/settings-webui-5n5mI55N.js.gz +0 -0
- package/out/renderer/assets/skills-installed-BqjN4mEl.js.br +0 -0
- package/out/renderer/assets/skills-installed-BqjN4mEl.js.gz +0 -0
- package/out/renderer/assets/skills-layout-C8b-pe9X.js.br +0 -0
- package/out/renderer/assets/skills-layout-C8b-pe9X.js.gz +0 -0
- package/out/renderer/assets/skills-skills-sh-Bh8KQ3PF.js.br +0 -0
- package/out/renderer/assets/skills-skills-sh-Bh8KQ3PF.js.gz +0 -0
- package/out/renderer/assets/sortable.esm-DARmP-Qe.js.br +0 -0
- package/out/renderer/assets/sortable.esm-DARmP-Qe.js.gz +0 -0
- package/out/renderer/assets/standard-schema-CtFhVVG9.js.br +0 -0
- package/out/renderer/assets/standard-schema-CtFhVVG9.js.gz +0 -0
- package/out/renderer/assets/stateDiagram-FHFEXIEX-Da2gV_KD.js.br +0 -0
- package/out/renderer/assets/stateDiagram-FHFEXIEX-Da2gV_KD.js.gz +0 -0
- package/out/renderer/assets/task-Ca7ur8ku.js.br +0 -0
- package/out/renderer/assets/task-Ca7ur8ku.js.gz +0 -0
- package/out/renderer/assets/timeline-definition-GMOUNBTQ-egFv4rLM.js.br +0 -0
- package/out/renderer/assets/timeline-definition-GMOUNBTQ-egFv4rLM.js.gz +0 -0
- package/out/renderer/assets/vennDiagram-DHZGUBPP-CnOs99wX.js.br +0 -0
- package/out/renderer/assets/vennDiagram-DHZGUBPP-CnOs99wX.js.gz +0 -0
- package/out/renderer/assets/wardley-RL74JXVD-Bb1llXhX.js.br +0 -0
- package/out/renderer/assets/wardley-RL74JXVD-Bb1llXhX.js.gz +0 -0
- package/out/renderer/assets/wardleyDiagram-NUSXRM2D-BupfUxsI.js.br +0 -0
- package/out/renderer/assets/wardleyDiagram-NUSXRM2D-BupfUxsI.js.gz +0 -0
- package/out/renderer/assets/wrench-Dj1S5dhM.js.br +0 -0
- package/out/renderer/assets/wrench-Dj1S5dhM.js.gz +0 -0
- package/out/renderer/assets/xlsx-view-DIarHecR.js.br +0 -0
- package/out/renderer/assets/xlsx-view-DIarHecR.js.gz +0 -0
- package/out/renderer/assets/xychartDiagram-5P7HB3ND-CtPNxvT_.js.br +0 -0
- package/out/renderer/assets/xychartDiagram-5P7HB3ND-CtPNxvT_.js.gz +0 -0
|
@@ -1,38 +1,37 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./code-editor-
|
|
2
|
-
import {
|
|
3
|
-
import { S as Settings2 } from "./settings-2-
|
|
4
|
-
import { i as isValidMessageToDisplay, M as MessageBubble, A as ArrowUpToLine, S as Square, j as jsonToPrettyYamlExports, p as parseFileReference, c as CodeCompareView, r as resolveFileUrl, I as ImageView, P as PdfView, D as DocxView, a as PptxView, X as XlsxView, R as RotateCcw, F as Folders } from "./xlsx-view-
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import { A as ArrowLeft } from "./arrow-left-
|
|
9
|
-
import { aQ as CodeView, S as StreamMarkdown, aR as FileIcon } from "./mermaid-GHXKKRXX-
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import
|
|
16
|
-
import "./
|
|
17
|
-
import "./item-CvcokSWl.js";
|
|
1
|
+
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./code-editor-CEXlC4aV.js","./index-LmYTNvdF.js","./index-aGJ_yZib.css","./mermaid-GHXKKRXX-CZqkhGx7.js","./code-editor-BwxubRqT.css"])))=>i.map(i=>d[i]);
|
|
2
|
+
import { h as createLucideIcon, r as reactExports, am as formatErrorMessage, bq as ReactStore, br as popupStoreSelectors, bs as triggerHover, al as triggerPress, bt as escapeKey, bu as attachPreventUnmountOnClose, bv as closePress, bw as PATIENT_CLICK_THRESHOLD, ae as reactDomExports, bx as focusOut, by as setPopupOpenState, bz as createInitialPopupStoreState, bA as createPopupFloatingRootContext, bB as Timeout, bC as PopupTriggerMap, j as jsxRuntimeExports, bD as FloatingTree, bE as usePopupRootSync, bF as useImplicitActiveTrigger, bG as useOpenStateTransitions, ak as createChangeEventDetails, bH as imperativeAction, bI as PopupHandleAttachment, bJ as usePopupRootStore, bK as useDismiss, bL as usePopupInteractionProps, bM as usePopupHandleStore, ai as useBaseUiId, bN as useTriggerDataForwarding, bO as useHoverReferenceInteraction, bP as safePolygon, bQ as useClick, bR as useOpenMethodTriggerProps, aq as useButton, bS as useTriggerFocusGuards, ap as useRenderElement, bT as CLICK_TRIGGER_IDENTIFIER, bU as FocusGuard, bV as pressableTriggerOpenStateMapping, bW as triggerOpenStateMapping, bX as FloatingPortal, bY as POPUP_COLLISION_AVOIDANCE, bZ as useFloatingNodeId, at as useAnimationsFinished, b_ as useAnchorPositioning, au as useIsoLayoutEffect, b$ as useAnchoredPopupScrollLock, c0 as usePositioner, c1 as InternalBackdrop, c2 as inertValue, c3 as FloatingNode, aj as useStableCallback, c4 as useToolbarRootContext, av as useOpenChangeComplete, c5 as useHoverFloatingInteraction, c6 as createDefaultInitialFocus, c7 as FOCUSABLE_POPUP_PROPS, ba as COMPOSITE_KEYS, c8 as getDisabledMountTransitionStyles, c9 as FloatingFocusManager, ca as isHTMLElement, cb as popupTransitionStateMapping, u as useTranslation, b as useMessage, X as useNavigate, a as useAppStore, _ as Badge, cc as formatUpdatedTime, e as request, V as electron, ab as ALL_FEATURES, ac as FEATURE_I18N_KEYS, M as cn$1, c as Switch, B as Button, R as LoaderCircle, cd as buttonVariants, i as isWebUI, U as FolderOpen, C as Check, d as Copy, f as extractErrorMessage, aG as reduceFlushStreaming, aF as reduceSessionNotification, g as copyText, ad as React, ce as Tooltip, cf as TooltipTrigger, cg as TooltipContent, S as ScrollArea, a5 as Bot, ch as formatDuration, af as getDefaultExportFromCjs, ci as ReactDOM, Y as subscribe, cj as clientId, A as DropdownMenu, E as DropdownMenuTrigger, ck as ChevronDown, F as DropdownMenuContent, G as DropdownMenuItem, cl as v$2, J as generateUUID, cm as HoverCard, cn as HoverCardTrigger, co as HoverCardContent, cp as X$1, aI as Folder, L as Library, cq as DropdownMenuSub, cr as DropdownMenuSubTrigger, cs as DropdownMenuSubContent, ct as CircleQuestionMark, cu as ChevronUp, aH as Clock, aB as Tabs, aC as TabsList, aD as TabsTrigger, cv as z$1, a0 as CircleCheck, cw as __vitePreload, I as Input, m as ContextMenuContent, n as ContextMenuItem, o as ContextMenuSeparator, cx as Code, bk as EDITOR_LABELS, k as ContextMenu, l as ContextMenuTrigger, aE as webUIBaseUrl, aa as ChevronRight, cy as MessageSquare, cz as FolderPlus, P as Pencil, T as Trash2, cA as useProjectState, cB as TabsContent } from "./index-LmYTNvdF.js";
|
|
3
|
+
import { S as Settings2 } from "./settings-2-DRhoXOO8.js";
|
|
4
|
+
import { i as isValidMessageToDisplay, M as MessageBubble, A as ArrowUpToLine, S as Square, j as jsonToPrettyYamlExports, p as parseFileReference, c as CodeCompareView, r as resolveFileUrl, I as ImageView, P as PdfView, D as DocxView, a as PptxView, X as XlsxView, R as RotateCcw, F as Folders } from "./xlsx-view-Bv0YhA5m.js";
|
|
5
|
+
import { M as Mic, C as Clipboard } from "./mic-BgSvicCB.js";
|
|
6
|
+
import { I as Image, W as Wrench } from "./wrench-7r-g9MUq.js";
|
|
7
|
+
import { F as FileText } from "./file-text-nGCW6zu1.js";
|
|
8
|
+
import { A as ArrowLeft } from "./arrow-left-CxS1t3f7.js";
|
|
9
|
+
import { aQ as CodeView, S as StreamMarkdown, aR as FileIcon } from "./mermaid-GHXKKRXX-CZqkhGx7.js";
|
|
10
|
+
import { S as Search } from "./search-BEY9yGF_.js";
|
|
11
|
+
import { E as ExternalLink } from "./link-2-DHUPzNSt.js";
|
|
12
|
+
import { R as RefreshCw } from "./refresh-cw-Bvm578nW.js";
|
|
13
|
+
import { P as Plus } from "./plus-YNCXW-GD.js";
|
|
14
|
+
import { R as ResizablePanelGroup, a as ResizablePanel, b as ResizableHandle } from "./resizable-cStzNJ8V.js";
|
|
15
|
+
import "./collapsible-CMuCJUWG.js";
|
|
16
|
+
import "./item-BHEUMM9H.js";
|
|
18
17
|
import "./schemas-c0X-G5_P.js";
|
|
19
|
-
import "./ellipsis-
|
|
20
|
-
const __iconNode$
|
|
18
|
+
import "./ellipsis-D1agTYu1.js";
|
|
19
|
+
const __iconNode$k = [
|
|
21
20
|
["path", { d: "M12 5v14", key: "s699le" }],
|
|
22
21
|
["path", { d: "m19 12-7 7-7-7", key: "1idqje" }]
|
|
23
22
|
];
|
|
24
|
-
const ArrowDown = createLucideIcon("arrow-down", __iconNode$
|
|
25
|
-
const __iconNode$
|
|
23
|
+
const ArrowDown = createLucideIcon("arrow-down", __iconNode$k);
|
|
24
|
+
const __iconNode$j = [
|
|
26
25
|
["path", { d: "M5 12h14", key: "1ays0h" }],
|
|
27
26
|
["path", { d: "m12 5 7 7-7 7", key: "xquz4c" }]
|
|
28
27
|
];
|
|
29
|
-
const ArrowRight = createLucideIcon("arrow-right", __iconNode$
|
|
30
|
-
const __iconNode$
|
|
28
|
+
const ArrowRight = createLucideIcon("arrow-right", __iconNode$j);
|
|
29
|
+
const __iconNode$i = [
|
|
31
30
|
["path", { d: "m5 12 7-7 7 7", key: "hav0vg" }],
|
|
32
31
|
["path", { d: "M12 19V5", key: "x0mq9r" }]
|
|
33
32
|
];
|
|
34
|
-
const ArrowUp = createLucideIcon("arrow-up", __iconNode$
|
|
35
|
-
const __iconNode$
|
|
33
|
+
const ArrowUp = createLucideIcon("arrow-up", __iconNode$i);
|
|
34
|
+
const __iconNode$h = [
|
|
36
35
|
[
|
|
37
36
|
"path",
|
|
38
37
|
{
|
|
@@ -41,20 +40,20 @@ const __iconNode$e = [
|
|
|
41
40
|
}
|
|
42
41
|
]
|
|
43
42
|
];
|
|
44
|
-
const Astroid = createLucideIcon("astroid", __iconNode$
|
|
45
|
-
const __iconNode$
|
|
43
|
+
const Astroid = createLucideIcon("astroid", __iconNode$h);
|
|
44
|
+
const __iconNode$g = [
|
|
46
45
|
["circle", { cx: "12", cy: "12", r: "4", key: "4exip2" }],
|
|
47
46
|
["path", { d: "M16 8v5a3 3 0 0 0 6 0v-1a10 10 0 1 0-4 8", key: "7n84p3" }]
|
|
48
47
|
];
|
|
49
|
-
const AtSign = createLucideIcon("at-sign", __iconNode$
|
|
50
|
-
const __iconNode$
|
|
51
|
-
const Circle = createLucideIcon("circle", __iconNode$
|
|
52
|
-
const __iconNode$
|
|
48
|
+
const AtSign = createLucideIcon("at-sign", __iconNode$g);
|
|
49
|
+
const __iconNode$f = [["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }]];
|
|
50
|
+
const Circle = createLucideIcon("circle", __iconNode$f);
|
|
51
|
+
const __iconNode$e = [
|
|
53
52
|
["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
|
|
54
53
|
["path", { d: "M12 2a7 7 0 1 0 10 10", key: "1yuj32" }]
|
|
55
54
|
];
|
|
56
|
-
const Eclipse = createLucideIcon("eclipse", __iconNode$
|
|
57
|
-
const __iconNode$
|
|
55
|
+
const Eclipse = createLucideIcon("eclipse", __iconNode$e);
|
|
56
|
+
const __iconNode$d = [
|
|
58
57
|
[
|
|
59
58
|
"path",
|
|
60
59
|
{
|
|
@@ -66,34 +65,58 @@ const __iconNode$a = [
|
|
|
66
65
|
["path", { d: "M9 15h6", key: "cctwl0" }],
|
|
67
66
|
["path", { d: "M12 18v-6", key: "17g6i2" }]
|
|
68
67
|
];
|
|
69
|
-
const FilePlus = createLucideIcon("file-plus", __iconNode$
|
|
70
|
-
const __iconNode$
|
|
68
|
+
const FilePlus = createLucideIcon("file-plus", __iconNode$d);
|
|
69
|
+
const __iconNode$c = [
|
|
71
70
|
["path", { d: "m12 14 4-4", key: "9kzdfg" }],
|
|
72
71
|
["path", { d: "M3.34 19a10 10 0 1 1 17.32 0", key: "19p75a" }]
|
|
73
72
|
];
|
|
74
|
-
const Gauge = createLucideIcon("gauge", __iconNode$
|
|
75
|
-
const __iconNode$
|
|
73
|
+
const Gauge = createLucideIcon("gauge", __iconNode$c);
|
|
74
|
+
const __iconNode$b = [
|
|
76
75
|
["path", { d: "M15 6a9 9 0 0 0-9 9V3", key: "1cii5b" }],
|
|
77
76
|
["circle", { cx: "18", cy: "6", r: "3", key: "1h7g24" }],
|
|
78
77
|
["circle", { cx: "6", cy: "18", r: "3", key: "fqmcym" }]
|
|
79
78
|
];
|
|
80
|
-
const GitBranch = createLucideIcon("git-branch", __iconNode$
|
|
81
|
-
const __iconNode$
|
|
79
|
+
const GitBranch = createLucideIcon("git-branch", __iconNode$b);
|
|
80
|
+
const __iconNode$a = [
|
|
82
81
|
["line", { x1: "4", x2: "20", y1: "9", y2: "9", key: "4lhtct" }],
|
|
83
82
|
["line", { x1: "4", x2: "20", y1: "15", y2: "15", key: "vyu0kd" }],
|
|
84
83
|
["line", { x1: "10", x2: "8", y1: "3", y2: "21", key: "1ggp8o" }],
|
|
85
84
|
["line", { x1: "16", x2: "14", y1: "3", y2: "21", key: "weycgp" }]
|
|
86
85
|
];
|
|
87
|
-
const Hash = createLucideIcon("hash", __iconNode$
|
|
88
|
-
const __iconNode$
|
|
86
|
+
const Hash = createLucideIcon("hash", __iconNode$a);
|
|
87
|
+
const __iconNode$9 = [
|
|
88
|
+
[
|
|
89
|
+
"path",
|
|
90
|
+
{
|
|
91
|
+
d: "M12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83z",
|
|
92
|
+
key: "zw3jo"
|
|
93
|
+
}
|
|
94
|
+
],
|
|
95
|
+
[
|
|
96
|
+
"path",
|
|
97
|
+
{
|
|
98
|
+
d: "M2 12a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 12",
|
|
99
|
+
key: "1wduqc"
|
|
100
|
+
}
|
|
101
|
+
],
|
|
102
|
+
[
|
|
103
|
+
"path",
|
|
104
|
+
{
|
|
105
|
+
d: "M2 17a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 17",
|
|
106
|
+
key: "kqbvx6"
|
|
107
|
+
}
|
|
108
|
+
]
|
|
109
|
+
];
|
|
110
|
+
const Layers = createLucideIcon("layers", __iconNode$9);
|
|
111
|
+
const __iconNode$8 = [
|
|
89
112
|
["path", { d: "M3 5h8", key: "18g2rq" }],
|
|
90
113
|
["path", { d: "M3 12h8", key: "1xfjp6" }],
|
|
91
114
|
["path", { d: "M3 19h8", key: "fpbke4" }],
|
|
92
115
|
["path", { d: "m15 5 3 3 3-3", key: "1t4thf" }],
|
|
93
116
|
["path", { d: "m15 19 3-3 3 3", key: "y4ckd2" }]
|
|
94
117
|
];
|
|
95
|
-
const ListChevronsDownUp = createLucideIcon("list-chevrons-down-up", __iconNode$
|
|
96
|
-
const __iconNode$
|
|
118
|
+
const ListChevronsDownUp = createLucideIcon("list-chevrons-down-up", __iconNode$8);
|
|
119
|
+
const __iconNode$7 = [
|
|
97
120
|
[
|
|
98
121
|
"path",
|
|
99
122
|
{
|
|
@@ -104,8 +127,25 @@ const __iconNode$5 = [
|
|
|
104
127
|
["path", { d: "M12 8v6", key: "1ib9pf" }],
|
|
105
128
|
["path", { d: "M9 11h6", key: "1fldmi" }]
|
|
106
129
|
];
|
|
107
|
-
const MessageSquarePlus = createLucideIcon("message-square-plus", __iconNode$
|
|
108
|
-
const __iconNode$
|
|
130
|
+
const MessageSquarePlus = createLucideIcon("message-square-plus", __iconNode$7);
|
|
131
|
+
const __iconNode$6 = [
|
|
132
|
+
[
|
|
133
|
+
"path",
|
|
134
|
+
{
|
|
135
|
+
d: "M16 10a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 14.286V4a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z",
|
|
136
|
+
key: "1n2ejm"
|
|
137
|
+
}
|
|
138
|
+
],
|
|
139
|
+
[
|
|
140
|
+
"path",
|
|
141
|
+
{
|
|
142
|
+
d: "M20 9a2 2 0 0 1 2 2v10.286a.71.71 0 0 1-1.212.502l-2.202-2.202A2 2 0 0 0 17.172 19H10a2 2 0 0 1-2-2v-1",
|
|
143
|
+
key: "1qfcsi"
|
|
144
|
+
}
|
|
145
|
+
]
|
|
146
|
+
];
|
|
147
|
+
const MessagesSquare = createLucideIcon("messages-square", __iconNode$6);
|
|
148
|
+
const __iconNode$5 = [
|
|
109
149
|
[
|
|
110
150
|
"path",
|
|
111
151
|
{
|
|
@@ -114,8 +154,8 @@ const __iconNode$4 = [
|
|
|
114
154
|
}
|
|
115
155
|
]
|
|
116
156
|
];
|
|
117
|
-
const Paperclip = createLucideIcon("paperclip", __iconNode$
|
|
118
|
-
const __iconNode$
|
|
157
|
+
const Paperclip = createLucideIcon("paperclip", __iconNode$5);
|
|
158
|
+
const __iconNode$4 = [
|
|
119
159
|
["path", { d: "M10 7v10a5 5 0 0 0 5-5", key: "1blmz7" }],
|
|
120
160
|
["path", { d: "m14 8-6 3", key: "2tb98i" }],
|
|
121
161
|
[
|
|
@@ -126,13 +166,13 @@ const __iconNode$3 = [
|
|
|
126
166
|
}
|
|
127
167
|
]
|
|
128
168
|
];
|
|
129
|
-
const ReceiptTurkishLira = createLucideIcon("receipt-turkish-lira", __iconNode$
|
|
130
|
-
const __iconNode$
|
|
169
|
+
const ReceiptTurkishLira = createLucideIcon("receipt-turkish-lira", __iconNode$4);
|
|
170
|
+
const __iconNode$3 = [
|
|
131
171
|
["path", { d: "M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8", key: "1p45f6" }],
|
|
132
172
|
["path", { d: "M21 3v5h-5", key: "1q7to0" }]
|
|
133
173
|
];
|
|
134
|
-
const RotateCw = createLucideIcon("rotate-cw", __iconNode$
|
|
135
|
-
const __iconNode$
|
|
174
|
+
const RotateCw = createLucideIcon("rotate-cw", __iconNode$3);
|
|
175
|
+
const __iconNode$2 = [
|
|
136
176
|
[
|
|
137
177
|
"path",
|
|
138
178
|
{
|
|
@@ -143,13 +183,23 @@ const __iconNode$1 = [
|
|
|
143
183
|
["path", { d: "M17 21v-7a1 1 0 0 0-1-1H8a1 1 0 0 0-1 1v7", key: "1ydtos" }],
|
|
144
184
|
["path", { d: "M7 3v4a1 1 0 0 0 1 1h7", key: "t51u73" }]
|
|
145
185
|
];
|
|
146
|
-
const Save = createLucideIcon("save", __iconNode$
|
|
147
|
-
const __iconNode = [
|
|
186
|
+
const Save = createLucideIcon("save", __iconNode$2);
|
|
187
|
+
const __iconNode$1 = [
|
|
148
188
|
["path", { d: "m7 11 2-2-2-2", key: "1lz0vl" }],
|
|
149
189
|
["path", { d: "M11 13h4", key: "1p7l4v" }],
|
|
150
190
|
["rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", ry: "2", key: "1m3agn" }]
|
|
151
191
|
];
|
|
152
|
-
const SquareTerminal = createLucideIcon("square-terminal", __iconNode);
|
|
192
|
+
const SquareTerminal = createLucideIcon("square-terminal", __iconNode$1);
|
|
193
|
+
const __iconNode = [
|
|
194
|
+
[
|
|
195
|
+
"path",
|
|
196
|
+
{
|
|
197
|
+
d: "M15.914 4a1.5 1.5 0 00-2.474-1.561l-9 9A1.5 1.5 0 005.5 14h4.002a.5.5 0 01.471.666L8.086 20a1.5 1.5 0 002.475 1.56l9-9A1.5 1.5 0 0018.5 10h-3.997a.5.5 0 01-.472-.667z",
|
|
198
|
+
key: "1v7up4"
|
|
199
|
+
}
|
|
200
|
+
]
|
|
201
|
+
];
|
|
202
|
+
const Zap = createLucideIcon("zap", __iconNode);
|
|
153
203
|
const PopoverRootContext = /* @__PURE__ */ reactExports.createContext(void 0);
|
|
154
204
|
function usePopoverRootContext(optional) {
|
|
155
205
|
const context = reactExports.useContext(PopoverRootContext);
|
|
@@ -626,6 +676,12 @@ function useClosePartCount() {
|
|
|
626
676
|
hasClosePart: closePartCount > 0
|
|
627
677
|
};
|
|
628
678
|
}
|
|
679
|
+
function useClosePartRegistration() {
|
|
680
|
+
const context = reactExports.useContext(ClosePartContext);
|
|
681
|
+
useIsoLayoutEffect(() => {
|
|
682
|
+
return context?.register();
|
|
683
|
+
}, [context]);
|
|
684
|
+
}
|
|
629
685
|
const PopoverPopup = /* @__PURE__ */ reactExports.forwardRef(function PopoverPopup2(componentProps, forwardedRef) {
|
|
630
686
|
const {
|
|
631
687
|
render,
|
|
@@ -716,6 +772,35 @@ const PopoverPopup = /* @__PURE__ */ reactExports.forwardRef(function PopoverPop
|
|
|
716
772
|
})
|
|
717
773
|
});
|
|
718
774
|
});
|
|
775
|
+
const PopoverClose = /* @__PURE__ */ reactExports.forwardRef(function PopoverClose2(componentProps, forwardedRef) {
|
|
776
|
+
const {
|
|
777
|
+
render,
|
|
778
|
+
className,
|
|
779
|
+
style,
|
|
780
|
+
disabled = false,
|
|
781
|
+
nativeButton = true,
|
|
782
|
+
...elementProps
|
|
783
|
+
} = componentProps;
|
|
784
|
+
const {
|
|
785
|
+
buttonRef,
|
|
786
|
+
getButtonProps
|
|
787
|
+
} = useButton({
|
|
788
|
+
disabled,
|
|
789
|
+
focusableWhenDisabled: false,
|
|
790
|
+
native: nativeButton
|
|
791
|
+
});
|
|
792
|
+
const store = usePopoverRootContext();
|
|
793
|
+
useClosePartRegistration();
|
|
794
|
+
const element = useRenderElement("button", componentProps, {
|
|
795
|
+
ref: [forwardedRef, buttonRef],
|
|
796
|
+
props: [{
|
|
797
|
+
onClick(event) {
|
|
798
|
+
store.setOpen(false, createChangeEventDetails(closePress, event.nativeEvent));
|
|
799
|
+
}
|
|
800
|
+
}, elementProps, getButtonProps]
|
|
801
|
+
});
|
|
802
|
+
return element;
|
|
803
|
+
});
|
|
719
804
|
function ChatHeader({ session }) {
|
|
720
805
|
const { t } = useTranslation();
|
|
721
806
|
const { toast } = useMessage();
|
|
@@ -836,20 +921,34 @@ function ChatHeader({ session }) {
|
|
|
836
921
|
children: [
|
|
837
922
|
/* @__PURE__ */ jsxRuntimeExports.jsx(PopoverTrigger, { className: "flex size-7 items-center justify-center rounded-md text-sidebar-foreground/45 hover:bg-sidebar-accent/30 hover:text-sidebar-foreground/70 outline-none transition-colors data-pressed:bg-sidebar-accent/40", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Settings2, { className: "size-4" }) }),
|
|
838
923
|
/* @__PURE__ */ jsxRuntimeExports.jsx(PopoverPortal, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(PopoverPositioner, { side: "bottom", align: "end", sideOffset: 4, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(PopoverPopup, { className: "z-10 min-w-96 rounded-lg border border-border bg-popover text-popover-foreground shadow-lg outline-none p-1.5 origin-(--transform-origin) data-ending-style:scale-90 data-starting-style:scale-90 data-ending-style:opacity-0 data-starting-style:opacity-0 transition-[transform,opacity] duration-100", children: [
|
|
839
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
924
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-1 py-1", children: [
|
|
925
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "px-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
926
|
+
CopyableRow,
|
|
927
|
+
{
|
|
928
|
+
label: t("chatHeader.sessionId", "Session"),
|
|
929
|
+
value: session.id,
|
|
930
|
+
openFolderTitle: t("chatHeader.openSessionFolder", "Open Session Folder"),
|
|
931
|
+
onOpenFolder: async () => {
|
|
932
|
+
const dirPath = await request.getSessionDataSystemPath({
|
|
933
|
+
sessionId: session.id
|
|
934
|
+
});
|
|
935
|
+
if (dirPath) electron.revealInFinder(dirPath);
|
|
936
|
+
}
|
|
850
937
|
}
|
|
851
|
-
}
|
|
852
|
-
|
|
938
|
+
) }),
|
|
939
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "px-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
940
|
+
CopyableRow,
|
|
941
|
+
{
|
|
942
|
+
label: t("chatHeader.projectId", "Project"),
|
|
943
|
+
value: currentProjectInfo?.cwd ?? session.projectTitle,
|
|
944
|
+
openFolderTitle: t("chatHeader.openProjectFolder", "Open Project Folder"),
|
|
945
|
+
onOpenFolder: async () => {
|
|
946
|
+
const dirPath = currentProjectInfo?.cwd;
|
|
947
|
+
if (dirPath) electron.revealInFinder(dirPath);
|
|
948
|
+
}
|
|
949
|
+
}
|
|
950
|
+
) })
|
|
951
|
+
] }),
|
|
853
952
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "border-t border-border/50 my-1" }),
|
|
854
953
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "px-2 py-1 text-xs font-semibold text-foreground/80", children: t("constant.feature.title", "Features") }),
|
|
855
954
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: ALL_FEATURES.length >= 2 ? "grid grid-cols-2 gap-0.5" : "", children: ALL_FEATURES.map((feature) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
@@ -961,7 +1060,11 @@ function ChatHeader({ session }) {
|
|
|
961
1060
|
}
|
|
962
1061
|
function UsageButton({ session }) {
|
|
963
1062
|
const { t } = useTranslation();
|
|
1063
|
+
const configuredAgents = useAppStore((s15) => s15.configuredAgents);
|
|
964
1064
|
const { lastTurnUsage, usage } = session;
|
|
1065
|
+
const isApiAgent = configuredAgents.some(
|
|
1066
|
+
(agent) => agent.id === session.agentId && agent.type === "api"
|
|
1067
|
+
);
|
|
965
1068
|
const hasData = usage || lastTurnUsage;
|
|
966
1069
|
if (!hasData) return null;
|
|
967
1070
|
const pct = usage?.size ? usage.used / usage.size * 100 : 0;
|
|
@@ -1022,7 +1125,21 @@ function UsageButton({ session }) {
|
|
|
1022
1125
|
}
|
|
1023
1126
|
)
|
|
1024
1127
|
] })
|
|
1025
|
-
] }) })
|
|
1128
|
+
] }) }),
|
|
1129
|
+
isApiAgent && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
1130
|
+
PopoverClose,
|
|
1131
|
+
{
|
|
1132
|
+
className: buttonVariants({
|
|
1133
|
+
variant: "outline",
|
|
1134
|
+
size: "xs",
|
|
1135
|
+
className: "w-full py-3 font-normal border-border!"
|
|
1136
|
+
}),
|
|
1137
|
+
onClick: () => {
|
|
1138
|
+
document.dispatchEvent(new CustomEvent("fello-open-token-usage"));
|
|
1139
|
+
},
|
|
1140
|
+
children: t("chatHeader.viewBreakdown", "View Breakdown")
|
|
1141
|
+
}
|
|
1142
|
+
)
|
|
1026
1143
|
] }) }) }) })
|
|
1027
1144
|
] });
|
|
1028
1145
|
}
|
|
@@ -4210,109 +4327,642 @@ function nodesToMentionText(nodes) {
|
|
|
4210
4327
|
return `@[${prefix}${n.name}](${n.id})`;
|
|
4211
4328
|
}).join(" ");
|
|
4212
4329
|
}
|
|
4213
|
-
|
|
4214
|
-
|
|
4215
|
-
|
|
4216
|
-
|
|
4217
|
-
|
|
4218
|
-
|
|
4219
|
-
|
|
4220
|
-
|
|
4221
|
-
|
|
4222
|
-
|
|
4330
|
+
const TARGET_SAMPLE_RATE = 16e3;
|
|
4331
|
+
const FRAME_SAMPLES = 320;
|
|
4332
|
+
const workletSource = `
|
|
4333
|
+
class FelloPcmProcessor extends AudioWorkletProcessor {
|
|
4334
|
+
constructor() {
|
|
4335
|
+
super();
|
|
4336
|
+
this.buffer = [];
|
|
4337
|
+
this.position = 0;
|
|
4338
|
+
this.output = [];
|
|
4339
|
+
this.ratio = sampleRate / ${TARGET_SAMPLE_RATE};
|
|
4340
|
+
}
|
|
4341
|
+
process(inputs, outputs) {
|
|
4342
|
+
const input = inputs[0] && inputs[0][0];
|
|
4343
|
+
if (input) {
|
|
4344
|
+
for (let i = 0; i < input.length; i++) this.buffer.push(input[i]);
|
|
4345
|
+
while (this.position + 1 < this.buffer.length) {
|
|
4346
|
+
const index = Math.floor(this.position);
|
|
4347
|
+
const fraction = this.position - index;
|
|
4348
|
+
const sample = this.buffer[index] * (1 - fraction) + this.buffer[index + 1] * fraction;
|
|
4349
|
+
const clamped = Math.max(-1, Math.min(1, sample));
|
|
4350
|
+
this.output.push(clamped < 0 ? clamped * 32768 : clamped * 32767);
|
|
4351
|
+
this.position += this.ratio;
|
|
4352
|
+
if (this.output.length >= ${FRAME_SAMPLES}) {
|
|
4353
|
+
const pcm = new Int16Array(${FRAME_SAMPLES});
|
|
4354
|
+
for (let i = 0; i < ${FRAME_SAMPLES}; i++) pcm[i] = this.output[i];
|
|
4355
|
+
this.output = this.output.slice(${FRAME_SAMPLES});
|
|
4356
|
+
this.port.postMessage(pcm.buffer, [pcm.buffer]);
|
|
4357
|
+
}
|
|
4358
|
+
}
|
|
4359
|
+
const remove = Math.max(0, Math.floor(this.position));
|
|
4360
|
+
if (remove > 0) {
|
|
4361
|
+
this.buffer = this.buffer.slice(remove);
|
|
4362
|
+
this.position -= remove;
|
|
4363
|
+
}
|
|
4364
|
+
}
|
|
4365
|
+
const output = outputs[0] && outputs[0][0];
|
|
4366
|
+
if (output) output.fill(0);
|
|
4367
|
+
return true;
|
|
4368
|
+
}
|
|
4223
4369
|
}
|
|
4224
|
-
|
|
4225
|
-
|
|
4226
|
-
|
|
4227
|
-
|
|
4228
|
-
|
|
4229
|
-
|
|
4230
|
-
|
|
4231
|
-
|
|
4370
|
+
registerProcessor("fello-pcm-processor", FelloPcmProcessor);
|
|
4371
|
+
`;
|
|
4372
|
+
function arrayBufferToBase64(buffer) {
|
|
4373
|
+
const bytes = new Uint8Array(buffer);
|
|
4374
|
+
let binary = "";
|
|
4375
|
+
const chunkSize = 32768;
|
|
4376
|
+
for (let offset = 0; offset < bytes.length; offset += chunkSize) {
|
|
4377
|
+
binary += String.fromCharCode(...bytes.subarray(offset, offset + chunkSize));
|
|
4378
|
+
}
|
|
4379
|
+
return btoa(binary);
|
|
4232
4380
|
}
|
|
4233
|
-
function
|
|
4234
|
-
return
|
|
4235
|
-
|
|
4236
|
-
|
|
4237
|
-
|
|
4238
|
-
|
|
4239
|
-
|
|
4240
|
-
|
|
4381
|
+
function errorMessage(error) {
|
|
4382
|
+
return error instanceof Error ? error.message : String(error);
|
|
4383
|
+
}
|
|
4384
|
+
function useRealtimeAsr(options) {
|
|
4385
|
+
const { onTranscript, onError, onRecordingChange } = options;
|
|
4386
|
+
const configured = useAppStore((state) => state.speechToText.some((provider) => provider.active));
|
|
4387
|
+
const [recording, setRecording] = reactExports.useState(false);
|
|
4388
|
+
const [audioLevel, setAudioLevel] = reactExports.useState(0);
|
|
4389
|
+
const [inputDevices, setInputDevices] = reactExports.useState([]);
|
|
4390
|
+
const asrSessionIdRef = reactExports.useRef(null);
|
|
4391
|
+
const streamRef = reactExports.useRef(null);
|
|
4392
|
+
const audioContextRef = reactExports.useRef(null);
|
|
4393
|
+
const sourceRef = reactExports.useRef(null);
|
|
4394
|
+
const nodeRef = reactExports.useRef(null);
|
|
4395
|
+
const stoppedRef = reactExports.useRef(false);
|
|
4396
|
+
const stoppingRef = reactExports.useRef(false);
|
|
4397
|
+
const recordingRef = reactExports.useRef(false);
|
|
4398
|
+
const audioLevelValueRef = reactExports.useRef(0);
|
|
4399
|
+
const audioLevelFrameRef = reactExports.useRef(null);
|
|
4400
|
+
const stopRef = reactExports.useRef(async () => {
|
|
4401
|
+
});
|
|
4402
|
+
const callbacksRef = reactExports.useRef({ onTranscript, onError, onRecordingChange });
|
|
4403
|
+
callbacksRef.current = { onTranscript, onError, onRecordingChange };
|
|
4404
|
+
const setRecordingState = reactExports.useCallback((value) => {
|
|
4405
|
+
recordingRef.current = value;
|
|
4406
|
+
setRecording(value);
|
|
4407
|
+
callbacksRef.current.onRecordingChange?.(value);
|
|
4408
|
+
}, []);
|
|
4409
|
+
reactExports.useEffect(() => {
|
|
4410
|
+
const handleTranscript = (event) => {
|
|
4411
|
+
if (event.clientId !== clientId || event.asrSessionId !== asrSessionIdRef.current) return;
|
|
4412
|
+
callbacksRef.current.onTranscript?.({
|
|
4413
|
+
text: event.text,
|
|
4414
|
+
isFinal: event.isFinal,
|
|
4415
|
+
id: event.id,
|
|
4416
|
+
index: event.index
|
|
4417
|
+
});
|
|
4418
|
+
};
|
|
4419
|
+
const handleError = (event) => {
|
|
4420
|
+
if (event.clientId !== clientId || event.asrSessionId !== asrSessionIdRef.current) return;
|
|
4421
|
+
callbacksRef.current.onError?.(event.message);
|
|
4422
|
+
};
|
|
4423
|
+
const handleClosed = (event) => {
|
|
4424
|
+
if (event.clientId !== clientId || event.asrSessionId !== asrSessionIdRef.current) return;
|
|
4425
|
+
if (recordingRef.current && !stoppingRef.current) {
|
|
4426
|
+
callbacksRef.current.onError?.("实时语音识别连接已关闭。");
|
|
4427
|
+
void stopRef.current();
|
|
4428
|
+
}
|
|
4429
|
+
};
|
|
4430
|
+
subscribe.on("asr-transcript", handleTranscript);
|
|
4431
|
+
subscribe.on("asr-error", handleError);
|
|
4432
|
+
subscribe.on("asr-closed", handleClosed);
|
|
4433
|
+
return () => {
|
|
4434
|
+
subscribe.off("asr-transcript", handleTranscript);
|
|
4435
|
+
subscribe.off("asr-error", handleError);
|
|
4436
|
+
subscribe.off("asr-closed", handleClosed);
|
|
4437
|
+
};
|
|
4438
|
+
}, [setRecordingState]);
|
|
4439
|
+
const updateAudioLevel = reactExports.useCallback((buffer) => {
|
|
4440
|
+
const samples = new Int16Array(buffer);
|
|
4441
|
+
if (samples.length === 0) return;
|
|
4442
|
+
let sumSquares = 0;
|
|
4443
|
+
for (const sample of samples) {
|
|
4444
|
+
const normalized = sample / 32768;
|
|
4445
|
+
sumSquares += normalized * normalized;
|
|
4446
|
+
}
|
|
4447
|
+
const rms = Math.sqrt(sumSquares / samples.length);
|
|
4448
|
+
audioLevelValueRef.current = Math.min(1, rms * 4);
|
|
4449
|
+
if (audioLevelFrameRef.current !== null) return;
|
|
4450
|
+
audioLevelFrameRef.current = requestAnimationFrame(() => {
|
|
4451
|
+
audioLevelFrameRef.current = null;
|
|
4452
|
+
setAudioLevel(audioLevelValueRef.current);
|
|
4453
|
+
});
|
|
4454
|
+
}, []);
|
|
4455
|
+
const cleanupAudio = reactExports.useCallback(async () => {
|
|
4456
|
+
if (audioLevelFrameRef.current !== null) {
|
|
4457
|
+
cancelAnimationFrame(audioLevelFrameRef.current);
|
|
4458
|
+
audioLevelFrameRef.current = null;
|
|
4459
|
+
}
|
|
4460
|
+
audioLevelValueRef.current = 0;
|
|
4461
|
+
setAudioLevel(0);
|
|
4462
|
+
nodeRef.current?.disconnect();
|
|
4463
|
+
sourceRef.current?.disconnect();
|
|
4464
|
+
streamRef.current?.getTracks().forEach((track) => track.stop());
|
|
4465
|
+
streamRef.current = null;
|
|
4466
|
+
nodeRef.current = null;
|
|
4467
|
+
sourceRef.current = null;
|
|
4468
|
+
const context = audioContextRef.current;
|
|
4469
|
+
audioContextRef.current = null;
|
|
4470
|
+
await context?.close().catch(() => void 0);
|
|
4471
|
+
}, []);
|
|
4472
|
+
const refreshInputDevices = reactExports.useCallback(async () => {
|
|
4473
|
+
if (!navigator.mediaDevices?.enumerateDevices) return [];
|
|
4474
|
+
try {
|
|
4475
|
+
let devices = await navigator.mediaDevices.enumerateDevices();
|
|
4476
|
+
if (devices.length > 0 && devices.every((device) => !device.label)) {
|
|
4477
|
+
try {
|
|
4478
|
+
const permissionStream = await navigator.mediaDevices.getUserMedia({ audio: true });
|
|
4479
|
+
permissionStream.getTracks().forEach((track) => track.stop());
|
|
4480
|
+
devices = await navigator.mediaDevices.enumerateDevices();
|
|
4481
|
+
} catch {
|
|
4482
|
+
}
|
|
4483
|
+
}
|
|
4484
|
+
const audioInputs = devices.filter((device) => device.kind === "audioinput").map((device, index) => ({
|
|
4485
|
+
deviceId: device.deviceId,
|
|
4486
|
+
label: device.label || `Microphone ${index + 1}`
|
|
4487
|
+
}));
|
|
4488
|
+
setInputDevices(audioInputs);
|
|
4489
|
+
return audioInputs;
|
|
4490
|
+
} catch (error) {
|
|
4491
|
+
callbacksRef.current.onError?.(errorMessage(error));
|
|
4492
|
+
return [];
|
|
4241
4493
|
}
|
|
4242
|
-
|
|
4243
|
-
|
|
4244
|
-
|
|
4245
|
-
|
|
4246
|
-
|
|
4494
|
+
}, []);
|
|
4495
|
+
const start = reactExports.useCallback(
|
|
4496
|
+
async (deviceId = "default") => {
|
|
4497
|
+
if (recordingRef.current || !configured) return;
|
|
4498
|
+
const asrSessionId = `asr_${Date.now()}_${Math.random().toString(36).slice(2)}`;
|
|
4499
|
+
asrSessionIdRef.current = asrSessionId;
|
|
4500
|
+
stoppedRef.current = false;
|
|
4501
|
+
stoppingRef.current = false;
|
|
4502
|
+
try {
|
|
4503
|
+
const stream = await navigator.mediaDevices.getUserMedia({
|
|
4504
|
+
audio: {
|
|
4505
|
+
channelCount: 1,
|
|
4506
|
+
echoCancellation: true,
|
|
4507
|
+
noiseSuppression: true,
|
|
4508
|
+
...deviceId !== "default" ? { deviceId: { exact: deviceId } } : {}
|
|
4509
|
+
}
|
|
4510
|
+
});
|
|
4511
|
+
streamRef.current = stream;
|
|
4512
|
+
const audioContext = new AudioContext();
|
|
4513
|
+
audioContextRef.current = audioContext;
|
|
4514
|
+
await audioContext.resume();
|
|
4515
|
+
const workletUrl = URL.createObjectURL(
|
|
4516
|
+
new Blob([workletSource], { type: "application/javascript" })
|
|
4517
|
+
);
|
|
4518
|
+
try {
|
|
4519
|
+
await audioContext.audioWorklet.addModule(workletUrl);
|
|
4520
|
+
} finally {
|
|
4521
|
+
URL.revokeObjectURL(workletUrl);
|
|
4522
|
+
}
|
|
4523
|
+
const source = audioContext.createMediaStreamSource(stream);
|
|
4524
|
+
const node = new AudioWorkletNode(audioContext, "fello-pcm-processor");
|
|
4525
|
+
const silentGain = audioContext.createGain();
|
|
4526
|
+
silentGain.gain.value = 0;
|
|
4527
|
+
node.port.onmessage = (message) => {
|
|
4528
|
+
if (stoppedRef.current || asrSessionIdRef.current !== asrSessionId) return;
|
|
4529
|
+
updateAudioLevel(message.data);
|
|
4530
|
+
void request.sendRealtimeAsrFrame({
|
|
4531
|
+
clientId,
|
|
4532
|
+
asrSessionId,
|
|
4533
|
+
audioB64: arrayBufferToBase64(message.data)
|
|
4534
|
+
}).catch((error) => callbacksRef.current.onError?.(errorMessage(error)));
|
|
4535
|
+
};
|
|
4536
|
+
sourceRef.current = source;
|
|
4537
|
+
nodeRef.current = node;
|
|
4538
|
+
await request.startRealtimeAsr({ clientId, asrSessionId });
|
|
4539
|
+
source.connect(node);
|
|
4540
|
+
node.connect(silentGain);
|
|
4541
|
+
silentGain.connect(audioContext.destination);
|
|
4542
|
+
setRecordingState(true);
|
|
4543
|
+
} catch (error) {
|
|
4544
|
+
await cleanupAudio();
|
|
4545
|
+
await request.stopRealtimeAsr({ clientId, asrSessionId }).catch(() => void 0);
|
|
4546
|
+
asrSessionIdRef.current = null;
|
|
4547
|
+
callbacksRef.current.onError?.(errorMessage(error));
|
|
4548
|
+
setRecordingState(false);
|
|
4247
4549
|
}
|
|
4550
|
+
},
|
|
4551
|
+
[cleanupAudio, configured, setRecordingState, updateAudioLevel]
|
|
4552
|
+
);
|
|
4553
|
+
const stop = reactExports.useCallback(async () => {
|
|
4554
|
+
const asrSessionId = asrSessionIdRef.current;
|
|
4555
|
+
if (!asrSessionId) return;
|
|
4556
|
+
stoppedRef.current = true;
|
|
4557
|
+
stoppingRef.current = true;
|
|
4558
|
+
await cleanupAudio();
|
|
4559
|
+
await request.stopRealtimeAsr({ clientId, asrSessionId }).catch((error) => {
|
|
4560
|
+
callbacksRef.current.onError?.(errorMessage(error));
|
|
4561
|
+
});
|
|
4562
|
+
asrSessionIdRef.current = null;
|
|
4563
|
+
stoppingRef.current = false;
|
|
4564
|
+
setRecordingState(false);
|
|
4565
|
+
}, [cleanupAudio, setRecordingState]);
|
|
4566
|
+
stopRef.current = stop;
|
|
4567
|
+
reactExports.useEffect(() => {
|
|
4568
|
+
return () => {
|
|
4569
|
+
stoppedRef.current = true;
|
|
4570
|
+
void stopRef.current();
|
|
4248
4571
|
};
|
|
4249
|
-
});
|
|
4572
|
+
}, []);
|
|
4573
|
+
const toggle = reactExports.useCallback(() => {
|
|
4574
|
+
void (recordingRef.current ? stop() : start());
|
|
4575
|
+
}, [start, stop]);
|
|
4576
|
+
return {
|
|
4577
|
+
recording,
|
|
4578
|
+
audioLevel,
|
|
4579
|
+
configured,
|
|
4580
|
+
inputDevices,
|
|
4581
|
+
refreshInputDevices,
|
|
4582
|
+
start,
|
|
4583
|
+
stop,
|
|
4584
|
+
toggle
|
|
4585
|
+
};
|
|
4250
4586
|
}
|
|
4251
|
-
|
|
4587
|
+
const ASR_WAVEFORM_BARS = [0.35, 0.65, 0.95, 0.55, 0.8, 0.45, 0.9, 0.6, 0.38];
|
|
4588
|
+
const DEFAULT_MAX_DURATION = 5 * 60 * 1e3;
|
|
4589
|
+
const VOICE_INPUT_DEVICE_STORAGE_KEY = "fello.voice-input.device-id";
|
|
4590
|
+
function getInputCursor(input) {
|
|
4591
|
+
return input.selectionStart ?? input.value.length;
|
|
4592
|
+
}
|
|
4593
|
+
function VoiceInputButton({
|
|
4594
|
+
inputRef,
|
|
4595
|
+
disabled = false,
|
|
4596
|
+
className,
|
|
4597
|
+
maxDuration = DEFAULT_MAX_DURATION,
|
|
4598
|
+
ref
|
|
4599
|
+
}) {
|
|
4252
4600
|
const { t } = useTranslation();
|
|
4253
|
-
const navigate = useNavigate();
|
|
4254
4601
|
const { toast } = useMessage();
|
|
4255
|
-
const
|
|
4256
|
-
const
|
|
4257
|
-
const
|
|
4258
|
-
const
|
|
4259
|
-
const
|
|
4260
|
-
const
|
|
4261
|
-
|
|
4262
|
-
|
|
4263
|
-
|
|
4264
|
-
|
|
4265
|
-
|
|
4266
|
-
const
|
|
4267
|
-
|
|
4268
|
-
|
|
4269
|
-
|
|
4270
|
-
const key =
|
|
4271
|
-
|
|
4272
|
-
|
|
4273
|
-
|
|
4274
|
-
|
|
4275
|
-
|
|
4276
|
-
|
|
4277
|
-
|
|
4278
|
-
|
|
4279
|
-
|
|
4280
|
-
useAppStore.getState().updateSession({
|
|
4281
|
-
...session,
|
|
4282
|
-
models: { ...session.models, currentModelId: modelId }
|
|
4283
|
-
});
|
|
4602
|
+
const asrApplyingRef = reactExports.useRef(false);
|
|
4603
|
+
const asrSegmentsRef = reactExports.useRef(/* @__PURE__ */ new Map());
|
|
4604
|
+
const asrTailRef = reactExports.useRef(0);
|
|
4605
|
+
const asrCurrentKeyRef = reactExports.useRef(null);
|
|
4606
|
+
const asrSequenceRef = reactExports.useRef(0);
|
|
4607
|
+
const freezeAsrSegments = reactExports.useCallback(() => {
|
|
4608
|
+
asrSegmentsRef.current.clear();
|
|
4609
|
+
asrCurrentKeyRef.current = null;
|
|
4610
|
+
const textarea = inputRef.current;
|
|
4611
|
+
if (textarea) asrTailRef.current = getInputCursor(textarea);
|
|
4612
|
+
}, [inputRef]);
|
|
4613
|
+
const applyAsrTranscript = reactExports.useCallback(
|
|
4614
|
+
(transcript) => {
|
|
4615
|
+
const textarea = inputRef.current;
|
|
4616
|
+
if (!textarea) return;
|
|
4617
|
+
const key = transcript.id ? `id:${transcript.id}` : transcript.index !== void 0 ? `index:${transcript.index}` : asrCurrentKeyRef.current ?? `stream:${asrSequenceRef.current++}`;
|
|
4618
|
+
let segment = asrSegmentsRef.current.get(key);
|
|
4619
|
+
if (!segment) {
|
|
4620
|
+
segment = { start: asrTailRef.current, length: 0 };
|
|
4621
|
+
asrSegmentsRef.current.set(key, segment);
|
|
4622
|
+
asrCurrentKeyRef.current = key;
|
|
4623
|
+
}
|
|
4624
|
+
textarea.focus();
|
|
4625
|
+
textarea.setSelectionRange(segment.start, segment.start + segment.length);
|
|
4626
|
+
asrApplyingRef.current = true;
|
|
4284
4627
|
try {
|
|
4285
|
-
|
|
4286
|
-
}
|
|
4287
|
-
|
|
4288
|
-
|
|
4628
|
+
document.execCommand("insertText", false, transcript.text);
|
|
4629
|
+
} finally {
|
|
4630
|
+
asrApplyingRef.current = false;
|
|
4631
|
+
}
|
|
4632
|
+
textarea.ownerDocument.dispatchEvent(new Event("selectionchange"));
|
|
4633
|
+
segment.length = transcript.text.length;
|
|
4634
|
+
asrTailRef.current = segment.start + segment.length;
|
|
4635
|
+
if (transcript.isFinal) {
|
|
4636
|
+
asrSegmentsRef.current.delete(key);
|
|
4637
|
+
asrCurrentKeyRef.current = null;
|
|
4289
4638
|
}
|
|
4290
4639
|
},
|
|
4291
|
-
[
|
|
4640
|
+
[inputRef]
|
|
4292
4641
|
);
|
|
4293
|
-
const
|
|
4294
|
-
|
|
4295
|
-
|
|
4296
|
-
|
|
4297
|
-
|
|
4298
|
-
|
|
4299
|
-
|
|
4300
|
-
|
|
4301
|
-
|
|
4302
|
-
|
|
4303
|
-
|
|
4304
|
-
|
|
4305
|
-
|
|
4642
|
+
const asr = useRealtimeAsr({
|
|
4643
|
+
onTranscript: applyAsrTranscript,
|
|
4644
|
+
onError: (message) => toast.error(message),
|
|
4645
|
+
onRecordingChange: (recording) => {
|
|
4646
|
+
if (!recording) freezeAsrSegments();
|
|
4647
|
+
}
|
|
4648
|
+
});
|
|
4649
|
+
const { start: startAsr, stop: stopAsr, refreshInputDevices } = asr;
|
|
4650
|
+
const handleStop = reactExports.useCallback(async () => {
|
|
4651
|
+
await stopAsr();
|
|
4652
|
+
}, [stopAsr]);
|
|
4653
|
+
reactExports.useImperativeHandle(
|
|
4654
|
+
ref,
|
|
4655
|
+
() => ({
|
|
4656
|
+
stop: handleStop
|
|
4657
|
+
}),
|
|
4658
|
+
[handleStop]
|
|
4659
|
+
);
|
|
4660
|
+
const handleStart = reactExports.useCallback(
|
|
4661
|
+
async (deviceId) => {
|
|
4662
|
+
const textarea = inputRef.current;
|
|
4663
|
+
if (!textarea) return;
|
|
4664
|
+
textarea.focus();
|
|
4665
|
+
const cursorPosition = getInputCursor(textarea);
|
|
4666
|
+
const before = textarea.value.slice(0, cursorPosition);
|
|
4667
|
+
if (before.length > 0 && !/\s$/.test(before)) {
|
|
4668
|
+
asrApplyingRef.current = true;
|
|
4669
|
+
try {
|
|
4670
|
+
document.execCommand("insertText", false, " ");
|
|
4671
|
+
} finally {
|
|
4672
|
+
asrApplyingRef.current = false;
|
|
4673
|
+
}
|
|
4306
4674
|
}
|
|
4675
|
+
asrSegmentsRef.current.clear();
|
|
4676
|
+
asrCurrentKeyRef.current = null;
|
|
4677
|
+
asrTailRef.current = getInputCursor(textarea);
|
|
4678
|
+
await startAsr(deviceId);
|
|
4307
4679
|
},
|
|
4308
|
-
[
|
|
4680
|
+
[startAsr, inputRef]
|
|
4309
4681
|
);
|
|
4310
|
-
const
|
|
4311
|
-
|
|
4312
|
-
|
|
4313
|
-
|
|
4314
|
-
|
|
4315
|
-
|
|
4682
|
+
const [savedDeviceId, setSavedDeviceId] = reactExports.useState(() => {
|
|
4683
|
+
try {
|
|
4684
|
+
return localStorage.getItem(VOICE_INPUT_DEVICE_STORAGE_KEY);
|
|
4685
|
+
} catch {
|
|
4686
|
+
return null;
|
|
4687
|
+
}
|
|
4688
|
+
});
|
|
4689
|
+
const [deviceMenuOpen, setDeviceMenuOpen] = reactExports.useState(false);
|
|
4690
|
+
const rememberDevice = reactExports.useCallback((deviceId) => {
|
|
4691
|
+
setSavedDeviceId(deviceId);
|
|
4692
|
+
try {
|
|
4693
|
+
localStorage.setItem(VOICE_INPUT_DEVICE_STORAGE_KEY, deviceId);
|
|
4694
|
+
} catch {
|
|
4695
|
+
}
|
|
4696
|
+
}, []);
|
|
4697
|
+
const handleSelectDevice = reactExports.useCallback(
|
|
4698
|
+
(deviceId) => {
|
|
4699
|
+
rememberDevice(deviceId);
|
|
4700
|
+
setDeviceMenuOpen(false);
|
|
4701
|
+
},
|
|
4702
|
+
[rememberDevice]
|
|
4703
|
+
);
|
|
4704
|
+
const handleMicClick = reactExports.useCallback(async () => {
|
|
4705
|
+
const devices = await refreshInputDevices();
|
|
4706
|
+
const hasSavedDevice = savedDeviceId != null && devices.some((device) => device.deviceId === savedDeviceId);
|
|
4707
|
+
if (hasSavedDevice) {
|
|
4708
|
+
await handleStart(savedDeviceId);
|
|
4709
|
+
} else {
|
|
4710
|
+
setDeviceMenuOpen(true);
|
|
4711
|
+
}
|
|
4712
|
+
}, [refreshInputDevices, handleStart, savedDeviceId]);
|
|
4713
|
+
const handleDeviceMenuChange = reactExports.useCallback(
|
|
4714
|
+
(open) => {
|
|
4715
|
+
setDeviceMenuOpen(open);
|
|
4716
|
+
if (open) void refreshInputDevices();
|
|
4717
|
+
},
|
|
4718
|
+
[refreshInputDevices]
|
|
4719
|
+
);
|
|
4720
|
+
reactExports.useEffect(() => {
|
|
4721
|
+
const textarea = inputRef.current;
|
|
4722
|
+
if (!textarea) return;
|
|
4723
|
+
const handleInput = () => {
|
|
4724
|
+
if (!asrApplyingRef.current && asr.recording) freezeAsrSegments();
|
|
4725
|
+
};
|
|
4726
|
+
textarea.addEventListener("input", handleInput);
|
|
4727
|
+
return () => textarea.removeEventListener("input", handleInput);
|
|
4728
|
+
}, [asr.recording, freezeAsrSegments, inputRef]);
|
|
4729
|
+
reactExports.useEffect(() => {
|
|
4730
|
+
if (disabled && asr.recording) void handleStop();
|
|
4731
|
+
}, [asr.recording, disabled, handleStop]);
|
|
4732
|
+
reactExports.useEffect(() => {
|
|
4733
|
+
if (!asr.recording || maxDuration <= 0 || !Number.isFinite(maxDuration)) return;
|
|
4734
|
+
const timer = setTimeout(() => void handleStop(), maxDuration);
|
|
4735
|
+
return () => clearTimeout(timer);
|
|
4736
|
+
}, [asr.recording, handleStop, maxDuration]);
|
|
4737
|
+
if (!asr.configured) return null;
|
|
4738
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
4739
|
+
"div",
|
|
4740
|
+
{
|
|
4741
|
+
className: cn$1(
|
|
4742
|
+
"relative inline-flex h-7 transition-[width] duration-300 ease-out",
|
|
4743
|
+
asr.recording ? "w-18" : "w-12.5",
|
|
4744
|
+
className
|
|
4745
|
+
),
|
|
4746
|
+
children: [
|
|
4747
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4748
|
+
"div",
|
|
4749
|
+
{
|
|
4750
|
+
className: cn$1(
|
|
4751
|
+
"absolute inset-0 transition-[opacity,transform,visibility] duration-300 ease-out",
|
|
4752
|
+
asr.recording ? "visible scale-100 opacity-100" : "pointer-events-none invisible scale-90 opacity-0"
|
|
4753
|
+
),
|
|
4754
|
+
"aria-hidden": !asr.recording,
|
|
4755
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
4756
|
+
Button,
|
|
4757
|
+
{
|
|
4758
|
+
variant: "default",
|
|
4759
|
+
size: "sm",
|
|
4760
|
+
className: "h-full w-full rounded-lg bg-muted hover:bg-input border border-input text-amber-300/50 hover:text-amber-200",
|
|
4761
|
+
onClick: () => void handleStop(),
|
|
4762
|
+
"aria-label": t("chatInput.stopVoiceInput", "Stop voice input"),
|
|
4763
|
+
"aria-pressed": "true",
|
|
4764
|
+
title: t("chatInput.stopVoiceInput", "Stop voice input"),
|
|
4765
|
+
children: [
|
|
4766
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Mic, { className: "size-3.5 shrink-0 animate-pulse" }),
|
|
4767
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4768
|
+
"span",
|
|
4769
|
+
{
|
|
4770
|
+
className: "flex h-4 flex-1 items-center justify-center gap-0.5 overflow-hidden",
|
|
4771
|
+
"aria-hidden": "true",
|
|
4772
|
+
children: ASR_WAVEFORM_BARS.map((scale, index) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4773
|
+
"span",
|
|
4774
|
+
{
|
|
4775
|
+
className: "border-l rounded-full bg-amber-300 transition-[height] duration-75",
|
|
4776
|
+
style: {
|
|
4777
|
+
height: `${Math.max(2, Math.round(2 + asr.audioLevel * 16 * scale))}px`
|
|
4778
|
+
}
|
|
4779
|
+
},
|
|
4780
|
+
index
|
|
4781
|
+
))
|
|
4782
|
+
}
|
|
4783
|
+
)
|
|
4784
|
+
]
|
|
4785
|
+
}
|
|
4786
|
+
)
|
|
4787
|
+
}
|
|
4788
|
+
),
|
|
4789
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4790
|
+
"div",
|
|
4791
|
+
{
|
|
4792
|
+
className: cn$1(
|
|
4793
|
+
"absolute inset-0 transition-[opacity,transform,visibility] duration-300 ease-out",
|
|
4794
|
+
asr.recording ? "pointer-events-none invisible scale-90 opacity-0" : "visible scale-100 opacity-100"
|
|
4795
|
+
),
|
|
4796
|
+
"aria-hidden": asr.recording,
|
|
4797
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsxs(DropdownMenu, { open: deviceMenuOpen, onOpenChange: handleDeviceMenuChange, children: [
|
|
4798
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex h-full items-stretch", children: [
|
|
4799
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4800
|
+
Button,
|
|
4801
|
+
{
|
|
4802
|
+
size: "sm",
|
|
4803
|
+
className: "h-full w-8 rounded-r-none border-r-0 bg-muted hover:bg-input border border-input text-amber-300/50 hover:text-amber-200",
|
|
4804
|
+
onClick: () => void handleMicClick(),
|
|
4805
|
+
disabled: disabled || !asr.configured,
|
|
4806
|
+
"aria-label": t("chatInput.voiceInput", "Voice input"),
|
|
4807
|
+
title: asr.configured ? t("chatInput.voiceInput", "Voice input") : t("chatInput.voiceInputNotConfigured", "Configure voice input in Settings"),
|
|
4808
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(Mic, { className: "size-3.5" })
|
|
4809
|
+
}
|
|
4810
|
+
),
|
|
4811
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4812
|
+
DropdownMenuTrigger,
|
|
4813
|
+
{
|
|
4814
|
+
render: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4815
|
+
Button,
|
|
4816
|
+
{
|
|
4817
|
+
size: "icon",
|
|
4818
|
+
className: "h-full w-4.5 rounded-l-none bg-muted hover:bg-input border border-input border-l-0 px-0 text-amber-300/50 hover:text-amber-200",
|
|
4819
|
+
disabled: disabled || !asr.configured,
|
|
4820
|
+
"aria-label": t("chatInput.selectVoiceInputDevice", "Select microphone"),
|
|
4821
|
+
title: t("chatInput.selectVoiceInputDevice", "Select microphone")
|
|
4822
|
+
}
|
|
4823
|
+
),
|
|
4824
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "size-3" })
|
|
4825
|
+
}
|
|
4826
|
+
)
|
|
4827
|
+
] }),
|
|
4828
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4829
|
+
DropdownMenuContent,
|
|
4830
|
+
{
|
|
4831
|
+
side: "top",
|
|
4832
|
+
align: "center",
|
|
4833
|
+
className: "w-auto! max-w-72 min-w-(--anchor-width)",
|
|
4834
|
+
children: asr.inputDevices.length > 0 ? asr.inputDevices.map((device) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
4835
|
+
DropdownMenuItem,
|
|
4836
|
+
{
|
|
4837
|
+
onClick: () => handleSelectDevice(device.deviceId),
|
|
4838
|
+
className: "gap-2",
|
|
4839
|
+
children: [
|
|
4840
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4841
|
+
Check,
|
|
4842
|
+
{
|
|
4843
|
+
className: cn$1(
|
|
4844
|
+
"size-3 shrink-0",
|
|
4845
|
+
device.deviceId === savedDeviceId ? "opacity-100" : "opacity-0"
|
|
4846
|
+
)
|
|
4847
|
+
}
|
|
4848
|
+
),
|
|
4849
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex min-w-0 flex-col gap-0.5 pr-3", children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "truncate", children: device.label }) })
|
|
4850
|
+
]
|
|
4851
|
+
},
|
|
4852
|
+
device.deviceId
|
|
4853
|
+
)) : /* @__PURE__ */ jsxRuntimeExports.jsx(DropdownMenuItem, { disabled: true, children: t("chatInput.noAudioInputDevices", "No audio input devices found") })
|
|
4854
|
+
}
|
|
4855
|
+
)
|
|
4856
|
+
] })
|
|
4857
|
+
}
|
|
4858
|
+
)
|
|
4859
|
+
]
|
|
4860
|
+
}
|
|
4861
|
+
);
|
|
4862
|
+
}
|
|
4863
|
+
function readFileAsBase64(file) {
|
|
4864
|
+
return new Promise((resolve, reject) => {
|
|
4865
|
+
const reader = new FileReader();
|
|
4866
|
+
reader.onload = () => {
|
|
4867
|
+
const result = reader.result;
|
|
4868
|
+
resolve(result.split(",")[1]);
|
|
4869
|
+
};
|
|
4870
|
+
reader.onerror = reject;
|
|
4871
|
+
reader.readAsDataURL(file);
|
|
4872
|
+
});
|
|
4873
|
+
}
|
|
4874
|
+
async function addFileAsAttachment(file, type, updateSessionState) {
|
|
4875
|
+
const data = await readFileAsBase64(file);
|
|
4876
|
+
updateSessionState((s15) => ({
|
|
4877
|
+
draftAttachments: [
|
|
4878
|
+
...s15.draftAttachments,
|
|
4879
|
+
{ id: generateUUID(), filename: file.name, mimeType: file.type, type, data }
|
|
4880
|
+
]
|
|
4881
|
+
}));
|
|
4882
|
+
}
|
|
4883
|
+
function buildAttachmentBlocks(attachments) {
|
|
4884
|
+
return attachments.map((att) => {
|
|
4885
|
+
if (att.type === "image") {
|
|
4886
|
+
return {
|
|
4887
|
+
type: "image",
|
|
4888
|
+
mimeType: att.mimeType,
|
|
4889
|
+
data: att.data
|
|
4890
|
+
};
|
|
4891
|
+
}
|
|
4892
|
+
return {
|
|
4893
|
+
type: "resource",
|
|
4894
|
+
resource: {
|
|
4895
|
+
uri: `file://${att.filename}`,
|
|
4896
|
+
text: att.data
|
|
4897
|
+
}
|
|
4898
|
+
};
|
|
4899
|
+
});
|
|
4900
|
+
}
|
|
4901
|
+
function ChatInput({ session }) {
|
|
4902
|
+
const { t } = useTranslation();
|
|
4903
|
+
const navigate = useNavigate();
|
|
4904
|
+
const { toast } = useMessage();
|
|
4905
|
+
const [isDragOver, setIsDragOver] = reactExports.useState(false);
|
|
4906
|
+
const containerRef = reactExports.useRef(null);
|
|
4907
|
+
const dragLeaveTimer = reactExports.useRef(null);
|
|
4908
|
+
const { addMessage, updateSession } = useAppStore();
|
|
4909
|
+
const snippets = useAppStore((s15) => s15.snippets);
|
|
4910
|
+
const isStreaming = session.isStreaming;
|
|
4911
|
+
const availableModels = reactExports.useMemo(
|
|
4912
|
+
() => session.models?.availableModels ?? [],
|
|
4913
|
+
[session.models?.availableModels]
|
|
4914
|
+
);
|
|
4915
|
+
const currentModelId = session.models?.currentModelId ?? null;
|
|
4916
|
+
const groupedModels = reactExports.useMemo(() => {
|
|
4917
|
+
const groups = /* @__PURE__ */ new Map();
|
|
4918
|
+
for (const m of availableModels) {
|
|
4919
|
+
const slashIdx = m.name.indexOf("/");
|
|
4920
|
+
const key = slashIdx > 0 ? m.name.slice(0, slashIdx) : "";
|
|
4921
|
+
if (!groups.has(key)) groups.set(key, []);
|
|
4922
|
+
groups.get(key).push(m);
|
|
4923
|
+
}
|
|
4924
|
+
return groups;
|
|
4925
|
+
}, [availableModels]);
|
|
4926
|
+
const handleModelChange = reactExports.useCallback(
|
|
4927
|
+
async (modelId) => {
|
|
4928
|
+
const sid = session.id;
|
|
4929
|
+
if (!sid) return;
|
|
4930
|
+
useAppStore.getState().updateSession({
|
|
4931
|
+
...session,
|
|
4932
|
+
models: { ...session.models, currentModelId: modelId }
|
|
4933
|
+
});
|
|
4934
|
+
try {
|
|
4935
|
+
await request.setModel({ sessionId: sid, modelId });
|
|
4936
|
+
} catch (err) {
|
|
4937
|
+
console.error("Failed to set model:", err);
|
|
4938
|
+
useAppStore.getState().updateSession(session);
|
|
4939
|
+
}
|
|
4940
|
+
},
|
|
4941
|
+
[session]
|
|
4942
|
+
);
|
|
4943
|
+
const handleModeChange = reactExports.useCallback(
|
|
4944
|
+
async (modeId) => {
|
|
4945
|
+
const sid = session.id;
|
|
4946
|
+
if (!sid) return;
|
|
4947
|
+
useAppStore.getState().updateSession({
|
|
4948
|
+
...session,
|
|
4949
|
+
modes: { ...session.modes, currentModeId: modeId }
|
|
4950
|
+
});
|
|
4951
|
+
try {
|
|
4952
|
+
await request.setMode({ sessionId: sid, modeId });
|
|
4953
|
+
} catch (err) {
|
|
4954
|
+
console.error("Failed to set mode:", err);
|
|
4955
|
+
useAppStore.getState().updateSession(session);
|
|
4956
|
+
}
|
|
4957
|
+
},
|
|
4958
|
+
[session]
|
|
4959
|
+
);
|
|
4960
|
+
const handleThoughtLevelChange = reactExports.useCallback(
|
|
4961
|
+
async (thoughtLevelId) => {
|
|
4962
|
+
const sid = session.id;
|
|
4963
|
+
if (!sid) return;
|
|
4964
|
+
useAppStore.getState().updateSession({
|
|
4965
|
+
...session,
|
|
4316
4966
|
thoughtLevels: { ...session.thoughtLevels, currentThoughtLevelId: thoughtLevelId }
|
|
4317
4967
|
});
|
|
4318
4968
|
try {
|
|
@@ -4343,10 +4993,9 @@ function ChatInput({ session }) {
|
|
|
4343
4993
|
const promptCapabilities = initializeInfo?.agentCapabilities?.promptCapabilities;
|
|
4344
4994
|
const supportsImage = promptCapabilities?.image ?? false;
|
|
4345
4995
|
const supportsEmbedded = promptCapabilities?.embeddedContext ?? false;
|
|
4346
|
-
const
|
|
4347
|
-
|
|
4348
|
-
|
|
4349
|
-
);
|
|
4996
|
+
const textareaRef = reactExports.useRef(null);
|
|
4997
|
+
const voiceInputRef = reactExports.useRef(null);
|
|
4998
|
+
const getTextarea = reactExports.useCallback(() => textareaRef.current, []);
|
|
4350
4999
|
const insertTriggerChar = reactExports.useCallback(
|
|
4351
5000
|
(char) => {
|
|
4352
5001
|
const textarea = getTextarea();
|
|
@@ -4513,6 +5162,7 @@ function ChatInput({ session }) {
|
|
|
4513
5162
|
[localInput, availableCommands]
|
|
4514
5163
|
);
|
|
4515
5164
|
const handleSubmit = reactExports.useCallback(async () => {
|
|
5165
|
+
await voiceInputRef.current?.stop();
|
|
4516
5166
|
v$2();
|
|
4517
5167
|
const state = useAppStore.getState().getSessionState(session.id);
|
|
4518
5168
|
const currentAttachments = state.draftAttachments;
|
|
@@ -4807,7 +5457,10 @@ function ChatInput({ session }) {
|
|
|
4807
5457
|
MentionsInput$1,
|
|
4808
5458
|
{
|
|
4809
5459
|
value: localInput,
|
|
4810
|
-
|
|
5460
|
+
inputRef: textareaRef,
|
|
5461
|
+
onChange: (_e3, newValue) => {
|
|
5462
|
+
setLocalInput(newValue);
|
|
5463
|
+
},
|
|
4811
5464
|
onBlur: handleBlur,
|
|
4812
5465
|
onKeyDown: handleKeyDown,
|
|
4813
5466
|
placeholder: disabled ? t("chatInput.placeholderDisabled") : t("chatInput.placeholderActive"),
|
|
@@ -5186,6 +5839,14 @@ function ChatInput({ session }) {
|
|
|
5186
5839
|
}
|
|
5187
5840
|
)
|
|
5188
5841
|
] }),
|
|
5842
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
5843
|
+
VoiceInputButton,
|
|
5844
|
+
{
|
|
5845
|
+
ref: voiceInputRef,
|
|
5846
|
+
inputRef: textareaRef,
|
|
5847
|
+
disabled
|
|
5848
|
+
}
|
|
5849
|
+
),
|
|
5189
5850
|
isStreaming ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
5190
5851
|
Button,
|
|
5191
5852
|
{
|
|
@@ -5418,13 +6079,12 @@ function AskUserOptions({
|
|
|
5418
6079
|
const [highlightedIndex, setHighlightedIndex] = reactExports.useState(null);
|
|
5419
6080
|
const [isDragOver, setIsDragOver] = reactExports.useState(false);
|
|
5420
6081
|
const inputContainerRef = reactExports.useRef(null);
|
|
6082
|
+
const textareaRef = reactExports.useRef(null);
|
|
6083
|
+
const voiceInputRef = reactExports.useRef(null);
|
|
5421
6084
|
const navigate = useNavigate();
|
|
5422
6085
|
const snippets = useAppStore((s15) => s15.snippets);
|
|
5423
6086
|
const fileInputRef = reactExports.useRef(null);
|
|
5424
|
-
const getTextarea = reactExports.useCallback(
|
|
5425
|
-
() => inputContainerRef.current?.querySelector("textarea"),
|
|
5426
|
-
[]
|
|
5427
|
-
);
|
|
6087
|
+
const getTextarea = reactExports.useCallback(() => textareaRef.current, []);
|
|
5428
6088
|
const insertTriggerChar = reactExports.useCallback(
|
|
5429
6089
|
(char) => {
|
|
5430
6090
|
const textarea = getTextarea();
|
|
@@ -5489,7 +6149,7 @@ function AskUserOptions({
|
|
|
5489
6149
|
}
|
|
5490
6150
|
if (paths.length === 0) return;
|
|
5491
6151
|
void (async () => {
|
|
5492
|
-
const textarea =
|
|
6152
|
+
const textarea = textareaRef.current;
|
|
5493
6153
|
if (!textarea) return;
|
|
5494
6154
|
textarea.focus();
|
|
5495
6155
|
const tags = await Promise.all(
|
|
@@ -5575,7 +6235,8 @@ function AskUserOptions({
|
|
|
5575
6235
|
window.addEventListener("keydown", handler);
|
|
5576
6236
|
return () => window.removeEventListener("keydown", handler);
|
|
5577
6237
|
}, [mode, hasOptions, request$1.options, handleSelectOption]);
|
|
5578
|
-
const handleSubmitInput = () => {
|
|
6238
|
+
const handleSubmitInput = async () => {
|
|
6239
|
+
await voiceInputRef.current?.stop();
|
|
5579
6240
|
const trimmed = resolveMentions(inputValue).trim();
|
|
5580
6241
|
request.respondAskUser({
|
|
5581
6242
|
sessionId: request$1.sessionId,
|
|
@@ -5589,12 +6250,12 @@ function AskUserOptions({
|
|
|
5589
6250
|
if (e.nativeEvent.isComposing) return;
|
|
5590
6251
|
if (e.key === "Enter" && !e.shiftKey) {
|
|
5591
6252
|
e.preventDefault();
|
|
5592
|
-
handleSubmitInput();
|
|
6253
|
+
void handleSubmitInput();
|
|
5593
6254
|
}
|
|
5594
6255
|
};
|
|
5595
6256
|
reactExports.useEffect(() => {
|
|
5596
6257
|
if (mode === "input") {
|
|
5597
|
-
|
|
6258
|
+
textareaRef.current?.focus();
|
|
5598
6259
|
}
|
|
5599
6260
|
}, [mode]);
|
|
5600
6261
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
@@ -5663,6 +6324,7 @@ function AskUserOptions({
|
|
|
5663
6324
|
MentionsInput$1,
|
|
5664
6325
|
{
|
|
5665
6326
|
value: inputValue,
|
|
6327
|
+
inputRef: textareaRef,
|
|
5666
6328
|
onChange: (_e3, newValue) => setInputValue(newValue),
|
|
5667
6329
|
onKeyDown: handleKeyDown,
|
|
5668
6330
|
placeholder: t("askUser.inputPlaceholder", "Type your response... (Enter to send)"),
|
|
@@ -5803,16 +6465,19 @@ function AskUserOptions({
|
|
|
5803
6465
|
)) : /* @__PURE__ */ jsxRuntimeExports.jsx(DropdownMenuItem, { onClick: () => navigate("/settings/snippets"), children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-muted-foreground", children: t("chatInput.snippetsEmpty", "No snippets. Click to add in Settings.") }) }) })
|
|
5804
6466
|
] })
|
|
5805
6467
|
] }),
|
|
5806
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
5807
|
-
|
|
5808
|
-
|
|
5809
|
-
|
|
5810
|
-
|
|
5811
|
-
|
|
5812
|
-
|
|
5813
|
-
|
|
5814
|
-
|
|
5815
|
-
|
|
6468
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
6469
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(VoiceInputButton, { ref: voiceInputRef, inputRef: textareaRef }),
|
|
6470
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
6471
|
+
Button,
|
|
6472
|
+
{
|
|
6473
|
+
size: "icon",
|
|
6474
|
+
className: "size-7 rounded-lg",
|
|
6475
|
+
onClick: handleSubmitInput,
|
|
6476
|
+
"aria-label": t("askUser.submit", "Submit"),
|
|
6477
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(ArrowUp, { className: "size-3.5" })
|
|
6478
|
+
}
|
|
6479
|
+
)
|
|
6480
|
+
] })
|
|
5816
6481
|
] })
|
|
5817
6482
|
]
|
|
5818
6483
|
}
|
|
@@ -6024,7 +6689,7 @@ function useFile(projectId, file, options = {}) {
|
|
|
6024
6689
|
};
|
|
6025
6690
|
}
|
|
6026
6691
|
const CodeEditor = reactExports.lazy(
|
|
6027
|
-
() => __vitePreload(() => import("./code-editor-
|
|
6692
|
+
() => __vitePreload(() => import("./code-editor-CEXlC4aV.js"), true ? __vite__mapDeps([0,1,2,3,4]) : void 0, import.meta.url).then((m) => ({ default: m.CodeEditor }))
|
|
6028
6693
|
);
|
|
6029
6694
|
const MAX_EDIT_SIZE = 1024 * 1024;
|
|
6030
6695
|
const EditPanel = reactExports.forwardRef(function EditPanel2({ projectId, filePath, content, loading = false, onCancel, onSaved }, ref) {
|
|
@@ -15883,7 +16548,689 @@ function TerminalDetail({ terminalId, projectId, onClose }) {
|
|
|
15883
16548
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "relative min-h-0 flex-1 bg-neutral-900", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { ref: containerRef, className: "h-full w-full px-2 py-1" }) })
|
|
15884
16549
|
] });
|
|
15885
16550
|
}
|
|
15886
|
-
function
|
|
16551
|
+
function TokenUsageDetail({ session, onClose }) {
|
|
16552
|
+
const { t } = useTranslation();
|
|
16553
|
+
const [records, setRecords] = reactExports.useState([]);
|
|
16554
|
+
const [loading, setLoading] = reactExports.useState(true);
|
|
16555
|
+
reactExports.useEffect(() => {
|
|
16556
|
+
let cancelled = false;
|
|
16557
|
+
let refreshTimer;
|
|
16558
|
+
const load = (silent = false) => {
|
|
16559
|
+
if (!silent) setLoading(true);
|
|
16560
|
+
request.getSessionTokenUsage({ sessionId: session.id }).then((res) => {
|
|
16561
|
+
if (!cancelled) {
|
|
16562
|
+
setRecords(parseTokenUsageRecords(res.records));
|
|
16563
|
+
}
|
|
16564
|
+
}).catch(() => {
|
|
16565
|
+
if (!cancelled) setRecords([]);
|
|
16566
|
+
}).finally(() => {
|
|
16567
|
+
if (!cancelled) setLoading(false);
|
|
16568
|
+
});
|
|
16569
|
+
};
|
|
16570
|
+
load();
|
|
16571
|
+
const handlePromptEnd = (payload) => {
|
|
16572
|
+
if (payload.sessionId !== session.id) return;
|
|
16573
|
+
if (refreshTimer) clearTimeout(refreshTimer);
|
|
16574
|
+
refreshTimer = setTimeout(() => {
|
|
16575
|
+
if (!cancelled) load(true);
|
|
16576
|
+
}, 500);
|
|
16577
|
+
};
|
|
16578
|
+
subscribe.on("prompt-end", handlePromptEnd);
|
|
16579
|
+
return () => {
|
|
16580
|
+
cancelled = true;
|
|
16581
|
+
if (refreshTimer) clearTimeout(refreshTimer);
|
|
16582
|
+
subscribe.off("prompt-end", handlePromptEnd);
|
|
16583
|
+
};
|
|
16584
|
+
}, [session.id]);
|
|
16585
|
+
const liveRecord = createLiveRecord(session.lastTurnUsage, session.updatedAt);
|
|
16586
|
+
const displayRecords = mergeLiveRecord(records, liveRecord);
|
|
16587
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col h-full min-h-0", children: [
|
|
16588
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
16589
|
+
"div",
|
|
16590
|
+
{
|
|
16591
|
+
className: "h-12 shrink-0 border-b border-border flex items-center justify-between gap-2 px-3 bg-background/95",
|
|
16592
|
+
style: { WebkitAppRegion: "drag" },
|
|
16593
|
+
children: [
|
|
16594
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1.5 min-w-0", children: [
|
|
16595
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex size-4 shrink-0 items-center justify-center", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Zap, { className: "size-3.5 text-amber-500/80" }) }),
|
|
16596
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "min-w-0", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 text-foreground/60", children: [
|
|
16597
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs font-semibold truncate", children: t("tokenUsage.title", "Token Usage Breakdown") }),
|
|
16598
|
+
displayRecords.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "rounded-full bg-muted px-1.5 py-0.5 text-[10px] font-medium text-muted-foreground tabular-nums shrink-0", children: t("tokenUsage.promptCount", "{{count}} prompts", {
|
|
16599
|
+
count: displayRecords.length
|
|
16600
|
+
}) })
|
|
16601
|
+
] }) })
|
|
16602
|
+
] }),
|
|
16603
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
16604
|
+
"button",
|
|
16605
|
+
{
|
|
16606
|
+
type: "button",
|
|
16607
|
+
onClick: onClose,
|
|
16608
|
+
className: "flex size-6 shrink-0 items-center justify-center rounded hover:bg-muted-foreground/10 text-muted-foreground hover:text-foreground transition-colors",
|
|
16609
|
+
style: { WebkitAppRegion: "no-drag" },
|
|
16610
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(X$1, { className: "size-3.5" })
|
|
16611
|
+
}
|
|
16612
|
+
)
|
|
16613
|
+
]
|
|
16614
|
+
}
|
|
16615
|
+
),
|
|
16616
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(ScrollArea, { className: "flex-1 min-h-0", viewportClassName: "p-4", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: loading ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex h-32 items-center justify-center text-xs text-muted-foreground", children: t("tokenUsage.loading", "Loading…") }) : displayRecords.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex h-full items-center justify-center text-xs text-muted-foreground", children: t("tokenUsage.noData", "No token breakdown data available") }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
16617
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(SessionSummary, { records: displayRecords }),
|
|
16618
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: displayRecords.map((record, index) => ({ record, index })).reverse().map(({ record, index }) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
16619
|
+
PromptUsageItem,
|
|
16620
|
+
{
|
|
16621
|
+
record,
|
|
16622
|
+
promptNumber: index + 1,
|
|
16623
|
+
defaultExpanded: index === displayRecords.length - 1
|
|
16624
|
+
},
|
|
16625
|
+
`${record.timestamp}-${index}`
|
|
16626
|
+
)) })
|
|
16627
|
+
] }) }) })
|
|
16628
|
+
] });
|
|
16629
|
+
}
|
|
16630
|
+
function PromptUsageItem({
|
|
16631
|
+
record,
|
|
16632
|
+
promptNumber,
|
|
16633
|
+
defaultExpanded
|
|
16634
|
+
}) {
|
|
16635
|
+
const { t } = useTranslation();
|
|
16636
|
+
const [expanded, setExpanded] = reactExports.useState(defaultExpanded);
|
|
16637
|
+
const breakdown = getBreakdown(record.usage);
|
|
16638
|
+
const stepCount = breakdown?.steps.length ?? breakdown?.stepCount ?? 0;
|
|
16639
|
+
const toolCount = breakdown?.steps.reduce((total, step) => total + step.toolCalls.length, 0) ?? 0;
|
|
16640
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "border-b border-border/50 transition-colors first:border-t", children: [
|
|
16641
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
16642
|
+
"button",
|
|
16643
|
+
{
|
|
16644
|
+
type: "button",
|
|
16645
|
+
onClick: () => setExpanded((current) => !current),
|
|
16646
|
+
className: "w-full flex items-center p-2 text-left hover:bg-muted/30 transition-colors",
|
|
16647
|
+
children: [
|
|
16648
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex size-5 shrink-0 items-center justify-center text-primary -ml-2.5", children: expanded ? /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "size-3.5" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "size-3.5" }) }),
|
|
16649
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(MessageSquare, { className: "size-3 shrink-0 text-muted-foreground ml-0.5" }),
|
|
16650
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "min-w-0 flex flex-1 ml-2 truncate", children: [
|
|
16651
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 mr-1", children: [
|
|
16652
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[11px] font-semibold", children: t("tokenUsage.promptLabel", "Prompt #{{count}}", { count: promptNumber }) }),
|
|
16653
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[10px] text-muted-foreground/60 tabular-nums mo", children: formatTimestamp(record.timestamp) })
|
|
16654
|
+
] }),
|
|
16655
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3 text-[10px] text-muted-foreground ml-2", children: [
|
|
16656
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-baseline shrink-0 gap-1", children: [
|
|
16657
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono text-[10px] font-semibold tabular-nums text-foreground/85", children: stepCount }),
|
|
16658
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[10px] text-muted-foreground/60", children: t("tokenUsage.steps", "steps") })
|
|
16659
|
+
] }),
|
|
16660
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-baseline shrink-0 gap-1", children: [
|
|
16661
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono text-[10px] font-semibold tabular-nums text-foreground/85", children: toolCount }),
|
|
16662
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[10px] text-muted-foreground/60", children: t("tokenUsage.toolCalls", "tool calls") })
|
|
16663
|
+
] })
|
|
16664
|
+
] })
|
|
16665
|
+
] }),
|
|
16666
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-baseline shrink-0 ml-2 gap-1", children: [
|
|
16667
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono text-[10px] font-semibold tabular-nums text-foreground/85", children: record.usage.totalTokens.toLocaleString() }),
|
|
16668
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[10px] text-muted-foreground/60", children: t("tokenUsage.tokens", "tokens") })
|
|
16669
|
+
] })
|
|
16670
|
+
]
|
|
16671
|
+
}
|
|
16672
|
+
),
|
|
16673
|
+
expanded && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border-t border-border/50 py-2.5 space-y-3", children: [
|
|
16674
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(PromptSummary, { usage: record.usage }),
|
|
16675
|
+
breakdown ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
16676
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(UserMessageSection, { text: breakdown.inputComposition.userMessageText }),
|
|
16677
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(InputCompositionSection, { composition: breakdown.inputComposition }),
|
|
16678
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(ToolsBreakdownSection, { tools: breakdown.inputComposition.toolsDefinition }),
|
|
16679
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(StepsSection, { steps: breakdown.steps }),
|
|
16680
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(PerformanceSection, { performance: breakdown.performance, steps: breakdown.steps })
|
|
16681
|
+
] }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "rounded-md border border-border/60 bg-muted/30 px-2.5 py-2 text-[11px] text-muted-foreground", children: t("tokenUsage.noBreakdown", "No detailed breakdown available for this prompt") })
|
|
16682
|
+
] })
|
|
16683
|
+
] });
|
|
16684
|
+
}
|
|
16685
|
+
function PromptSummary({ usage }) {
|
|
16686
|
+
const { t } = useTranslation();
|
|
16687
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-3 gap-1.5", children: [
|
|
16688
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
16689
|
+
MetricCard,
|
|
16690
|
+
{
|
|
16691
|
+
label: t("tokenUsage.input", "Input"),
|
|
16692
|
+
value: usage.inputTokens.toLocaleString()
|
|
16693
|
+
}
|
|
16694
|
+
),
|
|
16695
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
16696
|
+
MetricCard,
|
|
16697
|
+
{
|
|
16698
|
+
label: t("tokenUsage.output", "Output"),
|
|
16699
|
+
value: usage.outputTokens.toLocaleString()
|
|
16700
|
+
}
|
|
16701
|
+
),
|
|
16702
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
16703
|
+
MetricCard,
|
|
16704
|
+
{
|
|
16705
|
+
label: t("tokenUsage.totalTokens", "Total"),
|
|
16706
|
+
value: usage.totalTokens.toLocaleString()
|
|
16707
|
+
}
|
|
16708
|
+
),
|
|
16709
|
+
usage.thoughtTokens != null && usage.thoughtTokens > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
16710
|
+
MetricCard,
|
|
16711
|
+
{
|
|
16712
|
+
label: t("tokenUsage.thought", "Thought"),
|
|
16713
|
+
value: usage.thoughtTokens.toLocaleString()
|
|
16714
|
+
}
|
|
16715
|
+
),
|
|
16716
|
+
usage.cachedReadTokens != null && usage.cachedReadTokens > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
16717
|
+
MetricCard,
|
|
16718
|
+
{
|
|
16719
|
+
label: t("tokenUsage.cacheRead", "Cache Read"),
|
|
16720
|
+
value: usage.cachedReadTokens.toLocaleString()
|
|
16721
|
+
}
|
|
16722
|
+
),
|
|
16723
|
+
usage.cachedWriteTokens != null && usage.cachedWriteTokens > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
16724
|
+
MetricCard,
|
|
16725
|
+
{
|
|
16726
|
+
label: t("tokenUsage.cacheWrite", "Cache Write"),
|
|
16727
|
+
value: usage.cachedWriteTokens.toLocaleString()
|
|
16728
|
+
}
|
|
16729
|
+
)
|
|
16730
|
+
] });
|
|
16731
|
+
}
|
|
16732
|
+
function SessionSummary({ records }) {
|
|
16733
|
+
const { t } = useTranslation();
|
|
16734
|
+
const totalInput = records.reduce((sum, record) => sum + record.usage.inputTokens, 0);
|
|
16735
|
+
const totalOutput = records.reduce((sum, record) => sum + record.usage.outputTokens, 0);
|
|
16736
|
+
const totalThought = records.reduce((sum, record) => sum + (record.usage.thoughtTokens ?? 0), 0);
|
|
16737
|
+
const totalCached = records.reduce(
|
|
16738
|
+
(sum, record) => sum + (record.usage.cachedReadTokens ?? 0),
|
|
16739
|
+
0
|
|
16740
|
+
);
|
|
16741
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "pb-3", children: [
|
|
16742
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
16743
|
+
SectionHeader,
|
|
16744
|
+
{
|
|
16745
|
+
icon: MessagesSquare,
|
|
16746
|
+
title: t("tokenUsage.sessionTotal", "Session Total"),
|
|
16747
|
+
badge: t("tokenUsage.promptCount", "{{count}} prompts", {
|
|
16748
|
+
count: records.length
|
|
16749
|
+
})
|
|
16750
|
+
}
|
|
16751
|
+
),
|
|
16752
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-2 grid grid-cols-3 gap-1.5", children: [
|
|
16753
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(MetricCard, { label: t("tokenUsage.input", "Input"), value: totalInput.toLocaleString() }),
|
|
16754
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(MetricCard, { label: t("tokenUsage.output", "Output"), value: totalOutput.toLocaleString() }),
|
|
16755
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
16756
|
+
MetricCard,
|
|
16757
|
+
{
|
|
16758
|
+
label: t("tokenUsage.totalTokens", "Total"),
|
|
16759
|
+
value: (totalInput + totalOutput).toLocaleString()
|
|
16760
|
+
}
|
|
16761
|
+
),
|
|
16762
|
+
totalThought > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
16763
|
+
MetricCard,
|
|
16764
|
+
{
|
|
16765
|
+
label: t("tokenUsage.thought", "Thought"),
|
|
16766
|
+
value: totalThought.toLocaleString()
|
|
16767
|
+
}
|
|
16768
|
+
),
|
|
16769
|
+
totalCached > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
16770
|
+
MetricCard,
|
|
16771
|
+
{
|
|
16772
|
+
label: t("tokenUsage.cached", "Cached"),
|
|
16773
|
+
value: totalCached.toLocaleString()
|
|
16774
|
+
}
|
|
16775
|
+
)
|
|
16776
|
+
] })
|
|
16777
|
+
] });
|
|
16778
|
+
}
|
|
16779
|
+
function InputCompositionSection({ composition }) {
|
|
16780
|
+
const { t } = useTranslation();
|
|
16781
|
+
const parts = [
|
|
16782
|
+
{
|
|
16783
|
+
label: t("tokenUsage.systemPrompt", "System Prompt"),
|
|
16784
|
+
value: composition.systemPrompt,
|
|
16785
|
+
color: "bg-blue-500/80"
|
|
16786
|
+
},
|
|
16787
|
+
{
|
|
16788
|
+
label: t("tokenUsage.tools", "Tools"),
|
|
16789
|
+
value: composition.toolsDefinition.total,
|
|
16790
|
+
color: "bg-amber-500/80"
|
|
16791
|
+
},
|
|
16792
|
+
{
|
|
16793
|
+
label: t("tokenUsage.history", "History"),
|
|
16794
|
+
value: composition.history,
|
|
16795
|
+
color: "bg-emerald-500/80"
|
|
16796
|
+
},
|
|
16797
|
+
{
|
|
16798
|
+
label: t("tokenUsage.userMessage", "User Message"),
|
|
16799
|
+
value: composition.userMessage,
|
|
16800
|
+
color: "bg-purple-500/80"
|
|
16801
|
+
}
|
|
16802
|
+
];
|
|
16803
|
+
const total = composition.estimatedTotal || parts.reduce((sum, part) => sum + part.value, 0);
|
|
16804
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "border-t border-border/50 pt-3", children: [
|
|
16805
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(SectionHeader, { icon: Layers, title: t("tokenUsage.inputComposition", "Input Composition") }),
|
|
16806
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-2.5 w-full rounded-full bg-muted/80 overflow-hidden flex mt-2.5 ring-1 ring-border/30", children: parts.map(
|
|
16807
|
+
(part) => part.value > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
16808
|
+
"div",
|
|
16809
|
+
{
|
|
16810
|
+
className: cn$1("h-full", part.color),
|
|
16811
|
+
style: { width: `${total > 0 ? part.value / total * 100 : 0}%` }
|
|
16812
|
+
},
|
|
16813
|
+
part.label
|
|
16814
|
+
)
|
|
16815
|
+
) }),
|
|
16816
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "my-3 grid grid-cols-2 gap-x-4 gap-y-1 text-[10px]", children: parts.map((part) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between gap-2", children: [
|
|
16817
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1.5 min-w-0", children: [
|
|
16818
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: cn$1("size-2 rounded-sm shrink-0", part.color) }),
|
|
16819
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-muted-foreground truncate", children: part.label })
|
|
16820
|
+
] }),
|
|
16821
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono tabular-nums text-muted-foreground shrink-0", children: part.value.toLocaleString() })
|
|
16822
|
+
] }, part.label)) }),
|
|
16823
|
+
composition.delta !== 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-1.5 text-[10px] text-muted-foreground/60", children: [
|
|
16824
|
+
t("tokenUsage.delta", "Estimation delta"),
|
|
16825
|
+
": ",
|
|
16826
|
+
composition.delta > 0 ? "+" : "",
|
|
16827
|
+
composition.delta.toLocaleString(),
|
|
16828
|
+
" ",
|
|
16829
|
+
t("tokenUsage.tokens", "tokens")
|
|
16830
|
+
] })
|
|
16831
|
+
] });
|
|
16832
|
+
}
|
|
16833
|
+
function UserMessageSection({ text }) {
|
|
16834
|
+
const { t } = useTranslation();
|
|
16835
|
+
if (!text) return null;
|
|
16836
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "border-t border-border/50 pt-3", children: [
|
|
16837
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(SectionHeader, { icon: MessageSquare, title: t("tokenUsage.userMessage", "User Message") }),
|
|
16838
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(ScrollArea, { viewportClassName: "mt-2 max-h-40 rounded-md border border-border/60 bg-muted/30", children: /* @__PURE__ */ jsxRuntimeExports.jsx("pre", { className: "whitespace-pre-wrap wrap-break-word px-2 py-1.5 text-[10px] leading-relaxed text-foreground/70 font-mono", children: text }) })
|
|
16839
|
+
] });
|
|
16840
|
+
}
|
|
16841
|
+
function ToolsBreakdownSection({ tools }) {
|
|
16842
|
+
const { t } = useTranslation();
|
|
16843
|
+
const [expanded, setExpanded] = reactExports.useState(false);
|
|
16844
|
+
if (tools.perTool.length === 0) return null;
|
|
16845
|
+
const sorted = [...tools.perTool].sort((a, b2) => b2.tokens - a.tokens);
|
|
16846
|
+
const topCount = expanded ? sorted.length : 8;
|
|
16847
|
+
const topTools = sorted.slice(0, topCount);
|
|
16848
|
+
const rest = sorted.slice(topCount);
|
|
16849
|
+
const restTotal = rest.reduce((sum, tool) => sum + tool.tokens, 0);
|
|
16850
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "border-t border-border/50 pt-3", children: [
|
|
16851
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
16852
|
+
SectionHeader,
|
|
16853
|
+
{
|
|
16854
|
+
icon: Wrench,
|
|
16855
|
+
title: t("tokenUsage.toolsDefinition", "Tools Definition"),
|
|
16856
|
+
badge: t("tokenUsage.toolsCount", "{{count}} tools · {{tokens}} tokens", {
|
|
16857
|
+
count: tools.perTool.length,
|
|
16858
|
+
tokens: tools.total.toLocaleString()
|
|
16859
|
+
})
|
|
16860
|
+
}
|
|
16861
|
+
),
|
|
16862
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-2 space-y-1 text-[10px]", children: [
|
|
16863
|
+
topTools.map((tool) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
16864
|
+
"div",
|
|
16865
|
+
{
|
|
16866
|
+
className: "flex items-center gap-2 rounded px-1 -mx-1 py-0.5 hover:bg-muted/40 transition-colors",
|
|
16867
|
+
children: [
|
|
16868
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "flex-1 min-w-0 truncate font-mono text-muted-foreground", children: tool.name }),
|
|
16869
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono tabular-nums font-medium text-foreground/75 shrink-0", children: tool.tokens.toLocaleString() }),
|
|
16870
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-16 h-1 rounded-full bg-muted overflow-hidden shrink-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
16871
|
+
"div",
|
|
16872
|
+
{
|
|
16873
|
+
className: "h-full bg-amber-500/60 rounded-full",
|
|
16874
|
+
style: { width: `${tool.tokens / (sorted[0]?.tokens || 1) * 100}%` }
|
|
16875
|
+
}
|
|
16876
|
+
) })
|
|
16877
|
+
]
|
|
16878
|
+
},
|
|
16879
|
+
tool.name
|
|
16880
|
+
)),
|
|
16881
|
+
rest.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
16882
|
+
"div",
|
|
16883
|
+
{
|
|
16884
|
+
className: "flex items-center gap-2 text-muted-foreground/60 hover:underline cursor-default",
|
|
16885
|
+
onClick: () => setExpanded(true),
|
|
16886
|
+
children: [
|
|
16887
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "flex-1", children: t("tokenUsage.more", "+{{count}} more", { count: rest.length }) }),
|
|
16888
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono tabular-nums shrink-0", children: restTotal.toLocaleString() }),
|
|
16889
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-16 shrink-0" })
|
|
16890
|
+
]
|
|
16891
|
+
}
|
|
16892
|
+
)
|
|
16893
|
+
] })
|
|
16894
|
+
] });
|
|
16895
|
+
}
|
|
16896
|
+
function StepsSection({ steps }) {
|
|
16897
|
+
const { t } = useTranslation();
|
|
16898
|
+
const [expandedSteps, setExpandedSteps] = reactExports.useState(() => /* @__PURE__ */ new Set());
|
|
16899
|
+
if (steps.length === 0) return null;
|
|
16900
|
+
const toggleStep = (stepNumber) => {
|
|
16901
|
+
setExpandedSteps((current) => {
|
|
16902
|
+
const next = new Set(current);
|
|
16903
|
+
if (next.has(stepNumber)) next.delete(stepNumber);
|
|
16904
|
+
else next.add(stepNumber);
|
|
16905
|
+
return next;
|
|
16906
|
+
});
|
|
16907
|
+
};
|
|
16908
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "border-t border-border/50 pt-3", children: [
|
|
16909
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
16910
|
+
SectionHeader,
|
|
16911
|
+
{
|
|
16912
|
+
icon: Layers,
|
|
16913
|
+
title: t("tokenUsage.steps", "Steps"),
|
|
16914
|
+
badge: t("tokenUsage.stepsCount", "{{count}} steps", { count: steps.length })
|
|
16915
|
+
}
|
|
16916
|
+
),
|
|
16917
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-2", children: steps.map((step) => {
|
|
16918
|
+
const expanded = expandedSteps.has(step.stepNumber);
|
|
16919
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
16920
|
+
"div",
|
|
16921
|
+
{
|
|
16922
|
+
className: "transition-colors border-b border-border/70 last:border-transparent",
|
|
16923
|
+
children: [
|
|
16924
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
16925
|
+
"button",
|
|
16926
|
+
{
|
|
16927
|
+
type: "button",
|
|
16928
|
+
onClick: () => toggleStep(step.stepNumber),
|
|
16929
|
+
className: "w-full flex items-center py-1.5 text-left hover:bg-muted/30 transition-colors px-1",
|
|
16930
|
+
children: [
|
|
16931
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex size-5 shrink-0 items-center justify-center text-primary -ml-2", children: expanded ? /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "size-3" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "size-3" }) }),
|
|
16932
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-2 items-center ml-0.5", children: [
|
|
16933
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "flex items-center justify-center text-[11px] font-semibold text-muted-foreground shrink-0", children: [
|
|
16934
|
+
"#",
|
|
16935
|
+
step.stepNumber
|
|
16936
|
+
] }),
|
|
16937
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
16938
|
+
"span",
|
|
16939
|
+
{
|
|
16940
|
+
className: cn$1(
|
|
16941
|
+
"rounded-full px-1.5 py-0.5 text-[10px] font-medium uppercase truncate",
|
|
16942
|
+
finishReasonBadge(step.finishReason)
|
|
16943
|
+
),
|
|
16944
|
+
children: step.finishReason
|
|
16945
|
+
}
|
|
16946
|
+
)
|
|
16947
|
+
] }),
|
|
16948
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-4 ml-auto font-mono text-[10px] tabular-nums text-muted-foreground shrink-0", children: [
|
|
16949
|
+
step.toolCalls.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-baseline shrink-0 gap-1", children: [
|
|
16950
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: step.toolCalls.length }),
|
|
16951
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-muted-foreground/70", children: t("tokenUsage.toolCalls", "tool calls") })
|
|
16952
|
+
] }),
|
|
16953
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-1", children: [
|
|
16954
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: step.inputTokens.toLocaleString() }),
|
|
16955
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-muted-foreground/70", children: t("tokenUsage.inputShort", "in") })
|
|
16956
|
+
] }),
|
|
16957
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-1", children: [
|
|
16958
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: step.outputTokens.toLocaleString() }),
|
|
16959
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-muted-foreground/70", children: t("tokenUsage.outputShort", "out") })
|
|
16960
|
+
] })
|
|
16961
|
+
] })
|
|
16962
|
+
]
|
|
16963
|
+
}
|
|
16964
|
+
),
|
|
16965
|
+
expanded && /* @__PURE__ */ jsxRuntimeExports.jsx(StepDetails, { step })
|
|
16966
|
+
]
|
|
16967
|
+
},
|
|
16968
|
+
step.stepNumber
|
|
16969
|
+
);
|
|
16970
|
+
}) })
|
|
16971
|
+
] });
|
|
16972
|
+
}
|
|
16973
|
+
function StepDetails({ step }) {
|
|
16974
|
+
const { t } = useTranslation();
|
|
16975
|
+
const { inputDetails, outputDetails, performance: performance2 } = step;
|
|
16976
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border-t border-border/40", children: [
|
|
16977
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-2 gap-1 py-1", children: [
|
|
16978
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
16979
|
+
DetailMetric,
|
|
16980
|
+
{
|
|
16981
|
+
label: t("tokenUsage.input", "Input"),
|
|
16982
|
+
value: step.inputTokens.toLocaleString()
|
|
16983
|
+
}
|
|
16984
|
+
),
|
|
16985
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
16986
|
+
DetailMetric,
|
|
16987
|
+
{
|
|
16988
|
+
label: t("tokenUsage.output", "Output"),
|
|
16989
|
+
value: step.outputTokens.toLocaleString()
|
|
16990
|
+
}
|
|
16991
|
+
)
|
|
16992
|
+
] }),
|
|
16993
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-[10px] space-y-1", children: [
|
|
16994
|
+
inputDetails.cacheReadTokens != null && inputDetails.cacheReadTokens > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
16995
|
+
MetricRow,
|
|
16996
|
+
{
|
|
16997
|
+
label: t("tokenUsage.cacheRead", "Cache Read"),
|
|
16998
|
+
value: inputDetails.cacheReadTokens.toLocaleString()
|
|
16999
|
+
}
|
|
17000
|
+
),
|
|
17001
|
+
inputDetails.cacheWriteTokens != null && inputDetails.cacheWriteTokens > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
17002
|
+
MetricRow,
|
|
17003
|
+
{
|
|
17004
|
+
label: t("tokenUsage.cacheWrite", "Cache Write"),
|
|
17005
|
+
value: inputDetails.cacheWriteTokens.toLocaleString()
|
|
17006
|
+
}
|
|
17007
|
+
),
|
|
17008
|
+
inputDetails.noCacheTokens != null && inputDetails.noCacheTokens > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
17009
|
+
MetricRow,
|
|
17010
|
+
{
|
|
17011
|
+
label: t("tokenUsage.noCache", "No Cache"),
|
|
17012
|
+
value: inputDetails.noCacheTokens.toLocaleString()
|
|
17013
|
+
}
|
|
17014
|
+
),
|
|
17015
|
+
outputDetails.textTokens != null && outputDetails.textTokens > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
17016
|
+
MetricRow,
|
|
17017
|
+
{
|
|
17018
|
+
label: t("tokenUsage.text", "Text"),
|
|
17019
|
+
value: outputDetails.textTokens.toLocaleString()
|
|
17020
|
+
}
|
|
17021
|
+
),
|
|
17022
|
+
outputDetails.reasoningTokens != null && outputDetails.reasoningTokens > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
17023
|
+
MetricRow,
|
|
17024
|
+
{
|
|
17025
|
+
label: t("tokenUsage.thought", "Thought"),
|
|
17026
|
+
value: outputDetails.reasoningTokens.toLocaleString()
|
|
17027
|
+
}
|
|
17028
|
+
),
|
|
17029
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
17030
|
+
MetricRow,
|
|
17031
|
+
{
|
|
17032
|
+
label: t("tokenUsage.stepTime", "Step Time"),
|
|
17033
|
+
value: formatMs(performance2.stepTimeMs)
|
|
17034
|
+
}
|
|
17035
|
+
),
|
|
17036
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
17037
|
+
MetricRow,
|
|
17038
|
+
{
|
|
17039
|
+
label: t("tokenUsage.responseTime", "Response Time"),
|
|
17040
|
+
value: formatMs(performance2.responseTimeMs)
|
|
17041
|
+
}
|
|
17042
|
+
)
|
|
17043
|
+
] }),
|
|
17044
|
+
step.toolCalls.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "pt-1 mt-3 border-t border-border/40", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-1", children: step.toolCalls.map((toolCall, index) => /* @__PURE__ */ jsxRuntimeExports.jsx(ToolCallRow, { toolCall }, `${toolCall.toolName}-${index}`)) }) })
|
|
17045
|
+
] });
|
|
17046
|
+
}
|
|
17047
|
+
function ToolCallRow({ toolCall }) {
|
|
17048
|
+
const { t } = useTranslation();
|
|
17049
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "py-4 border-t border-border/40 first:border-transparent -mt-px", children: [
|
|
17050
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1.5 min-w-0", children: [
|
|
17051
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Wrench, { className: "size-3 shrink-0 text-foreground/80" }),
|
|
17052
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono text-[10px] font-medium text-foreground/80 truncate", children: shortToolName(toolCall.toolName) }),
|
|
17053
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ml-auto max-w-[45%] truncate text-[10px] text-muted-foreground/50 font-mono", children: toolCall.toolName })
|
|
17054
|
+
] }),
|
|
17055
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-3 gap-1 -mb-2", children: [
|
|
17056
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
17057
|
+
DetailMetric,
|
|
17058
|
+
{
|
|
17059
|
+
label: t("tokenUsage.arguments", "Arguments"),
|
|
17060
|
+
value: `${toolCall.argumentsOutputTokens.toLocaleString()} ${t("tokenUsage.token", "token")}`
|
|
17061
|
+
}
|
|
17062
|
+
),
|
|
17063
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
17064
|
+
DetailMetric,
|
|
17065
|
+
{
|
|
17066
|
+
label: t("tokenUsage.result", "Result"),
|
|
17067
|
+
value: `${toolCall.resultInputTokens.toLocaleString()} ${t("tokenUsage.token", "token")}`
|
|
17068
|
+
}
|
|
17069
|
+
),
|
|
17070
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
17071
|
+
DetailMetric,
|
|
17072
|
+
{
|
|
17073
|
+
label: t("tokenUsage.execution", "Execution"),
|
|
17074
|
+
value: toolCall.executionMs != null ? formatMs(toolCall.executionMs) : "—"
|
|
17075
|
+
}
|
|
17076
|
+
)
|
|
17077
|
+
] }),
|
|
17078
|
+
toolCall.args && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-2", children: [
|
|
17079
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-[10px] font-medium uppercase tracking-wide text-muted-foreground/70 mb-1", children: t("tokenUsage.arguments", "Arguments") }),
|
|
17080
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(ScrollArea, { viewportClassName: "max-h-32 rounded-md border border-border/60 bg-muted/30", children: /* @__PURE__ */ jsxRuntimeExports.jsx("pre", { className: "whitespace-pre-wrap wrap-break-word px-2 py-1.5 text-[10px] leading-relaxed text-foreground/70 font-mono", children: formatToolArgs(toolCall.args) }) })
|
|
17081
|
+
] })
|
|
17082
|
+
] });
|
|
17083
|
+
}
|
|
17084
|
+
function PerformanceSection({
|
|
17085
|
+
performance: performance2,
|
|
17086
|
+
steps
|
|
17087
|
+
}) {
|
|
17088
|
+
const { t } = useTranslation();
|
|
17089
|
+
const ttft = steps[0]?.performance.timeToFirstOutputMs;
|
|
17090
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "border-t border-border/50 pt-3", children: [
|
|
17091
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(SectionHeader, { icon: Gauge, title: t("tokenUsage.performance", "Performance") }),
|
|
17092
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-2 grid grid-cols-3 gap-1.5", children: [
|
|
17093
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
17094
|
+
DetailMetric,
|
|
17095
|
+
{
|
|
17096
|
+
label: t("tokenUsage.totalTime", "Total Time"),
|
|
17097
|
+
value: formatMs(performance2.totalTimeMs)
|
|
17098
|
+
}
|
|
17099
|
+
),
|
|
17100
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
17101
|
+
DetailMetric,
|
|
17102
|
+
{
|
|
17103
|
+
label: t("tokenUsage.outputSpeed", "Output Speed"),
|
|
17104
|
+
value: `${Math.round(performance2.effectiveOutputTokensPerSecond)} ${t("tokenUsage.tokensPerSecond", "token/s")}`
|
|
17105
|
+
}
|
|
17106
|
+
),
|
|
17107
|
+
ttft != null && /* @__PURE__ */ jsxRuntimeExports.jsx(DetailMetric, { label: t("tokenUsage.firstToken", "First Token"), value: formatMs(ttft) })
|
|
17108
|
+
] })
|
|
17109
|
+
] });
|
|
17110
|
+
}
|
|
17111
|
+
function MetricCard({ label, value }) {
|
|
17112
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "py-2", children: [
|
|
17113
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-[10px] font-medium uppercase tracking-wide text-muted-foreground/70", children: label }),
|
|
17114
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-1 font-mono text-sm font-semibold tabular-nums text-foreground/70 truncate", children: value })
|
|
17115
|
+
] });
|
|
17116
|
+
}
|
|
17117
|
+
function DetailMetric({ label, value }) {
|
|
17118
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "py-2", children: [
|
|
17119
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-[10px] font-medium uppercase tracking-wide truncate text-muted-foreground/70", children: label }),
|
|
17120
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-1.5 font-mono text-xs font-medium tabular-nums text-foreground/70 truncate", children: value })
|
|
17121
|
+
] });
|
|
17122
|
+
}
|
|
17123
|
+
function SectionHeader({
|
|
17124
|
+
icon: Icon,
|
|
17125
|
+
title,
|
|
17126
|
+
badge
|
|
17127
|
+
}) {
|
|
17128
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
17129
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Icon, { className: "size-3 text-muted-foreground" }),
|
|
17130
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs font-semibold text-foreground/80", children: title }),
|
|
17131
|
+
badge && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[10px] text-muted-foreground/60 ml-auto", children: badge })
|
|
17132
|
+
] });
|
|
17133
|
+
}
|
|
17134
|
+
function MetricRow({ label, value }) {
|
|
17135
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between min-w-0 gap-2 hover:bg-accent/60 px-1 py-0.5 -mx-1 rounded-sm", children: [
|
|
17136
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-muted-foreground truncate", children: label }),
|
|
17137
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono tabular-nums text-foreground/80 shrink-0", children: value })
|
|
17138
|
+
] });
|
|
17139
|
+
}
|
|
17140
|
+
function isRecord(value) {
|
|
17141
|
+
return typeof value === "object" && value !== null;
|
|
17142
|
+
}
|
|
17143
|
+
function parseTokenUsageRecords(records) {
|
|
17144
|
+
const parsed = [];
|
|
17145
|
+
for (const record of records) {
|
|
17146
|
+
if (isTokenUsageRecord(record)) parsed.push(record);
|
|
17147
|
+
}
|
|
17148
|
+
return parsed;
|
|
17149
|
+
}
|
|
17150
|
+
function isTokenUsageRecord(value) {
|
|
17151
|
+
if (!isRecord(value) || typeof value.timestamp !== "number" || !isRecord(value.usage)) {
|
|
17152
|
+
return false;
|
|
17153
|
+
}
|
|
17154
|
+
return typeof value.usage.totalTokens === "number" && typeof value.usage.inputTokens === "number" && typeof value.usage.outputTokens === "number";
|
|
17155
|
+
}
|
|
17156
|
+
function isTokenBreakdown(value) {
|
|
17157
|
+
if (!isRecord(value)) return false;
|
|
17158
|
+
const composition = value.inputComposition;
|
|
17159
|
+
return typeof value.stepCount === "number" && Array.isArray(value.steps) && isRecord(composition) && isRecord(composition.toolsDefinition) && Array.isArray(composition.toolsDefinition.perTool) && isRecord(value.performance);
|
|
17160
|
+
}
|
|
17161
|
+
function getBreakdown(usage) {
|
|
17162
|
+
const breakdown = usage._meta?.fello?.tokenBreakdown;
|
|
17163
|
+
return isTokenBreakdown(breakdown) ? breakdown : void 0;
|
|
17164
|
+
}
|
|
17165
|
+
function createLiveRecord(usage, timestamp) {
|
|
17166
|
+
if (!usage) return null;
|
|
17167
|
+
const breakdown = getBreakdownFromUnknownUsage(usage);
|
|
17168
|
+
if (!breakdown) return null;
|
|
17169
|
+
return {
|
|
17170
|
+
timestamp,
|
|
17171
|
+
usage: {
|
|
17172
|
+
totalTokens: usage.totalTokens,
|
|
17173
|
+
inputTokens: usage.inputTokens,
|
|
17174
|
+
outputTokens: usage.outputTokens,
|
|
17175
|
+
thoughtTokens: usage.thoughtTokens,
|
|
17176
|
+
cachedReadTokens: usage.cachedReadTokens,
|
|
17177
|
+
cachedWriteTokens: usage.cachedWriteTokens,
|
|
17178
|
+
_meta: { fello: { tokenBreakdown: breakdown } }
|
|
17179
|
+
}
|
|
17180
|
+
};
|
|
17181
|
+
}
|
|
17182
|
+
function finishReasonBadge(reason) {
|
|
17183
|
+
if (reason === "stop" || reason === "end_turn") {
|
|
17184
|
+
return "bg-emerald-500/10 text-emerald-600 dark:text-emerald-400";
|
|
17185
|
+
}
|
|
17186
|
+
if (reason === "tool_calls" || reason === "tool_call") {
|
|
17187
|
+
return "bg-amber-500/10 text-amber-600 dark:text-amber-400";
|
|
17188
|
+
}
|
|
17189
|
+
if (reason === "length" || reason === "max_tokens") {
|
|
17190
|
+
return "bg-orange-500/10 text-orange-600 dark:text-orange-400";
|
|
17191
|
+
}
|
|
17192
|
+
return "bg-muted text-muted-foreground";
|
|
17193
|
+
}
|
|
17194
|
+
function getBreakdownFromUnknownUsage(usage) {
|
|
17195
|
+
if (!isRecord(usage) || !isRecord(usage._meta) || !isRecord(usage._meta.fello)) {
|
|
17196
|
+
return void 0;
|
|
17197
|
+
}
|
|
17198
|
+
return isTokenBreakdown(usage._meta.fello.tokenBreakdown) ? usage._meta.fello.tokenBreakdown : void 0;
|
|
17199
|
+
}
|
|
17200
|
+
function mergeLiveRecord(records, liveRecord) {
|
|
17201
|
+
if (!liveRecord) return records;
|
|
17202
|
+
const lastRecord = records[records.length - 1];
|
|
17203
|
+
if (lastRecord && getUsageFingerprint(lastRecord.usage) === getUsageFingerprint(liveRecord.usage)) {
|
|
17204
|
+
return records;
|
|
17205
|
+
}
|
|
17206
|
+
return [...records, liveRecord];
|
|
17207
|
+
}
|
|
17208
|
+
function getUsageFingerprint(usage) {
|
|
17209
|
+
return JSON.stringify(usage) ?? "";
|
|
17210
|
+
}
|
|
17211
|
+
function shortToolName(name) {
|
|
17212
|
+
const parts = name.split("__");
|
|
17213
|
+
return parts[parts.length - 1] || name;
|
|
17214
|
+
}
|
|
17215
|
+
function formatToolArgs(args) {
|
|
17216
|
+
try {
|
|
17217
|
+
return JSON.stringify(JSON.parse(args), null, 2);
|
|
17218
|
+
} catch {
|
|
17219
|
+
return args;
|
|
17220
|
+
}
|
|
17221
|
+
}
|
|
17222
|
+
function formatTimestamp(timestamp) {
|
|
17223
|
+
return new Date(timestamp).toLocaleTimeString([], {
|
|
17224
|
+
hour: "2-digit",
|
|
17225
|
+
minute: "2-digit",
|
|
17226
|
+
second: "2-digit"
|
|
17227
|
+
});
|
|
17228
|
+
}
|
|
17229
|
+
function formatMs(ms2) {
|
|
17230
|
+
if (ms2 < 1e3) return `${Math.round(ms2)}ms`;
|
|
17231
|
+
return `${(ms2 / 1e3).toFixed(1)}s`;
|
|
17232
|
+
}
|
|
17233
|
+
function Detail({ detailType, projectId, file, terminalId, session, onClose }) {
|
|
15887
17234
|
const { t } = useTranslation();
|
|
15888
17235
|
if (!detailType) return null;
|
|
15889
17236
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col h-full min-h-0 overflow-hidden bg-background", children: [
|
|
@@ -15897,7 +17244,8 @@ function Detail({ detailType, projectId, file, terminalId, onClose }) {
|
|
|
15897
17244
|
},
|
|
15898
17245
|
terminalId
|
|
15899
17246
|
),
|
|
15900
|
-
|
|
17247
|
+
detailType === "token-usage" && session && /* @__PURE__ */ jsxRuntimeExports.jsx(TokenUsageDetail, { session, onClose }),
|
|
17248
|
+
(!detailType || detailType === "file" && (!projectId || !file) || detailType === "terminal" && (!projectId || !terminalId) || detailType === "token-usage" && !session) && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex h-full items-center justify-center text-xs text-muted-foreground", children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: t("detail.noContent", "No content") }) })
|
|
15901
17249
|
] });
|
|
15902
17250
|
}
|
|
15903
17251
|
const GIT_FOLDER_STATUS = {
|
|
@@ -17550,6 +18898,15 @@ function Session({ session }) {
|
|
|
17550
18898
|
document.addEventListener("fello-preview-file", handlePreviewFileEvent);
|
|
17551
18899
|
return () => document.removeEventListener("fello-preview-file", handlePreviewFileEvent);
|
|
17552
18900
|
}, [currentProjectId, handlePreviewFile]);
|
|
18901
|
+
reactExports.useEffect(() => {
|
|
18902
|
+
const handleOpenTokenUsage = () => {
|
|
18903
|
+
setDetailType("token-usage");
|
|
18904
|
+
setDetailFile(null);
|
|
18905
|
+
setDetailTerminalId(null);
|
|
18906
|
+
};
|
|
18907
|
+
document.addEventListener("fello-open-token-usage", handleOpenTokenUsage);
|
|
18908
|
+
return () => document.removeEventListener("fello-open-token-usage", handleOpenTokenUsage);
|
|
18909
|
+
}, []);
|
|
17553
18910
|
const fetchingRef = reactExports.useRef(null);
|
|
17554
18911
|
const [connectionError, setConnectionError] = reactExports.useState(false);
|
|
17555
18912
|
reactExports.useEffect(() => {
|
|
@@ -17655,6 +19012,7 @@ function Session({ session }) {
|
|
|
17655
19012
|
projectId: currentProjectId,
|
|
17656
19013
|
file: detailFile,
|
|
17657
19014
|
terminalId: detailTerminalId,
|
|
19015
|
+
session,
|
|
17658
19016
|
onClose: handleDetailClose
|
|
17659
19017
|
}
|
|
17660
19018
|
) })
|