@cc-monitoring/proxy-core 0.1.4 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -35
- package/dist/cli/commands/doc.d.ts +4 -0
- package/dist/cli/commands/doc.js +31 -0
- package/dist/cli/index.js +7 -0
- package/dist/config/index.js +2 -1
- package/dist/config/schema.d.ts +48 -0
- package/dist/config/schema.js +11 -1
- package/dist/parsers/docx-loader.d.ts +5 -0
- package/dist/parsers/docx-loader.js +15 -0
- package/dist/parsers/index.d.ts +3 -0
- package/dist/parsers/index.js +10 -0
- package/dist/parsers/md-loader.d.ts +5 -0
- package/dist/parsers/md-loader.js +13 -0
- package/dist/parsers/registry.d.ts +8 -0
- package/dist/parsers/registry.js +32 -0
- package/dist/parsers/types.d.ts +4 -0
- package/dist/parsers/types.js +1 -0
- package/dist/parsers/xlsx-loader.d.ts +5 -0
- package/dist/parsers/xlsx-loader.js +34 -0
- package/dist/server/__tests__/providers-route.test.js +4 -3
- package/dist/server/__tests__/proxy.test.js +11 -1
- package/dist/server/chat-route.d.ts +3 -0
- package/dist/server/chat-route.js +401 -0
- package/dist/server/claude-settings-route.d.ts +2 -0
- package/dist/server/claude-settings-route.js +76 -0
- package/dist/server/data-push.d.ts +3 -1
- package/dist/server/data-push.js +10 -3
- package/dist/server/docs-route.d.ts +2 -0
- package/dist/server/docs-route.js +63 -0
- package/dist/server/index.js +4 -0
- package/dist/server/mcp-route.d.ts +2 -0
- package/dist/server/mcp-route.js +161 -0
- package/dist/server/proxy.d.ts +4 -1
- package/dist/server/proxy.js +289 -128
- package/dist/server/ui-route.js +123 -46
- package/dist/tools/mcp-bridge.d.ts +13 -0
- package/dist/tools/mcp-bridge.js +36 -0
- package/dist/tools/registry.js +10 -4
- package/dist/ui/assets/{1c-CgVqmGt6.js → 1c-KmWe8RWs.js} +1 -1
- package/dist/ui/assets/{abnf-JPM4b6fj.js → abnf-BKQ6qIuo.js} +1 -1
- package/dist/ui/assets/{abnfDiagram-VRR7QNED-DJkd8PHl.js → abnfDiagram-VRR7QNED-CkRuDPu1.js} +1 -1
- package/dist/ui/assets/{accesslog-CLIMhXWi.js → accesslog-DD9H5Ktc.js} +1 -1
- package/dist/ui/assets/{actionscript-DqniQGld.js → actionscript-CAjf2Qtd.js} +1 -1
- package/dist/ui/assets/{ada-2BFfY7fF.js → ada-BXkXW16O.js} +1 -1
- package/dist/ui/assets/{angelscript-C47qRqcs.js → angelscript-BxT7o0Up.js} +1 -1
- package/dist/ui/assets/{apache-DP-LC5-h.js → apache-C5z_tmVm.js} +1 -1
- package/dist/ui/assets/{applescript-BB0gk3HQ.js → applescript-DdIxl8rr.js} +1 -1
- package/dist/ui/assets/{arc-D8wRCC4D.js → arc-hSdFaqKn.js} +1 -1
- package/dist/ui/assets/{arcade-1R6g1VPm.js → arcade-D5m0roat.js} +1 -1
- package/dist/ui/assets/{architectureDiagram-ZJ3FMSHR-CbHhHV9v.js → architectureDiagram-ZJ3FMSHR-DOSHSqzf.js} +1 -1
- package/dist/ui/assets/{arduino-B8YryK0R.js → arduino-FDap8kq-.js} +1 -1
- package/dist/ui/assets/{armasm-CYdj7mzR.js → armasm-Kzp-Jr1v.js} +1 -1
- package/dist/ui/assets/{asciidoc-bZ11zz6i.js → asciidoc-DbGMW3EE.js} +1 -1
- package/dist/ui/assets/{aspectj-D5WPU-RQ.js → aspectj-CVYMmBCO.js} +1 -1
- package/dist/ui/assets/{autohotkey-70tZvCLL.js → autohotkey-9PmBGTPd.js} +1 -1
- package/dist/ui/assets/{autoit-CX2GaaHP.js → autoit-B4F86jgh.js} +1 -1
- package/dist/ui/assets/{avrasm-C154El0d.js → avrasm-CSzv2eHX.js} +1 -1
- package/dist/ui/assets/{awk-DdXKOeux.js → awk-CjsvYvZE.js} +1 -1
- package/dist/ui/assets/{axapta-CwLwkXST.js → axapta-BVgMoNRY.js} +1 -1
- package/dist/ui/assets/{bash-Uu61S1nB.js → bash-IeBjW3pt.js} +1 -1
- package/dist/ui/assets/{basic-CeiAWoiF.js → basic-BTFJfmV1.js} +1 -1
- package/dist/ui/assets/{blockDiagram-677ZJIJ3-DcvhphUd.js → blockDiagram-677ZJIJ3-DLw3Bbhf.js} +1 -1
- package/dist/ui/assets/{bnf-B5KF61QW.js → bnf-rCkeRYk0.js} +1 -1
- package/dist/ui/assets/{brainfuck-CP0Y7_VW.js → brainfuck-DBHuB3uZ.js} +1 -1
- package/dist/ui/assets/{coq-D-WTlq_d.js → c-C95V0zHL.js} +1 -1
- package/dist/ui/assets/{c-like-DXr53gS6.js → c-like-CK1xGeX_.js} +1 -1
- package/dist/ui/assets/{c4Diagram-LMCZKHZV-Cn017lmJ.js → c4Diagram-LMCZKHZV-cqY51yJw.js} +1 -1
- package/dist/ui/assets/{cal-7ld1j-Wh.js → cal-BxGPpEZK.js} +1 -1
- package/dist/ui/assets/{capnproto-DrddNBCZ.js → capnproto-Bo2fgXF9.js} +1 -1
- package/dist/ui/assets/{ceylon-XPuE6IIL.js → ceylon-C4Bb4pNB.js} +1 -1
- package/dist/ui/assets/channel-D9Y4iN1l.js +1 -0
- package/dist/ui/assets/{chunk-2Q5K7J3B-BoX3IESS.js → chunk-2Q5K7J3B-CGTiTBmo.js} +1 -1
- package/dist/ui/assets/{chunk-32BRIVSS-C300ACzq.js → chunk-32BRIVSS-DWagYBp9.js} +1 -1
- package/dist/ui/assets/{chunk-5VM5RSS4-MtSkFsde.js → chunk-5VM5RSS4-BzSBMKJX.js} +1 -1
- package/dist/ui/assets/{chunk-EX3LRPZG-CEeHrGNV.js → chunk-EX3LRPZG-4-aKwCgZ.js} +1 -1
- package/dist/ui/assets/{chunk-JWPE2WC7-DTRgpK0R.js → chunk-JWPE2WC7-CPC_cBN0.js} +1 -1
- package/dist/ui/assets/{chunk-MOJQB5TN-DiOl0HJx.js → chunk-MOJQB5TN-DrDE4H9w.js} +1 -1
- package/dist/ui/assets/{chunk-RYQCIY6F-CVC3opqY.js → chunk-RYQCIY6F-DkdXe_kU.js} +1 -1
- package/dist/ui/assets/{chunk-V7JOEXUC-yQYlqQCC.js → chunk-V7JOEXUC-Da6EWcQt.js} +1 -1
- package/dist/ui/assets/{chunk-VR4S4FIN-iAA8ZgkK.js → chunk-VR4S4FIN-nP6dstD5.js} +1 -1
- package/dist/ui/assets/{chunk-XXDRQBXY-B303eieF.js → chunk-XXDRQBXY-Bi_rRAPA.js} +1 -1
- package/dist/ui/assets/classDiagram-OUVF2IWQ-C4UVH6RI.js +1 -0
- package/dist/ui/assets/classDiagram-v2-EOCWNBFH-C4UVH6RI.js +1 -0
- package/dist/ui/assets/{clean-MfHaW_uS.js → clean-cc1m9AxK.js} +1 -1
- package/dist/ui/assets/{clojure-9L8TfiWA.js → clojure-DX5V8QA8.js} +1 -1
- package/dist/ui/assets/{clojure-repl-CjsH9sxr.js → clojure-repl-FzjnVNWQ.js} +1 -1
- package/dist/ui/assets/{cmake-D0D1Q30G.js → cmake-COZZyrKs.js} +1 -1
- package/dist/ui/assets/{coffeescript-BI4jWZnB.js → coffeescript-DBsnOmC4.js} +1 -1
- package/dist/ui/assets/{c-BgqCrSpv.js → coq-TwFFolHa.js} +1 -1
- package/dist/ui/assets/{cos-DHax5LIJ.js → cos-Dm5g-IQT.js} +1 -1
- package/dist/ui/assets/{cose-bilkent-JH36ORCC-BzrKmTAZ.js → cose-bilkent-JH36ORCC-B3-weOQF.js} +1 -1
- package/dist/ui/assets/{cpp-M4aMPUas.js → cpp-_RZxQjg7.js} +1 -1
- package/dist/ui/assets/{crmsh-DAAczfR0.js → crmsh-DGPJ11Gt.js} +1 -1
- package/dist/ui/assets/{crystal-7g2CpWm4.js → crystal-BOMSPGge.js} +1 -1
- package/dist/ui/assets/{csharp-DW5GdKKf.js → csharp-DZXiHH72.js} +1 -1
- package/dist/ui/assets/{csp-Bq74fG7-.js → csp-DDSIMUoU.js} +1 -1
- package/dist/ui/assets/{css-DHyeLXff.js → css-Bjye-ZWr.js} +1 -1
- package/dist/ui/assets/{cynefin-VYW2F7L2-DwV1t9iV.js → cynefin-VYW2F7L2-Cj5c4L3y.js} +1 -1
- package/dist/ui/assets/{cynefinDiagram-TSTJHNR4-kBCFRYPz.js → cynefinDiagram-TSTJHNR4-BYsfTeNX.js} +1 -1
- package/dist/ui/assets/{d-yey2lm3v.js → d-22pfurOx.js} +1 -1
- package/dist/ui/assets/{dagre-VKFMJZFB-CErVJ1s0.js → dagre-VKFMJZFB-DiEob-by.js} +1 -1
- package/dist/ui/assets/{dart-BadDxflP.js → dart-Doiu8cDW.js} +1 -1
- package/dist/ui/assets/{delphi-CqzVqtDp.js → delphi-CQ7epp84.js} +1 -1
- package/dist/ui/assets/{diagram-FQU43EPY-C7zAW2DU.js → diagram-FQU43EPY-BOPbQcL4.js} +1 -1
- package/dist/ui/assets/{diagram-G47NLZAW-CbUb6BZI.js → diagram-G47NLZAW-C1UWDJTx.js} +1 -1
- package/dist/ui/assets/{diagram-NH7WQ7WH-C5mgi3dn.js → diagram-NH7WQ7WH-CYsBqW3J.js} +1 -1
- package/dist/ui/assets/{diagram-OA4YK3LP-Cok2YNfS.js → diagram-OA4YK3LP-Dnag0x_3.js} +1 -1
- package/dist/ui/assets/{diagram-WEI45ONY-BODuP2EB.js → diagram-WEI45ONY-Bo4CsDoj.js} +1 -1
- package/dist/ui/assets/{diff-EVigJ-h2.js → diff-Cs6VQQZt.js} +1 -1
- package/dist/ui/assets/{django-BH2EEal6.js → django-Bo3okOrw.js} +1 -1
- package/dist/ui/assets/{dns-BSc8VTm8.js → dns-BpG60eIX.js} +1 -1
- package/dist/ui/assets/{dockerfile-Br_pZjru.js → dockerfile-BWyH8SlV.js} +1 -1
- package/dist/ui/assets/{dos-Bx3ludet.js → dos-DWlNbaB9.js} +1 -1
- package/dist/ui/assets/{dsconfig-DSI-ePne.js → dsconfig-D_8y8YrJ.js} +1 -1
- package/dist/ui/assets/{dts-ClCuE1Xq.js → dts-Cz4SyMYR.js} +1 -1
- package/dist/ui/assets/{dust-CC9Z8iuW.js → dust-Cu4qLkeH.js} +1 -1
- package/dist/ui/assets/{ebnf-DI0w_fbi.js → ebnf-CTVHui3r.js} +1 -1
- package/dist/ui/assets/{ebnfDiagram-CCIWWBDH-CgsnO8Qm.js → ebnfDiagram-CCIWWBDH-epcXQLEj.js} +1 -1
- package/dist/ui/assets/{elixir-hdzZik8p.js → elixir-MAlwXhfU.js} +1 -1
- package/dist/ui/assets/{elm-DJAgqt5I.js → elm-Bdmwbvef.js} +1 -1
- package/dist/ui/assets/{erDiagram-Q63AITRT-K4zJcEKd.js → erDiagram-Q63AITRT-Bb60TqAM.js} +1 -1
- package/dist/ui/assets/{erb-Cq4OQqkl.js → erb-Ce9TpP4g.js} +1 -1
- package/dist/ui/assets/{erlang-CHoXLODu.js → erlang-CN2GEiqk.js} +1 -1
- package/dist/ui/assets/{erlang-repl-Brp70Zip.js → erlang-repl-D8K4O_cp.js} +1 -1
- package/dist/ui/assets/{excel-DjS-QR9P.js → excel-eVZU1r0f.js} +1 -1
- package/dist/ui/assets/{fix-BsO9Oq6H.js → fix-BzKerEv0.js} +1 -1
- package/dist/ui/assets/{flix-2A7CKozm.js → flix-B9CE3skV.js} +1 -1
- package/dist/ui/assets/{flowDiagram-23GEKE2U-Ck4tfxWX.js → flowDiagram-23GEKE2U-DzMLZIyt.js} +1 -1
- package/dist/ui/assets/{fortran-BQu3wORI.js → fortran-B4__3vos.js} +1 -1
- package/dist/ui/assets/{fsharp-D439S6PZ.js → fsharp-BJ3-ARHz.js} +1 -1
- package/dist/ui/assets/{gams-CPRxKfRH.js → gams-Cu43oSYT.js} +1 -1
- package/dist/ui/assets/{ganttDiagram-NO4QXBWP-QTPyXXxa.js → ganttDiagram-NO4QXBWP-D_aAoMRP.js} +1 -1
- package/dist/ui/assets/{gauss-GJFW9Vod.js → gauss-T8vk_TpE.js} +1 -1
- package/dist/ui/assets/{gcode-CF6woDAl.js → gcode-9j3BicpZ.js} +1 -1
- package/dist/ui/assets/{gherkin-Co-YjHfW.js → gherkin-Dyh5KFG-.js} +1 -1
- package/dist/ui/assets/{gitGraphDiagram-IHSO6WYX-Do9VfPHL.js → gitGraphDiagram-IHSO6WYX-CMxCHC-Z.js} +1 -1
- package/dist/ui/assets/{glsl-D3lldBTJ.js → glsl-DWWjN4ts.js} +1 -1
- package/dist/ui/assets/{gml-DyoCibnw.js → gml-BcYE-D5A.js} +1 -1
- package/dist/ui/assets/{go-BNeAS1jC.js → go-DUnUzOEI.js} +1 -1
- package/dist/ui/assets/{golo-BuXecWAH.js → golo-BDoc1QQL.js} +1 -1
- package/dist/ui/assets/{gradle-BP7ToLe9.js → gradle-B_WRa_bT.js} +1 -1
- package/dist/ui/assets/{groovy-GqWVT09g.js → groovy-CgjqFq1e.js} +1 -1
- package/dist/ui/assets/{haml-SLbvCHsC.js → haml-DCqcg7Ti.js} +1 -1
- package/dist/ui/assets/{handlebars-BnaCJTc5.js → handlebars-DSDUQrnw.js} +1 -1
- package/dist/ui/assets/{haskell-CrX9ftWp.js → haskell-DPVnctVi.js} +1 -1
- package/dist/ui/assets/{haxe-DNoaIxsE.js → haxe-BuCGXBa4.js} +1 -1
- package/dist/ui/assets/{hsp-CLjy3djj.js → hsp-BTKpS_u0.js} +1 -1
- package/dist/ui/assets/{htmlbars-w96Kz5NL.js → htmlbars-Cql3Jvy2.js} +1 -1
- package/dist/ui/assets/{http-VIMXIxM8.js → http-BB8I9jUh.js} +1 -1
- package/dist/ui/assets/{hy-_qE83_aW.js → hy-DG7xkZNz.js} +1 -1
- package/dist/ui/assets/index-CK_lJsTu.css +10 -0
- package/dist/ui/assets/index-CfTIGTiY.js +2677 -0
- package/dist/ui/assets/{index-DpcPfZl3.js → index-DqIiCkSD.js} +3 -3
- package/dist/ui/assets/{infoDiagram-FWYZ7A6U-D9O7SZ2X.js → infoDiagram-FWYZ7A6U-DIzEV-BJ.js} +1 -1
- package/dist/ui/assets/{inform7-CnyW73C1.js → inform7-BWNpVEkA.js} +1 -1
- package/dist/ui/assets/{ini-GFMFAjln.js → ini-BMw_C8EP.js} +1 -1
- package/dist/ui/assets/{irpf90-BPmSYATn.js → irpf90-Cy42ibFZ.js} +1 -1
- package/dist/ui/assets/{isbl-BnStGiBQ.js → isbl-CjFSc0hz.js} +1 -1
- package/dist/ui/assets/{ishikawaDiagram-FXEZZL3T-DgcUDM9X.js → ishikawaDiagram-FXEZZL3T-BZcxp5am.js} +1 -1
- package/dist/ui/assets/{java-CVORcFd8.js → java-BDxe9dp1.js} +1 -1
- package/dist/ui/assets/{javascript-B2pFzODm.js → javascript-CgLkkj7h.js} +1 -1
- package/dist/ui/assets/{jboss-cli-B9cQeKvZ.js → jboss-cli-C8biclrb.js} +1 -1
- package/dist/ui/assets/{journeyDiagram-5HDEW3XC-Bivjw4h7.js → journeyDiagram-5HDEW3XC-BbJu6m6Q.js} +1 -1
- package/dist/ui/assets/{json-BJof8L10.js → json-BjJKhmM6.js} +1 -1
- package/dist/ui/assets/{julia-D_dGrCpZ.js → julia-DvKEpg-R.js} +1 -1
- package/dist/ui/assets/{julia-repl-Dsw0K1B1.js → julia-repl-BDJWZxkU.js} +1 -1
- package/dist/ui/assets/{kanban-definition-HUTT4EX6-Dg7NbKta.js → kanban-definition-HUTT4EX6-DeIVPlbv.js} +1 -1
- package/dist/ui/assets/{kotlin-8oetHRtX.js → kotlin-DCoXcnEb.js} +1 -1
- package/dist/ui/assets/{lasso-e37r_NX1.js → lasso-C7m0QmV2.js} +1 -1
- package/dist/ui/assets/{latex-DAmwzl3n.js → latex-SHnTG9Eq.js} +1 -1
- package/dist/ui/assets/{ldif-CD0mgmt4.js → ldif-_6hUnKPV.js} +1 -1
- package/dist/ui/assets/{leaf-GfPKlp7a.js → leaf-Co9qxlaF.js} +1 -1
- package/dist/ui/assets/{less-PndaZJ6n.js → less-CJRDPwNA.js} +1 -1
- package/dist/ui/assets/{lisp-CNaspu3A.js → lisp-JEHGYbiW.js} +1 -1
- package/dist/ui/assets/{livecodeserver-DEKsXiP3.js → livecodeserver-BSYaUj4k.js} +1 -1
- package/dist/ui/assets/{livescript-DM7jasJn.js → livescript-WQMCQeuz.js} +1 -1
- package/dist/ui/assets/{llvm-D_29j9MV.js → llvm-DnAHqj5I.js} +1 -1
- package/dist/ui/assets/{lsl-DY0WRYhg.js → lsl--k-ghYia.js} +1 -1
- package/dist/ui/assets/{lua-DZ_v4xaE.js → lua-CXb23hbC.js} +1 -1
- package/dist/ui/assets/{makefile-VOjcUGXf.js → makefile-CM7o86yn.js} +1 -1
- package/dist/ui/assets/{markdown-yUEmZWvu.js → markdown-HB3HvChQ.js} +1 -1
- package/dist/ui/assets/{mathematica-BLXYGKkd.js → mathematica-9NTuf22N.js} +1 -1
- package/dist/ui/assets/{matlab-B7SkIpvh.js → matlab-CWv-ik4r.js} +1 -1
- package/dist/ui/assets/{maxima-C7Fw8Vyt.js → maxima-CqYiKCrw.js} +1 -1
- package/dist/ui/assets/{mel-C_Znst2Y.js → mel-BbsRpUm5.js} +1 -1
- package/dist/ui/assets/{mercury-DjUnQNsq.js → mercury-Cz2j4HhU.js} +1 -1
- package/dist/ui/assets/{mindmap-definition-LN4V7U3C-Dp6mEy6L.js → mindmap-definition-LN4V7U3C-WyJS8oye.js} +1 -1
- package/dist/ui/assets/{mipsasm-DaGHhR8c.js → mipsasm-BqWSRbQV.js} +1 -1
- package/dist/ui/assets/{mizar-CZnct-_Z.js → mizar-JLBfQ6vt.js} +1 -1
- package/dist/ui/assets/{mojolicious-BdWFK35j.js → mojolicious-D0LbMmyk.js} +1 -1
- package/dist/ui/assets/{monkey-ta_jgafo.js → monkey-DAGL6-JN.js} +1 -1
- package/dist/ui/assets/{moonscript-B9qovjV6.js → moonscript-DzbwNSKy.js} +1 -1
- package/dist/ui/assets/{n1ql-BciXbxiw.js → n1ql-dkgKq6Yv.js} +1 -1
- package/dist/ui/assets/{nginx-DRCZYbxj.js → nginx-AUoaDPV4.js} +1 -1
- package/dist/ui/assets/{nim-DTMCxPJt.js → nim-CdqYmVrl.js} +1 -1
- package/dist/ui/assets/{nix-D39yZxF9.js → nix-CxmVjwwo.js} +1 -1
- package/dist/ui/assets/{node-repl-vAEXdnYM.js → node-repl-B1Z3zUAh.js} +1 -1
- package/dist/ui/assets/{nsis-CCMP8mq3.js → nsis-CTAuPWhe.js} +1 -1
- package/dist/ui/assets/{objectivec-CZx4kSLP.js → objectivec-CvbKeAPz.js} +1 -1
- package/dist/ui/assets/{ocaml-DBnEo9uR.js → ocaml-DCiyXKOH.js} +1 -1
- package/dist/ui/assets/{openscad-BKc7u4Bl.js → openscad-CPGUwmeR.js} +1 -1
- package/dist/ui/assets/{oxygene-M_Z4lQ6l.js → oxygene-CI_bD1Gw.js} +1 -1
- package/dist/ui/assets/{parser3-DS9UKiKD.js → parser3-C91CVs85.js} +1 -1
- package/dist/ui/assets/{pegDiagram-2B236MQR-BBEXn76M.js → pegDiagram-2B236MQR-yF8AW7GR.js} +1 -1
- package/dist/ui/assets/{perl-D6iEALGE.js → perl-ChxfKl-n.js} +1 -1
- package/dist/ui/assets/{pf-JQL0ClGi.js → pf-CKCHkzIA.js} +1 -1
- package/dist/ui/assets/{pgsql-DEmCURBr.js → pgsql-BwOP20uH.js} +1 -1
- package/dist/ui/assets/{php-DVm-0PY5.js → php-B7Rs2tM5.js} +1 -1
- package/dist/ui/assets/{php-template-DfWbDpnE.js → php-template-Cx-Fh4AR.js} +1 -1
- package/dist/ui/assets/{pieDiagram-ENE6RG2P-D5PZFiDj.js → pieDiagram-ENE6RG2P-BS4hnGNX.js} +1 -1
- package/dist/ui/assets/{plaintext-BahVkGlu.js → plaintext-U7qkdtgS.js} +1 -1
- package/dist/ui/assets/{pony-wVig0caC.js → pony-_fGYgePh.js} +1 -1
- package/dist/ui/assets/{powershell-COjMBUit.js → powershell-CFBTcUce.js} +1 -1
- package/dist/ui/assets/{processing-DnUzvFZx.js → processing-BWHneU0K.js} +1 -1
- package/dist/ui/assets/{profile-mDlbwJeL.js → profile-BJ-HxhzS.js} +1 -1
- package/dist/ui/assets/{prolog-x2hG6DnA.js → prolog-ChHo7n6L.js} +1 -1
- package/dist/ui/assets/{properties-DzZyyivC.js → properties-e_DOYclC.js} +1 -1
- package/dist/ui/assets/{protobuf-a5NwbYD5.js → protobuf-5aGSIv7w.js} +1 -1
- package/dist/ui/assets/{puppet-CCWyPVuC.js → puppet-D2vQatzX.js} +1 -1
- package/dist/ui/assets/{purebasic-CXNdqtD4.js → purebasic-n6krfaeF.js} +1 -1
- package/dist/ui/assets/{python-iSR9YlDJ.js → python-CbIo0XxP.js} +1 -1
- package/dist/ui/assets/{python-repl-CCmKzWru.js → python-repl-BpIq9kyr.js} +1 -1
- package/dist/ui/assets/{q-B30ZmDuD.js → q-jntnvcCx.js} +1 -1
- package/dist/ui/assets/{qml-BGdPdB4X.js → qml-BafQlZNV.js} +1 -1
- package/dist/ui/assets/{quadrantDiagram-ABIIQ3AL-BBF1rAvI.js → quadrantDiagram-ABIIQ3AL-C3Th8mUJ.js} +1 -1
- package/dist/ui/assets/{r-B8ASdWL1.js → r-CHgvQFLK.js} +1 -1
- package/dist/ui/assets/{railroadDiagram-RFXS5EU6-DQFUXGVD.js → railroadDiagram-RFXS5EU6-CMQkbGJl.js} +1 -1
- package/dist/ui/assets/{reasonml-Dw4Bi5B5.js → reasonml-DNwlPD_T.js} +1 -1
- package/dist/ui/assets/{requirementDiagram-TGXJPOKE-DCgrs7-P.js → requirementDiagram-TGXJPOKE-B70_oR7v.js} +1 -1
- package/dist/ui/assets/{rib-CgUGGGZ9.js → rib-CX4e9JSF.js} +1 -1
- package/dist/ui/assets/{roboconf-CCZNQvSP.js → roboconf-ee4qsPGf.js} +1 -1
- package/dist/ui/assets/{routeros-DVT5M6iV.js → routeros-BJSwvu2L.js} +1 -1
- package/dist/ui/assets/{rsl-BY-LhdKq.js → rsl-BiKdMl_F.js} +1 -1
- package/dist/ui/assets/{ruby-CZW4dclw.js → ruby-CAXTU5LY.js} +1 -1
- package/dist/ui/assets/{ruleslanguage-CZdjv1of.js → ruleslanguage-C1kgDGXM.js} +1 -1
- package/dist/ui/assets/{rust-D5Xa_mSD.js → rust-DyEf_GXL.js} +1 -1
- package/dist/ui/assets/{sankeyDiagram-HTMAVEWB-BXeEgUB7.js → sankeyDiagram-HTMAVEWB-CvUfseMg.js} +1 -1
- package/dist/ui/assets/{sas-B_UJ-HCZ.js → sas-Q1rlUxPH.js} +1 -1
- package/dist/ui/assets/{scala-B8wSdZik.js → scala-Dg6KNmge.js} +1 -1
- package/dist/ui/assets/{scheme-DD7U81eh.js → scheme-D9iooUxI.js} +1 -1
- package/dist/ui/assets/{scilab-aJGpbkKs.js → scilab-CztEJXJY.js} +1 -1
- package/dist/ui/assets/{scss-BBqyvWYh.js → scss-BMh-JkdE.js} +1 -1
- package/dist/ui/assets/{sequenceDiagram-DBY2YBRQ-CnDTZN18.js → sequenceDiagram-DBY2YBRQ-DB0c9kf4.js} +1 -1
- package/dist/ui/assets/{shell-CR23jqfz.js → shell-DWo6z0MG.js} +1 -1
- package/dist/ui/assets/{sizeCapture-X5ZJPWSS-joZ477RB.js → sizeCapture-X5ZJPWSS-BcQlgjfD.js} +1 -1
- package/dist/ui/assets/{smali-ZmLyRCrQ.js → smali-Cijeb6pL.js} +1 -1
- package/dist/ui/assets/{smalltalk-CnADYfPr.js → smalltalk-D0lvqa_d.js} +1 -1
- package/dist/ui/assets/{sml-zj1KD04_.js → sml-B-vqWZ3b.js} +1 -1
- package/dist/ui/assets/{sqf-DCCaZ3e3.js → sqf-BJ-1Q583.js} +1 -1
- package/dist/ui/assets/{sql-CHGw2SCR.js → sql-CMGLxEYV.js} +1 -1
- package/dist/ui/assets/{sql_more-DsnvjMwh.js → sql_more-gsRmbNCH.js} +1 -1
- package/dist/ui/assets/{stan-ChxdV8f9.js → stan-D1AlTSpf.js} +1 -1
- package/dist/ui/assets/{stata-CgFw45qg.js → stata-DnEYviI0.js} +1 -1
- package/dist/ui/assets/{stateDiagram-2N3HPSRC-CzLIdKbt.js → stateDiagram-2N3HPSRC-BSRgVsHO.js} +1 -1
- package/dist/ui/assets/stateDiagram-v2-6OUMAXLB-BLdfpGJO.js +1 -0
- package/dist/ui/assets/{step21-DaraQMOk.js → step21-DbQV9sMo.js} +1 -1
- package/dist/ui/assets/{stylus-BZpiJEzN.js → stylus-Cyc7vdUc.js} +1 -1
- package/dist/ui/assets/{subunit-B6Gp0n7h.js → subunit-16ipyMie.js} +1 -1
- package/dist/ui/assets/{swift-DQzoz60p.js → swift-DTNnw4qS.js} +1 -1
- package/dist/ui/assets/{swimlanes-5IMT3BWC-DOMOhwX0.js → swimlanes-5IMT3BWC-DgOdcc4_.js} +2 -2
- package/dist/ui/assets/swimlanesDiagram-G3AALYLV-DRVnkg3M.js +8 -0
- package/dist/ui/assets/{taggerscript-BMLkfiab.js → taggerscript-DM6pvUWE.js} +1 -1
- package/dist/ui/assets/{tap-PUNWTFgu.js → tap-Ch-uyKZq.js} +1 -1
- package/dist/ui/assets/{tcl-BODH5qJa.js → tcl-D0T_V5dA.js} +1 -1
- package/dist/ui/assets/{thrift-BQ-W_YlC.js → thrift-D9xJjYw4.js} +1 -1
- package/dist/ui/assets/{timeline-definition-FHXFAJF6-DQBDeTzH.js → timeline-definition-FHXFAJF6-BBeDMHxb.js} +1 -1
- package/dist/ui/assets/{tp-Dt3WwOGF.js → tp-kUrCGo9X.js} +1 -1
- package/dist/ui/assets/{twig-44RQtw7Z.js → twig-Cgub6rxA.js} +1 -1
- package/dist/ui/assets/{typescript-BsouHXHR.js → typescript-BxNP9Ap9.js} +1 -1
- package/dist/ui/assets/{vala-DqJj6fPT.js → vala-DF9ZZagU.js} +1 -1
- package/dist/ui/assets/{vbnet-CuqWYg5r.js → vbnet-Cf46ypDg.js} +1 -1
- package/dist/ui/assets/{vbscript-w20MQMYP.js → vbscript-DNs-QKLH.js} +1 -1
- package/dist/ui/assets/{vbscript-html-BP0D0WEV.js → vbscript-html-DyS6I5L1.js} +1 -1
- package/dist/ui/assets/{vennDiagram-L72KCM5P-DwNnj3Kc.js → vennDiagram-L72KCM5P-8WpWycE-.js} +1 -1
- package/dist/ui/assets/{verilog-DIpBpJAe.js → verilog-CF5wC4X-.js} +1 -1
- package/dist/ui/assets/{vhdl-D5nCxDbL.js → vhdl-Dm0jpDMn.js} +1 -1
- package/dist/ui/assets/{vim-CPfbBM_x.js → vim-nyO2DRAx.js} +1 -1
- package/dist/ui/assets/{wardleyDiagram-EHGQE667-WxVQHmM7.js → wardleyDiagram-EHGQE667-UeIOK-jv.js} +1 -1
- package/dist/ui/assets/{x86asm-D_t4Z_eq.js → x86asm-BNw2-6GG.js} +1 -1
- package/dist/ui/assets/{xl-DQf5IG_W.js → xl-D-YHxr6V.js} +1 -1
- package/dist/ui/assets/{xml-D-Bn0NMR.js → xml-BijAlrow.js} +1 -1
- package/dist/ui/assets/{xquery-DqushYX1.js → xquery-z0wxWBKz.js} +1 -1
- package/dist/ui/assets/{xychartDiagram-FW5EYKEG-B6D8mgs8.js → xychartDiagram-FW5EYKEG-BNzHLweN.js} +1 -1
- package/dist/ui/assets/{yaml-B2GFZenc.js → yaml-n5TIQArR.js} +1 -1
- package/dist/ui/assets/{zephir-SiNGockR.js → zephir-DrGhH8jG.js} +1 -1
- package/dist/ui/index.html +2 -2
- package/dist/utils/__tests__/providers-db.test.js +2 -1
- package/dist/utils/__tests__/tool-injector.test.js +32 -35
- package/dist/utils/db.d.ts +3 -0
- package/dist/utils/db.js +54 -0
- package/dist/utils/inject-loop.d.ts +52 -1
- package/dist/utils/inject-loop.js +70 -2
- package/dist/utils/mcp-db.d.ts +35 -0
- package/dist/utils/mcp-db.js +79 -0
- package/dist/utils/mcp-manager.d.ts +36 -0
- package/dist/utils/mcp-manager.js +215 -0
- package/dist/utils/openai-converter.d.ts +99 -0
- package/dist/utils/openai-converter.js +293 -0
- package/dist/utils/providers-db.d.ts +2 -0
- package/dist/utils/providers-db.js +19 -7
- package/dist/utils/request-writer.d.ts +20 -0
- package/dist/utils/request-writer.js +184 -4
- package/dist/utils/sse-stream-processor.d.ts +27 -0
- package/dist/utils/sse-stream-processor.js +144 -0
- package/dist/utils/stats-aggregator.js +2 -0
- package/dist/utils/status-history.js +3 -3
- package/dist/utils/tool-injector.d.ts +6 -9
- package/dist/utils/tool-injector.js +13 -14
- package/dist/utils/version.d.ts +6 -0
- package/dist/utils/version.js +11 -1
- package/package.json +14 -12
- package/dist/ui/assets/channel-C5JlZ38H.js +0 -1
- package/dist/ui/assets/classDiagram-OUVF2IWQ-j5FVBKaD.js +0 -1
- package/dist/ui/assets/classDiagram-v2-EOCWNBFH-j5FVBKaD.js +0 -1
- package/dist/ui/assets/index-Baqd6LlK.js +0 -2625
- package/dist/ui/assets/index-fHtNI_e8.css +0 -1
- package/dist/ui/assets/stateDiagram-v2-6OUMAXLB-Bg4GAkB5.js +0 -1
- package/dist/ui/assets/swimlanesDiagram-G3AALYLV-99wEK8yq.js +0 -8
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
import { Transform } from 'stream';
|
|
2
|
+
/**
|
|
3
|
+
* Recursively cleans a JSON Schema for OpenAI API compatibility.
|
|
4
|
+
* Removes '$schema' and 'additionalProperties'.
|
|
5
|
+
* For string types, removes 'format' unless it's 'date-time' or 'enum'.
|
|
6
|
+
*/
|
|
7
|
+
function recursivelyCleanSchema(schema) {
|
|
8
|
+
if (schema === null || typeof schema !== 'object')
|
|
9
|
+
return schema;
|
|
10
|
+
if (Array.isArray(schema))
|
|
11
|
+
return schema.map(item => recursivelyCleanSchema(item));
|
|
12
|
+
const newSchema = {};
|
|
13
|
+
for (const key in schema) {
|
|
14
|
+
if (Object.prototype.hasOwnProperty.call(schema, key)) {
|
|
15
|
+
if (key === '$schema' || key === 'additionalProperties')
|
|
16
|
+
continue;
|
|
17
|
+
newSchema[key] = recursivelyCleanSchema(schema[key]);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
if (newSchema.type === 'string' && newSchema.format) {
|
|
21
|
+
const supportedFormats = ['date-time', 'enum'];
|
|
22
|
+
if (!supportedFormats.includes(newSchema.format)) {
|
|
23
|
+
delete newSchema.format;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return newSchema;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Converts a Claude API request body to OpenAI format.
|
|
30
|
+
*/
|
|
31
|
+
export function convertClaudeToOpenAIRequest(claudeRequest, modelName) {
|
|
32
|
+
const openaiMessages = [];
|
|
33
|
+
if (claudeRequest.system) {
|
|
34
|
+
const systemContent = typeof claudeRequest.system === 'string'
|
|
35
|
+
? claudeRequest.system
|
|
36
|
+
: Array.isArray(claudeRequest.system)
|
|
37
|
+
? claudeRequest.system.map((block) => block.type === 'text' ? block.text : '').join('\n')
|
|
38
|
+
: String(claudeRequest.system);
|
|
39
|
+
openaiMessages.push({ role: 'system', content: systemContent });
|
|
40
|
+
}
|
|
41
|
+
for (const message of claudeRequest.messages) {
|
|
42
|
+
if (message.role === 'user') {
|
|
43
|
+
if (Array.isArray(message.content)) {
|
|
44
|
+
const toolResults = message.content.filter(c => c.type === 'tool_result');
|
|
45
|
+
const otherContent = message.content.filter(c => c.type !== 'tool_result');
|
|
46
|
+
if (toolResults.length > 0) {
|
|
47
|
+
toolResults.forEach(block => {
|
|
48
|
+
openaiMessages.push({
|
|
49
|
+
role: 'tool',
|
|
50
|
+
tool_call_id: block.tool_use_id,
|
|
51
|
+
content: typeof block.content === 'string' ? block.content : JSON.stringify(block.content),
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
if (otherContent.length > 0) {
|
|
56
|
+
openaiMessages.push({
|
|
57
|
+
role: 'user',
|
|
58
|
+
content: otherContent.map(block => block.type === 'text'
|
|
59
|
+
? { type: 'text', text: block.text }
|
|
60
|
+
: { type: 'image_url', image_url: { url: `data:${block.source.media_type};base64,${block.source.data}` } })
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
openaiMessages.push({ role: 'user', content: message.content });
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
else if (message.role === 'assistant') {
|
|
69
|
+
const textParts = [];
|
|
70
|
+
const toolCalls = [];
|
|
71
|
+
if (Array.isArray(message.content)) {
|
|
72
|
+
message.content.forEach(block => {
|
|
73
|
+
if (block.type === 'text') {
|
|
74
|
+
textParts.push(block.text);
|
|
75
|
+
}
|
|
76
|
+
else if (block.type === 'tool_use') {
|
|
77
|
+
toolCalls.push({
|
|
78
|
+
id: block.id,
|
|
79
|
+
type: 'function',
|
|
80
|
+
function: { name: block.name, arguments: JSON.stringify(block.input || {}) },
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
const assistantMessage = {
|
|
86
|
+
role: 'assistant',
|
|
87
|
+
content: textParts.join('\n') || null
|
|
88
|
+
};
|
|
89
|
+
if (toolCalls.length > 0) {
|
|
90
|
+
assistantMessage.tool_calls = toolCalls;
|
|
91
|
+
}
|
|
92
|
+
openaiMessages.push(assistantMessage);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
const openaiRequest = {
|
|
96
|
+
model: modelName,
|
|
97
|
+
messages: openaiMessages,
|
|
98
|
+
max_tokens: claudeRequest.max_tokens,
|
|
99
|
+
temperature: claudeRequest.temperature,
|
|
100
|
+
top_p: claudeRequest.top_p,
|
|
101
|
+
stream: claudeRequest.stream,
|
|
102
|
+
stop: claudeRequest.stop_sequences,
|
|
103
|
+
};
|
|
104
|
+
if (claudeRequest.tools) {
|
|
105
|
+
openaiRequest.tools = claudeRequest.tools.map((tool) => {
|
|
106
|
+
const cleanedParameters = recursivelyCleanSchema(tool.input_schema);
|
|
107
|
+
return {
|
|
108
|
+
type: 'function',
|
|
109
|
+
function: {
|
|
110
|
+
name: tool.name,
|
|
111
|
+
description: tool.description,
|
|
112
|
+
parameters: cleanedParameters,
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
if (claudeRequest.tool_choice) {
|
|
118
|
+
if (claudeRequest.tool_choice.type === 'auto' || claudeRequest.tool_choice.type === 'any') {
|
|
119
|
+
openaiRequest.tool_choice = 'auto';
|
|
120
|
+
}
|
|
121
|
+
else if (claudeRequest.tool_choice.type === 'tool') {
|
|
122
|
+
openaiRequest.tool_choice = { type: 'function', function: { name: claudeRequest.tool_choice.name } };
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return openaiRequest;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Converts a non-streaming OpenAI response to Claude format.
|
|
129
|
+
*/
|
|
130
|
+
export function convertOpenAIToClaudeResponse(openaiResponse, model) {
|
|
131
|
+
const choice = openaiResponse.choices[0];
|
|
132
|
+
const contentBlocks = [];
|
|
133
|
+
if (choice.message.content) {
|
|
134
|
+
contentBlocks.push({ type: 'text', text: choice.message.content });
|
|
135
|
+
}
|
|
136
|
+
if (choice.message.tool_calls) {
|
|
137
|
+
choice.message.tool_calls.forEach((call) => {
|
|
138
|
+
contentBlocks.push({
|
|
139
|
+
type: 'tool_use',
|
|
140
|
+
id: call.id,
|
|
141
|
+
name: call.function.name,
|
|
142
|
+
input: JSON.parse(call.function.arguments),
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
const stopReasonMap = {
|
|
147
|
+
stop: 'end_turn',
|
|
148
|
+
length: 'max_tokens',
|
|
149
|
+
tool_calls: 'tool_use'
|
|
150
|
+
};
|
|
151
|
+
return {
|
|
152
|
+
id: openaiResponse.id,
|
|
153
|
+
type: 'message',
|
|
154
|
+
role: 'assistant',
|
|
155
|
+
model,
|
|
156
|
+
content: contentBlocks,
|
|
157
|
+
stop_reason: stopReasonMap[choice.finish_reason] || 'end_turn',
|
|
158
|
+
usage: {
|
|
159
|
+
input_tokens: openaiResponse.usage.prompt_tokens,
|
|
160
|
+
output_tokens: openaiResponse.usage.completion_tokens,
|
|
161
|
+
},
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Builds headers for OpenAI-compatible API requests.
|
|
166
|
+
*/
|
|
167
|
+
export function buildOpenAIHeaders(apiKey) {
|
|
168
|
+
return {
|
|
169
|
+
'Content-Type': 'application/json',
|
|
170
|
+
'Authorization': `Bearer ${apiKey}`,
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Creates a Node.js Transform stream that converts OpenAI SSE chunks to Claude SSE events.
|
|
175
|
+
*/
|
|
176
|
+
export function createStreamTransformer(model) {
|
|
177
|
+
let initialized = false;
|
|
178
|
+
let buffer = '';
|
|
179
|
+
const messageId = `msg_${Math.random().toString(36).substr(2, 9)}`;
|
|
180
|
+
const toolCalls = {};
|
|
181
|
+
let contentBlockIndex = 0;
|
|
182
|
+
const sendEvent = (event, data) => {
|
|
183
|
+
return `event: ${event}\ndata: ${JSON.stringify(data)}\n\n`;
|
|
184
|
+
};
|
|
185
|
+
return new Transform({
|
|
186
|
+
transform(chunk, _encoding, callback) {
|
|
187
|
+
if (!initialized) {
|
|
188
|
+
this.push(sendEvent('message_start', {
|
|
189
|
+
type: 'message_start',
|
|
190
|
+
message: {
|
|
191
|
+
id: messageId,
|
|
192
|
+
type: 'message',
|
|
193
|
+
role: 'assistant',
|
|
194
|
+
model,
|
|
195
|
+
content: [],
|
|
196
|
+
stop_reason: null,
|
|
197
|
+
usage: { input_tokens: 0, output_tokens: 0 }
|
|
198
|
+
}
|
|
199
|
+
}));
|
|
200
|
+
this.push(sendEvent('content_block_start', {
|
|
201
|
+
type: 'content_block_start',
|
|
202
|
+
index: 0,
|
|
203
|
+
content_block: { type: 'text', text: '' }
|
|
204
|
+
}));
|
|
205
|
+
initialized = true;
|
|
206
|
+
}
|
|
207
|
+
buffer += chunk.toString();
|
|
208
|
+
const lines = buffer.split('\n');
|
|
209
|
+
buffer = lines.pop() || '';
|
|
210
|
+
for (const line of lines) {
|
|
211
|
+
if (!line.startsWith('data: '))
|
|
212
|
+
continue;
|
|
213
|
+
const data = line.substring(6);
|
|
214
|
+
if (data.trim() === '[DONE]') {
|
|
215
|
+
// Send closing events
|
|
216
|
+
this.push(sendEvent('content_block_stop', { type: 'content_block_stop', index: 0 }));
|
|
217
|
+
Object.values(toolCalls).forEach(tc => {
|
|
218
|
+
if (tc.started) {
|
|
219
|
+
this.push(sendEvent('content_block_stop', { type: 'content_block_stop', index: tc.claudeIndex }));
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
let finalStopReason = 'end_turn';
|
|
223
|
+
try {
|
|
224
|
+
const lastChunk = JSON.parse(lines[lines.length - 2].substring(6));
|
|
225
|
+
const finishReason = lastChunk.choices[0].finish_reason;
|
|
226
|
+
if (finishReason === 'tool_calls')
|
|
227
|
+
finalStopReason = 'tool_use';
|
|
228
|
+
if (finishReason === 'length')
|
|
229
|
+
finalStopReason = 'max_tokens';
|
|
230
|
+
}
|
|
231
|
+
catch { }
|
|
232
|
+
this.push(sendEvent('message_delta', {
|
|
233
|
+
type: 'message_delta',
|
|
234
|
+
delta: { stop_reason: finalStopReason, stop_sequence: null },
|
|
235
|
+
usage: { output_tokens: 0 }
|
|
236
|
+
}));
|
|
237
|
+
this.push(sendEvent('message_stop', { type: 'message_stop' }));
|
|
238
|
+
callback();
|
|
239
|
+
this.destroy();
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
try {
|
|
243
|
+
const openaiChunk = JSON.parse(data);
|
|
244
|
+
const delta = openaiChunk.choices[0]?.delta;
|
|
245
|
+
if (!delta)
|
|
246
|
+
continue;
|
|
247
|
+
if (delta.content) {
|
|
248
|
+
this.push(sendEvent('content_block_delta', {
|
|
249
|
+
type: 'content_block_delta',
|
|
250
|
+
index: 0,
|
|
251
|
+
delta: { type: 'text_delta', text: delta.content }
|
|
252
|
+
}));
|
|
253
|
+
}
|
|
254
|
+
if (delta.tool_calls) {
|
|
255
|
+
for (const tc_delta of delta.tool_calls) {
|
|
256
|
+
const index = tc_delta.index;
|
|
257
|
+
if (!toolCalls[index]) {
|
|
258
|
+
toolCalls[index] = { id: '', name: '', args: '', claudeIndex: 0, started: false };
|
|
259
|
+
}
|
|
260
|
+
if (tc_delta.id)
|
|
261
|
+
toolCalls[index].id = tc_delta.id;
|
|
262
|
+
if (tc_delta.function?.name)
|
|
263
|
+
toolCalls[index].name = tc_delta.function.name;
|
|
264
|
+
if (tc_delta.function?.arguments)
|
|
265
|
+
toolCalls[index].args += tc_delta.function.arguments;
|
|
266
|
+
if (toolCalls[index].id && toolCalls[index].name && !toolCalls[index].started) {
|
|
267
|
+
contentBlockIndex++;
|
|
268
|
+
toolCalls[index].claudeIndex = contentBlockIndex;
|
|
269
|
+
toolCalls[index].started = true;
|
|
270
|
+
this.push(sendEvent('content_block_start', {
|
|
271
|
+
type: 'content_block_start',
|
|
272
|
+
index: contentBlockIndex,
|
|
273
|
+
content_block: { type: 'tool_use', id: toolCalls[index].id, name: toolCalls[index].name, input: {} }
|
|
274
|
+
}));
|
|
275
|
+
}
|
|
276
|
+
if (toolCalls[index].started && tc_delta.function?.arguments) {
|
|
277
|
+
this.push(sendEvent('content_block_delta', {
|
|
278
|
+
type: 'content_block_delta',
|
|
279
|
+
index: toolCalls[index].claudeIndex,
|
|
280
|
+
delta: { type: 'input_json_delta', partial_json: tc_delta.function.arguments }
|
|
281
|
+
}));
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
catch {
|
|
287
|
+
// Ignore JSON parse errors in SSE chunks
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
callback();
|
|
291
|
+
}
|
|
292
|
+
});
|
|
293
|
+
}
|
|
@@ -11,6 +11,7 @@ export interface Provider {
|
|
|
11
11
|
subagent_model: string | null;
|
|
12
12
|
provider: string;
|
|
13
13
|
default: boolean;
|
|
14
|
+
is_openai_compatible: boolean;
|
|
14
15
|
created_at: string;
|
|
15
16
|
updated_at: string;
|
|
16
17
|
}
|
|
@@ -25,6 +26,7 @@ export interface ProviderInput {
|
|
|
25
26
|
subagent_model?: string;
|
|
26
27
|
provider: string;
|
|
27
28
|
default?: boolean;
|
|
29
|
+
is_openai_compatible?: boolean;
|
|
28
30
|
}
|
|
29
31
|
export interface ProviderValidationError {
|
|
30
32
|
index?: number;
|
|
@@ -1,10 +1,22 @@
|
|
|
1
1
|
const REQUIRED_FIELDS = ['name', 'provider'];
|
|
2
2
|
export function listProviders(db) {
|
|
3
3
|
const rows = db.prepare('SELECT * FROM providers ORDER BY created_at DESC').all();
|
|
4
|
-
return rows.map(r => {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
return rows.map(r => ({
|
|
5
|
+
id: r.id,
|
|
6
|
+
name: r.name,
|
|
7
|
+
base_url: r.base_url,
|
|
8
|
+
api_key: r.api_key,
|
|
9
|
+
model: r.model,
|
|
10
|
+
haiku_model: r.haiku_model,
|
|
11
|
+
sonnet_model: r.sonnet_model,
|
|
12
|
+
opus_model: r.opus_model,
|
|
13
|
+
subagent_model: r.subagent_model,
|
|
14
|
+
provider: r.provider,
|
|
15
|
+
default: !!r.is_default,
|
|
16
|
+
is_openai_compatible: !!r.is_openai_compatible,
|
|
17
|
+
created_at: r.created_at,
|
|
18
|
+
updated_at: r.updated_at,
|
|
19
|
+
}));
|
|
8
20
|
}
|
|
9
21
|
/**
|
|
10
22
|
* Destructive full replacement: deletes ALL existing providers then inserts the given list.
|
|
@@ -16,13 +28,13 @@ export function listProviders(db) {
|
|
|
16
28
|
export function saveProviders(db, providers) {
|
|
17
29
|
const deleteAll = db.prepare('DELETE FROM providers');
|
|
18
30
|
const insertOne = db.prepare(`
|
|
19
|
-
INSERT INTO providers (name, base_url, api_key, model, haiku_model, sonnet_model, opus_model, subagent_model, provider, is_default)
|
|
20
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
31
|
+
INSERT INTO providers (name, base_url, api_key, model, haiku_model, sonnet_model, opus_model, subagent_model, provider, is_default, is_openai_compatible)
|
|
32
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
21
33
|
`);
|
|
22
34
|
const transaction = db.transaction(() => {
|
|
23
35
|
deleteAll.run();
|
|
24
36
|
for (const p of providers) {
|
|
25
|
-
insertOne.run(p.name, p.base_url && p.base_url.trim() !== '' ? p.base_url : null, p.api_key && p.api_key.trim() !== '' ? p.api_key : null, p.model && p.model.trim() !== '' ? p.model : null, p.haiku_model && p.haiku_model.trim() !== '' ? p.haiku_model : null, p.sonnet_model && p.sonnet_model.trim() !== '' ? p.sonnet_model : null, p.opus_model && p.opus_model.trim() !== '' ? p.opus_model : null, p.subagent_model && p.subagent_model.trim() !== '' ? p.subagent_model : null, p.provider, p.default ? 1 : 0);
|
|
37
|
+
insertOne.run(p.name, p.base_url && p.base_url.trim() !== '' ? p.base_url : null, p.api_key && p.api_key.trim() !== '' ? p.api_key : null, p.model && p.model.trim() !== '' ? p.model : null, p.haiku_model && p.haiku_model.trim() !== '' ? p.haiku_model : null, p.sonnet_model && p.sonnet_model.trim() !== '' ? p.sonnet_model : null, p.opus_model && p.opus_model.trim() !== '' ? p.opus_model : null, p.subagent_model && p.subagent_model.trim() !== '' ? p.subagent_model : null, p.provider, p.default ? 1 : 0, p.is_openai_compatible ? 1 : 0);
|
|
26
38
|
}
|
|
27
39
|
});
|
|
28
40
|
transaction();
|
|
@@ -45,7 +45,23 @@ export interface RequestSummary {
|
|
|
45
45
|
usage?: TokenUsage;
|
|
46
46
|
}
|
|
47
47
|
export declare function extractTokenUsage(events: any[] | undefined): TokenUsage | undefined;
|
|
48
|
+
export declare const EVENT_BATCH_SIZE = 10;
|
|
49
|
+
/**
|
|
50
|
+
* Flush a batch of SSE events to the response_events table.
|
|
51
|
+
* Called during streaming every ~10 events to avoid in-memory accumulation.
|
|
52
|
+
*/
|
|
53
|
+
export declare function flushEventBatch(sessionId: string, requestId: string, batch: Array<{
|
|
54
|
+
index: number;
|
|
55
|
+
type?: string;
|
|
56
|
+
data: unknown;
|
|
57
|
+
}>, startIndex: number): void;
|
|
58
|
+
/**
|
|
59
|
+
* Delete response_events rows for a request (used when cloudRequestId differs from local requestId).
|
|
60
|
+
*/
|
|
61
|
+
export declare function deleteResponseEvents(requestId: string, sessionId: string): void;
|
|
48
62
|
export declare function saveRequestDB(sessionId: string, requestId: string, data: RequestData): Promise<void>;
|
|
63
|
+
export declare function updateRequestTokens(requestId: string, sessionId: string, usage: TokenUsage | undefined): void;
|
|
64
|
+
export declare function deleteRequestRow(requestId: string, sessionId: string): void;
|
|
49
65
|
export declare function loadRequestDB(compositeId: string): Promise<RequestData>;
|
|
50
66
|
export declare function listRequestDB(limit?: number, before?: string): Promise<{
|
|
51
67
|
requests: RequestSummary[];
|
|
@@ -53,3 +69,7 @@ export declare function listRequestDB(limit?: number, before?: string): Promise<
|
|
|
53
69
|
}>;
|
|
54
70
|
export declare function cleanOldRequestsDB(daysToKeep?: number): Promise<void>;
|
|
55
71
|
export declare function sessionIdExists(sessionId: string): boolean;
|
|
72
|
+
export declare function loadSessionHistory(sessionId: string): {
|
|
73
|
+
messages: any[];
|
|
74
|
+
system?: any;
|
|
75
|
+
} | null;
|
|
@@ -1,14 +1,62 @@
|
|
|
1
|
-
import { initDatabase } from './db.js';
|
|
1
|
+
import { initDatabase, getDatabase } from './db.js';
|
|
2
|
+
import { parseUpstreamEvents } from './inject-loop.js';
|
|
2
3
|
export function extractTokenUsage(events) {
|
|
3
4
|
if (!events)
|
|
4
5
|
return undefined;
|
|
5
6
|
const messageDelta = events.find((e) => e?.type === 'message_delta');
|
|
6
7
|
return messageDelta?.usage;
|
|
7
8
|
}
|
|
9
|
+
// --- SSE Event Batch Writer (incremental DB writes during streaming) ---
|
|
10
|
+
export const EVENT_BATCH_SIZE = 10;
|
|
11
|
+
// Cached prepared statements for batch writes
|
|
12
|
+
let insertEventStmt = null;
|
|
13
|
+
let deleteRequestStmt = null;
|
|
14
|
+
let cachedDbInstance = null;
|
|
15
|
+
// Invalidate cached stmts when DB instance changes (tests create fresh DB per suite)
|
|
16
|
+
function ensureStmtCacheValid(db) {
|
|
17
|
+
if (db !== cachedDbInstance) {
|
|
18
|
+
insertEventStmt = null;
|
|
19
|
+
deleteRequestStmt = null;
|
|
20
|
+
cachedDbInstance = db;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Flush a batch of SSE events to the response_events table.
|
|
25
|
+
* Called during streaming every ~10 events to avoid in-memory accumulation.
|
|
26
|
+
*/
|
|
27
|
+
export function flushEventBatch(sessionId, requestId, batch, startIndex) {
|
|
28
|
+
const db = getDatabase();
|
|
29
|
+
ensureStmtCacheValid(db);
|
|
30
|
+
if (!insertEventStmt) {
|
|
31
|
+
insertEventStmt = db.prepare('INSERT INTO response_events (request_id, session_id, event_index, event_type, event_data) VALUES (?, ?, ?, ?, ?)');
|
|
32
|
+
}
|
|
33
|
+
for (let i = 0; i < batch.length; i++) {
|
|
34
|
+
const event = batch[i];
|
|
35
|
+
insertEventStmt.run(requestId, sessionId, startIndex + i, event.type ?? null, JSON.stringify(event.data));
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Delete response_events rows for a request (used when cloudRequestId differs from local requestId).
|
|
40
|
+
*/
|
|
41
|
+
export function deleteResponseEvents(requestId, sessionId) {
|
|
42
|
+
const db = getDatabase();
|
|
43
|
+
db.prepare('DELETE FROM response_events WHERE request_id = ? AND session_id = ?').run(requestId, sessionId);
|
|
44
|
+
}
|
|
45
|
+
// --- Request DB Operations ---
|
|
8
46
|
// Save request to SQLite database
|
|
9
47
|
export async function saveRequestDB(sessionId, requestId, data) {
|
|
10
48
|
const db = initDatabase();
|
|
11
|
-
const
|
|
49
|
+
const events = data.response?.events;
|
|
50
|
+
const usage = events ? extractTokenUsage(events) : undefined;
|
|
51
|
+
// For JSON responses (non-streaming), events are still in the array — flush them first
|
|
52
|
+
if (events && events.length > 0) {
|
|
53
|
+
const batch = events.map((e, i) => ({
|
|
54
|
+
index: i,
|
|
55
|
+
type: e?.type ?? undefined,
|
|
56
|
+
data: e
|
|
57
|
+
}));
|
|
58
|
+
flushEventBatch(sessionId, requestId, batch, 0);
|
|
59
|
+
}
|
|
12
60
|
const stmt = db.prepare(`
|
|
13
61
|
INSERT OR REPLACE INTO requests (
|
|
14
62
|
request_id, session_id, timestamp, method, path, status_code, response_time,
|
|
@@ -22,7 +70,22 @@ export async function saveRequestDB(sessionId, requestId, data) {
|
|
|
22
70
|
`);
|
|
23
71
|
stmt.run(requestId, sessionId, data.timestamp, data.request.method, data.request.path, data.response?.statusCode ?? 0, data.response?.completedAt && data.timestamp
|
|
24
72
|
? Math.round(new Date(data.response.completedAt).getTime() - new Date(data.timestamp).getTime())
|
|
25
|
-
: 0, data.apiKey || null, data.proxyApiKey || null, data.baseUrl || null, data.model || null, data.machineId || null, usage?.input_tokens || null, usage?.output_tokens || null, usage?.cache_read_input_tokens || null, usage?.cache_creation_input_tokens || null, JSON.stringify(data.request.headers), data.request.body ? JSON.stringify(data.request.body) : null, data.response?.headers ? JSON.stringify(data.response.headers) : null,
|
|
73
|
+
: 0, data.apiKey || null, data.proxyApiKey || null, data.baseUrl || null, data.model || null, data.machineId || null, usage?.input_tokens || null, usage?.output_tokens || null, usage?.cache_read_input_tokens || null, usage?.cache_creation_input_tokens || null, JSON.stringify(data.request.headers), data.request.body ? JSON.stringify(data.request.body) : null, data.response?.headers ? JSON.stringify(data.response.headers) : null, null, // response_events now stored in separate table
|
|
74
|
+
data.response?.completedAt || null, data.response?.closedAt || null, data.response?.error || null);
|
|
75
|
+
}
|
|
76
|
+
// Update token columns for a request (streaming: usage extracted from tailBuffer after save)
|
|
77
|
+
export function updateRequestTokens(requestId, sessionId, usage) {
|
|
78
|
+
const db = getDatabase();
|
|
79
|
+
db.prepare('UPDATE requests SET input_tokens = ?, output_tokens = ?, cache_read_tokens = ?, cache_creation_tokens = ? WHERE request_id = ? AND session_id = ?').run(usage?.input_tokens || null, usage?.output_tokens || null, usage?.cache_read_input_tokens || null, usage?.cache_creation_input_tokens || null, requestId, sessionId);
|
|
80
|
+
}
|
|
81
|
+
// Delete a request row by requestId + sessionId (for pending → completed replacement)
|
|
82
|
+
export function deleteRequestRow(requestId, sessionId) {
|
|
83
|
+
const db = getDatabase();
|
|
84
|
+
ensureStmtCacheValid(db);
|
|
85
|
+
if (!deleteRequestStmt) {
|
|
86
|
+
deleteRequestStmt = db.prepare('DELETE FROM requests WHERE request_id = ? AND session_id = ?');
|
|
87
|
+
}
|
|
88
|
+
deleteRequestStmt.run(requestId, sessionId);
|
|
26
89
|
}
|
|
27
90
|
// Load single request by compositeId (sessionId:requestId)
|
|
28
91
|
export async function loadRequestDB(compositeId) {
|
|
@@ -39,6 +102,35 @@ export async function loadRequestDB(compositeId) {
|
|
|
39
102
|
if (!row) {
|
|
40
103
|
throw new Error(`Request not found: ${compositeId}`);
|
|
41
104
|
}
|
|
105
|
+
// Load events from separate table; fallback to old JSON column for historical data
|
|
106
|
+
const eventRows = db.prepare(`
|
|
107
|
+
SELECT event_index, event_type, event_data FROM response_events
|
|
108
|
+
WHERE request_id = ? AND session_id = ?
|
|
109
|
+
ORDER BY event_index ASC
|
|
110
|
+
`).all(requestId, sessionId);
|
|
111
|
+
let events;
|
|
112
|
+
if (eventRows.length > 0) {
|
|
113
|
+
events = eventRows.map(r => {
|
|
114
|
+
try {
|
|
115
|
+
return JSON.parse(r.event_data);
|
|
116
|
+
}
|
|
117
|
+
catch {
|
|
118
|
+
return { raw: r.event_data };
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
else if (row.response_events) {
|
|
123
|
+
// Fallback: historical data stored events in the requests.response_events JSON column
|
|
124
|
+
try {
|
|
125
|
+
events = JSON.parse(row.response_events);
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
events = [];
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
events = [];
|
|
133
|
+
}
|
|
42
134
|
return {
|
|
43
135
|
requestId: row.request_id,
|
|
44
136
|
sessionId: row.session_id,
|
|
@@ -57,7 +149,7 @@ export async function loadRequestDB(compositeId) {
|
|
|
57
149
|
response: {
|
|
58
150
|
statusCode: row.status_code,
|
|
59
151
|
headers: row.response_headers ? JSON.parse(row.response_headers) : undefined,
|
|
60
|
-
events:
|
|
152
|
+
events: events.length > 0 ? events : undefined,
|
|
61
153
|
completedAt: row.completed_at,
|
|
62
154
|
closedAt: row.closed_at,
|
|
63
155
|
error: row.error
|
|
@@ -115,6 +207,8 @@ export async function cleanOldRequestsDB(daysToKeep = 7) {
|
|
|
115
207
|
}
|
|
116
208
|
const db = initDatabase();
|
|
117
209
|
const cutoff = new Date(Date.now() - daysToKeep * 86400000).toISOString();
|
|
210
|
+
// Delete response_events first (foreign data), then requests
|
|
211
|
+
db.prepare(`DELETE FROM response_events WHERE request_id IN (SELECT request_id FROM requests WHERE timestamp < ?)`).run(cutoff);
|
|
118
212
|
db.prepare(`DELETE FROM requests WHERE timestamp < ?`).run(cutoff);
|
|
119
213
|
}
|
|
120
214
|
// Check if a sessionId exists in the database
|
|
@@ -125,3 +219,89 @@ export function sessionIdExists(sessionId) {
|
|
|
125
219
|
`).get(sessionId);
|
|
126
220
|
return !!row;
|
|
127
221
|
}
|
|
222
|
+
// Load session history for multi-turn chat resume
|
|
223
|
+
// Returns the last request's messages + assistant response, to prepend to new messages
|
|
224
|
+
export function loadSessionHistory(sessionId) {
|
|
225
|
+
const db = initDatabase();
|
|
226
|
+
// Get the last completed request for this session
|
|
227
|
+
const row = db.prepare(`
|
|
228
|
+
SELECT request_id, request_body, response_headers
|
|
229
|
+
FROM requests
|
|
230
|
+
WHERE session_id = ? AND completed_at IS NOT NULL AND status_code = 200
|
|
231
|
+
ORDER BY timestamp DESC
|
|
232
|
+
LIMIT 1
|
|
233
|
+
`).get(sessionId);
|
|
234
|
+
if (!row)
|
|
235
|
+
return null;
|
|
236
|
+
let requestBody = null;
|
|
237
|
+
try {
|
|
238
|
+
requestBody = row.request_body ? JSON.parse(row.request_body) : null;
|
|
239
|
+
}
|
|
240
|
+
catch {
|
|
241
|
+
return null;
|
|
242
|
+
}
|
|
243
|
+
// Load response events from separate table; fallback to old JSON column for historical data
|
|
244
|
+
const eventRows = db.prepare(`
|
|
245
|
+
SELECT event_data FROM response_events
|
|
246
|
+
WHERE request_id = ? AND session_id = ?
|
|
247
|
+
ORDER BY event_index ASC
|
|
248
|
+
`).all(row.request_id, sessionId);
|
|
249
|
+
let responseEvents;
|
|
250
|
+
if (eventRows.length > 0) {
|
|
251
|
+
try {
|
|
252
|
+
responseEvents = eventRows.map(r => JSON.parse(r.event_data));
|
|
253
|
+
}
|
|
254
|
+
catch {
|
|
255
|
+
responseEvents = [];
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
else {
|
|
259
|
+
// Fallback: read from old requests.response_events JSON column
|
|
260
|
+
const legacyRow = db.prepare('SELECT response_events FROM requests WHERE request_id = ? AND session_id = ?')
|
|
261
|
+
.get(row.request_id, sessionId);
|
|
262
|
+
try {
|
|
263
|
+
responseEvents = legacyRow?.response_events ? JSON.parse(legacyRow.response_events) : [];
|
|
264
|
+
}
|
|
265
|
+
catch {
|
|
266
|
+
responseEvents = [];
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
if (!requestBody?.messages)
|
|
270
|
+
return null;
|
|
271
|
+
// Rebuild conversation: previous messages from request_body + assistant response from response_events
|
|
272
|
+
const messages = [...requestBody.messages];
|
|
273
|
+
// Extract assistant content from response events
|
|
274
|
+
// For JSON responses, the first event is the full response with .content
|
|
275
|
+
// For SSE responses, need to parse content blocks
|
|
276
|
+
const firstEvent = responseEvents[0];
|
|
277
|
+
if (firstEvent?.type === 'message' && firstEvent?.content) {
|
|
278
|
+
// JSON (non-streaming) response
|
|
279
|
+
messages.push({ role: 'assistant', content: firstEvent.content });
|
|
280
|
+
}
|
|
281
|
+
else if (responseEvents.length > 1) {
|
|
282
|
+
// SSE response — rebuild content blocks from events
|
|
283
|
+
const parsed = parseUpstreamEvents(responseEvents);
|
|
284
|
+
const assistantContent = [];
|
|
285
|
+
for (const block of parsed.blocks) {
|
|
286
|
+
if (block.type === 'text' && block.text) {
|
|
287
|
+
assistantContent.push({ type: 'text', text: block.text });
|
|
288
|
+
}
|
|
289
|
+
else if (block.type === 'tool_use') {
|
|
290
|
+
assistantContent.push({ type: 'tool_use', id: block.id, name: block.name, input: block.input });
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
// Find tool_result blocks in subsequent events
|
|
294
|
+
for (const event of responseEvents) {
|
|
295
|
+
if (event?.type === 'tool_result' || (event?.role === 'user' && Array.isArray(event?.content))) {
|
|
296
|
+
messages.push({ role: 'user', content: event.content });
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
if (assistantContent.length > 0) {
|
|
300
|
+
messages.push({ role: 'assistant', content: assistantContent });
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
return {
|
|
304
|
+
messages,
|
|
305
|
+
system: requestBody.system || requestBody.system_prompt
|
|
306
|
+
};
|
|
307
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { ServerResponse } from 'http';
|
|
2
|
+
import { type ParsedUpstream } from './inject-loop.js';
|
|
3
|
+
/**
|
|
4
|
+
* SSE 增量流式处理器:边转发原始 chunk 到客户端,边增量解析事件累积状态。
|
|
5
|
+
* stream end 后提供 getParsedUpstream() 和 hasInjectedToolUse() 供注入检测。
|
|
6
|
+
*
|
|
7
|
+
* 跨 chunk 行边界通过 leftover 缓冲处理(参考 SSEAccumulator)。
|
|
8
|
+
*/
|
|
9
|
+
export declare class SSEStreamProcessor {
|
|
10
|
+
events: any[];
|
|
11
|
+
private contentBlocks;
|
|
12
|
+
private stopReason;
|
|
13
|
+
private usage;
|
|
14
|
+
private leftover;
|
|
15
|
+
private raw;
|
|
16
|
+
constructor(raw: ServerResponse);
|
|
17
|
+
/** 处理一个 chunk:转发到 reply.raw + 增量解析事件 */
|
|
18
|
+
processChunk(chunk: Buffer): void;
|
|
19
|
+
/** 处理 leftover 中残留的最后一行(stream end 后调用) */
|
|
20
|
+
flushLeftover(): void;
|
|
21
|
+
/** 增量解析单个事件,更新 contentBlocks / stopReason / usage */
|
|
22
|
+
private processEvent;
|
|
23
|
+
/** 从累积状态构建 ParsedUpstream */
|
|
24
|
+
getParsedUpstream(): ParsedUpstream;
|
|
25
|
+
/** 检测是否有注入的 MCP tool_use */
|
|
26
|
+
hasInjectedToolUse(): boolean;
|
|
27
|
+
}
|