@cc-monitoring/proxy-core 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/__tests__/commands.test.js +1 -1
- package/dist/cli/commands/exec.js +31 -42
- package/dist/docs/404.html +2 -2
- package/dist/docs/assets/{app.Dc46Hlqp.js → app.DtYNT5zS.js} +1 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.C4sjikMO.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.Snq5jR6J.js → VPLocalSearchBox.DpXF9ZAI.js} +1 -1
- package/dist/docs/assets/chunks/{theme.XLtxGM-l.js → theme.TS_gUyc7.js} +2 -2
- package/dist/docs/assets/{proxy-cli_data-hooks.md.w9Oe1OD3.js → proxy-cli_data-hooks.md.Bz8CVbxO.js} +1 -1
- package/dist/docs/assets/{proxy-core_ui-routes.md.Dyqkeoiv.js → proxy-core_ui-routes.md.B21t1p7R.js} +1 -1
- package/dist/docs/hashmap.json +1 -1
- package/dist/docs/index.html +3 -3
- package/dist/docs/overview.html +3 -3
- package/dist/docs/packages-utils.html +3 -3
- package/dist/docs/proxy-admin/env-and-build.html +3 -3
- package/dist/docs/proxy-admin/index.html +3 -3
- package/dist/docs/proxy-admin/layout-and-menu.html +3 -3
- package/dist/docs/proxy-admin/pages.html +3 -3
- package/dist/docs/proxy-admin/routing-and-auth.html +3 -3
- package/dist/docs/proxy-admin/services-and-mock.html +3 -3
- package/dist/docs/proxy-cli/api-layer.html +3 -3
- package/dist/docs/proxy-cli/app-shell.html +3 -3
- package/dist/docs/proxy-cli/components-common.html +3 -3
- package/dist/docs/proxy-cli/components-config.html +3 -3
- package/dist/docs/proxy-cli/components-requests.html +3 -3
- package/dist/docs/proxy-cli/components-stats.html +3 -3
- package/dist/docs/proxy-cli/components-status.html +3 -3
- package/dist/docs/proxy-cli/data-hooks.html +5 -5
- package/dist/docs/proxy-cli/index.html +3 -3
- package/dist/docs/proxy-cli/utils-and-i18n.html +3 -3
- package/dist/docs/proxy-core/chat-api.html +3 -3
- package/dist/docs/proxy-core/cli.html +3 -3
- package/dist/docs/proxy-core/config.html +3 -3
- package/dist/docs/proxy-core/data-layer.html +3 -3
- package/dist/docs/proxy-core/entry.html +3 -3
- package/dist/docs/proxy-core/index.html +3 -3
- package/dist/docs/proxy-core/pm2.html +3 -3
- package/dist/docs/proxy-core/providers.html +3 -3
- package/dist/docs/proxy-core/proxy.html +3 -3
- package/dist/docs/proxy-core/stats.html +3 -3
- package/dist/docs/proxy-core/tool.html +3 -3
- package/dist/docs/proxy-core/ui-routes.html +5 -5
- package/dist/docs/proxy-core/utilities.html +3 -3
- package/dist/docs/quickstart.html +3 -3
- package/dist/docs/request-flow.html +3 -3
- package/dist/logger/index.d.ts +0 -3
- package/dist/logger/index.js +0 -1
- package/dist/mcp-server/index.js +5 -3
- package/dist/mcp-server/tools.js +31 -10
- package/dist/server/__tests__/providers-route.test.js +1 -0
- package/dist/server/auth.d.ts +0 -1
- package/dist/server/auth.js +1 -1
- package/dist/server/chat-route.js +48 -156
- package/dist/server/data-push.d.ts +0 -1
- package/dist/server/data-push.js +0 -7
- package/dist/server/proxy.js +128 -219
- package/dist/server/ui-route.js +76 -59
- package/dist/tools/index.d.ts +1 -1
- package/dist/tools/index.js +1 -1
- package/dist/tools/registry.d.ts +0 -4
- package/dist/tools/registry.js +0 -8
- package/dist/types/config.d.ts +0 -13
- package/dist/types/pm2.d.ts +1 -2
- package/dist/ui/assets/{1c-Bx3CHH-I.js → 1c-CCx-FOtz.js} +1 -1
- package/dist/ui/assets/{abnf-NN4-iXDM.js → abnf-Bwbi42Z8.js} +1 -1
- package/dist/ui/assets/{abnfDiagram-VRR7QNED-CXFZgDk7.js → abnfDiagram-VRR7QNED-Dm1-8q0E.js} +1 -1
- package/dist/ui/assets/{accesslog-Bq9x4vSZ.js → accesslog-DCytz_-m.js} +1 -1
- package/dist/ui/assets/{actionscript-CeaB6gjT.js → actionscript-3udf15oh.js} +1 -1
- package/dist/ui/assets/{ada-DObFDSC6.js → ada-M5Xa74xG.js} +1 -1
- package/dist/ui/assets/{angelscript-4pIbuWPH.js → angelscript-qlrFxfW-.js} +1 -1
- package/dist/ui/assets/{apache-w0LzP4me.js → apache-B-sF-DQH.js} +1 -1
- package/dist/ui/assets/{applescript-DXpD6Cc9.js → applescript-4FdcBnbI.js} +1 -1
- package/dist/ui/assets/{arc-Dtt1H4m8.js → arc-BB3K1enp.js} +1 -1
- package/dist/ui/assets/{arcade-D_zU9Djr.js → arcade-B_yqWaaG.js} +1 -1
- package/dist/ui/assets/{architectureDiagram-ZJ3FMSHR-C0E_eQDM.js → architectureDiagram-ZJ3FMSHR-B39vkY8V.js} +1 -1
- package/dist/ui/assets/{arduino-BnmN_xp_.js → arduino-yAcBoTWU.js} +1 -1
- package/dist/ui/assets/{armasm-CH_xJaHf.js → armasm-wIcY84bI.js} +1 -1
- package/dist/ui/assets/{asciidoc-BlvZZ-hO.js → asciidoc-Bxnu28-Z.js} +1 -1
- package/dist/ui/assets/{aspectj-DP5DdFKQ.js → aspectj-B2cKJA_O.js} +1 -1
- package/dist/ui/assets/{autohotkey-Cy7dy_B1.js → autohotkey-B_rMWTtE.js} +1 -1
- package/dist/ui/assets/{autoit-BmQwjQdM.js → autoit-DwcuvMwv.js} +1 -1
- package/dist/ui/assets/{avrasm-fcPy4w1X.js → avrasm-heGX1PXK.js} +1 -1
- package/dist/ui/assets/{awk-AlcwGSdk.js → awk-BiqCQAEf.js} +1 -1
- package/dist/ui/assets/{axapta-NyMN6Mvz.js → axapta-Cv8M-Ih6.js} +1 -1
- package/dist/ui/assets/{bash-Bn3yyTUs.js → bash-Divgn3JV.js} +1 -1
- package/dist/ui/assets/{basic-gp9eOjjv.js → basic-B9dnAP55.js} +1 -1
- package/dist/ui/assets/{blockDiagram-677ZJIJ3-BHAadGGo.js → blockDiagram-677ZJIJ3-DQ1mf7A_.js} +1 -1
- package/dist/ui/assets/{bnf-DRAiK-_J.js → bnf-kIL5mSsP.js} +1 -1
- package/dist/ui/assets/{brainfuck-IYgPavhh.js → brainfuck-DqB7xDjH.js} +1 -1
- package/dist/ui/assets/{coq-BYVsAo31.js → c-HmsCM6sx.js} +1 -1
- package/dist/ui/assets/{c-like-B7T39dtK.js → c-like-De5MhE7G.js} +1 -1
- package/dist/ui/assets/{c4Diagram-LMCZKHZV-4cXT8R9f.js → c4Diagram-LMCZKHZV-DQxtYsAx.js} +1 -1
- package/dist/ui/assets/{cal-DmXm_WLX.js → cal-mYdfz9en.js} +1 -1
- package/dist/ui/assets/{capnproto-Cb-rKd-Z.js → capnproto-D04CRlOt.js} +1 -1
- package/dist/ui/assets/{ceylon-Bn2aNwEq.js → ceylon-pi9lFCja.js} +1 -1
- package/dist/ui/assets/channel-ChTtxQDg.js +1 -0
- package/dist/ui/assets/{chunk-2Q5K7J3B-B3N_AddF.js → chunk-2Q5K7J3B-BDD1nPt8.js} +1 -1
- package/dist/ui/assets/{chunk-32BRIVSS-CW7iU3gE.js → chunk-32BRIVSS-DgeQFBb5.js} +1 -1
- package/dist/ui/assets/{chunk-5VM5RSS4-M8Ep3dJD.js → chunk-5VM5RSS4-C7Xf2SnI.js} +1 -1
- package/dist/ui/assets/{chunk-EX3LRPZG-t2hCXH-v.js → chunk-EX3LRPZG-B_3p1HEv.js} +1 -1
- package/dist/ui/assets/{chunk-JWPE2WC7-rQK8maXo.js → chunk-JWPE2WC7-Dvs7u8eY.js} +1 -1
- package/dist/ui/assets/{chunk-MOJQB5TN-BpU7vp3L.js → chunk-MOJQB5TN-By21wDCN.js} +1 -1
- package/dist/ui/assets/{chunk-RYQCIY6F-CJVNOulR.js → chunk-RYQCIY6F-6NC700r1.js} +1 -1
- package/dist/ui/assets/{chunk-V7JOEXUC-B--maww3.js → chunk-V7JOEXUC-vEUqZ3rh.js} +1 -1
- package/dist/ui/assets/{chunk-VR4S4FIN-QJ5u9nSh.js → chunk-VR4S4FIN-6tX2dNN9.js} +1 -1
- package/dist/ui/assets/{chunk-XXDRQBXY-BcM9JOXa.js → chunk-XXDRQBXY-qDb2jxAR.js} +1 -1
- package/dist/ui/assets/classDiagram-OUVF2IWQ-Ccbvamlu.js +1 -0
- package/dist/ui/assets/classDiagram-v2-EOCWNBFH-Ccbvamlu.js +1 -0
- package/dist/ui/assets/{clean-BCfhFoON.js → clean-CLCsDUl1.js} +1 -1
- package/dist/ui/assets/{clojure-DtnBj8eB.js → clojure-dVi5Xifj.js} +1 -1
- package/dist/ui/assets/{clojure-repl-D8X-urCW.js → clojure-repl-BO_FpFmF.js} +1 -1
- package/dist/ui/assets/{cmake-BH2RXBgt.js → cmake-CP5aJbyK.js} +1 -1
- package/dist/ui/assets/{coffeescript-CuoLiQ_d.js → coffeescript-ZEfu_9pF.js} +1 -1
- package/dist/ui/assets/{c-Dht0EgwX.js → coq-6aKUn3zn.js} +1 -1
- package/dist/ui/assets/{cos-t-cDfrf6.js → cos-BohCnRN2.js} +1 -1
- package/dist/ui/assets/{cose-bilkent-JH36ORCC-CYip_9u7.js → cose-bilkent-JH36ORCC-DyXCbbro.js} +1 -1
- package/dist/ui/assets/{cpp-Cgv0dQ7g.js → cpp-FOgPWPEt.js} +1 -1
- package/dist/ui/assets/{crmsh-7pr1Pq_e.js → crmsh-B0OYb-Oe.js} +1 -1
- package/dist/ui/assets/{crystal-BHZFifeV.js → crystal-CuWb_dXm.js} +1 -1
- package/dist/ui/assets/{csharp-CVMfBRGF.js → csharp-BbcqM09j.js} +1 -1
- package/dist/ui/assets/{csp-NEBRDuZY.js → csp-rgHnTaDq.js} +1 -1
- package/dist/ui/assets/{css-B0fbMkoQ.js → css-C-ibh7ZG.js} +1 -1
- package/dist/ui/assets/{cynefin-VYW2F7L2-CycR2u2l.js → cynefin-VYW2F7L2-CkuBhgC4.js} +1 -1
- package/dist/ui/assets/{cynefinDiagram-TSTJHNR4-CvXYb5em.js → cynefinDiagram-TSTJHNR4-eycFyDao.js} +1 -1
- package/dist/ui/assets/{d-AzA6F7Ab.js → d-C0gXxJ0O.js} +1 -1
- package/dist/ui/assets/{dagre-VKFMJZFB-6NuSYMRG.js → dagre-VKFMJZFB-DzqX9e49.js} +1 -1
- package/dist/ui/assets/{dart-D0VXSwKi.js → dart-C-fTpuUV.js} +1 -1
- package/dist/ui/assets/{delphi-B-bkLmCx.js → delphi-Chm0B9xv.js} +1 -1
- package/dist/ui/assets/{diagram-FQU43EPY-CNNW_5O7.js → diagram-FQU43EPY-BEgCqfg1.js} +1 -1
- package/dist/ui/assets/{diagram-G47NLZAW-C60bRph-.js → diagram-G47NLZAW-Cw11Vs2v.js} +1 -1
- package/dist/ui/assets/{diagram-NH7WQ7WH-CwERNWac.js → diagram-NH7WQ7WH-DSG_UWpP.js} +1 -1
- package/dist/ui/assets/{diagram-OA4YK3LP-9XSTmf1Z.js → diagram-OA4YK3LP-CJz-WOaJ.js} +1 -1
- package/dist/ui/assets/{diagram-WEI45ONY-h8K41_YA.js → diagram-WEI45ONY-CBXjBCvc.js} +1 -1
- package/dist/ui/assets/{diff-Ch9RlEn8.js → diff-C-vyuMSL.js} +1 -1
- package/dist/ui/assets/{django-C00rhzcB.js → django-CJK7lReT.js} +1 -1
- package/dist/ui/assets/{dns-C5MKVde0.js → dns-D02SHjSy.js} +1 -1
- package/dist/ui/assets/{dockerfile-BpRaVDMB.js → dockerfile-trKL1Bqu.js} +1 -1
- package/dist/ui/assets/{dos-CjQOJ_vn.js → dos-C52dy-sK.js} +1 -1
- package/dist/ui/assets/{dsconfig-3zd3UkyN.js → dsconfig-MzHgzVrt.js} +1 -1
- package/dist/ui/assets/{dts-Bb6PtK5T.js → dts-B137dHyX.js} +1 -1
- package/dist/ui/assets/{dust-BEJKezIa.js → dust-BcbM0r5C.js} +1 -1
- package/dist/ui/assets/{ebnf-5-TvfsoC.js → ebnf-DkbpI7bK.js} +1 -1
- package/dist/ui/assets/{ebnfDiagram-CCIWWBDH-CRmIjeas.js → ebnfDiagram-CCIWWBDH-aI5uQ7w1.js} +1 -1
- package/dist/ui/assets/{elixir-B6gSEyen.js → elixir-BOtDuqQy.js} +1 -1
- package/dist/ui/assets/{elm-rR0aqyyf.js → elm-DS8Tyyu-.js} +1 -1
- package/dist/ui/assets/{erDiagram-Q63AITRT-DS3jYOq8.js → erDiagram-Q63AITRT-2vCbd4Mm.js} +1 -1
- package/dist/ui/assets/{erb-DUu22Jxg.js → erb-CSXECRbn.js} +1 -1
- package/dist/ui/assets/{erlang-C0m-R-6W.js → erlang-BMxlgKPJ.js} +1 -1
- package/dist/ui/assets/{erlang-repl-B7O2MhlI.js → erlang-repl-DPzlolPg.js} +1 -1
- package/dist/ui/assets/{excel-CIqnqFs1.js → excel-CW2Uxed3.js} +1 -1
- package/dist/ui/assets/{fix-Ds9tcTzQ.js → fix-UW84SlCs.js} +1 -1
- package/dist/ui/assets/{flix-ByzuevTB.js → flix-4UGiPULd.js} +1 -1
- package/dist/ui/assets/{flowDiagram-23GEKE2U-B9F3S_Hl.js → flowDiagram-23GEKE2U-R5PbCbZI.js} +1 -1
- package/dist/ui/assets/{fortran-DieSVGx5.js → fortran-nhHsngdu.js} +1 -1
- package/dist/ui/assets/{fsharp-DGP8m6H3.js → fsharp-CDyZ1ST5.js} +1 -1
- package/dist/ui/assets/{gams-BiLGBohb.js → gams-DHzkkUie.js} +1 -1
- package/dist/ui/assets/{ganttDiagram-NO4QXBWP-CHiCWnJt.js → ganttDiagram-NO4QXBWP-CGcq4Ie_.js} +1 -1
- package/dist/ui/assets/{gauss-Btl1fjJ0.js → gauss-DdhFGyBv.js} +1 -1
- package/dist/ui/assets/{gcode-DWl2YoL_.js → gcode-ImHh8OLA.js} +1 -1
- package/dist/ui/assets/{gherkin-D42ESIJ2.js → gherkin-CTWAW-XR.js} +1 -1
- package/dist/ui/assets/{gitGraphDiagram-IHSO6WYX-0pEKZnJg.js → gitGraphDiagram-IHSO6WYX-8nM2Z9lD.js} +1 -1
- package/dist/ui/assets/{glsl-Dx1QhGIM.js → glsl-0_W_27G2.js} +1 -1
- package/dist/ui/assets/{gml-f0noEVTB.js → gml-BoDggu2z.js} +1 -1
- package/dist/ui/assets/{go-DXT6c-0g.js → go-DYfFygwl.js} +1 -1
- package/dist/ui/assets/{golo-D3NuJxTg.js → golo-Mlq-TCg9.js} +1 -1
- package/dist/ui/assets/{gradle-CUsTLc_e.js → gradle-BALAinEB.js} +1 -1
- package/dist/ui/assets/{groovy-BIkOcIpQ.js → groovy-Dht--dWU.js} +1 -1
- package/dist/ui/assets/{haml-C5jI7YVN.js → haml-DpMrxg0d.js} +1 -1
- package/dist/ui/assets/{handlebars-UOvbWwDx.js → handlebars-DqHzujNj.js} +1 -1
- package/dist/ui/assets/{haskell-DuO_Av2n.js → haskell-DZSchhkY.js} +1 -1
- package/dist/ui/assets/{haxe-C0Cg5Hjh.js → haxe-C0zBRjdy.js} +1 -1
- package/dist/ui/assets/{hsp-CTDajZig.js → hsp-D_PwbSv2.js} +1 -1
- package/dist/ui/assets/{htmlbars-_ITuCkOs.js → htmlbars-DxAFMG8u.js} +1 -1
- package/dist/ui/assets/{http-Dr26PHfb.js → http-DvTRF0Do.js} +1 -1
- package/dist/ui/assets/{hy-B-ThgV4T.js → hy-lVO-kNyp.js} +1 -1
- package/dist/ui/assets/{index-CpQr158p.js → index-BbMRVVGt.js} +3 -3
- package/dist/ui/assets/{index-CwcnuNUs.js → index-Ci23SMK2.js} +242 -242
- package/dist/ui/assets/index-DlsVXaHT.css +10 -0
- package/dist/ui/assets/{infoDiagram-FWYZ7A6U-ClKPOdlx.js → infoDiagram-FWYZ7A6U-C7WYDlvc.js} +1 -1
- package/dist/ui/assets/{inform7-D7JYYkX9.js → inform7-B8Tf2n8v.js} +1 -1
- package/dist/ui/assets/{ini-BZwCkFAf.js → ini-DSoYMaLF.js} +1 -1
- package/dist/ui/assets/{irpf90-omMve0rd.js → irpf90-RCPdkB14.js} +1 -1
- package/dist/ui/assets/{isbl-C4xosfum.js → isbl-C2p75PPj.js} +1 -1
- package/dist/ui/assets/{ishikawaDiagram-FXEZZL3T-PtbNBMgh.js → ishikawaDiagram-FXEZZL3T-Cm6jsPlc.js} +1 -1
- package/dist/ui/assets/{java-CWjWDe7Q.js → java-DeY4Yuia.js} +1 -1
- package/dist/ui/assets/{javascript-C3dxrGuA.js → javascript-3uX1CO-H.js} +1 -1
- package/dist/ui/assets/{jboss-cli-CJE7m0Y-.js → jboss-cli-DgnD8mEc.js} +1 -1
- package/dist/ui/assets/{journeyDiagram-5HDEW3XC-DgK9V4yg.js → journeyDiagram-5HDEW3XC-DEGV1uA5.js} +1 -1
- package/dist/ui/assets/{json-DFUiNV7v.js → json-BV2PmJJp.js} +1 -1
- package/dist/ui/assets/{julia-CUTHpx8X.js → julia-B-m8kQm7.js} +1 -1
- package/dist/ui/assets/{julia-repl-_ZaQqdrz.js → julia-repl-C51atU2X.js} +1 -1
- package/dist/ui/assets/{kanban-definition-HUTT4EX6-BFrDfKdv.js → kanban-definition-HUTT4EX6-BJ4k5iTX.js} +1 -1
- package/dist/ui/assets/{kotlin-CrYjQYp8.js → kotlin-CYBziIgl.js} +1 -1
- package/dist/ui/assets/{lasso-CAiVg9m2.js → lasso-Dw2SBMDW.js} +1 -1
- package/dist/ui/assets/{latex-BkxnXIrT.js → latex-Dpd35yke.js} +1 -1
- package/dist/ui/assets/{ldif-CBOqxiN7.js → ldif-Ce9EZU__.js} +1 -1
- package/dist/ui/assets/{leaf-CbBZyOGH.js → leaf-CpkZzQtC.js} +1 -1
- package/dist/ui/assets/{less-Ca6uLPP0.js → less-Uzo7M0FD.js} +1 -1
- package/dist/ui/assets/{lisp-0Cm7_Bzv.js → lisp-DWXDlJYm.js} +1 -1
- package/dist/ui/assets/{livecodeserver-B7ka0vFT.js → livecodeserver-uEyPEgVJ.js} +1 -1
- package/dist/ui/assets/{livescript-CGmWmcLd.js → livescript-BQ5f07oK.js} +1 -1
- package/dist/ui/assets/{llvm-DCVMvkrH.js → llvm-BAvP-skE.js} +1 -1
- package/dist/ui/assets/{lsl-PVrTScpn.js → lsl-DhbiIKu6.js} +1 -1
- package/dist/ui/assets/{lua-BTo3z2Ux.js → lua-COxeUeLx.js} +1 -1
- package/dist/ui/assets/{makefile-DJGh9r9C.js → makefile-DhDx-IgL.js} +1 -1
- package/dist/ui/assets/{markdown-BOloL-q7.js → markdown-DX5_kSxq.js} +1 -1
- package/dist/ui/assets/{mathematica-CtMMQM2V.js → mathematica-D351ZddB.js} +1 -1
- package/dist/ui/assets/{matlab-Bfg_AWdR.js → matlab-CELqIiwF.js} +1 -1
- package/dist/ui/assets/{maxima-B2cdS7BY.js → maxima-B_YljrMm.js} +1 -1
- package/dist/ui/assets/{mel-BvfPvpYI.js → mel-DltsbNS8.js} +1 -1
- package/dist/ui/assets/{mercury-B6KgNIai.js → mercury-axX-5Vjj.js} +1 -1
- package/dist/ui/assets/{mindmap-definition-LN4V7U3C-BkeXo5If.js → mindmap-definition-LN4V7U3C-Bl1EJo6p.js} +1 -1
- package/dist/ui/assets/{mipsasm-Csras-cD.js → mipsasm-BxmerVwX.js} +1 -1
- package/dist/ui/assets/{mizar-C3WDI1-X.js → mizar-XNHfbpL2.js} +1 -1
- package/dist/ui/assets/{mojolicious-MnD2Whic.js → mojolicious-BR0U_7zk.js} +1 -1
- package/dist/ui/assets/{monkey-DLvUPYTI.js → monkey-lLuu9_f-.js} +1 -1
- package/dist/ui/assets/{moonscript-B0XEb3R3.js → moonscript-DoaZ3DRQ.js} +1 -1
- package/dist/ui/assets/{n1ql-BMRF54sY.js → n1ql-C6TId6Iu.js} +1 -1
- package/dist/ui/assets/{nginx-DqUyeHb8.js → nginx-BezSG-JT.js} +1 -1
- package/dist/ui/assets/{nim-3xwg8mOL.js → nim-Bb0rfXie.js} +1 -1
- package/dist/ui/assets/{nix-ByTkLdcH.js → nix-o3sJ5-54.js} +1 -1
- package/dist/ui/assets/{node-repl-sGSuIUFG.js → node-repl-Sv5hhcTf.js} +1 -1
- package/dist/ui/assets/{nsis-Dng5mFSM.js → nsis-B45BJFhF.js} +1 -1
- package/dist/ui/assets/{objectivec-DSQ8vb7n.js → objectivec-CzS6zVgh.js} +1 -1
- package/dist/ui/assets/{ocaml-BHOhEgRu.js → ocaml-Bqux7PyP.js} +1 -1
- package/dist/ui/assets/{openscad-DcUxQ-FQ.js → openscad-4Wf6mF84.js} +1 -1
- package/dist/ui/assets/{oxygene-DNlmqhsR.js → oxygene-Fvwqgkkt.js} +1 -1
- package/dist/ui/assets/{parser3-DIR98Q6n.js → parser3-zEfzT5wv.js} +1 -1
- package/dist/ui/assets/{pegDiagram-2B236MQR-BrXp_1_9.js → pegDiagram-2B236MQR-Dd4rIztM.js} +1 -1
- package/dist/ui/assets/{perl-16cY7fyu.js → perl-CsS1Gs6o.js} +1 -1
- package/dist/ui/assets/{pf-KrAq2BW7.js → pf-BNH1jO0R.js} +1 -1
- package/dist/ui/assets/{pgsql-BV1Z2bjp.js → pgsql-DqPigHrq.js} +1 -1
- package/dist/ui/assets/{php-FGjYSZqs.js → php-CdOl9bRs.js} +1 -1
- package/dist/ui/assets/{php-template-B1OW86WT.js → php-template-DPfirJg2.js} +1 -1
- package/dist/ui/assets/{pieDiagram-ENE6RG2P-Bh0bhWSa.js → pieDiagram-ENE6RG2P-DGaJNf4S.js} +1 -1
- package/dist/ui/assets/{plaintext-Cvn_UgSv.js → plaintext-EHbgBKzw.js} +1 -1
- package/dist/ui/assets/{pony-CRWnA3MR.js → pony-DmJajtp2.js} +1 -1
- package/dist/ui/assets/{powershell-Cwn155MZ.js → powershell-DfGzdWR6.js} +1 -1
- package/dist/ui/assets/{processing-BS6-1lrQ.js → processing-BT0ETgPG.js} +1 -1
- package/dist/ui/assets/{profile-C45OLQrv.js → profile-B3I-x5Lt.js} +1 -1
- package/dist/ui/assets/{prolog-C5YafSzY.js → prolog-B_4QJIvI.js} +1 -1
- package/dist/ui/assets/{properties-BULd-Zhg.js → properties-BFVI8weS.js} +1 -1
- package/dist/ui/assets/{protobuf-Qf1IuG5l.js → protobuf-PaF39oZZ.js} +1 -1
- package/dist/ui/assets/{puppet-93XdQvnn.js → puppet-BDC6Q8VF.js} +1 -1
- package/dist/ui/assets/{purebasic-DlYNScQP.js → purebasic-B2ejrOZK.js} +1 -1
- package/dist/ui/assets/{python-D-Do6-F0.js → python-BOxtIk9H.js} +1 -1
- package/dist/ui/assets/{python-repl-DGutP04w.js → python-repl-BslBh_Mx.js} +1 -1
- package/dist/ui/assets/{q-lmgfrySy.js → q-BPe8WLGW.js} +1 -1
- package/dist/ui/assets/{qml-BbjX_mSU.js → qml-BazRR6fz.js} +1 -1
- package/dist/ui/assets/{quadrantDiagram-ABIIQ3AL-B891FOO8.js → quadrantDiagram-ABIIQ3AL-BQ7aPkHk.js} +1 -1
- package/dist/ui/assets/{r--x8NzO9N.js → r-C09pGNJC.js} +1 -1
- package/dist/ui/assets/{railroadDiagram-RFXS5EU6-R3O-GKNe.js → railroadDiagram-RFXS5EU6-sCO9VGvE.js} +1 -1
- package/dist/ui/assets/{reasonml-DwHsAflh.js → reasonml-S7dzwVL9.js} +1 -1
- package/dist/ui/assets/{requirementDiagram-TGXJPOKE-D4l_xEXt.js → requirementDiagram-TGXJPOKE-CfT5aVZg.js} +1 -1
- package/dist/ui/assets/{rib-DMJNtDwV.js → rib-fM2EwQd4.js} +1 -1
- package/dist/ui/assets/{roboconf-BNNGTvHr.js → roboconf-D7AaeyrW.js} +1 -1
- package/dist/ui/assets/{routeros-BF7SVruD.js → routeros-c6Q7mKuq.js} +1 -1
- package/dist/ui/assets/{rsl-1EHeIZqp.js → rsl-sCpEQBxh.js} +1 -1
- package/dist/ui/assets/{ruby-B-v_BYYp.js → ruby-lcKhz2w9.js} +1 -1
- package/dist/ui/assets/{ruleslanguage-GFeEMSdK.js → ruleslanguage-BW4ATOuX.js} +1 -1
- package/dist/ui/assets/{rust-ApqGtMhh.js → rust-BbpU-0VY.js} +1 -1
- package/dist/ui/assets/{sankeyDiagram-HTMAVEWB-Dc-2lhBq.js → sankeyDiagram-HTMAVEWB-CaweCpvN.js} +1 -1
- package/dist/ui/assets/{sas-YkxX6N9_.js → sas-BPt5R0dx.js} +1 -1
- package/dist/ui/assets/{scala-BpHi86GZ.js → scala-DxW_vqXs.js} +1 -1
- package/dist/ui/assets/{scheme-D889qY8Y.js → scheme-T2Q_jWzT.js} +1 -1
- package/dist/ui/assets/{scilab-C3l-bcRx.js → scilab-DMORg9lV.js} +1 -1
- package/dist/ui/assets/{scss-D0iGASxm.js → scss-t0VsosqT.js} +1 -1
- package/dist/ui/assets/{sequenceDiagram-DBY2YBRQ-DvppgciC.js → sequenceDiagram-DBY2YBRQ-o-H_R4zb.js} +1 -1
- package/dist/ui/assets/{shell-PUnaEPCO.js → shell-CnCDa1s9.js} +1 -1
- package/dist/ui/assets/{sizeCapture-X5ZJPWSS-DhvIbxXs.js → sizeCapture-X5ZJPWSS-BNLkHGDS.js} +1 -1
- package/dist/ui/assets/{smali-Du_dF9hl.js → smali-_n-BxJyG.js} +1 -1
- package/dist/ui/assets/{smalltalk-CSr2Gc1v.js → smalltalk-B90PXJwK.js} +1 -1
- package/dist/ui/assets/{sml-D3zkvzP2.js → sml-fuY7bj-n.js} +1 -1
- package/dist/ui/assets/{sqf-BZQ34qEZ.js → sqf-COpwkyuo.js} +1 -1
- package/dist/ui/assets/{sql-BFKScMsf.js → sql-CXIT0j-x.js} +1 -1
- package/dist/ui/assets/{sql_more-C2Lc_Qqq.js → sql_more-C1Oxq4rx.js} +1 -1
- package/dist/ui/assets/{stan-CzY8VdxU.js → stan-BZEpaHeC.js} +1 -1
- package/dist/ui/assets/{stata-9GxyhPpV.js → stata-CkBwaiZM.js} +1 -1
- package/dist/ui/assets/{stateDiagram-2N3HPSRC-CM63y6f0.js → stateDiagram-2N3HPSRC-BkdnNF7I.js} +1 -1
- package/dist/ui/assets/stateDiagram-v2-6OUMAXLB-0JnZ1VSQ.js +1 -0
- package/dist/ui/assets/{step21-BpK_Zw3v.js → step21-fs9N_U3O.js} +1 -1
- package/dist/ui/assets/{stylus-DQ4k28M4.js → stylus-Bs_9cvKZ.js} +1 -1
- package/dist/ui/assets/{subunit-C6ciOPNF.js → subunit-DvgcOCqJ.js} +1 -1
- package/dist/ui/assets/{swift-CJfqqSbT.js → swift-BE4ONsur.js} +1 -1
- package/dist/ui/assets/{swimlanes-5IMT3BWC-DS6_HNF7.js → swimlanes-5IMT3BWC-uqTAc7o7.js} +2 -2
- package/dist/ui/assets/swimlanesDiagram-G3AALYLV-DQRIIEmi.js +8 -0
- package/dist/ui/assets/{taggerscript-VouMmJ_v.js → taggerscript-BhmPJ64C.js} +1 -1
- package/dist/ui/assets/{tap-wXCy18ot.js → tap-DkueIVKV.js} +1 -1
- package/dist/ui/assets/{tcl-ewDOmCFX.js → tcl-DyXOOkFi.js} +1 -1
- package/dist/ui/assets/{thrift-BfFA03rE.js → thrift-Dhgbk56T.js} +1 -1
- package/dist/ui/assets/{timeline-definition-FHXFAJF6-Dz2m6S6x.js → timeline-definition-FHXFAJF6-DBAk9Ouc.js} +1 -1
- package/dist/ui/assets/{tp-HGBcpNf9.js → tp-BsXyrRGH.js} +1 -1
- package/dist/ui/assets/{twig-nrQZ0pw8.js → twig-J0HqIuHw.js} +1 -1
- package/dist/ui/assets/{typescript-B7tNYFEQ.js → typescript-Dkwvul39.js} +1 -1
- package/dist/ui/assets/{vala-BIjQtoo6.js → vala-CRGnf8aY.js} +1 -1
- package/dist/ui/assets/{vbnet-Bbspccm6.js → vbnet-BtJAUe3z.js} +1 -1
- package/dist/ui/assets/{vbscript-C45_QgOy.js → vbscript-RgFFNuM3.js} +1 -1
- package/dist/ui/assets/{vbscript-html-DlF2QBc7.js → vbscript-html-DO32Io9Y.js} +1 -1
- package/dist/ui/assets/{vennDiagram-L72KCM5P-BPEphYtX.js → vennDiagram-L72KCM5P-BJi6y0hh.js} +1 -1
- package/dist/ui/assets/{verilog-BSitd8W0.js → verilog-C4h6MLcI.js} +1 -1
- package/dist/ui/assets/{vhdl-C1bbeiC4.js → vhdl-DOafePyU.js} +1 -1
- package/dist/ui/assets/{vim-DchwbT8X.js → vim-BAdTA9TY.js} +1 -1
- package/dist/ui/assets/{wardleyDiagram-EHGQE667-BttTCoBT.js → wardleyDiagram-EHGQE667-C7c_4IJ6.js} +1 -1
- package/dist/ui/assets/{x86asm-vARxMUvn.js → x86asm-BCL6__QH.js} +1 -1
- package/dist/ui/assets/{xl-dx63vvXo.js → xl-qIzE4HOe.js} +1 -1
- package/dist/ui/assets/{xml-BUnj27wL.js → xml-DE2sJXYU.js} +1 -1
- package/dist/ui/assets/{xquery-T7gpnf0e.js → xquery-CQ35t92y.js} +1 -1
- package/dist/ui/assets/{xychartDiagram-FW5EYKEG-BfrNhdrG.js → xychartDiagram-FW5EYKEG-D2ILn0jL.js} +1 -1
- package/dist/ui/assets/{yaml-xRgQKzeL.js → yaml-5KaAvG5C.js} +1 -1
- package/dist/ui/assets/{zephir-Yu6l5qJj.js → zephir-CbR3Ryfq.js} +1 -1
- package/dist/ui/index.html +2 -2
- package/dist/utils/__tests__/abort-signals.test.js +67 -0
- package/dist/utils/__tests__/inject-loop.test.js +1 -53
- package/dist/utils/__tests__/learn-tasks-db.test.js +82 -0
- package/dist/utils/__tests__/openai-converter.test.js +25 -0
- package/dist/utils/__tests__/pi-crawl-tools.test.js +15 -4
- package/dist/utils/__tests__/pi-dedup-reconcile.test.js +11 -9
- package/dist/utils/__tests__/pi-events.test.js +172 -0
- package/dist/utils/__tests__/pi-learn-orchestrator.test.js +216 -6
- package/dist/utils/__tests__/pi-runtime-json.test.js +38 -3
- package/dist/utils/__tests__/providers-db.test.js +40 -2
- package/dist/utils/__tests__/request-writer.test.js +271 -39
- package/dist/utils/__tests__/sse-protocol.test.d.ts +1 -0
- package/dist/utils/__tests__/sse-protocol.test.js +115 -0
- package/dist/utils/__tests__/vault.test.d.ts +1 -0
- package/dist/utils/__tests__/{knowledge-store.test.js → vault.test.js} +16 -16
- package/dist/utils/abort-signals.d.ts +13 -0
- package/dist/utils/abort-signals.js +33 -0
- package/dist/utils/db.d.ts +2 -0
- package/dist/utils/db.js +42 -0
- package/dist/utils/esm-dirname.d.ts +0 -15
- package/dist/utils/esm-dirname.js +0 -4
- package/dist/utils/inject-loop.d.ts +0 -27
- package/dist/utils/inject-loop.js +2 -56
- package/dist/utils/learn-tasks-db.d.ts +15 -0
- package/dist/utils/learn-tasks-db.js +35 -0
- package/dist/utils/openai-converter.js +88 -78
- package/dist/utils/pi-browser-tools.d.ts +0 -2
- package/dist/utils/pi-browser-tools.js +0 -174
- package/dist/utils/pi-crawl-tools.d.ts +2 -1
- package/dist/utils/pi-crawl-tools.js +16 -11
- package/dist/utils/pi-dedup.d.ts +8 -30
- package/dist/utils/pi-dedup.js +32 -67
- package/dist/utils/pi-events.d.ts +65 -0
- package/dist/utils/pi-events.js +98 -0
- package/dist/utils/pi-learn-orchestrator.d.ts +6 -5
- package/dist/utils/pi-learn-orchestrator.js +71 -106
- package/dist/utils/pi-runtime.d.ts +5 -6
- package/dist/utils/pi-runtime.js +38 -42
- package/dist/utils/pi-sandbox-ops.d.ts +0 -36
- package/dist/utils/pi-sandbox-ops.js +5 -190
- package/dist/utils/providers-db.d.ts +3 -0
- package/dist/utils/providers-db.js +21 -7
- package/dist/utils/request-writer.d.ts +60 -30
- package/dist/utils/request-writer.js +182 -61
- package/dist/utils/sse-protocol.d.ts +34 -0
- package/dist/utils/sse-protocol.js +121 -0
- package/dist/utils/sse-stream-processor.d.ts +4 -9
- package/dist/utils/sse-stream-processor.js +13 -104
- package/dist/utils/sse-writer.d.ts +1 -1
- package/dist/utils/sse-writer.js +3 -2
- package/dist/utils/stats-aggregator.js +3 -0
- package/dist/utils/tool-injector.js +7 -0
- package/dist/utils/vault.d.ts +111 -0
- package/dist/utils/vault.js +434 -0
- package/package.json +1 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.BN6hB8Jr.js +0 -1
- package/dist/types/api.d.ts +0 -20
- package/dist/types/index.d.ts +0 -4
- package/dist/types/index.js +0 -4
- package/dist/types/log.d.ts +0 -13
- package/dist/ui/assets/channel-BgAIihW-.js +0 -1
- package/dist/ui/assets/classDiagram-OUVF2IWQ-0fsnUoNI.js +0 -1
- package/dist/ui/assets/classDiagram-v2-EOCWNBFH-0fsnUoNI.js +0 -1
- package/dist/ui/assets/index-C0fxlU9d.css +0 -10
- package/dist/ui/assets/stateDiagram-v2-6OUMAXLB-OA9dcuA9.js +0 -1
- package/dist/ui/assets/swimlanesDiagram-G3AALYLV-BLEnJU_R.js +0 -8
- package/dist/utils/__tests__/sse-accumulator.test.js +0 -83
- package/dist/utils/knowledge-store.d.ts +0 -44
- package/dist/utils/knowledge-store.js +0 -193
- package/dist/utils/migrate-files-to-db.d.ts +0 -1
- package/dist/utils/migrate-files-to-db.js +0 -138
- package/dist/utils/sse-accumulator.d.ts +0 -9
- package/dist/utils/sse-accumulator.js +0 -59
- /package/dist/docs/assets/{proxy-cli_data-hooks.md.w9Oe1OD3.lean.js → proxy-cli_data-hooks.md.Bz8CVbxO.lean.js} +0 -0
- /package/dist/docs/assets/{proxy-core_ui-routes.md.Dyqkeoiv.lean.js → proxy-core_ui-routes.md.B21t1p7R.lean.js} +0 -0
- /package/dist/{types/api.js → utils/__tests__/abort-signals.test.d.ts} +0 -0
- /package/dist/{types/log.js → utils/__tests__/learn-tasks-db.test.d.ts} +0 -0
- /package/dist/utils/__tests__/{knowledge-store.test.d.ts → openai-converter.test.d.ts} +0 -0
- /package/dist/utils/__tests__/{sse-accumulator.test.d.ts → pi-events.test.d.ts} +0 -0
package/dist/server/proxy.js
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import { Readable, finished } from 'stream';
|
|
2
2
|
import { convertClaudeToOpenAIRequest, convertOpenAIToClaudeResponse, createStreamTransformer, buildOpenAIHeaders } from '../utils/openai-converter.js';
|
|
3
3
|
import { loadConfig } from '../config/index.js';
|
|
4
|
-
import {
|
|
5
|
-
import { cleanOldRequestsDB } from '../utils/request-writer.js';
|
|
4
|
+
import { createRequestRecorder } from '../utils/request-writer.js';
|
|
5
|
+
import { cleanOldRequestsDB, interruptStaleRequestsOnStartup } from '../utils/request-writer.js';
|
|
6
6
|
import { pushNewRequest } from './data-push.js';
|
|
7
7
|
import { initDatabase, closeDatabase, getDatabase } from '../utils/db.js';
|
|
8
|
+
import { recoverCrashedTasks } from '../utils/learn-tasks-db.js';
|
|
9
|
+
import { getActiveProvider } from '../utils/providers-db.js';
|
|
8
10
|
import { aggregateStats } from '../utils/stats-aggregator.js';
|
|
9
11
|
import { mcpManager } from '../utils/mcp-manager.js';
|
|
10
12
|
import { getMachineIdSync, preloadMachineId } from '../utils/machine-id.js';
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
let cachedDbInstance = null;
|
|
13
|
+
import { createEventDecoder } from '../utils/sse-protocol.js';
|
|
14
|
+
import { createClientAbortSignal, createTimeoutSignal } from '../utils/abort-signals.js';
|
|
14
15
|
/**
|
|
15
16
|
* Resolves the proxy target per request:
|
|
16
17
|
* - If a provider with is_default=1 exists in DB, use its base_url + api_key + tier models (partial replacement)
|
|
@@ -36,15 +37,7 @@ export function resolveProxyTarget(proxyConfig) {
|
|
|
36
37
|
baseUrl = configUrl.origin;
|
|
37
38
|
targetPath = configUrl.pathname.replace(/\/$/, '');
|
|
38
39
|
const db = getDatabase();
|
|
39
|
-
|
|
40
|
-
if (db !== cachedDbInstance) {
|
|
41
|
-
activeProviderStmt = null;
|
|
42
|
-
cachedDbInstance = db;
|
|
43
|
-
}
|
|
44
|
-
if (!activeProviderStmt) {
|
|
45
|
-
activeProviderStmt = db.prepare('SELECT base_url, api_key, model, haiku_model, sonnet_model, opus_model, is_openai_compatible, auth_style FROM providers WHERE is_default = 1 LIMIT 1');
|
|
46
|
-
}
|
|
47
|
-
const active = activeProviderStmt.get();
|
|
40
|
+
const active = getActiveProvider(db);
|
|
48
41
|
if (active) {
|
|
49
42
|
// Replace base_url only if provided
|
|
50
43
|
if (active.base_url && active.base_url.trim() !== '') {
|
|
@@ -163,57 +156,6 @@ export function getErrorStatusCode(error) {
|
|
|
163
156
|
}
|
|
164
157
|
return 500;
|
|
165
158
|
}
|
|
166
|
-
/**
|
|
167
|
-
* Push a parsed SSE event into batch/tail buffers.
|
|
168
|
-
* Flushes batch to DB when it reaches EVENT_BATCH_SIZE (10).
|
|
169
|
-
* Only memory held: current batch (≤10 events) + tail (≤5 events).
|
|
170
|
-
*/
|
|
171
|
-
function pushEventToBuffers(event, sessionId, requestId, eventBatch, tailBuffer, eventIndexRef) {
|
|
172
|
-
const entry = { index: eventIndexRef.value, type: event?.type, data: event };
|
|
173
|
-
eventBatch.push(entry);
|
|
174
|
-
// Maintain tail buffer (last 5 events for usage extraction)
|
|
175
|
-
tailBuffer.push(event);
|
|
176
|
-
if (tailBuffer.length > 5) {
|
|
177
|
-
tailBuffer.shift();
|
|
178
|
-
}
|
|
179
|
-
// Flush batch to DB when threshold reached
|
|
180
|
-
if (eventBatch.length >= EVENT_BATCH_SIZE) {
|
|
181
|
-
flushEventBatch(sessionId, requestId, eventBatch, eventIndexRef.value - eventBatch.length + 1);
|
|
182
|
-
eventBatch.length = 0; // Reset batch (memory freed)
|
|
183
|
-
}
|
|
184
|
-
eventIndexRef.value++;
|
|
185
|
-
}
|
|
186
|
-
/**
|
|
187
|
-
* Flush remaining batch + update request completion in DB.
|
|
188
|
-
* Extracts token usage from tail buffer (no need for full events array).
|
|
189
|
-
*/
|
|
190
|
-
async function completeStreamSave(sessionId, requestId, requestData, eventBatch, tailBuffer, eventIndexRef, startTime, statusCode, resolved, forwardedModel, originalModel, machineId, request) {
|
|
191
|
-
// Flush remaining events in batch
|
|
192
|
-
if (eventBatch.length > 0) {
|
|
193
|
-
flushEventBatch(sessionId, requestId, eventBatch, eventIndexRef.value - eventBatch.length);
|
|
194
|
-
eventBatch.length = 0;
|
|
195
|
-
}
|
|
196
|
-
requestData.response.completedAt = new Date().toISOString();
|
|
197
|
-
requestData.response.events = []; // Not needed for streaming, clear to avoid serialization
|
|
198
|
-
await saveRequestDB(sessionId, requestId, requestData);
|
|
199
|
-
const usage = extractTokenUsage(tailBuffer);
|
|
200
|
-
updateRequestTokens(requestId, sessionId, usage);
|
|
201
|
-
pushNewRequest({
|
|
202
|
-
requestId,
|
|
203
|
-
sessionId,
|
|
204
|
-
compositeId: `${sessionId}:${requestId}`,
|
|
205
|
-
method: request.method,
|
|
206
|
-
path: request.url,
|
|
207
|
-
timestamp: requestData.timestamp,
|
|
208
|
-
statusCode,
|
|
209
|
-
responseTime: Date.now() - startTime,
|
|
210
|
-
model: forwardedModel || originalModel,
|
|
211
|
-
machineId,
|
|
212
|
-
baseUrl: resolved.baseUrl,
|
|
213
|
-
usage,
|
|
214
|
-
pendingId: requestId !== request.id ? `${sessionId}:${request.id}` : undefined
|
|
215
|
-
}, 'completed');
|
|
216
|
-
}
|
|
217
159
|
export function getErrorMessage(error) {
|
|
218
160
|
if (error.code === 'ECONNREFUSED') {
|
|
219
161
|
return 'Target server unreachable';
|
|
@@ -226,12 +168,50 @@ export function getErrorMessage(error) {
|
|
|
226
168
|
}
|
|
227
169
|
return 'Proxy error';
|
|
228
170
|
}
|
|
171
|
+
// SSE 流空闲看门狗:超过该时长无上游数据则销毁流,避免挂死产生僵尸行
|
|
172
|
+
const STREAM_IDLE_TIMEOUT_MS = 120000;
|
|
173
|
+
/**
|
|
174
|
+
* 给上游 nodeStream 挂空闲看门狗:data 到达重置定时器;
|
|
175
|
+
* end/close/error 清理定时器;超时且流未销毁时以 idle timeout 销毁。
|
|
176
|
+
*/
|
|
177
|
+
function attachIdleWatchdog(nodeStream) {
|
|
178
|
+
let timer = null;
|
|
179
|
+
const clearTimer = () => {
|
|
180
|
+
if (timer) {
|
|
181
|
+
clearTimeout(timer);
|
|
182
|
+
timer = null;
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
const resetTimer = () => {
|
|
186
|
+
clearTimer();
|
|
187
|
+
timer = setTimeout(() => {
|
|
188
|
+
if (!nodeStream.destroyed) {
|
|
189
|
+
nodeStream.destroy(new Error('upstream idle timeout'));
|
|
190
|
+
}
|
|
191
|
+
}, STREAM_IDLE_TIMEOUT_MS);
|
|
192
|
+
};
|
|
193
|
+
nodeStream.on('data', resetTimer);
|
|
194
|
+
nodeStream.on('end', clearTimer);
|
|
195
|
+
nodeStream.on('close', clearTimer);
|
|
196
|
+
nodeStream.on('error', clearTimer);
|
|
197
|
+
resetTimer();
|
|
198
|
+
}
|
|
229
199
|
export async function setupProxy(fastify, proxyConfig) {
|
|
230
200
|
// Load full config to get storage.maxDays
|
|
231
201
|
const fullConfig = await loadConfig();
|
|
232
202
|
const maxDays = fullConfig.storage?.maxDays ?? 7;
|
|
233
203
|
// Initialize SQLite database
|
|
234
|
-
initDatabase();
|
|
204
|
+
const db = initDatabase();
|
|
205
|
+
// 回收上次进程遗留的无主 running learn 任务(进程崩溃/被 kill)
|
|
206
|
+
const recoveredTasks = recoverCrashedTasks(db);
|
|
207
|
+
if (recoveredTasks > 0) {
|
|
208
|
+
console.log(`Recovered ${recoveredTasks} crashed learn task(s) from previous run`);
|
|
209
|
+
}
|
|
210
|
+
// 回收上次进程遗留的僵尸 SSE 请求行(流中断/挂死未回调)
|
|
211
|
+
const interruptedRequests = interruptStaleRequestsOnStartup();
|
|
212
|
+
if (interruptedRequests > 0) {
|
|
213
|
+
console.log(`Interrupted ${interruptedRequests} stale request(s) from previous run`);
|
|
214
|
+
}
|
|
235
215
|
// Initialize MCP connections (after DB is ready)
|
|
236
216
|
try {
|
|
237
217
|
await mcpManager.init();
|
|
@@ -285,9 +265,12 @@ export async function setupProxy(fastify, proxyConfig) {
|
|
|
285
265
|
fastify.all('/v1/*', async (request, reply) => {
|
|
286
266
|
const startTime = Date.now();
|
|
287
267
|
const resolved = resolveProxyTarget(proxyConfig);
|
|
268
|
+
// 下游客户端中止:整个请求作用域建一次,两处上游 fetch 复用
|
|
269
|
+
const clientSignal = createClientAbortSignal(request.raw);
|
|
288
270
|
const sessionId = request.headers['x-claude-code-session-id'] || 'unknown-session';
|
|
289
271
|
// Replace model based on tier matching (getProxyModel)
|
|
290
272
|
const originalModel = request.body?.model;
|
|
273
|
+
let rec;
|
|
291
274
|
try {
|
|
292
275
|
const proxyModel = getProxyModel(originalModel, resolved);
|
|
293
276
|
if (proxyModel && request.body && typeof request.body === 'object') {
|
|
@@ -311,9 +294,9 @@ export async function setupProxy(fastify, proxyConfig) {
|
|
|
311
294
|
(forwardedAuthHeader?.startsWith('Bearer ') ? forwardedAuthHeader.slice(7) : undefined);
|
|
312
295
|
// Log complete request data (Fastify already parsed body)
|
|
313
296
|
const machineId = getMachineIdSync() ?? undefined;
|
|
314
|
-
const
|
|
315
|
-
requestId: request.id, // Will be updated with cloud x-request-id later
|
|
297
|
+
const meta = {
|
|
316
298
|
sessionId,
|
|
299
|
+
localRequestId: request.id, // Will be replaced with cloud x-request-id row on completion
|
|
317
300
|
timestamp: new Date().toISOString(),
|
|
318
301
|
apiKey,
|
|
319
302
|
proxyApiKey,
|
|
@@ -325,33 +308,12 @@ export async function setupProxy(fastify, proxyConfig) {
|
|
|
325
308
|
path: request.url,
|
|
326
309
|
headers: forwardHeaders,
|
|
327
310
|
body: request.body // Full payload: model, messages, tools, MCP params, etc.
|
|
328
|
-
},
|
|
329
|
-
response: {
|
|
330
|
-
statusCode: 0, // Will be updated after fetch
|
|
331
|
-
events: [] // Only used for JSON responses; streaming uses batch buffer
|
|
332
311
|
}
|
|
333
312
|
};
|
|
334
|
-
|
|
335
|
-
// Tail buffer: keep last 5 events for token usage extraction at stream end
|
|
336
|
-
const eventBatch = [];
|
|
337
|
-
const tailBuffer = [];
|
|
338
|
-
const eventIndexRef = { value: 0 };
|
|
313
|
+
rec = createRequestRecorder(meta);
|
|
339
314
|
request.log.info(`request logged: ${request.id} ${request.method} ${request.url}`);
|
|
340
315
|
// Save initial record + push pending status to frontend
|
|
341
|
-
await
|
|
342
|
-
pushNewRequest({
|
|
343
|
-
requestId: request.id,
|
|
344
|
-
sessionId,
|
|
345
|
-
compositeId: `${sessionId}:${request.id}`,
|
|
346
|
-
method: request.method,
|
|
347
|
-
path: request.url,
|
|
348
|
-
timestamp: requestData.timestamp,
|
|
349
|
-
statusCode: 0,
|
|
350
|
-
responseTime: 0,
|
|
351
|
-
model: forwardedModel,
|
|
352
|
-
machineId,
|
|
353
|
-
baseUrl: resolved.baseUrl
|
|
354
|
-
}, 'pending');
|
|
316
|
+
await rec.pending();
|
|
355
317
|
// --- OpenAI Compatible Mode ---
|
|
356
318
|
if (resolved.is_openai_compatible) {
|
|
357
319
|
const openaiRequest = convertClaudeToOpenAIRequest(request.body, forwardedModel);
|
|
@@ -364,14 +326,11 @@ export async function setupProxy(fastify, proxyConfig) {
|
|
|
364
326
|
method: request.method,
|
|
365
327
|
headers: openaiHeaders,
|
|
366
328
|
body: JSON.stringify(openaiRequest),
|
|
367
|
-
signal:
|
|
329
|
+
signal: createTimeoutSignal(300000, clientSignal)
|
|
368
330
|
});
|
|
369
331
|
request.log.info(`response status: ${response.status}`);
|
|
370
332
|
// Extract cloud request ID
|
|
371
333
|
const cloudRequestId = response.headers.get('x-request-id') || request.id;
|
|
372
|
-
requestData.requestId = cloudRequestId;
|
|
373
|
-
requestData.response.statusCode = response.status;
|
|
374
|
-
requestData.response.headers = Object.fromEntries(response.headers);
|
|
375
334
|
// Check response type
|
|
376
335
|
const contentType = response.headers.get('content-type') || '';
|
|
377
336
|
const isSSE = contentType.includes('text/event-stream');
|
|
@@ -384,45 +343,30 @@ export async function setupProxy(fastify, proxyConfig) {
|
|
|
384
343
|
const openaiRes = JSON.parse(responseBody);
|
|
385
344
|
const claudeRes = convertOpenAIToClaudeResponse(openaiRes, forwardedModel || originalModel);
|
|
386
345
|
claudeResponseBody = JSON.stringify(claudeRes);
|
|
387
|
-
|
|
346
|
+
rec.appendEvent(claudeRes);
|
|
388
347
|
}
|
|
389
348
|
catch {
|
|
390
349
|
claudeResponseBody = responseBody;
|
|
391
350
|
try {
|
|
392
|
-
|
|
351
|
+
rec.appendEvent(JSON.parse(responseBody));
|
|
393
352
|
}
|
|
394
353
|
catch {
|
|
395
|
-
|
|
354
|
+
rec.appendEvent({ raw: responseBody });
|
|
396
355
|
}
|
|
397
356
|
}
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
deleteResponseEvents(request.id, sessionId);
|
|
401
|
-
deleteRequestRow(request.id, sessionId);
|
|
402
|
-
}
|
|
403
|
-
await saveRequestDB(sessionId, cloudRequestId, requestData);
|
|
404
|
-
const usage = extractTokenUsage(requestData.response.events);
|
|
405
|
-
pushNewRequest({
|
|
406
|
-
requestId: cloudRequestId,
|
|
407
|
-
sessionId,
|
|
408
|
-
compositeId: `${sessionId}:${cloudRequestId}`,
|
|
409
|
-
method: request.method,
|
|
410
|
-
path: request.url,
|
|
411
|
-
timestamp: requestData.timestamp,
|
|
357
|
+
await rec.complete({
|
|
358
|
+
cloudRequestId: cloudRequestId !== request.id ? cloudRequestId : undefined,
|
|
412
359
|
statusCode: response.status,
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
machineId,
|
|
416
|
-
baseUrl: resolved.baseUrl,
|
|
417
|
-
usage,
|
|
418
|
-
pendingId: cloudRequestId !== request.id ? `${sessionId}:${request.id}` : undefined
|
|
419
|
-
}, 'completed');
|
|
360
|
+
headers: Object.fromEntries(response.headers)
|
|
361
|
+
});
|
|
420
362
|
const elapsed = Date.now() - startTime;
|
|
421
363
|
request.log.info(`json response (openai): ${cloudRequestId} ${response.status} (${elapsed}ms)`);
|
|
422
364
|
reply.code(response.status).headers({ 'Content-Type': 'application/json' }).send(claudeResponseBody);
|
|
423
365
|
return;
|
|
424
366
|
}
|
|
425
367
|
// Handle SSE streaming response
|
|
368
|
+
// 上游响应头已到达:回写真实 status_code(状态仍 pending,保留 spinner)
|
|
369
|
+
rec.headers({ statusCode: response.status, headers: Object.fromEntries(response.headers) });
|
|
426
370
|
reply.hijack();
|
|
427
371
|
const responseHeaders = Object.fromEntries(response.headers);
|
|
428
372
|
// Replace content-type with Claude SSE format
|
|
@@ -430,51 +374,35 @@ export async function setupProxy(fastify, proxyConfig) {
|
|
|
430
374
|
reply.raw.writeHead(response.status, responseHeaders);
|
|
431
375
|
if (response.body) {
|
|
432
376
|
const nodeStream = Readable.fromWeb(response.body);
|
|
377
|
+
// 客户端断开:销毁上游流,finished 回调走中断落库
|
|
378
|
+
clientSignal.addEventListener('abort', () => {
|
|
379
|
+
if (!nodeStream.destroyed)
|
|
380
|
+
nodeStream.destroy(new Error('client disconnected'));
|
|
381
|
+
});
|
|
382
|
+
attachIdleWatchdog(nodeStream);
|
|
433
383
|
const transformStream = createStreamTransformer(forwardedModel || originalModel);
|
|
434
|
-
//
|
|
384
|
+
// 旁路解码器:只做事件入库,不介入转发管道;[DONE] 走 onDone 留空,天然不入库
|
|
385
|
+
const tapDecoder = createEventDecoder((e) => rec.appendEvent(e));
|
|
435
386
|
nodeStream.on('data', (chunk) => {
|
|
436
|
-
|
|
437
|
-
const lines = text.split('\n');
|
|
438
|
-
for (const line of lines) {
|
|
439
|
-
if (line.startsWith('data:')) {
|
|
440
|
-
const eventData = line.slice(5).trim();
|
|
441
|
-
if (eventData && eventData !== '[DONE]') {
|
|
442
|
-
try {
|
|
443
|
-
const event = JSON.parse(eventData);
|
|
444
|
-
pushEventToBuffers(event, sessionId, cloudRequestId, eventBatch, tailBuffer, eventIndexRef);
|
|
445
|
-
}
|
|
446
|
-
catch {
|
|
447
|
-
// Not valid JSON, skip
|
|
448
|
-
}
|
|
449
|
-
}
|
|
450
|
-
}
|
|
451
|
-
}
|
|
387
|
+
tapDecoder.write(chunk);
|
|
452
388
|
});
|
|
453
389
|
// Use finished() for reliable stream completion detection
|
|
454
390
|
finished(nodeStream, async (err) => {
|
|
391
|
+
tapDecoder.end();
|
|
455
392
|
if (err) {
|
|
456
393
|
request.log.error(`openai stream error: ${err.message}`);
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
const lastChunk = tailBuffer.find((e) => e?.usage);
|
|
460
|
-
if (lastChunk?.usage) {
|
|
461
|
-
const syntheticEvent = {
|
|
462
|
-
type: 'message_delta',
|
|
463
|
-
usage: {
|
|
464
|
-
output_tokens: lastChunk.usage.completion_tokens || 0
|
|
465
|
-
}
|
|
466
|
-
};
|
|
467
|
-
pushEventToBuffers(syntheticEvent, sessionId, cloudRequestId, eventBatch, tailBuffer, eventIndexRef);
|
|
468
|
-
}
|
|
469
|
-
if (cloudRequestId !== request.id) {
|
|
470
|
-
deleteResponseEvents(request.id, sessionId);
|
|
471
|
-
deleteRequestRow(request.id, sessionId);
|
|
394
|
+
rec.interrupt({ statusCode: response.status, error: `stream interrupted: ${err.message}` });
|
|
395
|
+
return;
|
|
472
396
|
}
|
|
473
397
|
// Flush remaining batch + complete request
|
|
474
398
|
try {
|
|
475
|
-
await
|
|
399
|
+
await rec.complete({
|
|
400
|
+
cloudRequestId: cloudRequestId !== request.id ? cloudRequestId : undefined,
|
|
401
|
+
statusCode: response.status,
|
|
402
|
+
headers: Object.fromEntries(response.headers)
|
|
403
|
+
});
|
|
476
404
|
const elapsed = Date.now() - startTime;
|
|
477
|
-
request.log.info(`stream completed (openai): ${cloudRequestId} ${response.status} (${elapsed}ms
|
|
405
|
+
request.log.info(`stream completed (openai): ${cloudRequestId} ${response.status} (${elapsed}ms)`);
|
|
478
406
|
}
|
|
479
407
|
catch (dbErr) {
|
|
480
408
|
request.log.error(`openai stream save failed: ${dbErr.message}`);
|
|
@@ -495,15 +423,11 @@ export async function setupProxy(fastify, proxyConfig) {
|
|
|
495
423
|
method: request.method,
|
|
496
424
|
headers: forwardHeaders,
|
|
497
425
|
body: request.method !== 'GET' ? JSON.stringify(request.body) : undefined,
|
|
498
|
-
signal:
|
|
426
|
+
signal: createTimeoutSignal(300000, clientSignal)
|
|
499
427
|
});
|
|
500
428
|
request.log.info(`response status: ${response.status}`);
|
|
501
429
|
// Extract cloud request ID from response header
|
|
502
430
|
const cloudRequestId = response.headers.get('x-request-id') || request.id;
|
|
503
|
-
requestData.requestId = cloudRequestId;
|
|
504
|
-
// Update response status in requestData
|
|
505
|
-
requestData.response.statusCode = response.status;
|
|
506
|
-
requestData.response.headers = Object.fromEntries(response.headers);
|
|
507
431
|
// Check response type: SSE stream or JSON
|
|
508
432
|
const contentType = response.headers.get('content-type') || '';
|
|
509
433
|
const isSSE = contentType.includes('text/event-stream');
|
|
@@ -514,34 +438,16 @@ export async function setupProxy(fastify, proxyConfig) {
|
|
|
514
438
|
// Record JSON body as a single event
|
|
515
439
|
try {
|
|
516
440
|
const jsonBody = JSON.parse(responseBody);
|
|
517
|
-
|
|
441
|
+
rec.appendEvent(jsonBody);
|
|
518
442
|
}
|
|
519
443
|
catch {
|
|
520
|
-
|
|
444
|
+
rec.appendEvent({ raw: responseBody });
|
|
521
445
|
}
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
if (cloudRequestId !== request.id) {
|
|
525
|
-
deleteResponseEvents(request.id, sessionId);
|
|
526
|
-
deleteRequestRow(request.id, sessionId);
|
|
527
|
-
}
|
|
528
|
-
await saveRequestDB(sessionId, cloudRequestId, requestData);
|
|
529
|
-
const usage = extractTokenUsage(requestData.response.events);
|
|
530
|
-
pushNewRequest({
|
|
531
|
-
requestId: cloudRequestId,
|
|
532
|
-
sessionId,
|
|
533
|
-
compositeId: `${sessionId}:${cloudRequestId}`,
|
|
534
|
-
method: request.method,
|
|
535
|
-
path: request.url,
|
|
536
|
-
timestamp: requestData.timestamp,
|
|
446
|
+
await rec.complete({
|
|
447
|
+
cloudRequestId: cloudRequestId !== request.id ? cloudRequestId : undefined,
|
|
537
448
|
statusCode: response.status,
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
machineId,
|
|
541
|
-
baseUrl: resolved.baseUrl,
|
|
542
|
-
usage,
|
|
543
|
-
pendingId: cloudRequestId !== request.id ? `${sessionId}:${request.id}` : undefined
|
|
544
|
-
}, 'completed');
|
|
449
|
+
headers: Object.fromEntries(response.headers)
|
|
450
|
+
});
|
|
545
451
|
const elapsed = Date.now() - startTime;
|
|
546
452
|
request.log.info(`json response: ${cloudRequestId} ${response.status} (${elapsed}ms)`);
|
|
547
453
|
reply.code(response.status);
|
|
@@ -550,6 +456,8 @@ export async function setupProxy(fastify, proxyConfig) {
|
|
|
550
456
|
return;
|
|
551
457
|
}
|
|
552
458
|
// Hijack reply to take full control of SSE stream
|
|
459
|
+
// 上游响应头已到达:回写真实 status_code(状态仍 pending,保留 spinner)
|
|
460
|
+
rec.headers({ statusCode: response.status, headers: Object.fromEntries(response.headers) });
|
|
553
461
|
reply.hijack();
|
|
554
462
|
// Write response headers (preserve original from Aliyun)
|
|
555
463
|
const responseHeaders = Object.fromEntries(response.headers);
|
|
@@ -558,38 +466,33 @@ export async function setupProxy(fastify, proxyConfig) {
|
|
|
558
466
|
if (response.body) {
|
|
559
467
|
// Convert Web ReadableStream to Node Readable stream
|
|
560
468
|
const nodeStream = Readable.fromWeb(response.body);
|
|
561
|
-
//
|
|
469
|
+
// 客户端断开:销毁上游流,finished 回调走中断落库
|
|
470
|
+
clientSignal.addEventListener('abort', () => {
|
|
471
|
+
if (!nodeStream.destroyed)
|
|
472
|
+
nodeStream.destroy(new Error('client disconnected'));
|
|
473
|
+
});
|
|
474
|
+
attachIdleWatchdog(nodeStream);
|
|
475
|
+
// 旁路解码器:只做事件入库,不介入转发管道;[DONE] 走 onDone 留空,天然不入库
|
|
476
|
+
const tapDecoder = createEventDecoder((e) => rec.appendEvent(e));
|
|
562
477
|
nodeStream.on('data', (chunk) => {
|
|
563
|
-
|
|
564
|
-
const lines = text.split('\n');
|
|
565
|
-
for (const line of lines) {
|
|
566
|
-
if (line.startsWith('data:')) {
|
|
567
|
-
const eventData = line.slice(5).trim();
|
|
568
|
-
if (eventData && eventData !== '[DONE]') {
|
|
569
|
-
try {
|
|
570
|
-
const event = JSON.parse(eventData);
|
|
571
|
-
pushEventToBuffers(event, sessionId, cloudRequestId, eventBatch, tailBuffer, eventIndexRef);
|
|
572
|
-
}
|
|
573
|
-
catch {
|
|
574
|
-
// Not valid JSON, skip
|
|
575
|
-
}
|
|
576
|
-
}
|
|
577
|
-
}
|
|
578
|
-
}
|
|
478
|
+
tapDecoder.write(chunk);
|
|
579
479
|
});
|
|
580
480
|
// Save request data when stream completes
|
|
581
481
|
finished(nodeStream, async (err) => {
|
|
482
|
+
tapDecoder.end();
|
|
582
483
|
if (err) {
|
|
583
484
|
request.log.error(`claude stream error: ${err.message}`);
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
deleteResponseEvents(request.id, sessionId);
|
|
587
|
-
deleteRequestRow(request.id, sessionId);
|
|
485
|
+
rec.interrupt({ statusCode: response.status, error: `stream interrupted: ${err.message}` });
|
|
486
|
+
return;
|
|
588
487
|
}
|
|
589
488
|
try {
|
|
590
|
-
await
|
|
489
|
+
await rec.complete({
|
|
490
|
+
cloudRequestId: cloudRequestId !== request.id ? cloudRequestId : undefined,
|
|
491
|
+
statusCode: response.status,
|
|
492
|
+
headers: Object.fromEntries(response.headers)
|
|
493
|
+
});
|
|
591
494
|
const elapsed = Date.now() - startTime;
|
|
592
|
-
request.log.info(`stream completed: ${cloudRequestId} ${response.status} (${elapsed}ms
|
|
495
|
+
request.log.info(`stream completed: ${cloudRequestId} ${response.status} (${elapsed}ms)`);
|
|
593
496
|
}
|
|
594
497
|
catch (dbErr) {
|
|
595
498
|
request.log.error(`stream save failed: ${dbErr.message}`);
|
|
@@ -606,21 +509,27 @@ export async function setupProxy(fastify, proxyConfig) {
|
|
|
606
509
|
errorMessage: error.message,
|
|
607
510
|
errorCode: error.code || 'unknown'
|
|
608
511
|
}, 'proxy error');
|
|
609
|
-
// Fetch failed — no cloudRequestId available, use Fastify request.id
|
|
610
|
-
pushNewRequest({
|
|
611
|
-
requestId: request.id,
|
|
612
|
-
sessionId,
|
|
613
|
-
compositeId: `${sessionId}:${request.id}`,
|
|
614
|
-
method: request.method,
|
|
615
|
-
path: request.url,
|
|
616
|
-
timestamp: new Date().toISOString(),
|
|
617
|
-
statusCode: getErrorStatusCode(error),
|
|
618
|
-
responseTime: Date.now() - startTime,
|
|
619
|
-
model: originalModel,
|
|
620
|
-
machineId: getMachineIdSync() ?? undefined,
|
|
621
|
-
baseUrl: resolved.baseUrl
|
|
622
|
-
}, 'completed');
|
|
623
512
|
const statusCode = getErrorStatusCode(error);
|
|
513
|
+
if (rec) {
|
|
514
|
+
rec.fail({ statusCode, error: getErrorMessage(error) });
|
|
515
|
+
}
|
|
516
|
+
else {
|
|
517
|
+
// pending() 之前就抛错(header/meta 准备阶段),无 DB 行可更新,仅推送
|
|
518
|
+
pushNewRequest({
|
|
519
|
+
requestId: request.id,
|
|
520
|
+
sessionId,
|
|
521
|
+
compositeId: `${sessionId}:${request.id}`,
|
|
522
|
+
method: request.method,
|
|
523
|
+
path: request.url,
|
|
524
|
+
timestamp: new Date().toISOString(),
|
|
525
|
+
statusCode,
|
|
526
|
+
responseTime: Date.now() - startTime,
|
|
527
|
+
model: originalModel,
|
|
528
|
+
machineId: getMachineIdSync() ?? undefined,
|
|
529
|
+
userAgent: request.headers['user-agent'],
|
|
530
|
+
baseUrl: resolved.baseUrl
|
|
531
|
+
}, 'completed');
|
|
532
|
+
}
|
|
624
533
|
reply.code(statusCode).send({
|
|
625
534
|
error: getErrorMessage(error),
|
|
626
535
|
requestId: request.id
|