@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
package/dist/utils/db.js
CHANGED
|
@@ -52,6 +52,18 @@ export function initDatabase() {
|
|
|
52
52
|
applySchemaV5(db);
|
|
53
53
|
db.prepare('INSERT OR REPLACE INTO schema_version (version) VALUES (5)').run();
|
|
54
54
|
}
|
|
55
|
+
if (currentVersion < 6) {
|
|
56
|
+
applySchemaV6(db);
|
|
57
|
+
db.prepare('INSERT OR REPLACE INTO schema_version (version) VALUES (6)').run();
|
|
58
|
+
}
|
|
59
|
+
if (currentVersion < 7) {
|
|
60
|
+
applySchemaV7(db);
|
|
61
|
+
db.prepare('INSERT OR REPLACE INTO schema_version (version) VALUES (7)').run();
|
|
62
|
+
}
|
|
63
|
+
if (currentVersion < 8) {
|
|
64
|
+
applySchemaV8(db);
|
|
65
|
+
db.prepare('INSERT OR REPLACE INTO schema_version (version) VALUES (8)').run();
|
|
66
|
+
}
|
|
55
67
|
return db;
|
|
56
68
|
}
|
|
57
69
|
export function applySchemaV2(db) {
|
|
@@ -197,6 +209,48 @@ export function applySchemaV5(db) {
|
|
|
197
209
|
// Create index for machine_id
|
|
198
210
|
db.exec(`CREATE INDEX IF NOT EXISTS idx_requests_machine_id ON requests(machine_id)`);
|
|
199
211
|
}
|
|
212
|
+
export function applySchemaV6(db) {
|
|
213
|
+
db.exec(`
|
|
214
|
+
CREATE TABLE IF NOT EXISTS mcp_servers (
|
|
215
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
216
|
+
name TEXT UNIQUE NOT NULL,
|
|
217
|
+
transport_type TEXT NOT NULL CHECK(transport_type IN ('stdio', 'sse', 'streamable-http')),
|
|
218
|
+
command TEXT,
|
|
219
|
+
args TEXT,
|
|
220
|
+
env TEXT,
|
|
221
|
+
url TEXT,
|
|
222
|
+
headers TEXT,
|
|
223
|
+
enabled INTEGER NOT NULL DEFAULT 1,
|
|
224
|
+
created_at TEXT DEFAULT CURRENT_TIMESTAMP,
|
|
225
|
+
updated_at TEXT DEFAULT CURRENT_TIMESTAMP
|
|
226
|
+
)
|
|
227
|
+
`);
|
|
228
|
+
db.exec('CREATE UNIQUE INDEX IF NOT EXISTS idx_mcp_servers_name ON mcp_servers(name)');
|
|
229
|
+
}
|
|
230
|
+
export function applySchemaV7(db) {
|
|
231
|
+
// Add is_openai_compatible column for OpenAI format conversion toggle
|
|
232
|
+
const columns = db.prepare("PRAGMA table_info(providers)").all();
|
|
233
|
+
if (!columns.some(c => c.name === 'is_openai_compatible')) {
|
|
234
|
+
db.exec('ALTER TABLE providers ADD COLUMN is_openai_compatible INTEGER NOT NULL DEFAULT 0');
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
export function applySchemaV8(db) {
|
|
238
|
+
// Separate table for streaming SSE events — eliminates in-memory accumulation
|
|
239
|
+
db.exec(`
|
|
240
|
+
CREATE TABLE IF NOT EXISTS response_events (
|
|
241
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
242
|
+
request_id TEXT NOT NULL,
|
|
243
|
+
session_id TEXT NOT NULL,
|
|
244
|
+
event_index INTEGER NOT NULL,
|
|
245
|
+
event_type TEXT,
|
|
246
|
+
event_data TEXT NOT NULL
|
|
247
|
+
)
|
|
248
|
+
`);
|
|
249
|
+
db.exec(`
|
|
250
|
+
CREATE INDEX IF NOT EXISTS idx_response_events_request
|
|
251
|
+
ON response_events(request_id, session_id, event_index)
|
|
252
|
+
`);
|
|
253
|
+
}
|
|
200
254
|
export function closeDatabase() {
|
|
201
255
|
if (db) {
|
|
202
256
|
db.close();
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { ServerResponse } from 'http';
|
|
2
|
+
import type { SSEStreamProcessor } from './sse-stream-processor.js';
|
|
1
3
|
/**
|
|
2
4
|
* 内部循环(后端)——命中注入 tool 后,proxy 代行「执行 tool -> 追加对话 -> 再调上游」,
|
|
3
5
|
* 直到模型给出 end_turn 的最终文本,再由调用方合成 SSE 回写给客户端。
|
|
@@ -28,7 +30,7 @@ export interface InjectLoopResult {
|
|
|
28
30
|
stoppedByLimit: boolean;
|
|
29
31
|
}
|
|
30
32
|
/**
|
|
31
|
-
* 内部循环:命中已启用 tool -> 执行 exec -> 追加对话 -> 再调上游 -> 直到 end_turn。
|
|
33
|
+
* SSE 内部循环:命中已启用 tool -> 执行 exec -> 追加对话 -> 再调上游 -> 直到 end_turn。
|
|
32
34
|
* opts.body 会被原地追加 messages。
|
|
33
35
|
*
|
|
34
36
|
* @param opts.events 首次上游响应事件(已确认命中注入 tool)
|
|
@@ -41,3 +43,52 @@ export declare function runInjectLoop(opts: {
|
|
|
41
43
|
callUpstream: (body: any) => Promise<any[]>;
|
|
42
44
|
maxIterations?: number;
|
|
43
45
|
}): Promise<InjectLoopResult>;
|
|
46
|
+
/**
|
|
47
|
+
* SSE 流式注入循环:命中已启用 tool → 执行 exec → 追加对话 → 再调上游 → 新 SSE 流式转发到同一 reply.raw。
|
|
48
|
+
* 每次迭代作为独立 DB 记录。客户端实时看到续接 SSE。
|
|
49
|
+
*
|
|
50
|
+
* 与 runInjectLoop 的区别:
|
|
51
|
+
* - 不缓冲上游响应,直接流式转发
|
|
52
|
+
* - 不返回合成 text,客户端已实时收到原始 SSE
|
|
53
|
+
* - 每次迭代用 SSEStreamProcessor 边转发边解析
|
|
54
|
+
*/
|
|
55
|
+
export interface StreamingInjectLoopResult {
|
|
56
|
+
iterations: number;
|
|
57
|
+
stoppedByLimit: boolean;
|
|
58
|
+
}
|
|
59
|
+
export declare function runStreamingInjectLoop(opts: {
|
|
60
|
+
initialParsed: ParsedUpstream;
|
|
61
|
+
body: any;
|
|
62
|
+
callUpstream: (body: any) => Promise<{
|
|
63
|
+
response: Response;
|
|
64
|
+
requestId: string;
|
|
65
|
+
}>;
|
|
66
|
+
streamAndParse: (response: Response) => Promise<{
|
|
67
|
+
processor: SSEStreamProcessor;
|
|
68
|
+
statusCode: number;
|
|
69
|
+
}>;
|
|
70
|
+
sessionId: string;
|
|
71
|
+
saveIterationDB: (requestId: string, processor: SSEStreamProcessor, statusCode: number, requestBody: any) => Promise<void>;
|
|
72
|
+
raw: ServerResponse;
|
|
73
|
+
maxIterations?: number;
|
|
74
|
+
}): Promise<StreamingInjectLoopResult>;
|
|
75
|
+
export interface JsonInjectLoopResult {
|
|
76
|
+
finalBody: any;
|
|
77
|
+
iterations: number;
|
|
78
|
+
stoppedByLimit: boolean;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* JSON 内部循环:非流式请求中命中 MCP tool -> 执行 exec -> 追加对话 -> 再调上游 -> 直到 end_turn。
|
|
82
|
+
* 与 SSE 版 runInjectLoop 对称,但处理 parsed JSON response body 而非 SSE event 数组。
|
|
83
|
+
*
|
|
84
|
+
* @param opts.initialBody 首次上游 JSON 响应(已确认命中 MCP tool)
|
|
85
|
+
* @param opts.requestBody 请求体(messages 会被原地追加)
|
|
86
|
+
* @param opts.callUpstream 用给定 body 再次调上游,返回 parsed JSON body
|
|
87
|
+
* @param opts.maxIterations 死循环护栏
|
|
88
|
+
*/
|
|
89
|
+
export declare function runJsonInjectLoop(opts: {
|
|
90
|
+
initialBody: any;
|
|
91
|
+
requestBody: any;
|
|
92
|
+
callUpstream: (body: any) => Promise<any>;
|
|
93
|
+
maxIterations?: number;
|
|
94
|
+
}): Promise<JsonInjectLoopResult>;
|
|
@@ -89,7 +89,7 @@ function collectText(parsed) {
|
|
|
89
89
|
.join('');
|
|
90
90
|
}
|
|
91
91
|
/**
|
|
92
|
-
* 内部循环:命中已启用 tool -> 执行 exec -> 追加对话 -> 再调上游 -> 直到 end_turn。
|
|
92
|
+
* SSE 内部循环:命中已启用 tool -> 执行 exec -> 追加对话 -> 再调上游 -> 直到 end_turn。
|
|
93
93
|
* opts.body 会被原地追加 messages。
|
|
94
94
|
*
|
|
95
95
|
* @param opts.events 首次上游响应事件(已确认命中注入 tool)
|
|
@@ -105,7 +105,7 @@ export async function runInjectLoop(opts) {
|
|
|
105
105
|
if (!call || parsed.stopReason !== 'tool_use') {
|
|
106
106
|
return { text: collectText(parsed), iterations, stoppedByLimit: false };
|
|
107
107
|
}
|
|
108
|
-
const tool = findEnabledTool(call.name);
|
|
108
|
+
const tool = findEnabledTool(call.name);
|
|
109
109
|
const result = await tool.exec(call.input);
|
|
110
110
|
opts.body.messages.push({ role: 'assistant', content: blocksToAssistantContent(parsed.blocks) });
|
|
111
111
|
opts.body.messages.push({
|
|
@@ -118,3 +118,71 @@ export async function runInjectLoop(opts) {
|
|
|
118
118
|
}
|
|
119
119
|
return { text: collectText(parsed) || '(内部循环达到最大轮次)', iterations, stoppedByLimit: true };
|
|
120
120
|
}
|
|
121
|
+
export async function runStreamingInjectLoop(opts) {
|
|
122
|
+
const maxIterations = opts.maxIterations ?? 3;
|
|
123
|
+
let parsed = opts.initialParsed;
|
|
124
|
+
let iterations = 0;
|
|
125
|
+
while (iterations < maxIterations) {
|
|
126
|
+
if (opts.raw.destroyed)
|
|
127
|
+
break;
|
|
128
|
+
const call = findInjectedCall(parsed);
|
|
129
|
+
if (!call || parsed.stopReason !== 'tool_use') {
|
|
130
|
+
return { iterations, stoppedByLimit: false };
|
|
131
|
+
}
|
|
132
|
+
// 执行注入的 tool
|
|
133
|
+
const tool = findEnabledTool(call.name);
|
|
134
|
+
const result = await tool.exec(call.input);
|
|
135
|
+
// 追加 assistant + tool_result 消息
|
|
136
|
+
opts.body.messages.push({ role: 'assistant', content: blocksToAssistantContent(parsed.blocks) });
|
|
137
|
+
opts.body.messages.push({
|
|
138
|
+
role: 'user',
|
|
139
|
+
content: [{ type: 'tool_result', tool_use_id: call.id, content: result }]
|
|
140
|
+
});
|
|
141
|
+
// 调上游,获取流式响应
|
|
142
|
+
const { response, requestId } = await opts.callUpstream(opts.body);
|
|
143
|
+
// 流式转发到客户端 + 增量解析
|
|
144
|
+
const { processor, statusCode } = await opts.streamAndParse(response);
|
|
145
|
+
// 保存这次迭代到 DB
|
|
146
|
+
await opts.saveIterationDB(requestId, processor, statusCode, opts.body);
|
|
147
|
+
parsed = processor.getParsedUpstream();
|
|
148
|
+
processor.flushLeftover();
|
|
149
|
+
iterations++;
|
|
150
|
+
}
|
|
151
|
+
const stoppedByLimit = iterations >= (opts.maxIterations ?? 3) &&
|
|
152
|
+
parsed.stopReason === 'tool_use' &&
|
|
153
|
+
!!findInjectedCall(parsed);
|
|
154
|
+
return { iterations, stoppedByLimit };
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* JSON 内部循环:非流式请求中命中 MCP tool -> 执行 exec -> 追加对话 -> 再调上游 -> 直到 end_turn。
|
|
158
|
+
* 与 SSE 版 runInjectLoop 对称,但处理 parsed JSON response body 而非 SSE event 数组。
|
|
159
|
+
*
|
|
160
|
+
* @param opts.initialBody 首次上游 JSON 响应(已确认命中 MCP tool)
|
|
161
|
+
* @param opts.requestBody 请求体(messages 会被原地追加)
|
|
162
|
+
* @param opts.callUpstream 用给定 body 再次调上游,返回 parsed JSON body
|
|
163
|
+
* @param opts.maxIterations 死循环护栏
|
|
164
|
+
*/
|
|
165
|
+
export async function runJsonInjectLoop(opts) {
|
|
166
|
+
const maxIterations = opts.maxIterations ?? 3;
|
|
167
|
+
let lastResponse = opts.initialBody;
|
|
168
|
+
let iterations = 0;
|
|
169
|
+
while (iterations < maxIterations) {
|
|
170
|
+
const toolCalls = (lastResponse.content || []).filter((b) => b.type === 'tool_use');
|
|
171
|
+
const hitCall = toolCalls.find((b) => findEnabledTool(b.name));
|
|
172
|
+
if (!hitCall || lastResponse.stop_reason !== 'tool_use')
|
|
173
|
+
break;
|
|
174
|
+
const tool = findEnabledTool(hitCall.name);
|
|
175
|
+
const result = await tool.exec(hitCall.input);
|
|
176
|
+
opts.requestBody.messages.push({ role: 'assistant', content: lastResponse.content });
|
|
177
|
+
opts.requestBody.messages.push({
|
|
178
|
+
role: 'user',
|
|
179
|
+
content: [{ type: 'tool_result', tool_use_id: hitCall.id, content: result }]
|
|
180
|
+
});
|
|
181
|
+
lastResponse = await opts.callUpstream(opts.requestBody);
|
|
182
|
+
iterations++;
|
|
183
|
+
}
|
|
184
|
+
const stoppedByLimit = iterations >= maxIterations &&
|
|
185
|
+
lastResponse.stop_reason === 'tool_use' &&
|
|
186
|
+
(lastResponse.content || []).some((b) => b.type === 'tool_use' && findEnabledTool(b.name));
|
|
187
|
+
return { finalBody: lastResponse, iterations, stoppedByLimit };
|
|
188
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import Database from 'better-sqlite3';
|
|
2
|
+
export type TransportType = 'stdio' | 'sse' | 'streamable-http';
|
|
3
|
+
export interface McpServer {
|
|
4
|
+
id: number;
|
|
5
|
+
name: string;
|
|
6
|
+
transport_type: TransportType;
|
|
7
|
+
command: string | null;
|
|
8
|
+
args: string | null;
|
|
9
|
+
env: string | null;
|
|
10
|
+
url: string | null;
|
|
11
|
+
headers: string | null;
|
|
12
|
+
enabled: boolean;
|
|
13
|
+
created_at: string;
|
|
14
|
+
updated_at: string;
|
|
15
|
+
}
|
|
16
|
+
export interface McpServerInput {
|
|
17
|
+
name: string;
|
|
18
|
+
transport_type: TransportType;
|
|
19
|
+
command?: string;
|
|
20
|
+
args?: string[];
|
|
21
|
+
env?: Record<string, string>;
|
|
22
|
+
url?: string;
|
|
23
|
+
headers?: Record<string, string>;
|
|
24
|
+
enabled?: boolean;
|
|
25
|
+
}
|
|
26
|
+
export interface McpServerError {
|
|
27
|
+
field: string;
|
|
28
|
+
message: string;
|
|
29
|
+
}
|
|
30
|
+
export declare function listMcpServers(db: Database.Database): McpServer[];
|
|
31
|
+
export declare function getMcpServer(db: Database.Database, id: number): McpServer | undefined;
|
|
32
|
+
export declare function createMcpServer(db: Database.Database, input: McpServerInput): McpServer;
|
|
33
|
+
export declare function updateMcpServer(db: Database.Database, id: number, input: Partial<McpServerInput>): McpServer | undefined;
|
|
34
|
+
export declare function deleteMcpServer(db: Database.Database, id: number): boolean;
|
|
35
|
+
export declare function validateMcpServerInput(input: McpServerInput): McpServerError[];
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
export function listMcpServers(db) {
|
|
2
|
+
const rows = db.prepare('SELECT * FROM mcp_servers ORDER BY created_at DESC')
|
|
3
|
+
.all();
|
|
4
|
+
return rows.map(r => ({ ...r, enabled: !!r.enabled }));
|
|
5
|
+
}
|
|
6
|
+
export function getMcpServer(db, id) {
|
|
7
|
+
const row = db.prepare('SELECT * FROM mcp_servers WHERE id = ?').get(id);
|
|
8
|
+
return row ? { ...row, enabled: !!row.enabled } : undefined;
|
|
9
|
+
}
|
|
10
|
+
export function createMcpServer(db, input) {
|
|
11
|
+
const errors = validateMcpServerInput(input);
|
|
12
|
+
if (errors.length)
|
|
13
|
+
throw new Error(errors.map(e => `${e.field}: ${e.message}`).join('; '));
|
|
14
|
+
const insert = db.prepare(`
|
|
15
|
+
INSERT INTO mcp_servers (name, transport_type, command, args, env, url, headers, enabled)
|
|
16
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
17
|
+
`);
|
|
18
|
+
insert.run(input.name, input.transport_type, input.command || null, input.args ? JSON.stringify(input.args) : null, input.env ? JSON.stringify(input.env) : null, input.url || null, input.headers ? JSON.stringify(input.headers) : null, input.enabled !== false ? 1 : 0);
|
|
19
|
+
const row = db.prepare('SELECT * FROM mcp_servers WHERE name = ?').get(input.name);
|
|
20
|
+
return { ...row, enabled: !!row.enabled };
|
|
21
|
+
}
|
|
22
|
+
export function updateMcpServer(db, id, input) {
|
|
23
|
+
const existing = getMcpServer(db, id);
|
|
24
|
+
if (!existing)
|
|
25
|
+
return undefined;
|
|
26
|
+
const merged = {
|
|
27
|
+
name: input.name ?? existing.name,
|
|
28
|
+
transport_type: input.transport_type ?? existing.transport_type,
|
|
29
|
+
command: input.command ?? existing.command ?? undefined,
|
|
30
|
+
args: input.args ?? (existing.args ? JSON.parse(existing.args) : undefined),
|
|
31
|
+
env: input.env ?? (existing.env ? JSON.parse(existing.env) : undefined),
|
|
32
|
+
url: input.url ?? existing.url ?? undefined,
|
|
33
|
+
headers: input.headers ?? (existing.headers ? JSON.parse(existing.headers) : undefined),
|
|
34
|
+
enabled: input.enabled ?? existing.enabled
|
|
35
|
+
};
|
|
36
|
+
const errors = validateMcpServerInput(merged);
|
|
37
|
+
if (errors.length)
|
|
38
|
+
throw new Error(errors.map(e => `${e.field}: ${e.message}`).join('; '));
|
|
39
|
+
db.prepare(`
|
|
40
|
+
UPDATE mcp_servers SET name=?, transport_type=?, command=?, args=?, env=?, url=?, headers=?, enabled=?, updated_at=CURRENT_TIMESTAMP
|
|
41
|
+
WHERE id=?
|
|
42
|
+
`).run(merged.name, merged.transport_type, merged.command || null, merged.args ? JSON.stringify(merged.args) : null, merged.env ? JSON.stringify(merged.env) : null, merged.url || null, merged.headers ? JSON.stringify(merged.headers) : null, merged.enabled !== false ? 1 : 0, id);
|
|
43
|
+
return getMcpServer(db, id);
|
|
44
|
+
}
|
|
45
|
+
export function deleteMcpServer(db, id) {
|
|
46
|
+
const result = db.prepare('DELETE FROM mcp_servers WHERE id = ?').run(id);
|
|
47
|
+
return result.changes > 0;
|
|
48
|
+
}
|
|
49
|
+
export function validateMcpServerInput(input) {
|
|
50
|
+
const errors = [];
|
|
51
|
+
if (!input.name || input.name.trim() === '') {
|
|
52
|
+
errors.push({ field: 'name', message: 'name is required' });
|
|
53
|
+
}
|
|
54
|
+
const validTypes = ['stdio', 'sse', 'streamable-http'];
|
|
55
|
+
if (!validTypes.includes(input.transport_type)) {
|
|
56
|
+
errors.push({ field: 'transport_type', message: `must be one of: ${validTypes.join(',')}` });
|
|
57
|
+
}
|
|
58
|
+
// Transport-specific validation
|
|
59
|
+
if (input.transport_type === 'stdio') {
|
|
60
|
+
if (!input.command || input.command.trim() === '') {
|
|
61
|
+
errors.push({ field: 'command', message: 'command is required for stdio transport' });
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
// HTTP-based transport (sse / streamable-http)
|
|
66
|
+
if (!input.url || input.url.trim() === '') {
|
|
67
|
+
errors.push({ field: 'url', message: 'url is required for HTTP transport' });
|
|
68
|
+
}
|
|
69
|
+
if (input.url) {
|
|
70
|
+
try {
|
|
71
|
+
new URL(input.url);
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
errors.push({ field: 'url', message: 'url must be a valid URL' });
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return errors;
|
|
79
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { McpServer } from './mcp-db.js';
|
|
2
|
+
import type { InjectableTool } from '../tools/types.js';
|
|
3
|
+
declare class McpManager {
|
|
4
|
+
private connections;
|
|
5
|
+
/** Init: seed config.json mcpServers into DB, then connect all enabled servers */
|
|
6
|
+
init(): Promise<void>;
|
|
7
|
+
/** Connect to one MCP server */
|
|
8
|
+
private connectServer;
|
|
9
|
+
/** Create transport based on server config */
|
|
10
|
+
private createTransport;
|
|
11
|
+
/** Periodic health check via ping */
|
|
12
|
+
private startHealthCheck;
|
|
13
|
+
private clearHealthCheck;
|
|
14
|
+
/** Reconnect with exponential backoff */
|
|
15
|
+
private scheduleReconnect;
|
|
16
|
+
private clearReconnect;
|
|
17
|
+
/** Get all tools from connected servers */
|
|
18
|
+
getMcpTools(): InjectableTool[];
|
|
19
|
+
/** Get all connections with status info (for API) */
|
|
20
|
+
getConnectionsInfo(): Array<{
|
|
21
|
+
serverId: number;
|
|
22
|
+
serverName: string;
|
|
23
|
+
status: string;
|
|
24
|
+
toolCount: number;
|
|
25
|
+
}>;
|
|
26
|
+
/** Add a new server (after REST API create) */
|
|
27
|
+
addServer(server: McpServer): Promise<void>;
|
|
28
|
+
/** Remove a server (before REST API delete) */
|
|
29
|
+
removeServer(serverId: number): Promise<void>;
|
|
30
|
+
/** Reconnect a server (after config update) */
|
|
31
|
+
reconnectServer(serverId: number): Promise<void>;
|
|
32
|
+
/** Close all connections */
|
|
33
|
+
close(): Promise<void>;
|
|
34
|
+
}
|
|
35
|
+
export declare const mcpManager: McpManager;
|
|
36
|
+
export {};
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
2
|
+
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
|
|
3
|
+
import { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js';
|
|
4
|
+
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
|
|
5
|
+
import { listMcpServers } from './mcp-db.js';
|
|
6
|
+
import { mcpToolToInjectable } from '../tools/mcp-bridge.js';
|
|
7
|
+
import { getDatabase } from './db.js';
|
|
8
|
+
import { loadConfig } from '../config/index.js';
|
|
9
|
+
import { createMcpServer } from './mcp-db.js';
|
|
10
|
+
class McpManager {
|
|
11
|
+
constructor() {
|
|
12
|
+
Object.defineProperty(this, "connections", {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
configurable: true,
|
|
15
|
+
writable: true,
|
|
16
|
+
value: new Map()
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
/** Init: seed config.json mcpServers into DB, then connect all enabled servers */
|
|
20
|
+
async init() {
|
|
21
|
+
const db = getDatabase();
|
|
22
|
+
// Seed config.json mcpServers into DB (skip duplicates by name)
|
|
23
|
+
try {
|
|
24
|
+
const config = await loadConfig();
|
|
25
|
+
const cfgServers = config.mcpServers ?? [];
|
|
26
|
+
if (cfgServers.length > 0) {
|
|
27
|
+
const existing = listMcpServers(db);
|
|
28
|
+
for (const s of cfgServers) {
|
|
29
|
+
if (!existing.some(e => e.name === s.name)) {
|
|
30
|
+
createMcpServer(db, s);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
// Config seeding is optional; ignore errors
|
|
37
|
+
}
|
|
38
|
+
// Connect to all enabled servers
|
|
39
|
+
const servers = listMcpServers(db).filter(s => s.enabled);
|
|
40
|
+
for (const server of servers) {
|
|
41
|
+
await this.connectServer(server);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/** Connect to one MCP server */
|
|
45
|
+
async connectServer(server) {
|
|
46
|
+
// Disconnect existing connection if present
|
|
47
|
+
const existing = this.connections.get(server.id);
|
|
48
|
+
if (existing) {
|
|
49
|
+
this.clearHealthCheck(existing);
|
|
50
|
+
this.clearReconnect(existing);
|
|
51
|
+
try {
|
|
52
|
+
await existing.client.close();
|
|
53
|
+
}
|
|
54
|
+
catch { /* ignore */ }
|
|
55
|
+
}
|
|
56
|
+
const transport = this.createTransport(server);
|
|
57
|
+
const client = new Client({ name: 'cc-monitoring-proxy', version: '0.1.4' });
|
|
58
|
+
const conn = {
|
|
59
|
+
client,
|
|
60
|
+
transport,
|
|
61
|
+
serverId: server.id,
|
|
62
|
+
serverName: server.name,
|
|
63
|
+
status: 'connecting',
|
|
64
|
+
tools: [],
|
|
65
|
+
reconnectAttempts: 0,
|
|
66
|
+
serverConfig: server
|
|
67
|
+
};
|
|
68
|
+
this.connections.set(server.id, conn);
|
|
69
|
+
try {
|
|
70
|
+
await client.connect(transport);
|
|
71
|
+
conn.status = 'connected';
|
|
72
|
+
// Discover tools
|
|
73
|
+
const { tools } = await client.listTools();
|
|
74
|
+
conn.tools = tools.map(t => mcpToolToInjectable(t, server.name, client));
|
|
75
|
+
this.startHealthCheck(conn);
|
|
76
|
+
}
|
|
77
|
+
catch (err) {
|
|
78
|
+
conn.status = 'disconnected';
|
|
79
|
+
conn.tools = [];
|
|
80
|
+
console.error(`[MCP] connect failed: ${server.name} (${server.transport_type}) — ${err instanceof Error ? err.message : String(err)}`);
|
|
81
|
+
this.scheduleReconnect(conn, server);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/** Create transport based on server config */
|
|
85
|
+
createTransport(server) {
|
|
86
|
+
if (server.transport_type === 'stdio') {
|
|
87
|
+
const env = server.env
|
|
88
|
+
? { ...process.env, ...JSON.parse(server.env) }
|
|
89
|
+
: process.env;
|
|
90
|
+
// Split command string: "npx -y foo" → command="npx", args=["-y","foo"]
|
|
91
|
+
// StdioClientTransport uses spawn(command, args), command must be a single binary.
|
|
92
|
+
const parts = server.command.trim().split(/\s+/);
|
|
93
|
+
const cmd = parts[0];
|
|
94
|
+
const cmdArgs = parts.slice(1);
|
|
95
|
+
const storedArgs = server.args ? JSON.parse(server.args) : [];
|
|
96
|
+
const mergedArgs = [...cmdArgs, ...storedArgs];
|
|
97
|
+
return new StdioClientTransport({
|
|
98
|
+
command: cmd,
|
|
99
|
+
args: mergedArgs.length > 0 ? mergedArgs : undefined,
|
|
100
|
+
env
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
if (server.transport_type === 'streamable-http') {
|
|
104
|
+
const opts = {
|
|
105
|
+
url: new URL(server.url)
|
|
106
|
+
};
|
|
107
|
+
if (server.headers) {
|
|
108
|
+
opts.requestInit = { headers: JSON.parse(server.headers) };
|
|
109
|
+
}
|
|
110
|
+
return new StreamableHTTPClientTransport(opts.url, opts.requestInit ? { requestInit: opts.requestInit } : undefined);
|
|
111
|
+
}
|
|
112
|
+
if (server.transport_type === 'sse') {
|
|
113
|
+
return new SSEClientTransport(new URL(server.url));
|
|
114
|
+
}
|
|
115
|
+
throw new Error(`Unknown transport type: ${server.transport_type}`);
|
|
116
|
+
}
|
|
117
|
+
/** Periodic health check via ping */
|
|
118
|
+
startHealthCheck(conn) {
|
|
119
|
+
conn.healthTimer = setInterval(async () => {
|
|
120
|
+
try {
|
|
121
|
+
await conn.client.ping();
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
conn.status = 'disconnected';
|
|
125
|
+
conn.tools = [];
|
|
126
|
+
this.clearHealthCheck(conn);
|
|
127
|
+
this.scheduleReconnect(conn, conn.serverConfig);
|
|
128
|
+
}
|
|
129
|
+
}, 30000);
|
|
130
|
+
}
|
|
131
|
+
clearHealthCheck(conn) {
|
|
132
|
+
if (conn.healthTimer) {
|
|
133
|
+
clearInterval(conn.healthTimer);
|
|
134
|
+
conn.healthTimer = undefined;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
/** Reconnect with exponential backoff */
|
|
138
|
+
scheduleReconnect(conn, server) {
|
|
139
|
+
const delay = Math.min(2 ** conn.reconnectAttempts * 1000, 30000);
|
|
140
|
+
conn.reconnectAttempts++;
|
|
141
|
+
conn.reconnectTimer = setTimeout(async () => {
|
|
142
|
+
try {
|
|
143
|
+
await this.connectServer(server);
|
|
144
|
+
}
|
|
145
|
+
catch {
|
|
146
|
+
// Will schedule another reconnect in connectServer
|
|
147
|
+
}
|
|
148
|
+
}, delay);
|
|
149
|
+
}
|
|
150
|
+
clearReconnect(conn) {
|
|
151
|
+
if (conn.reconnectTimer) {
|
|
152
|
+
clearTimeout(conn.reconnectTimer);
|
|
153
|
+
conn.reconnectTimer = undefined;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
/** Get all tools from connected servers */
|
|
157
|
+
getMcpTools() {
|
|
158
|
+
return Array.from(this.connections.values())
|
|
159
|
+
.filter(c => c.status === 'connected')
|
|
160
|
+
.flatMap(c => c.tools);
|
|
161
|
+
}
|
|
162
|
+
/** Get all connections with status info (for API) */
|
|
163
|
+
getConnectionsInfo() {
|
|
164
|
+
return Array.from(this.connections.values()).map(c => ({
|
|
165
|
+
serverId: c.serverId,
|
|
166
|
+
serverName: c.serverName,
|
|
167
|
+
status: c.status,
|
|
168
|
+
toolCount: c.tools.length
|
|
169
|
+
}));
|
|
170
|
+
}
|
|
171
|
+
/** Add a new server (after REST API create) */
|
|
172
|
+
async addServer(server) {
|
|
173
|
+
if (server.enabled) {
|
|
174
|
+
await this.connectServer(server);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
/** Remove a server (before REST API delete) */
|
|
178
|
+
async removeServer(serverId) {
|
|
179
|
+
const conn = this.connections.get(serverId);
|
|
180
|
+
if (conn) {
|
|
181
|
+
this.clearHealthCheck(conn);
|
|
182
|
+
this.clearReconnect(conn);
|
|
183
|
+
try {
|
|
184
|
+
await conn.client.close();
|
|
185
|
+
}
|
|
186
|
+
catch { /* ignore */ }
|
|
187
|
+
this.connections.delete(serverId);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
/** Reconnect a server (after config update) */
|
|
191
|
+
async reconnectServer(serverId) {
|
|
192
|
+
const db = getDatabase();
|
|
193
|
+
const server = listMcpServers(db).find(s => s.id === serverId);
|
|
194
|
+
if (server && server.enabled) {
|
|
195
|
+
await this.connectServer(server);
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
// Server disabled — disconnect
|
|
199
|
+
await this.removeServer(serverId);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
/** Close all connections */
|
|
203
|
+
async close() {
|
|
204
|
+
for (const conn of this.connections.values()) {
|
|
205
|
+
this.clearHealthCheck(conn);
|
|
206
|
+
this.clearReconnect(conn);
|
|
207
|
+
try {
|
|
208
|
+
await conn.client.close();
|
|
209
|
+
}
|
|
210
|
+
catch { /* ignore */ }
|
|
211
|
+
}
|
|
212
|
+
this.connections.clear();
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
export const mcpManager = new McpManager();
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { Transform } from 'stream';
|
|
2
|
+
interface ClaudeTool {
|
|
3
|
+
name: string;
|
|
4
|
+
description?: string;
|
|
5
|
+
input_schema: any;
|
|
6
|
+
}
|
|
7
|
+
type ClaudeContent = string | Array<{
|
|
8
|
+
type: 'text' | 'image' | 'tool_use' | 'tool_result';
|
|
9
|
+
text?: string;
|
|
10
|
+
source?: {
|
|
11
|
+
type: 'base64';
|
|
12
|
+
media_type: string;
|
|
13
|
+
data: string;
|
|
14
|
+
};
|
|
15
|
+
id?: string;
|
|
16
|
+
name?: string;
|
|
17
|
+
input?: any;
|
|
18
|
+
tool_use_id?: string;
|
|
19
|
+
content?: any;
|
|
20
|
+
}>;
|
|
21
|
+
interface ClaudeMessage {
|
|
22
|
+
role: 'user' | 'assistant';
|
|
23
|
+
content: ClaudeContent;
|
|
24
|
+
}
|
|
25
|
+
interface ClaudeMessagesRequest {
|
|
26
|
+
model: string;
|
|
27
|
+
messages: ClaudeMessage[];
|
|
28
|
+
system?: string | Array<{
|
|
29
|
+
type: 'text';
|
|
30
|
+
text: string;
|
|
31
|
+
}>;
|
|
32
|
+
max_tokens: number;
|
|
33
|
+
stop_sequences?: string[];
|
|
34
|
+
stream?: boolean;
|
|
35
|
+
temperature?: number;
|
|
36
|
+
top_p?: number;
|
|
37
|
+
top_k?: number;
|
|
38
|
+
tools?: ClaudeTool[];
|
|
39
|
+
tool_choice?: {
|
|
40
|
+
type: 'auto' | 'any' | 'tool';
|
|
41
|
+
name?: string;
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
interface OpenAIMessage {
|
|
45
|
+
role: 'system' | 'user' | 'assistant' | 'tool';
|
|
46
|
+
content: string | Array<{
|
|
47
|
+
type: 'text' | 'image_url';
|
|
48
|
+
text?: string;
|
|
49
|
+
image_url?: {
|
|
50
|
+
url: string;
|
|
51
|
+
};
|
|
52
|
+
}>;
|
|
53
|
+
tool_calls?: OpenAIToolCall[];
|
|
54
|
+
tool_call_id?: string;
|
|
55
|
+
}
|
|
56
|
+
interface OpenAIToolCall {
|
|
57
|
+
id: string;
|
|
58
|
+
type: 'function';
|
|
59
|
+
function: {
|
|
60
|
+
name: string;
|
|
61
|
+
arguments: string;
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
interface OpenAIRequest {
|
|
65
|
+
model: string;
|
|
66
|
+
messages: OpenAIMessage[];
|
|
67
|
+
max_tokens?: number;
|
|
68
|
+
temperature?: number;
|
|
69
|
+
top_p?: number;
|
|
70
|
+
stop?: string[];
|
|
71
|
+
stream?: boolean;
|
|
72
|
+
tools?: Array<{
|
|
73
|
+
type: 'function';
|
|
74
|
+
function: any;
|
|
75
|
+
}>;
|
|
76
|
+
tool_choice?: 'auto' | 'none' | {
|
|
77
|
+
type: 'function';
|
|
78
|
+
function: {
|
|
79
|
+
name: string;
|
|
80
|
+
};
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Converts a Claude API request body to OpenAI format.
|
|
85
|
+
*/
|
|
86
|
+
export declare function convertClaudeToOpenAIRequest(claudeRequest: ClaudeMessagesRequest, modelName: string): OpenAIRequest;
|
|
87
|
+
/**
|
|
88
|
+
* Converts a non-streaming OpenAI response to Claude format.
|
|
89
|
+
*/
|
|
90
|
+
export declare function convertOpenAIToClaudeResponse(openaiResponse: any, model: string): any;
|
|
91
|
+
/**
|
|
92
|
+
* Builds headers for OpenAI-compatible API requests.
|
|
93
|
+
*/
|
|
94
|
+
export declare function buildOpenAIHeaders(apiKey: string): Record<string, string>;
|
|
95
|
+
/**
|
|
96
|
+
* Creates a Node.js Transform stream that converts OpenAI SSE chunks to Claude SSE events.
|
|
97
|
+
*/
|
|
98
|
+
export declare function createStreamTransformer(model: string): Transform;
|
|
99
|
+
export {};
|