@cc-monitoring/proxy-core 0.3.1 → 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.B9A39uFv.js → app.DtYNT5zS.js} +1 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.C4sjikMO.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.DdhC696L.js → VPLocalSearchBox.DpXF9ZAI.js} +1 -1
- package/dist/docs/assets/chunks/{theme.CfB2tOFi.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/tools.js +8 -9
- 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 -162
- package/dist/server/data-push.d.ts +0 -1
- package/dist/server/data-push.js +0 -7
- package/dist/server/proxy.js +128 -224
- 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-DAu68mP4.js → 1c-CCx-FOtz.js} +1 -1
- package/dist/ui/assets/{abnf-Cu8RHCHK.js → abnf-Bwbi42Z8.js} +1 -1
- package/dist/ui/assets/{abnfDiagram-VRR7QNED-BUBToPXF.js → abnfDiagram-VRR7QNED-Dm1-8q0E.js} +1 -1
- package/dist/ui/assets/{accesslog-BG-34XOy.js → accesslog-DCytz_-m.js} +1 -1
- package/dist/ui/assets/{actionscript-iw0HHMGM.js → actionscript-3udf15oh.js} +1 -1
- package/dist/ui/assets/{ada-qRqj6VGQ.js → ada-M5Xa74xG.js} +1 -1
- package/dist/ui/assets/{angelscript-BeaXyx_P.js → angelscript-qlrFxfW-.js} +1 -1
- package/dist/ui/assets/{apache-CU8d-z9X.js → apache-B-sF-DQH.js} +1 -1
- package/dist/ui/assets/{applescript-d1Wxkqz1.js → applescript-4FdcBnbI.js} +1 -1
- package/dist/ui/assets/{arc-BMsPIm3j.js → arc-BB3K1enp.js} +1 -1
- package/dist/ui/assets/{arcade-CtbgrWTM.js → arcade-B_yqWaaG.js} +1 -1
- package/dist/ui/assets/{architectureDiagram-ZJ3FMSHR-CVjC5TrS.js → architectureDiagram-ZJ3FMSHR-B39vkY8V.js} +1 -1
- package/dist/ui/assets/{arduino-Bc9L39Hr.js → arduino-yAcBoTWU.js} +1 -1
- package/dist/ui/assets/{armasm-DuWmpjWR.js → armasm-wIcY84bI.js} +1 -1
- package/dist/ui/assets/{asciidoc-CDIhFTnx.js → asciidoc-Bxnu28-Z.js} +1 -1
- package/dist/ui/assets/{aspectj-SYj-57Es.js → aspectj-B2cKJA_O.js} +1 -1
- package/dist/ui/assets/{autohotkey-hBi5dq37.js → autohotkey-B_rMWTtE.js} +1 -1
- package/dist/ui/assets/{autoit-BSawXzhg.js → autoit-DwcuvMwv.js} +1 -1
- package/dist/ui/assets/{avrasm-CwYom8Np.js → avrasm-heGX1PXK.js} +1 -1
- package/dist/ui/assets/{awk-BvBRfGo2.js → awk-BiqCQAEf.js} +1 -1
- package/dist/ui/assets/{axapta-CqUavA8k.js → axapta-Cv8M-Ih6.js} +1 -1
- package/dist/ui/assets/{bash-BS_ZnmEu.js → bash-Divgn3JV.js} +1 -1
- package/dist/ui/assets/{basic-xbP4IXrN.js → basic-B9dnAP55.js} +1 -1
- package/dist/ui/assets/{blockDiagram-677ZJIJ3-CmpI3f5p.js → blockDiagram-677ZJIJ3-DQ1mf7A_.js} +1 -1
- package/dist/ui/assets/{bnf-BECwu6uW.js → bnf-kIL5mSsP.js} +1 -1
- package/dist/ui/assets/{brainfuck-QQgu4j4N.js → brainfuck-DqB7xDjH.js} +1 -1
- package/dist/ui/assets/{coq-IDMIFfem.js → c-HmsCM6sx.js} +1 -1
- package/dist/ui/assets/{c-like-DYrFOtXy.js → c-like-De5MhE7G.js} +1 -1
- package/dist/ui/assets/{c4Diagram-LMCZKHZV-B6Hgngz9.js → c4Diagram-LMCZKHZV-DQxtYsAx.js} +1 -1
- package/dist/ui/assets/{cal-CNMrJ6v5.js → cal-mYdfz9en.js} +1 -1
- package/dist/ui/assets/{capnproto-DYCKl6oY.js → capnproto-D04CRlOt.js} +1 -1
- package/dist/ui/assets/{ceylon-mb8tRPl0.js → ceylon-pi9lFCja.js} +1 -1
- package/dist/ui/assets/channel-ChTtxQDg.js +1 -0
- package/dist/ui/assets/{chunk-2Q5K7J3B-LxvQ-G67.js → chunk-2Q5K7J3B-BDD1nPt8.js} +1 -1
- package/dist/ui/assets/{chunk-32BRIVSS-DxzKK6Aw.js → chunk-32BRIVSS-DgeQFBb5.js} +1 -1
- package/dist/ui/assets/{chunk-5VM5RSS4-CZEoYJ2W.js → chunk-5VM5RSS4-C7Xf2SnI.js} +1 -1
- package/dist/ui/assets/{chunk-EX3LRPZG-DS2PytrN.js → chunk-EX3LRPZG-B_3p1HEv.js} +1 -1
- package/dist/ui/assets/{chunk-JWPE2WC7-UX0Sr1Ie.js → chunk-JWPE2WC7-Dvs7u8eY.js} +1 -1
- package/dist/ui/assets/{chunk-MOJQB5TN-YbJgT9t4.js → chunk-MOJQB5TN-By21wDCN.js} +1 -1
- package/dist/ui/assets/{chunk-RYQCIY6F-DS2VH_U9.js → chunk-RYQCIY6F-6NC700r1.js} +1 -1
- package/dist/ui/assets/{chunk-V7JOEXUC-CZr0pkI1.js → chunk-V7JOEXUC-vEUqZ3rh.js} +1 -1
- package/dist/ui/assets/{chunk-VR4S4FIN-50opPAD3.js → chunk-VR4S4FIN-6tX2dNN9.js} +1 -1
- package/dist/ui/assets/{chunk-XXDRQBXY-DAAX9l7U.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-C4X7dSkh.js → clean-CLCsDUl1.js} +1 -1
- package/dist/ui/assets/{clojure-DSg9gUa7.js → clojure-dVi5Xifj.js} +1 -1
- package/dist/ui/assets/{clojure-repl-CagRYx7h.js → clojure-repl-BO_FpFmF.js} +1 -1
- package/dist/ui/assets/{cmake-CFdBn53c.js → cmake-CP5aJbyK.js} +1 -1
- package/dist/ui/assets/{coffeescript-CJZtMOPx.js → coffeescript-ZEfu_9pF.js} +1 -1
- package/dist/ui/assets/{c-BRJEPYra.js → coq-6aKUn3zn.js} +1 -1
- package/dist/ui/assets/{cos-Bx2VJuzG.js → cos-BohCnRN2.js} +1 -1
- package/dist/ui/assets/{cose-bilkent-JH36ORCC-zWRLsZpZ.js → cose-bilkent-JH36ORCC-DyXCbbro.js} +1 -1
- package/dist/ui/assets/{cpp-CsG6DlC4.js → cpp-FOgPWPEt.js} +1 -1
- package/dist/ui/assets/{crmsh-DTy9MnmJ.js → crmsh-B0OYb-Oe.js} +1 -1
- package/dist/ui/assets/{crystal-BwgrLrZ1.js → crystal-CuWb_dXm.js} +1 -1
- package/dist/ui/assets/{csharp-B2VeTPAF.js → csharp-BbcqM09j.js} +1 -1
- package/dist/ui/assets/{csp-CTpydNhH.js → csp-rgHnTaDq.js} +1 -1
- package/dist/ui/assets/{css-B0mMUbpY.js → css-C-ibh7ZG.js} +1 -1
- package/dist/ui/assets/{cynefin-VYW2F7L2-BmjQEj6q.js → cynefin-VYW2F7L2-CkuBhgC4.js} +1 -1
- package/dist/ui/assets/{cynefinDiagram-TSTJHNR4-Dr0Zrke0.js → cynefinDiagram-TSTJHNR4-eycFyDao.js} +1 -1
- package/dist/ui/assets/{d-DjuDZnbI.js → d-C0gXxJ0O.js} +1 -1
- package/dist/ui/assets/{dagre-VKFMJZFB-xoTPT2Uu.js → dagre-VKFMJZFB-DzqX9e49.js} +1 -1
- package/dist/ui/assets/{dart-xR3GU9TJ.js → dart-C-fTpuUV.js} +1 -1
- package/dist/ui/assets/{delphi-bJas5QnG.js → delphi-Chm0B9xv.js} +1 -1
- package/dist/ui/assets/{diagram-FQU43EPY-rL_IU7gU.js → diagram-FQU43EPY-BEgCqfg1.js} +1 -1
- package/dist/ui/assets/{diagram-G47NLZAW-EcDiCVGj.js → diagram-G47NLZAW-Cw11Vs2v.js} +1 -1
- package/dist/ui/assets/{diagram-NH7WQ7WH-CGGXOjev.js → diagram-NH7WQ7WH-DSG_UWpP.js} +1 -1
- package/dist/ui/assets/{diagram-OA4YK3LP-DnE7hDjD.js → diagram-OA4YK3LP-CJz-WOaJ.js} +1 -1
- package/dist/ui/assets/{diagram-WEI45ONY-CTJH5eD8.js → diagram-WEI45ONY-CBXjBCvc.js} +1 -1
- package/dist/ui/assets/{diff-doJFF3fv.js → diff-C-vyuMSL.js} +1 -1
- package/dist/ui/assets/{django-D3b-owa_.js → django-CJK7lReT.js} +1 -1
- package/dist/ui/assets/{dns-C42KYV-Z.js → dns-D02SHjSy.js} +1 -1
- package/dist/ui/assets/{dockerfile-9KUINc2j.js → dockerfile-trKL1Bqu.js} +1 -1
- package/dist/ui/assets/{dos-CxnlJ6qp.js → dos-C52dy-sK.js} +1 -1
- package/dist/ui/assets/{dsconfig-6CMMCwmY.js → dsconfig-MzHgzVrt.js} +1 -1
- package/dist/ui/assets/{dts-D78rdUIB.js → dts-B137dHyX.js} +1 -1
- package/dist/ui/assets/{dust-Dv1uTfJU.js → dust-BcbM0r5C.js} +1 -1
- package/dist/ui/assets/{ebnf-BGbG1cFK.js → ebnf-DkbpI7bK.js} +1 -1
- package/dist/ui/assets/{ebnfDiagram-CCIWWBDH-z2VgRSUV.js → ebnfDiagram-CCIWWBDH-aI5uQ7w1.js} +1 -1
- package/dist/ui/assets/{elixir-ZgAQVY1J.js → elixir-BOtDuqQy.js} +1 -1
- package/dist/ui/assets/{elm-CudiFuNu.js → elm-DS8Tyyu-.js} +1 -1
- package/dist/ui/assets/{erDiagram-Q63AITRT-X1TODuRv.js → erDiagram-Q63AITRT-2vCbd4Mm.js} +1 -1
- package/dist/ui/assets/{erb-Bz_NZh6W.js → erb-CSXECRbn.js} +1 -1
- package/dist/ui/assets/{erlang-DNuj1nb2.js → erlang-BMxlgKPJ.js} +1 -1
- package/dist/ui/assets/{erlang-repl-SP1Gan9W.js → erlang-repl-DPzlolPg.js} +1 -1
- package/dist/ui/assets/{excel-0K77uECF.js → excel-CW2Uxed3.js} +1 -1
- package/dist/ui/assets/{fix-CalJq7JD.js → fix-UW84SlCs.js} +1 -1
- package/dist/ui/assets/{flix-BlIs11_w.js → flix-4UGiPULd.js} +1 -1
- package/dist/ui/assets/{flowDiagram-23GEKE2U-DA2dnmc0.js → flowDiagram-23GEKE2U-R5PbCbZI.js} +1 -1
- package/dist/ui/assets/{fortran-ZCobXY2R.js → fortran-nhHsngdu.js} +1 -1
- package/dist/ui/assets/{fsharp-Be8rwUtc.js → fsharp-CDyZ1ST5.js} +1 -1
- package/dist/ui/assets/{gams-DUat8frQ.js → gams-DHzkkUie.js} +1 -1
- package/dist/ui/assets/{ganttDiagram-NO4QXBWP-DdFwaIGZ.js → ganttDiagram-NO4QXBWP-CGcq4Ie_.js} +1 -1
- package/dist/ui/assets/{gauss-BB4U88dy.js → gauss-DdhFGyBv.js} +1 -1
- package/dist/ui/assets/{gcode-DzeUZuZg.js → gcode-ImHh8OLA.js} +1 -1
- package/dist/ui/assets/{gherkin-B_8vW_BO.js → gherkin-CTWAW-XR.js} +1 -1
- package/dist/ui/assets/{gitGraphDiagram-IHSO6WYX-B-Dn8x6I.js → gitGraphDiagram-IHSO6WYX-8nM2Z9lD.js} +1 -1
- package/dist/ui/assets/{glsl-DGHGjPC1.js → glsl-0_W_27G2.js} +1 -1
- package/dist/ui/assets/{gml-BYEku8Yh.js → gml-BoDggu2z.js} +1 -1
- package/dist/ui/assets/{go-D8aSgQMc.js → go-DYfFygwl.js} +1 -1
- package/dist/ui/assets/{golo-CDjCU_jh.js → golo-Mlq-TCg9.js} +1 -1
- package/dist/ui/assets/{gradle-BeUw7tl_.js → gradle-BALAinEB.js} +1 -1
- package/dist/ui/assets/{groovy-5iCQOtR3.js → groovy-Dht--dWU.js} +1 -1
- package/dist/ui/assets/{haml-BEdL8FJi.js → haml-DpMrxg0d.js} +1 -1
- package/dist/ui/assets/{handlebars-BuYQNzoK.js → handlebars-DqHzujNj.js} +1 -1
- package/dist/ui/assets/{haskell-I4FCBcW0.js → haskell-DZSchhkY.js} +1 -1
- package/dist/ui/assets/{haxe-yigyKfFr.js → haxe-C0zBRjdy.js} +1 -1
- package/dist/ui/assets/{hsp-ZUk4j7d1.js → hsp-D_PwbSv2.js} +1 -1
- package/dist/ui/assets/{htmlbars-QYP3lT3u.js → htmlbars-DxAFMG8u.js} +1 -1
- package/dist/ui/assets/{http-BJpD1O71.js → http-DvTRF0Do.js} +1 -1
- package/dist/ui/assets/{hy-CIJ1bP6S.js → hy-lVO-kNyp.js} +1 -1
- package/dist/ui/assets/{index-BDXWttnT.js → index-BbMRVVGt.js} +3 -3
- package/dist/ui/assets/{index-COAgrx1J.js → index-Ci23SMK2.js} +242 -242
- package/dist/ui/assets/index-DlsVXaHT.css +10 -0
- package/dist/ui/assets/{infoDiagram-FWYZ7A6U-fTg9eLNt.js → infoDiagram-FWYZ7A6U-C7WYDlvc.js} +1 -1
- package/dist/ui/assets/{inform7-DAsu-lC2.js → inform7-B8Tf2n8v.js} +1 -1
- package/dist/ui/assets/{ini-Bhz-zHCg.js → ini-DSoYMaLF.js} +1 -1
- package/dist/ui/assets/{irpf90-BunhbwBl.js → irpf90-RCPdkB14.js} +1 -1
- package/dist/ui/assets/{isbl-q9L6hOhP.js → isbl-C2p75PPj.js} +1 -1
- package/dist/ui/assets/{ishikawaDiagram-FXEZZL3T-B8G0sdgd.js → ishikawaDiagram-FXEZZL3T-Cm6jsPlc.js} +1 -1
- package/dist/ui/assets/{java-Iks5Pkau.js → java-DeY4Yuia.js} +1 -1
- package/dist/ui/assets/{javascript-C4vltXPw.js → javascript-3uX1CO-H.js} +1 -1
- package/dist/ui/assets/{jboss-cli-BQBvd2X2.js → jboss-cli-DgnD8mEc.js} +1 -1
- package/dist/ui/assets/{journeyDiagram-5HDEW3XC-Crbzgrum.js → journeyDiagram-5HDEW3XC-DEGV1uA5.js} +1 -1
- package/dist/ui/assets/{json-DXK0_jUK.js → json-BV2PmJJp.js} +1 -1
- package/dist/ui/assets/{julia-CCYoBiYK.js → julia-B-m8kQm7.js} +1 -1
- package/dist/ui/assets/{julia-repl-y8v2Oorl.js → julia-repl-C51atU2X.js} +1 -1
- package/dist/ui/assets/{kanban-definition-HUTT4EX6-C8sCOsBX.js → kanban-definition-HUTT4EX6-BJ4k5iTX.js} +1 -1
- package/dist/ui/assets/{kotlin-Bnjk7_fw.js → kotlin-CYBziIgl.js} +1 -1
- package/dist/ui/assets/{lasso-B-al6x63.js → lasso-Dw2SBMDW.js} +1 -1
- package/dist/ui/assets/{latex-BUmqlb9r.js → latex-Dpd35yke.js} +1 -1
- package/dist/ui/assets/{ldif-D42RWj6Q.js → ldif-Ce9EZU__.js} +1 -1
- package/dist/ui/assets/{leaf-CrH4BZ0m.js → leaf-CpkZzQtC.js} +1 -1
- package/dist/ui/assets/{less-upmRlQQW.js → less-Uzo7M0FD.js} +1 -1
- package/dist/ui/assets/{lisp-DHYS22SA.js → lisp-DWXDlJYm.js} +1 -1
- package/dist/ui/assets/{livecodeserver-CeQNmFP3.js → livecodeserver-uEyPEgVJ.js} +1 -1
- package/dist/ui/assets/{livescript-PJWpY1JI.js → livescript-BQ5f07oK.js} +1 -1
- package/dist/ui/assets/{llvm-BKtKWwCt.js → llvm-BAvP-skE.js} +1 -1
- package/dist/ui/assets/{lsl-RWRLRjk7.js → lsl-DhbiIKu6.js} +1 -1
- package/dist/ui/assets/{lua-BFUDiPGm.js → lua-COxeUeLx.js} +1 -1
- package/dist/ui/assets/{makefile-CUDyOz5D.js → makefile-DhDx-IgL.js} +1 -1
- package/dist/ui/assets/{markdown-zZCLypc6.js → markdown-DX5_kSxq.js} +1 -1
- package/dist/ui/assets/{mathematica-BHbxKxnq.js → mathematica-D351ZddB.js} +1 -1
- package/dist/ui/assets/{matlab-DlGtg--p.js → matlab-CELqIiwF.js} +1 -1
- package/dist/ui/assets/{maxima-BBBeS3Ra.js → maxima-B_YljrMm.js} +1 -1
- package/dist/ui/assets/{mel-nh8j7W_6.js → mel-DltsbNS8.js} +1 -1
- package/dist/ui/assets/{mercury-DyyD-pqr.js → mercury-axX-5Vjj.js} +1 -1
- package/dist/ui/assets/{mindmap-definition-LN4V7U3C-CJlhDHqM.js → mindmap-definition-LN4V7U3C-Bl1EJo6p.js} +1 -1
- package/dist/ui/assets/{mipsasm-hiEhRRiq.js → mipsasm-BxmerVwX.js} +1 -1
- package/dist/ui/assets/{mizar-BZa3iAAL.js → mizar-XNHfbpL2.js} +1 -1
- package/dist/ui/assets/{mojolicious-BCIm2V_y.js → mojolicious-BR0U_7zk.js} +1 -1
- package/dist/ui/assets/{monkey-zmK-7N8b.js → monkey-lLuu9_f-.js} +1 -1
- package/dist/ui/assets/{moonscript-BsS_Mn3D.js → moonscript-DoaZ3DRQ.js} +1 -1
- package/dist/ui/assets/{n1ql-D7xVgDP0.js → n1ql-C6TId6Iu.js} +1 -1
- package/dist/ui/assets/{nginx-ct2q4dtd.js → nginx-BezSG-JT.js} +1 -1
- package/dist/ui/assets/{nim-RO0UOmW3.js → nim-Bb0rfXie.js} +1 -1
- package/dist/ui/assets/{nix-BcRJxPKH.js → nix-o3sJ5-54.js} +1 -1
- package/dist/ui/assets/{node-repl-DgIefwxW.js → node-repl-Sv5hhcTf.js} +1 -1
- package/dist/ui/assets/{nsis-DqHs9QhB.js → nsis-B45BJFhF.js} +1 -1
- package/dist/ui/assets/{objectivec-BBcWqc7Y.js → objectivec-CzS6zVgh.js} +1 -1
- package/dist/ui/assets/{ocaml-BExfw7D6.js → ocaml-Bqux7PyP.js} +1 -1
- package/dist/ui/assets/{openscad-CHPRELQb.js → openscad-4Wf6mF84.js} +1 -1
- package/dist/ui/assets/{oxygene-DpS9uMJW.js → oxygene-Fvwqgkkt.js} +1 -1
- package/dist/ui/assets/{parser3-CjJ_QdBp.js → parser3-zEfzT5wv.js} +1 -1
- package/dist/ui/assets/{pegDiagram-2B236MQR-GM70woGy.js → pegDiagram-2B236MQR-Dd4rIztM.js} +1 -1
- package/dist/ui/assets/{perl-BSNM2Kt8.js → perl-CsS1Gs6o.js} +1 -1
- package/dist/ui/assets/{pf-Z-hKf_88.js → pf-BNH1jO0R.js} +1 -1
- package/dist/ui/assets/{pgsql-DDgznxBg.js → pgsql-DqPigHrq.js} +1 -1
- package/dist/ui/assets/{php-BzAhxF-l.js → php-CdOl9bRs.js} +1 -1
- package/dist/ui/assets/{php-template-DkgcKHRc.js → php-template-DPfirJg2.js} +1 -1
- package/dist/ui/assets/{pieDiagram-ENE6RG2P-Bst7mPyz.js → pieDiagram-ENE6RG2P-DGaJNf4S.js} +1 -1
- package/dist/ui/assets/{plaintext-BYEppD0R.js → plaintext-EHbgBKzw.js} +1 -1
- package/dist/ui/assets/{pony-BT_kQd1K.js → pony-DmJajtp2.js} +1 -1
- package/dist/ui/assets/{powershell-BfRsuSsf.js → powershell-DfGzdWR6.js} +1 -1
- package/dist/ui/assets/{processing-DpzWe5Iu.js → processing-BT0ETgPG.js} +1 -1
- package/dist/ui/assets/{profile-BCOhS5cM.js → profile-B3I-x5Lt.js} +1 -1
- package/dist/ui/assets/{prolog-OxaCCaW8.js → prolog-B_4QJIvI.js} +1 -1
- package/dist/ui/assets/{properties-DMFlA2Ca.js → properties-BFVI8weS.js} +1 -1
- package/dist/ui/assets/{protobuf-CRDFkXvZ.js → protobuf-PaF39oZZ.js} +1 -1
- package/dist/ui/assets/{puppet-DnrVyLzx.js → puppet-BDC6Q8VF.js} +1 -1
- package/dist/ui/assets/{purebasic-Dht4Hniv.js → purebasic-B2ejrOZK.js} +1 -1
- package/dist/ui/assets/{python-B0aMirWu.js → python-BOxtIk9H.js} +1 -1
- package/dist/ui/assets/{python-repl-BlYDBGa7.js → python-repl-BslBh_Mx.js} +1 -1
- package/dist/ui/assets/{q-DzrtW9kT.js → q-BPe8WLGW.js} +1 -1
- package/dist/ui/assets/{qml-DnfQsR3i.js → qml-BazRR6fz.js} +1 -1
- package/dist/ui/assets/{quadrantDiagram-ABIIQ3AL-DNRYurBT.js → quadrantDiagram-ABIIQ3AL-BQ7aPkHk.js} +1 -1
- package/dist/ui/assets/{r-DGI_ZuTD.js → r-C09pGNJC.js} +1 -1
- package/dist/ui/assets/{railroadDiagram-RFXS5EU6-CmbC3Vz4.js → railroadDiagram-RFXS5EU6-sCO9VGvE.js} +1 -1
- package/dist/ui/assets/{reasonml-3SohMgh2.js → reasonml-S7dzwVL9.js} +1 -1
- package/dist/ui/assets/{requirementDiagram-TGXJPOKE-8CxrXHco.js → requirementDiagram-TGXJPOKE-CfT5aVZg.js} +1 -1
- package/dist/ui/assets/{rib-DfRSd4Qa.js → rib-fM2EwQd4.js} +1 -1
- package/dist/ui/assets/{roboconf-CQczGdGW.js → roboconf-D7AaeyrW.js} +1 -1
- package/dist/ui/assets/{routeros-DCka-T2i.js → routeros-c6Q7mKuq.js} +1 -1
- package/dist/ui/assets/{rsl-Dr8MOwMo.js → rsl-sCpEQBxh.js} +1 -1
- package/dist/ui/assets/{ruby-C2zFSkh_.js → ruby-lcKhz2w9.js} +1 -1
- package/dist/ui/assets/{ruleslanguage-C97YsgQq.js → ruleslanguage-BW4ATOuX.js} +1 -1
- package/dist/ui/assets/{rust-H3h8kd9A.js → rust-BbpU-0VY.js} +1 -1
- package/dist/ui/assets/{sankeyDiagram-HTMAVEWB-DBXLWjEq.js → sankeyDiagram-HTMAVEWB-CaweCpvN.js} +1 -1
- package/dist/ui/assets/{sas-04z0Xu8P.js → sas-BPt5R0dx.js} +1 -1
- package/dist/ui/assets/{scala-DyB9Aoiv.js → scala-DxW_vqXs.js} +1 -1
- package/dist/ui/assets/{scheme-DBj6nxUi.js → scheme-T2Q_jWzT.js} +1 -1
- package/dist/ui/assets/{scilab-Btj7AD9s.js → scilab-DMORg9lV.js} +1 -1
- package/dist/ui/assets/{scss-BXZJyXt7.js → scss-t0VsosqT.js} +1 -1
- package/dist/ui/assets/{sequenceDiagram-DBY2YBRQ-DXIkBFKC.js → sequenceDiagram-DBY2YBRQ-o-H_R4zb.js} +1 -1
- package/dist/ui/assets/{shell-BsreQR1Z.js → shell-CnCDa1s9.js} +1 -1
- package/dist/ui/assets/{sizeCapture-X5ZJPWSS-ocS9jxAQ.js → sizeCapture-X5ZJPWSS-BNLkHGDS.js} +1 -1
- package/dist/ui/assets/{smali-D9wQw9zm.js → smali-_n-BxJyG.js} +1 -1
- package/dist/ui/assets/{smalltalk-Dku6G_H3.js → smalltalk-B90PXJwK.js} +1 -1
- package/dist/ui/assets/{sml-BknyU6ya.js → sml-fuY7bj-n.js} +1 -1
- package/dist/ui/assets/{sqf-DRYMaOg8.js → sqf-COpwkyuo.js} +1 -1
- package/dist/ui/assets/{sql-Cw3Ax4KA.js → sql-CXIT0j-x.js} +1 -1
- package/dist/ui/assets/{sql_more-vWdslLE0.js → sql_more-C1Oxq4rx.js} +1 -1
- package/dist/ui/assets/{stan-8XH5bDS6.js → stan-BZEpaHeC.js} +1 -1
- package/dist/ui/assets/{stata-4e77wgfe.js → stata-CkBwaiZM.js} +1 -1
- package/dist/ui/assets/{stateDiagram-2N3HPSRC-RMmL9jMG.js → stateDiagram-2N3HPSRC-BkdnNF7I.js} +1 -1
- package/dist/ui/assets/stateDiagram-v2-6OUMAXLB-0JnZ1VSQ.js +1 -0
- package/dist/ui/assets/{step21-ByIeDMY3.js → step21-fs9N_U3O.js} +1 -1
- package/dist/ui/assets/{stylus-ZAhJyWsw.js → stylus-Bs_9cvKZ.js} +1 -1
- package/dist/ui/assets/{subunit-pPW2UGkj.js → subunit-DvgcOCqJ.js} +1 -1
- package/dist/ui/assets/{swift-CX3BB5az.js → swift-BE4ONsur.js} +1 -1
- package/dist/ui/assets/{swimlanes-5IMT3BWC-C2zAuJ56.js → swimlanes-5IMT3BWC-uqTAc7o7.js} +2 -2
- package/dist/ui/assets/swimlanesDiagram-G3AALYLV-DQRIIEmi.js +8 -0
- package/dist/ui/assets/{taggerscript-BHcjbWIC.js → taggerscript-BhmPJ64C.js} +1 -1
- package/dist/ui/assets/{tap-BOl1lBlS.js → tap-DkueIVKV.js} +1 -1
- package/dist/ui/assets/{tcl-DZjeOBDh.js → tcl-DyXOOkFi.js} +1 -1
- package/dist/ui/assets/{thrift-BxboWg4x.js → thrift-Dhgbk56T.js} +1 -1
- package/dist/ui/assets/{timeline-definition-FHXFAJF6-BOxsxyq_.js → timeline-definition-FHXFAJF6-DBAk9Ouc.js} +1 -1
- package/dist/ui/assets/{tp-BNM6ql3J.js → tp-BsXyrRGH.js} +1 -1
- package/dist/ui/assets/{twig-Dj9ZiXD4.js → twig-J0HqIuHw.js} +1 -1
- package/dist/ui/assets/{typescript-7MEJlu_6.js → typescript-Dkwvul39.js} +1 -1
- package/dist/ui/assets/{vala-DNqOAgHJ.js → vala-CRGnf8aY.js} +1 -1
- package/dist/ui/assets/{vbnet-T0mNKVc_.js → vbnet-BtJAUe3z.js} +1 -1
- package/dist/ui/assets/{vbscript-CeuwVMAI.js → vbscript-RgFFNuM3.js} +1 -1
- package/dist/ui/assets/{vbscript-html-BbJSt2w6.js → vbscript-html-DO32Io9Y.js} +1 -1
- package/dist/ui/assets/{vennDiagram-L72KCM5P-BX9mWeiT.js → vennDiagram-L72KCM5P-BJi6y0hh.js} +1 -1
- package/dist/ui/assets/{verilog-DYuhYfkX.js → verilog-C4h6MLcI.js} +1 -1
- package/dist/ui/assets/{vhdl-Cf9aT-t7.js → vhdl-DOafePyU.js} +1 -1
- package/dist/ui/assets/{vim-DciP44K1.js → vim-BAdTA9TY.js} +1 -1
- package/dist/ui/assets/{wardleyDiagram-EHGQE667-CDj2rOzu.js → wardleyDiagram-EHGQE667-C7c_4IJ6.js} +1 -1
- package/dist/ui/assets/{x86asm-E-AN_LXO.js → x86asm-BCL6__QH.js} +1 -1
- package/dist/ui/assets/{xl-CxYLJelN.js → xl-qIzE4HOe.js} +1 -1
- package/dist/ui/assets/{xml-yz1SRLuU.js → xml-DE2sJXYU.js} +1 -1
- package/dist/ui/assets/{xquery-BLzBF3tV.js → xquery-CQ35t92y.js} +1 -1
- package/dist/ui/assets/{xychartDiagram-FW5EYKEG-Czapk9-Z.js → xychartDiagram-FW5EYKEG-D2ILn0jL.js} +1 -1
- package/dist/ui/assets/{yaml-Cv4Y7iN_.js → yaml-5KaAvG5C.js} +1 -1
- package/dist/ui/assets/{zephir-KRcdQfEX.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 +1 -0
- package/dist/utils/db.js +24 -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 +59 -30
- package/dist/utils/request-writer.js +178 -58
- 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.B6Qfxe6W.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-Bc4Td8eZ.js +0 -1
- package/dist/ui/assets/classDiagram-OUVF2IWQ-BicxhZFq.js +0 -1
- package/dist/ui/assets/classDiagram-v2-EOCWNBFH-BicxhZFq.js +0 -1
- package/dist/ui/assets/index-C0fxlU9d.css +0 -10
- package/dist/ui/assets/stateDiagram-v2-6OUMAXLB-QvaEO5U6.js +0 -1
- package/dist/ui/assets/swimlanesDiagram-G3AALYLV-DPgCOY0D.js +0 -8
- package/dist/utils/__tests__/sse-accumulator.test.js +0 -83
- package/dist/utils/knowledge-store.d.ts +0 -51
- package/dist/utils/knowledge-store.js +0 -241
- 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,58 +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
|
-
userAgent: request.headers['user-agent'],
|
|
213
|
-
baseUrl: resolved.baseUrl,
|
|
214
|
-
usage,
|
|
215
|
-
pendingId: requestId !== request.id ? `${sessionId}:${request.id}` : undefined
|
|
216
|
-
}, 'completed');
|
|
217
|
-
}
|
|
218
159
|
export function getErrorMessage(error) {
|
|
219
160
|
if (error.code === 'ECONNREFUSED') {
|
|
220
161
|
return 'Target server unreachable';
|
|
@@ -227,12 +168,50 @@ export function getErrorMessage(error) {
|
|
|
227
168
|
}
|
|
228
169
|
return 'Proxy error';
|
|
229
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
|
+
}
|
|
230
199
|
export async function setupProxy(fastify, proxyConfig) {
|
|
231
200
|
// Load full config to get storage.maxDays
|
|
232
201
|
const fullConfig = await loadConfig();
|
|
233
202
|
const maxDays = fullConfig.storage?.maxDays ?? 7;
|
|
234
203
|
// Initialize SQLite database
|
|
235
|
-
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
|
+
}
|
|
236
215
|
// Initialize MCP connections (after DB is ready)
|
|
237
216
|
try {
|
|
238
217
|
await mcpManager.init();
|
|
@@ -286,9 +265,12 @@ export async function setupProxy(fastify, proxyConfig) {
|
|
|
286
265
|
fastify.all('/v1/*', async (request, reply) => {
|
|
287
266
|
const startTime = Date.now();
|
|
288
267
|
const resolved = resolveProxyTarget(proxyConfig);
|
|
268
|
+
// 下游客户端中止:整个请求作用域建一次,两处上游 fetch 复用
|
|
269
|
+
const clientSignal = createClientAbortSignal(request.raw);
|
|
289
270
|
const sessionId = request.headers['x-claude-code-session-id'] || 'unknown-session';
|
|
290
271
|
// Replace model based on tier matching (getProxyModel)
|
|
291
272
|
const originalModel = request.body?.model;
|
|
273
|
+
let rec;
|
|
292
274
|
try {
|
|
293
275
|
const proxyModel = getProxyModel(originalModel, resolved);
|
|
294
276
|
if (proxyModel && request.body && typeof request.body === 'object') {
|
|
@@ -312,9 +294,9 @@ export async function setupProxy(fastify, proxyConfig) {
|
|
|
312
294
|
(forwardedAuthHeader?.startsWith('Bearer ') ? forwardedAuthHeader.slice(7) : undefined);
|
|
313
295
|
// Log complete request data (Fastify already parsed body)
|
|
314
296
|
const machineId = getMachineIdSync() ?? undefined;
|
|
315
|
-
const
|
|
316
|
-
requestId: request.id, // Will be updated with cloud x-request-id later
|
|
297
|
+
const meta = {
|
|
317
298
|
sessionId,
|
|
299
|
+
localRequestId: request.id, // Will be replaced with cloud x-request-id row on completion
|
|
318
300
|
timestamp: new Date().toISOString(),
|
|
319
301
|
apiKey,
|
|
320
302
|
proxyApiKey,
|
|
@@ -326,34 +308,12 @@ export async function setupProxy(fastify, proxyConfig) {
|
|
|
326
308
|
path: request.url,
|
|
327
309
|
headers: forwardHeaders,
|
|
328
310
|
body: request.body // Full payload: model, messages, tools, MCP params, etc.
|
|
329
|
-
},
|
|
330
|
-
response: {
|
|
331
|
-
statusCode: 0, // Will be updated after fetch
|
|
332
|
-
events: [] // Only used for JSON responses; streaming uses batch buffer
|
|
333
311
|
}
|
|
334
312
|
};
|
|
335
|
-
|
|
336
|
-
// Tail buffer: keep last 5 events for token usage extraction at stream end
|
|
337
|
-
const eventBatch = [];
|
|
338
|
-
const tailBuffer = [];
|
|
339
|
-
const eventIndexRef = { value: 0 };
|
|
313
|
+
rec = createRequestRecorder(meta);
|
|
340
314
|
request.log.info(`request logged: ${request.id} ${request.method} ${request.url}`);
|
|
341
315
|
// Save initial record + push pending status to frontend
|
|
342
|
-
await
|
|
343
|
-
pushNewRequest({
|
|
344
|
-
requestId: request.id,
|
|
345
|
-
sessionId,
|
|
346
|
-
compositeId: `${sessionId}:${request.id}`,
|
|
347
|
-
method: request.method,
|
|
348
|
-
path: request.url,
|
|
349
|
-
timestamp: requestData.timestamp,
|
|
350
|
-
statusCode: 0,
|
|
351
|
-
responseTime: 0,
|
|
352
|
-
model: forwardedModel,
|
|
353
|
-
machineId,
|
|
354
|
-
userAgent: request.headers['user-agent'],
|
|
355
|
-
baseUrl: resolved.baseUrl
|
|
356
|
-
}, 'pending');
|
|
316
|
+
await rec.pending();
|
|
357
317
|
// --- OpenAI Compatible Mode ---
|
|
358
318
|
if (resolved.is_openai_compatible) {
|
|
359
319
|
const openaiRequest = convertClaudeToOpenAIRequest(request.body, forwardedModel);
|
|
@@ -366,14 +326,11 @@ export async function setupProxy(fastify, proxyConfig) {
|
|
|
366
326
|
method: request.method,
|
|
367
327
|
headers: openaiHeaders,
|
|
368
328
|
body: JSON.stringify(openaiRequest),
|
|
369
|
-
signal:
|
|
329
|
+
signal: createTimeoutSignal(300000, clientSignal)
|
|
370
330
|
});
|
|
371
331
|
request.log.info(`response status: ${response.status}`);
|
|
372
332
|
// Extract cloud request ID
|
|
373
333
|
const cloudRequestId = response.headers.get('x-request-id') || request.id;
|
|
374
|
-
requestData.requestId = cloudRequestId;
|
|
375
|
-
requestData.response.statusCode = response.status;
|
|
376
|
-
requestData.response.headers = Object.fromEntries(response.headers);
|
|
377
334
|
// Check response type
|
|
378
335
|
const contentType = response.headers.get('content-type') || '';
|
|
379
336
|
const isSSE = contentType.includes('text/event-stream');
|
|
@@ -386,46 +343,30 @@ export async function setupProxy(fastify, proxyConfig) {
|
|
|
386
343
|
const openaiRes = JSON.parse(responseBody);
|
|
387
344
|
const claudeRes = convertOpenAIToClaudeResponse(openaiRes, forwardedModel || originalModel);
|
|
388
345
|
claudeResponseBody = JSON.stringify(claudeRes);
|
|
389
|
-
|
|
346
|
+
rec.appendEvent(claudeRes);
|
|
390
347
|
}
|
|
391
348
|
catch {
|
|
392
349
|
claudeResponseBody = responseBody;
|
|
393
350
|
try {
|
|
394
|
-
|
|
351
|
+
rec.appendEvent(JSON.parse(responseBody));
|
|
395
352
|
}
|
|
396
353
|
catch {
|
|
397
|
-
|
|
354
|
+
rec.appendEvent({ raw: responseBody });
|
|
398
355
|
}
|
|
399
356
|
}
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
deleteResponseEvents(request.id, sessionId);
|
|
403
|
-
deleteRequestRow(request.id, sessionId);
|
|
404
|
-
}
|
|
405
|
-
await saveRequestDB(sessionId, cloudRequestId, requestData);
|
|
406
|
-
const usage = extractTokenUsage(requestData.response.events);
|
|
407
|
-
pushNewRequest({
|
|
408
|
-
requestId: cloudRequestId,
|
|
409
|
-
sessionId,
|
|
410
|
-
compositeId: `${sessionId}:${cloudRequestId}`,
|
|
411
|
-
method: request.method,
|
|
412
|
-
path: request.url,
|
|
413
|
-
timestamp: requestData.timestamp,
|
|
357
|
+
await rec.complete({
|
|
358
|
+
cloudRequestId: cloudRequestId !== request.id ? cloudRequestId : undefined,
|
|
414
359
|
statusCode: response.status,
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
machineId,
|
|
418
|
-
userAgent: request.headers['user-agent'],
|
|
419
|
-
baseUrl: resolved.baseUrl,
|
|
420
|
-
usage,
|
|
421
|
-
pendingId: cloudRequestId !== request.id ? `${sessionId}:${request.id}` : undefined
|
|
422
|
-
}, 'completed');
|
|
360
|
+
headers: Object.fromEntries(response.headers)
|
|
361
|
+
});
|
|
423
362
|
const elapsed = Date.now() - startTime;
|
|
424
363
|
request.log.info(`json response (openai): ${cloudRequestId} ${response.status} (${elapsed}ms)`);
|
|
425
364
|
reply.code(response.status).headers({ 'Content-Type': 'application/json' }).send(claudeResponseBody);
|
|
426
365
|
return;
|
|
427
366
|
}
|
|
428
367
|
// Handle SSE streaming response
|
|
368
|
+
// 上游响应头已到达:回写真实 status_code(状态仍 pending,保留 spinner)
|
|
369
|
+
rec.headers({ statusCode: response.status, headers: Object.fromEntries(response.headers) });
|
|
429
370
|
reply.hijack();
|
|
430
371
|
const responseHeaders = Object.fromEntries(response.headers);
|
|
431
372
|
// Replace content-type with Claude SSE format
|
|
@@ -433,51 +374,35 @@ export async function setupProxy(fastify, proxyConfig) {
|
|
|
433
374
|
reply.raw.writeHead(response.status, responseHeaders);
|
|
434
375
|
if (response.body) {
|
|
435
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);
|
|
436
383
|
const transformStream = createStreamTransformer(forwardedModel || originalModel);
|
|
437
|
-
//
|
|
384
|
+
// 旁路解码器:只做事件入库,不介入转发管道;[DONE] 走 onDone 留空,天然不入库
|
|
385
|
+
const tapDecoder = createEventDecoder((e) => rec.appendEvent(e));
|
|
438
386
|
nodeStream.on('data', (chunk) => {
|
|
439
|
-
|
|
440
|
-
const lines = text.split('\n');
|
|
441
|
-
for (const line of lines) {
|
|
442
|
-
if (line.startsWith('data:')) {
|
|
443
|
-
const eventData = line.slice(5).trim();
|
|
444
|
-
if (eventData && eventData !== '[DONE]') {
|
|
445
|
-
try {
|
|
446
|
-
const event = JSON.parse(eventData);
|
|
447
|
-
pushEventToBuffers(event, sessionId, cloudRequestId, eventBatch, tailBuffer, eventIndexRef);
|
|
448
|
-
}
|
|
449
|
-
catch {
|
|
450
|
-
// Not valid JSON, skip
|
|
451
|
-
}
|
|
452
|
-
}
|
|
453
|
-
}
|
|
454
|
-
}
|
|
387
|
+
tapDecoder.write(chunk);
|
|
455
388
|
});
|
|
456
389
|
// Use finished() for reliable stream completion detection
|
|
457
390
|
finished(nodeStream, async (err) => {
|
|
391
|
+
tapDecoder.end();
|
|
458
392
|
if (err) {
|
|
459
393
|
request.log.error(`openai stream error: ${err.message}`);
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
const lastChunk = tailBuffer.find((e) => e?.usage);
|
|
463
|
-
if (lastChunk?.usage) {
|
|
464
|
-
const syntheticEvent = {
|
|
465
|
-
type: 'message_delta',
|
|
466
|
-
usage: {
|
|
467
|
-
output_tokens: lastChunk.usage.completion_tokens || 0
|
|
468
|
-
}
|
|
469
|
-
};
|
|
470
|
-
pushEventToBuffers(syntheticEvent, sessionId, cloudRequestId, eventBatch, tailBuffer, eventIndexRef);
|
|
471
|
-
}
|
|
472
|
-
if (cloudRequestId !== request.id) {
|
|
473
|
-
deleteResponseEvents(request.id, sessionId);
|
|
474
|
-
deleteRequestRow(request.id, sessionId);
|
|
394
|
+
rec.interrupt({ statusCode: response.status, error: `stream interrupted: ${err.message}` });
|
|
395
|
+
return;
|
|
475
396
|
}
|
|
476
397
|
// Flush remaining batch + complete request
|
|
477
398
|
try {
|
|
478
|
-
await
|
|
399
|
+
await rec.complete({
|
|
400
|
+
cloudRequestId: cloudRequestId !== request.id ? cloudRequestId : undefined,
|
|
401
|
+
statusCode: response.status,
|
|
402
|
+
headers: Object.fromEntries(response.headers)
|
|
403
|
+
});
|
|
479
404
|
const elapsed = Date.now() - startTime;
|
|
480
|
-
request.log.info(`stream completed (openai): ${cloudRequestId} ${response.status} (${elapsed}ms
|
|
405
|
+
request.log.info(`stream completed (openai): ${cloudRequestId} ${response.status} (${elapsed}ms)`);
|
|
481
406
|
}
|
|
482
407
|
catch (dbErr) {
|
|
483
408
|
request.log.error(`openai stream save failed: ${dbErr.message}`);
|
|
@@ -498,15 +423,11 @@ export async function setupProxy(fastify, proxyConfig) {
|
|
|
498
423
|
method: request.method,
|
|
499
424
|
headers: forwardHeaders,
|
|
500
425
|
body: request.method !== 'GET' ? JSON.stringify(request.body) : undefined,
|
|
501
|
-
signal:
|
|
426
|
+
signal: createTimeoutSignal(300000, clientSignal)
|
|
502
427
|
});
|
|
503
428
|
request.log.info(`response status: ${response.status}`);
|
|
504
429
|
// Extract cloud request ID from response header
|
|
505
430
|
const cloudRequestId = response.headers.get('x-request-id') || request.id;
|
|
506
|
-
requestData.requestId = cloudRequestId;
|
|
507
|
-
// Update response status in requestData
|
|
508
|
-
requestData.response.statusCode = response.status;
|
|
509
|
-
requestData.response.headers = Object.fromEntries(response.headers);
|
|
510
431
|
// Check response type: SSE stream or JSON
|
|
511
432
|
const contentType = response.headers.get('content-type') || '';
|
|
512
433
|
const isSSE = contentType.includes('text/event-stream');
|
|
@@ -517,35 +438,16 @@ export async function setupProxy(fastify, proxyConfig) {
|
|
|
517
438
|
// Record JSON body as a single event
|
|
518
439
|
try {
|
|
519
440
|
const jsonBody = JSON.parse(responseBody);
|
|
520
|
-
|
|
441
|
+
rec.appendEvent(jsonBody);
|
|
521
442
|
}
|
|
522
443
|
catch {
|
|
523
|
-
|
|
524
|
-
}
|
|
525
|
-
requestData.response.completedAt = new Date().toISOString();
|
|
526
|
-
// Remove pending row if cloudRequestId differs from request.id
|
|
527
|
-
if (cloudRequestId !== request.id) {
|
|
528
|
-
deleteResponseEvents(request.id, sessionId);
|
|
529
|
-
deleteRequestRow(request.id, sessionId);
|
|
444
|
+
rec.appendEvent({ raw: responseBody });
|
|
530
445
|
}
|
|
531
|
-
await
|
|
532
|
-
|
|
533
|
-
pushNewRequest({
|
|
534
|
-
requestId: cloudRequestId,
|
|
535
|
-
sessionId,
|
|
536
|
-
compositeId: `${sessionId}:${cloudRequestId}`,
|
|
537
|
-
method: request.method,
|
|
538
|
-
path: request.url,
|
|
539
|
-
timestamp: requestData.timestamp,
|
|
446
|
+
await rec.complete({
|
|
447
|
+
cloudRequestId: cloudRequestId !== request.id ? cloudRequestId : undefined,
|
|
540
448
|
statusCode: response.status,
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
machineId,
|
|
544
|
-
userAgent: request.headers['user-agent'],
|
|
545
|
-
baseUrl: resolved.baseUrl,
|
|
546
|
-
usage,
|
|
547
|
-
pendingId: cloudRequestId !== request.id ? `${sessionId}:${request.id}` : undefined
|
|
548
|
-
}, 'completed');
|
|
449
|
+
headers: Object.fromEntries(response.headers)
|
|
450
|
+
});
|
|
549
451
|
const elapsed = Date.now() - startTime;
|
|
550
452
|
request.log.info(`json response: ${cloudRequestId} ${response.status} (${elapsed}ms)`);
|
|
551
453
|
reply.code(response.status);
|
|
@@ -554,6 +456,8 @@ export async function setupProxy(fastify, proxyConfig) {
|
|
|
554
456
|
return;
|
|
555
457
|
}
|
|
556
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) });
|
|
557
461
|
reply.hijack();
|
|
558
462
|
// Write response headers (preserve original from Aliyun)
|
|
559
463
|
const responseHeaders = Object.fromEntries(response.headers);
|
|
@@ -562,38 +466,33 @@ export async function setupProxy(fastify, proxyConfig) {
|
|
|
562
466
|
if (response.body) {
|
|
563
467
|
// Convert Web ReadableStream to Node Readable stream
|
|
564
468
|
const nodeStream = Readable.fromWeb(response.body);
|
|
565
|
-
//
|
|
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));
|
|
566
477
|
nodeStream.on('data', (chunk) => {
|
|
567
|
-
|
|
568
|
-
const lines = text.split('\n');
|
|
569
|
-
for (const line of lines) {
|
|
570
|
-
if (line.startsWith('data:')) {
|
|
571
|
-
const eventData = line.slice(5).trim();
|
|
572
|
-
if (eventData && eventData !== '[DONE]') {
|
|
573
|
-
try {
|
|
574
|
-
const event = JSON.parse(eventData);
|
|
575
|
-
pushEventToBuffers(event, sessionId, cloudRequestId, eventBatch, tailBuffer, eventIndexRef);
|
|
576
|
-
}
|
|
577
|
-
catch {
|
|
578
|
-
// Not valid JSON, skip
|
|
579
|
-
}
|
|
580
|
-
}
|
|
581
|
-
}
|
|
582
|
-
}
|
|
478
|
+
tapDecoder.write(chunk);
|
|
583
479
|
});
|
|
584
480
|
// Save request data when stream completes
|
|
585
481
|
finished(nodeStream, async (err) => {
|
|
482
|
+
tapDecoder.end();
|
|
586
483
|
if (err) {
|
|
587
484
|
request.log.error(`claude stream error: ${err.message}`);
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
deleteResponseEvents(request.id, sessionId);
|
|
591
|
-
deleteRequestRow(request.id, sessionId);
|
|
485
|
+
rec.interrupt({ statusCode: response.status, error: `stream interrupted: ${err.message}` });
|
|
486
|
+
return;
|
|
592
487
|
}
|
|
593
488
|
try {
|
|
594
|
-
await
|
|
489
|
+
await rec.complete({
|
|
490
|
+
cloudRequestId: cloudRequestId !== request.id ? cloudRequestId : undefined,
|
|
491
|
+
statusCode: response.status,
|
|
492
|
+
headers: Object.fromEntries(response.headers)
|
|
493
|
+
});
|
|
595
494
|
const elapsed = Date.now() - startTime;
|
|
596
|
-
request.log.info(`stream completed: ${cloudRequestId} ${response.status} (${elapsed}ms
|
|
495
|
+
request.log.info(`stream completed: ${cloudRequestId} ${response.status} (${elapsed}ms)`);
|
|
597
496
|
}
|
|
598
497
|
catch (dbErr) {
|
|
599
498
|
request.log.error(`stream save failed: ${dbErr.message}`);
|
|
@@ -610,22 +509,27 @@ export async function setupProxy(fastify, proxyConfig) {
|
|
|
610
509
|
errorMessage: error.message,
|
|
611
510
|
errorCode: error.code || 'unknown'
|
|
612
511
|
}, 'proxy error');
|
|
613
|
-
// Fetch failed — no cloudRequestId available, use Fastify request.id
|
|
614
|
-
pushNewRequest({
|
|
615
|
-
requestId: request.id,
|
|
616
|
-
sessionId,
|
|
617
|
-
compositeId: `${sessionId}:${request.id}`,
|
|
618
|
-
method: request.method,
|
|
619
|
-
path: request.url,
|
|
620
|
-
timestamp: new Date().toISOString(),
|
|
621
|
-
statusCode: getErrorStatusCode(error),
|
|
622
|
-
responseTime: Date.now() - startTime,
|
|
623
|
-
model: originalModel,
|
|
624
|
-
machineId: getMachineIdSync() ?? undefined,
|
|
625
|
-
userAgent: request.headers['user-agent'],
|
|
626
|
-
baseUrl: resolved.baseUrl
|
|
627
|
-
}, 'completed');
|
|
628
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
|
+
}
|
|
629
533
|
reply.code(statusCode).send({
|
|
630
534
|
error: getErrorMessage(error),
|
|
631
535
|
requestId: request.id
|