@rynx-ai/server 0.1.11-beta.24 → 0.1.11-beta.26
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/control-api.js +492 -69
- package/dist/control-web/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
- package/dist/control-web/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
- package/dist/control-web/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
- package/dist/control-web/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
- package/dist/control-web/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
- package/dist/control-web/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
- package/dist/control-web/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
- package/dist/control-web/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
- package/dist/control-web/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
- package/dist/control-web/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
- package/dist/control-web/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
- package/dist/control-web/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
- package/dist/control-web/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
- package/dist/control-web/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
- package/dist/control-web/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
- package/dist/control-web/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
- package/dist/control-web/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
- package/dist/control-web/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
- package/dist/control-web/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
- package/dist/control-web/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
- package/dist/control-web/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
- package/dist/control-web/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
- package/dist/control-web/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
- package/dist/control-web/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
- package/dist/control-web/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
- package/dist/control-web/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
- package/dist/control-web/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
- package/dist/control-web/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
- package/dist/control-web/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
- package/dist/control-web/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
- package/dist/control-web/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
- package/dist/control-web/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
- package/dist/control-web/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
- package/dist/control-web/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
- package/dist/control-web/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
- package/dist/control-web/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
- package/dist/control-web/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
- package/dist/control-web/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
- package/dist/control-web/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
- package/dist/control-web/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
- package/dist/control-web/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
- package/dist/control-web/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
- package/dist/control-web/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
- package/dist/control-web/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
- package/dist/control-web/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
- package/dist/control-web/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
- package/dist/control-web/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
- package/dist/control-web/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
- package/dist/control-web/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
- package/dist/control-web/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
- package/dist/control-web/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
- package/dist/control-web/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
- package/dist/control-web/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
- package/dist/control-web/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
- package/dist/control-web/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
- package/dist/control-web/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
- package/dist/control-web/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
- package/dist/control-web/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
- package/dist/control-web/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
- package/dist/control-web/assets/abap-BdImnpbu.js +1 -0
- package/dist/control-web/assets/abnfDiagram-VRR7QNED-COu02MlJ.js +1 -0
- package/dist/control-web/assets/actionscript-3-CoDkCxhg.js +1 -0
- package/dist/control-web/assets/ada-bCR0ucgS.js +1 -0
- package/dist/control-web/assets/andromeeda-C4gqWexZ.js +1 -0
- package/dist/control-web/assets/angular-html-CU67Zn6k.js +1 -0
- package/dist/control-web/assets/angular-ts-BwZT4LLn.js +1 -0
- package/dist/control-web/assets/apache-Pmp26Uib.js +1 -0
- package/dist/control-web/assets/apex-D8_7TLub.js +1 -0
- package/dist/control-web/assets/apl-dKokRX4l.js +1 -0
- package/dist/control-web/assets/applescript-Co6uUVPk.js +1 -0
- package/dist/control-web/assets/ara-BRHolxvo.js +1 -0
- package/dist/control-web/assets/arc-DqiFeYAM.js +1 -0
- package/dist/control-web/assets/architectureDiagram-ZJ3FMSHR-BWFGgUV4.js +36 -0
- package/dist/control-web/assets/asciidoc-Ve4PFQV2.js +1 -0
- package/dist/control-web/assets/asm-D_Q5rh1f.js +1 -0
- package/dist/control-web/assets/astro-CbQHKStN.js +1 -0
- package/dist/control-web/assets/aurora-x-D-2ljcwZ.js +1 -0
- package/dist/control-web/assets/awk-DMzUqQB5.js +1 -0
- package/dist/control-web/assets/ayu-dark-DYE7WIF3.js +1 -0
- package/dist/control-web/assets/ayu-light-BA47KaF1.js +1 -0
- package/dist/control-web/assets/ayu-mirage-32ctXXKs.js +1 -0
- package/dist/control-web/assets/ballerina-BFfxhgS-.js +1 -0
- package/dist/control-web/assets/bat-BkioyH1T.js +1 -0
- package/dist/control-web/assets/beancount-k_qm7-4y.js +1 -0
- package/dist/control-web/assets/berry-uYugtg8r.js +1 -0
- package/dist/control-web/assets/bibtex-CHM0blh-.js +1 -0
- package/dist/control-web/assets/bicep-Bmn6On1c.js +1 -0
- package/dist/control-web/assets/bird2-DPOp833l.js +1 -0
- package/dist/control-web/assets/blade-D4QpJJKB.js +1 -0
- package/dist/control-web/assets/blockDiagram-677ZJIJ3-ZC0bXDzB.js +132 -0
- package/dist/control-web/assets/bsl-BO_Y6i37.js +1 -0
- package/dist/control-web/assets/c-BIGW1oBm.js +1 -0
- package/dist/control-web/assets/c3-eo99z4R2.js +1 -0
- package/dist/control-web/assets/c4Diagram-LMCZKHZV-Uupq5I-s.js +10 -0
- package/dist/control-web/assets/cadence-Bv_4Rxtq.js +1 -0
- package/dist/control-web/assets/cairo-KRGpt6FW.js +1 -0
- package/dist/control-web/assets/catppuccin-frappe-DFWUc33u.js +1 -0
- package/dist/control-web/assets/catppuccin-latte-C9dUb6Cb.js +1 -0
- package/dist/control-web/assets/catppuccin-macchiato-DQyhUUbL.js +1 -0
- package/dist/control-web/assets/catppuccin-mocha-D87Tk5Gz.js +1 -0
- package/dist/control-web/assets/channel-3HG15wfa.js +1 -0
- package/dist/control-web/assets/chunk-2Q5K7J3B-C77vwuDM.js +1 -0
- package/dist/control-web/assets/chunk-32BRIVSS-BkfLE_TX.js +1 -0
- package/dist/control-web/assets/chunk-5VM5RSS4-By6zfDWW.js +15 -0
- package/dist/control-web/assets/chunk-EX3LRPZG-CO439p_3.js +231 -0
- package/dist/control-web/assets/chunk-JWPE2WC7-B9BPEwug.js +1 -0
- package/dist/control-web/assets/chunk-MOJQB5TN-CYKygWZz.js +88 -0
- package/dist/control-web/assets/chunk-RYQCIY6F-ug-An4HG.js +1 -0
- package/dist/control-web/assets/chunk-V7JOEXUC-3UFQGnKX.js +206 -0
- package/dist/control-web/assets/chunk-VR4S4FIN-DjspjYUb.js +1 -0
- package/dist/control-web/assets/chunk-XXDRQBXY-3znnutie.js +1 -0
- package/dist/control-web/assets/clarity-D53aC0YG.js +1 -0
- package/dist/control-web/assets/classDiagram-OUVF2IWQ-WmU4L9YT.js +1 -0
- package/dist/control-web/assets/classDiagram-v2-EOCWNBFH-WmU4L9YT.js +1 -0
- package/dist/control-web/assets/clojure-P80f7IUj.js +1 -0
- package/dist/control-web/assets/cmake-D1j8_8rp.js +1 -0
- package/dist/control-web/assets/cobol-nwyudZeR.js +1 -0
- package/dist/control-web/assets/codeowners-Bp6g37R7.js +1 -0
- package/dist/control-web/assets/codeql-DsOJ9woJ.js +1 -0
- package/dist/control-web/assets/coffee-Ch7k5sss.js +1 -0
- package/dist/control-web/assets/common-lisp-Cg-RD9OK.js +1 -0
- package/dist/control-web/assets/coq-DkFqJrB1.js +1 -0
- package/dist/control-web/assets/cose-bilkent-JH36ORCC-Dr28goCd.js +1 -0
- package/dist/control-web/assets/cpp-CofmeUqb.js +1 -0
- package/dist/control-web/assets/crystal-tKQVLTB8.js +1 -0
- package/dist/control-web/assets/csharp-COcwbKMJ.js +1 -0
- package/dist/control-web/assets/css-DPfMkruS.js +1 -0
- package/dist/control-web/assets/csv-fuZLfV_i.js +1 -0
- package/dist/control-web/assets/cue-D82EKSYY.js +1 -0
- package/dist/control-web/assets/cynefin-VYW2F7L2-Be5uJhnw.js +178 -0
- package/dist/control-web/assets/cynefinDiagram-TSTJHNR4-BLxtSvL6.js +62 -0
- package/dist/control-web/assets/cypher-COkxafJQ.js +1 -0
- package/dist/control-web/assets/cytoscape.esm-DTSO7Bv0.js +331 -0
- package/dist/control-web/assets/d-85-TOEBH.js +1 -0
- package/dist/control-web/assets/dagre-VKFMJZFB-DPRuDV5p.js +4 -0
- package/dist/control-web/assets/dark-plus-C3mMm8J8.js +1 -0
- package/dist/control-web/assets/dart-CF10PKvl.js +1 -0
- package/dist/control-web/assets/dax-CEL-wOlO.js +1 -0
- package/dist/control-web/assets/defaultLocale-DX6XiGOO.js +1 -0
- package/dist/control-web/assets/desktop-BmXAJ9_W.js +1 -0
- package/dist/control-web/assets/diagram-FQU43EPY-Cybg22U0.js +3 -0
- package/dist/control-web/assets/diagram-G47NLZAW-CGeIKUfW.js +24 -0
- package/dist/control-web/assets/diagram-NH7WQ7WH-BJq5MBRm.js +24 -0
- package/dist/control-web/assets/diagram-OA4YK3LP-DquOQGwg.js +30 -0
- package/dist/control-web/assets/diagram-WEI45ONY-Cblb4xP2.js +41 -0
- package/dist/control-web/assets/diff-D97Zzqfu.js +1 -0
- package/dist/control-web/assets/docker-BcOcwvcX.js +1 -0
- package/dist/control-web/assets/dotenv-Da5cRb03.js +1 -0
- package/dist/control-web/assets/dracula-BzJJZx-M.js +1 -0
- package/dist/control-web/assets/dracula-soft-BXkSAIEj.js +1 -0
- package/dist/control-web/assets/dream-maker-BtqSS_iP.js +1 -0
- package/dist/control-web/assets/ebnfDiagram-CCIWWBDH-CQjHiOqj.js +1 -0
- package/dist/control-web/assets/edge-BkV0erSs.js +1 -0
- package/dist/control-web/assets/elixir-CDX3lj18.js +1 -0
- package/dist/control-web/assets/elm-DbKCFpqz.js +1 -0
- package/dist/control-web/assets/emacs-lisp-C9XAeP06.js +1 -0
- package/dist/control-web/assets/erDiagram-Q63AITRT-Bspr3uKJ.js +85 -0
- package/dist/control-web/assets/erb-B12qg9BL.js +1 -0
- package/dist/control-web/assets/erlang-DsQrWhSR.js +1 -0
- package/dist/control-web/assets/everforest-dark-BgDCqdQA.js +1 -0
- package/dist/control-web/assets/everforest-light-C8M2exoo.js +1 -0
- package/dist/control-web/assets/fennel-BYunw83y.js +1 -0
- package/dist/control-web/assets/fish-BvzEVeQv.js +1 -0
- package/dist/control-web/assets/flowDiagram-23GEKE2U-CxcZyBA-.js +156 -0
- package/dist/control-web/assets/fluent-C4IJs8-o.js +1 -0
- package/dist/control-web/assets/fortran-fixed-form-CkoXwp7k.js +1 -0
- package/dist/control-web/assets/fortran-free-form-BxgE0vQu.js +1 -0
- package/dist/control-web/assets/fsharp-CXgrBDvD.js +1 -0
- package/dist/control-web/assets/ganttDiagram-NO4QXBWP-qBdh7A-P.js +292 -0
- package/dist/control-web/assets/gdresource-BOOCDP_w.js +1 -0
- package/dist/control-web/assets/gdscript-C5YyOfLZ.js +1 -0
- package/dist/control-web/assets/gdshader-DkwncUOv.js +1 -0
- package/dist/control-web/assets/genie-D0YGMca9.js +1 -0
- package/dist/control-web/assets/gherkin-DyxjwDmM.js +1 -0
- package/dist/control-web/assets/git-commit-F4YmCXRG.js +1 -0
- package/dist/control-web/assets/git-rebase-r7XF79zn.js +1 -0
- package/dist/control-web/assets/gitGraphDiagram-IHSO6WYX-BTYub2KT.js +106 -0
- package/dist/control-web/assets/github-dark-DHJKELXO.js +1 -0
- package/dist/control-web/assets/github-dark-default-Cuk6v7N8.js +1 -0
- package/dist/control-web/assets/github-dark-dimmed-DH5Ifo-i.js +1 -0
- package/dist/control-web/assets/github-dark-high-contrast-E3gJ1_iC.js +1 -0
- package/dist/control-web/assets/github-light-DAi9KRSo.js +1 -0
- package/dist/control-web/assets/github-light-default-D7oLnXFd.js +1 -0
- package/dist/control-web/assets/github-light-high-contrast-BfjtVDDH.js +1 -0
- package/dist/control-web/assets/gleam-BspZqrRM.js +1 -0
- package/dist/control-web/assets/glimmer-js-Rg0-pVw9.js +1 -0
- package/dist/control-web/assets/glimmer-ts-U6CK756n.js +1 -0
- package/dist/control-web/assets/glsl-DplSGwfg.js +1 -0
- package/dist/control-web/assets/gn-n2N0HUVH.js +1 -0
- package/dist/control-web/assets/gnuplot-DdkO51Og.js +1 -0
- package/dist/control-web/assets/go-CxLEBnE3.js +1 -0
- package/dist/control-web/assets/graph-C9eacEi8.js +1 -0
- package/dist/control-web/assets/graphql-ChdNCCLP.js +1 -0
- package/dist/control-web/assets/groovy-gcz8RCvz.js +1 -0
- package/dist/control-web/assets/gruvbox-dark-hard-CFHQjOhq.js +1 -0
- package/dist/control-web/assets/gruvbox-dark-medium-GsRaNv29.js +1 -0
- package/dist/control-web/assets/gruvbox-dark-soft-CVdnzihN.js +1 -0
- package/dist/control-web/assets/gruvbox-light-hard-CH1njM8p.js +1 -0
- package/dist/control-web/assets/gruvbox-light-medium-DRw_LuNl.js +1 -0
- package/dist/control-web/assets/gruvbox-light-soft-hJgmCMqR.js +1 -0
- package/dist/control-web/assets/hack-CaT9iCJl.js +1 -0
- package/dist/control-web/assets/haml-B8DHNrY2.js +1 -0
- package/dist/control-web/assets/handlebars-BL8al0AC.js +1 -0
- package/dist/control-web/assets/haskell-Df6bDoY_.js +1 -0
- package/dist/control-web/assets/haxe-CzTSHFRz.js +1 -0
- package/dist/control-web/assets/hcl-BWvSN4gD.js +1 -0
- package/dist/control-web/assets/{highlighted-body-OFNGDK62-DV5jYwcf.js → highlighted-body-OFNGDK62-DyksUrwu.js} +1 -1
- package/dist/control-web/assets/hjson-D5-asLiD.js +1 -0
- package/dist/control-web/assets/hlsl-D3lLCCz7.js +1 -0
- package/dist/control-web/assets/horizon-BUw7H-hv.js +1 -0
- package/dist/control-web/assets/horizon-bright-Cn-bp-IR.js +1 -0
- package/dist/control-web/assets/houston-DnULxvSX.js +1 -0
- package/dist/control-web/assets/html-GMplVEZG.js +1 -0
- package/dist/control-web/assets/html-derivative-BFtXZ54Q.js +1 -0
- package/dist/control-web/assets/http-jrhK8wxY.js +1 -0
- package/dist/control-web/assets/hurl-irOxFIW8.js +1 -0
- package/dist/control-web/assets/hxml-Bvhsp5Yf.js +1 -0
- package/dist/control-web/assets/hy-DFXneXwc.js +1 -0
- package/dist/control-web/assets/imba-DGztddWO.js +1 -0
- package/dist/control-web/assets/index-B9SAq_63.js +718 -0
- package/dist/control-web/assets/index-BDaSctIT.js +153 -0
- package/dist/control-web/assets/index-CtaYRNgJ.css +32 -0
- package/dist/control-web/assets/infoDiagram-FWYZ7A6U-ChbQR3Zo.js +2 -0
- package/dist/control-web/assets/ini-BEwlwnbL.js +1 -0
- package/dist/control-web/assets/init-Gi6I4Gst.js +1 -0
- package/dist/control-web/assets/ishikawaDiagram-FXEZZL3T-C-4_qGzn.js +70 -0
- package/dist/control-web/assets/java-CylS5w8V.js +1 -0
- package/dist/control-web/assets/javascript-wDzz0qaB.js +1 -0
- package/dist/control-web/assets/jinja-4LBKfQ-Z.js +1 -0
- package/dist/control-web/assets/jison-wvAkD_A8.js +1 -0
- package/dist/control-web/assets/journeyDiagram-5HDEW3XC-B090zN18.js +139 -0
- package/dist/control-web/assets/json-Cp-IABpG.js +1 -0
- package/dist/control-web/assets/json5-C9tS-k6U.js +1 -0
- package/dist/control-web/assets/jsonc-Des-eS-w.js +1 -0
- package/dist/control-web/assets/jsonl-DcaNXYhu.js +1 -0
- package/dist/control-web/assets/jsonnet-DFQXde-d.js +1 -0
- package/dist/control-web/assets/jssm-C2t-YnRu.js +1 -0
- package/dist/control-web/assets/jsx-g9-lgVsj.js +1 -0
- package/dist/control-web/assets/julia-CxzCAyBv.js +1 -0
- package/dist/control-web/assets/just-Cw27pwNe.js +1 -0
- package/dist/control-web/assets/kanagawa-dragon-CkXjmgJE.js +1 -0
- package/dist/control-web/assets/kanagawa-lotus-CfQXZHmo.js +1 -0
- package/dist/control-web/assets/kanagawa-wave-DWedfzmr.js +1 -0
- package/dist/control-web/assets/kanban-definition-HUTT4EX6-RlTcRbPs.js +89 -0
- package/dist/control-web/assets/kdl-DV7GczEv.js +1 -0
- package/dist/control-web/assets/kotlin-BdnUsdx6.js +1 -0
- package/dist/control-web/assets/kusto-DZf3V79B.js +1 -0
- package/dist/control-web/assets/laserwave-DUszq2jm.js +1 -0
- package/dist/control-web/assets/latex-CWtU0Tv5.js +1 -0
- package/dist/control-web/assets/layout-DEXfKzaS.js +1 -0
- package/dist/control-web/assets/lean-BZvkOJ9d.js +1 -0
- package/dist/control-web/assets/less-B1dDrJ26.js +1 -0
- package/dist/control-web/assets/light-plus-B7mTdjB0.js +1 -0
- package/dist/control-web/assets/linear-DTuNxDqu.js +1 -0
- package/dist/control-web/assets/liquid-DYVedYrR.js +1 -0
- package/dist/control-web/assets/llvm-DjAJT7YJ.js +1 -0
- package/dist/control-web/assets/log-2UxHyX5q.js +1 -0
- package/dist/control-web/assets/logo-BtOb2qkB.js +1 -0
- package/dist/control-web/assets/lua-BaeVxFsk.js +1 -0
- package/dist/control-web/assets/luau-C-HG3fhB.js +1 -0
- package/dist/control-web/assets/make-CHLpvVh8.js +1 -0
- package/dist/control-web/assets/map-Czzmt4hB.js +1 -0
- package/dist/control-web/assets/markdown-Cvjx9yec.js +1 -0
- package/dist/control-web/assets/marko-CnJfTvn9.js +1 -0
- package/dist/control-web/assets/material-theme-D5KoaKCx.js +1 -0
- package/dist/control-web/assets/material-theme-darker-BfHTSMKl.js +1 -0
- package/dist/control-web/assets/material-theme-lighter-B0m2ddpp.js +1 -0
- package/dist/control-web/assets/material-theme-ocean-CyktbL80.js +1 -0
- package/dist/control-web/assets/material-theme-palenight-Csfq5Kiy.js +1 -0
- package/dist/control-web/assets/matlab-D7o27uSR.js +1 -0
- package/dist/control-web/assets/mdc-BMNejdWA.js +1 -0
- package/dist/control-web/assets/mdx-Cmh6b_Ma.js +1 -0
- package/dist/control-web/assets/mermaid-GHXKKRXX-BYZTj3zW.css +1 -0
- package/dist/control-web/assets/mermaid-GHXKKRXX-BkcV3dgg.js +710 -0
- package/dist/control-web/assets/mermaid-mWjccvbQ.js +1 -0
- package/dist/control-web/assets/min-dark-CafNBF8u.js +1 -0
- package/dist/control-web/assets/min-light-CTRr51gU.js +1 -0
- package/dist/control-web/assets/mindmap-definition-LN4V7U3C-DYby41E9.js +96 -0
- package/dist/control-web/assets/mipsasm-CKIfxQSi.js +1 -0
- package/dist/control-web/assets/mojo-rZm6bMo-.js +1 -0
- package/dist/control-web/assets/monokai-D4h5O-jR.js +1 -0
- package/dist/control-web/assets/moonbit-_H4v1dQx.js +1 -0
- package/dist/control-web/assets/move-IF9eRakj.js +1 -0
- package/dist/control-web/assets/narrat-DRg8JJMk.js +1 -0
- package/dist/control-web/assets/nextflow-Zz6hmt5N.js +1 -0
- package/dist/control-web/assets/nextflow-groovy-BeH2EWoN.js +1 -0
- package/dist/control-web/assets/nginx-BpAMiNFr.js +1 -0
- package/dist/control-web/assets/night-owl-C39BiMTA.js +1 -0
- package/dist/control-web/assets/night-owl-light-CMTm3GFP.js +1 -0
- package/dist/control-web/assets/nim-CVrawwO9.js +1 -0
- package/dist/control-web/assets/nix-CwoSXNpI.js +1 -0
- package/dist/control-web/assets/nord-Ddv68eIx.js +1 -0
- package/dist/control-web/assets/nushell-Cz2AlsmD.js +1 -0
- package/dist/control-web/assets/objective-c-DXmwc3jG.js +1 -0
- package/dist/control-web/assets/objective-cpp-CLxacb5B.js +1 -0
- package/dist/control-web/assets/ocaml-C0hk2d4L.js +1 -0
- package/dist/control-web/assets/odin-BBf5iR-q.js +1 -0
- package/dist/control-web/assets/one-dark-pro-DVMEJ2y_.js +1 -0
- package/dist/control-web/assets/one-light-C3Wv6jpd.js +1 -0
- package/dist/control-web/assets/openscad-C4EeE6gA.js +1 -0
- package/dist/control-web/assets/ordinal-Cboi1Yqb.js +1 -0
- package/dist/control-web/assets/pascal-D93ZcfNL.js +1 -0
- package/dist/control-web/assets/pegDiagram-2B236MQR-CPK6GaEv.js +1 -0
- package/dist/control-web/assets/perl-C0TMdlhV.js +1 -0
- package/dist/control-web/assets/php-Dhbhpdrm.js +1 -0
- package/dist/control-web/assets/pieDiagram-ENE6RG2P-DLCmXuji.js +39 -0
- package/dist/control-web/assets/pkl-u5AG7uiY.js +1 -0
- package/dist/control-web/assets/plastic-3e1v2bzS.js +1 -0
- package/dist/control-web/assets/plsql-ChMvpjG-.js +1 -0
- package/dist/control-web/assets/po-BTJTHyun.js +1 -0
- package/dist/control-web/assets/poimandres-CS3Unz2-.js +1 -0
- package/dist/control-web/assets/polar-C0HS_06l.js +1 -0
- package/dist/control-web/assets/postcss-CXtECtnM.js +1 -0
- package/dist/control-web/assets/powerquery-CEu0bR-o.js +1 -0
- package/dist/control-web/assets/powershell-Dpen1YoG.js +1 -0
- package/dist/control-web/assets/prisma-Dd19v3D-.js +1 -0
- package/dist/control-web/assets/prolog-CbFg5uaA.js +1 -0
- package/dist/control-web/assets/proto-C7zT0LnQ.js +1 -0
- package/dist/control-web/assets/pug-CGlum2m_.js +1 -0
- package/dist/control-web/assets/puppet-BMWR74SV.js +1 -0
- package/dist/control-web/assets/purescript-CklMAg4u.js +1 -0
- package/dist/control-web/assets/python-B6aJPvgy.js +1 -0
- package/dist/control-web/assets/qml-3beO22l8.js +1 -0
- package/dist/control-web/assets/qmldir-C8lEn-DE.js +1 -0
- package/dist/control-web/assets/qss-IeuSbFQv.js +1 -0
- package/dist/control-web/assets/quadrantDiagram-ABIIQ3AL-RIS8r7CA.js +7 -0
- package/dist/control-web/assets/r-Dspwwk_N.js +1 -0
- package/dist/control-web/assets/racket-BqYA7rlc.js +1 -0
- package/dist/control-web/assets/railroadDiagram-RFXS5EU6-B1HB7xsg.js +1 -0
- package/dist/control-web/assets/raku-DXvB9xmW.js +1 -0
- package/dist/control-web/assets/razor-Uh8Bk_45.js +1 -0
- package/dist/control-web/assets/red-bN70gL4F.js +1 -0
- package/dist/control-web/assets/reg-C-SQnVFl.js +1 -0
- package/dist/control-web/assets/regexp-CDVJQ6XC.js +1 -0
- package/dist/control-web/assets/rel-C3B-1QV4.js +1 -0
- package/dist/control-web/assets/requirementDiagram-TGXJPOKE-Inh_4hU0.js +84 -0
- package/dist/control-web/assets/riscv-BM1_JUlF.js +1 -0
- package/dist/control-web/assets/ron-D8l8udqQ.js +1 -0
- package/dist/control-web/assets/rose-pine-dawn-DHQR4-dF.js +1 -0
- package/dist/control-web/assets/rose-pine-moon-D4_iv3hh.js +1 -0
- package/dist/control-web/assets/rose-pine-qdsjHGoJ.js +1 -0
- package/dist/control-web/assets/rosmsg-BJDFO7_C.js +1 -0
- package/dist/control-web/assets/rst-BrH8l1NY.js +1 -0
- package/dist/control-web/assets/ruby-Dw2BHqvy.js +1 -0
- package/dist/control-web/assets/rust-B1yitclQ.js +1 -0
- package/dist/control-web/assets/sankeyDiagram-HTMAVEWB-DPF33kPB.js +40 -0
- package/dist/control-web/assets/sas-cz2c8ADy.js +1 -0
- package/dist/control-web/assets/sass-Cj5Yp3dK.js +1 -0
- package/dist/control-web/assets/scala-C151Ov-r.js +1 -0
- package/dist/control-web/assets/scheme-C98Dy4si.js +1 -0
- package/dist/control-web/assets/scss-OYdSNvt2.js +1 -0
- package/dist/control-web/assets/sdbl-DVxCFoDh.js +1 -0
- package/dist/control-web/assets/sequenceDiagram-DBY2YBRQ-iywKWoYc.js +162 -0
- package/dist/control-web/assets/shaderlab-Dg9Lc6iA.js +1 -0
- package/dist/control-web/assets/shellscript-Yzrsuije.js +1 -0
- package/dist/control-web/assets/shellsession-BADoaaVG.js +1 -0
- package/dist/control-web/assets/sizeCapture-X5ZJPWSS-DlnHubz9.js +1 -0
- package/dist/control-web/assets/slack-dark-BthQWCQV.js +1 -0
- package/dist/control-web/assets/slack-ochin-DqwNpetd.js +1 -0
- package/dist/control-web/assets/smalltalk-BERRCDM3.js +1 -0
- package/dist/control-web/assets/snazzy-light-Bw305WKR.js +1 -0
- package/dist/control-web/assets/solarized-dark-DXbdFlpD.js +1 -0
- package/dist/control-web/assets/solarized-light-L9t79GZl.js +1 -0
- package/dist/control-web/assets/solidity-rGO070M0.js +1 -0
- package/dist/control-web/assets/soy-Brmx7dQM.js +1 -0
- package/dist/control-web/assets/sparql-rVzFXLq3.js +1 -0
- package/dist/control-web/assets/splunk-BtCnVYZw.js +1 -0
- package/dist/control-web/assets/sql-BLtJtn59.js +1 -0
- package/dist/control-web/assets/ssh-config-_ykCGR6B.js +1 -0
- package/dist/control-web/assets/stata-BH5u7GGu.js +1 -0
- package/dist/control-web/assets/stateDiagram-2N3HPSRC-CShzll2N.js +1 -0
- package/dist/control-web/assets/stateDiagram-v2-6OUMAXLB-Cdx0fWna.js +1 -0
- package/dist/control-web/assets/stylus-BEDo0Tqx.js +1 -0
- package/dist/control-web/assets/surrealql-Bq5Q-fJD.js +1 -0
- package/dist/control-web/assets/svelte-C_ipcX3V.js +1 -0
- package/dist/control-web/assets/swift-D82vCrfD.js +1 -0
- package/dist/control-web/assets/swimlanes-5IMT3BWC-CxlQpFBv.js +2 -0
- package/dist/control-web/assets/swimlanesDiagram-G3AALYLV-CoX0jnUu.js +8 -0
- package/dist/control-web/assets/synthwave-84-CbfX1IO0.js +1 -0
- package/dist/control-web/assets/system-verilog-CnnmHF94.js +1 -0
- package/dist/control-web/assets/systemd-4A_iFExJ.js +1 -0
- package/dist/control-web/assets/talonscript-CkByrt1z.js +1 -0
- package/dist/control-web/assets/tasl-QIJgUcNo.js +1 -0
- package/dist/control-web/assets/tcl-dwOrl1Do.js +1 -0
- package/dist/control-web/assets/templ-P3uqSqPl.js +1 -0
- package/dist/control-web/assets/terraform-BETggiCN.js +1 -0
- package/dist/control-web/assets/tex-idrVyKtj.js +1 -0
- package/dist/control-web/assets/timeline-definition-FHXFAJF6-Dlx59Xc3.js +120 -0
- package/dist/control-web/assets/tokyo-night-hegEt444.js +1 -0
- package/dist/control-web/assets/toml-vGWfd6FD.js +1 -0
- package/dist/control-web/assets/ts-tags-zn1MmPIZ.js +1 -0
- package/dist/control-web/assets/tsv-B_m7g4N7.js +1 -0
- package/dist/control-web/assets/tsx-COt5Ahok.js +1 -0
- package/dist/control-web/assets/turtle-BsS91CYL.js +1 -0
- package/dist/control-web/assets/twig-DNn4PbVi.js +1 -0
- package/dist/control-web/assets/typescript-BPQ3VLAy.js +1 -0
- package/dist/control-web/assets/typespec-BGHnOYBU.js +1 -0
- package/dist/control-web/assets/typst-DHCkPAjA.js +1 -0
- package/dist/control-web/assets/v-BcVCzyr7.js +1 -0
- package/dist/control-web/assets/vala-CsfeWuGM.js +1 -0
- package/dist/control-web/assets/vb-D17OF-Vu.js +1 -0
- package/dist/control-web/assets/vennDiagram-L72KCM5P-DLsv4i_t.js +34 -0
- package/dist/control-web/assets/verilog-BQ8w6xss.js +1 -0
- package/dist/control-web/assets/vesper-DU1UobuO.js +1 -0
- package/dist/control-web/assets/vhdl-CeAyd5Ju.js +1 -0
- package/dist/control-web/assets/viml-CJc9bBzg.js +1 -0
- package/dist/control-web/assets/vitesse-black-Bkuqu6BP.js +1 -0
- package/dist/control-web/assets/vitesse-dark-D0r3Knsf.js +1 -0
- package/dist/control-web/assets/vitesse-light-CVO1_9PV.js +1 -0
- package/dist/control-web/assets/vue-DN_0RTcg.js +1 -0
- package/dist/control-web/assets/vue-html-AaS7Mt5G.js +1 -0
- package/dist/control-web/assets/vue-vine-CQOfvN7w.js +1 -0
- package/dist/control-web/assets/vyper-CDx5xZoG.js +1 -0
- package/dist/control-web/assets/wardleyDiagram-EHGQE667-BazV8fpH.js +78 -0
- package/dist/control-web/assets/wasm-CG6Dc4jp.js +1 -0
- package/dist/control-web/assets/wasm-MzD3tlZU.js +1 -0
- package/dist/control-web/assets/wenyan-BV7otONQ.js +1 -0
- package/dist/control-web/assets/wgsl-Dx-B1_4e.js +1 -0
- package/dist/control-web/assets/wikitext-BhOHFoWU.js +1 -0
- package/dist/control-web/assets/wit-5i3qLPDT.js +1 -0
- package/dist/control-web/assets/wolfram-lXgVvXCa.js +1 -0
- package/dist/control-web/assets/xml-sdJ4AIDG.js +1 -0
- package/dist/control-web/assets/xsl-CtQFsRM5.js +1 -0
- package/dist/control-web/assets/xychartDiagram-FW5EYKEG-Bx9uDlYu.js +7 -0
- package/dist/control-web/assets/yaml-Buea-lGh.js +1 -0
- package/dist/control-web/assets/zenscript-DVFEvuxE.js +1 -0
- package/dist/control-web/assets/zig-VOosw3JB.js +1 -0
- package/dist/control-web/index.html +2 -2
- package/dist/machine-session-service.d.ts +62 -7
- package/dist/machine-session-service.js +559 -18
- package/dist/remote-runtime-dispatcher.d.ts +1 -1
- package/dist/remote-runtime-dispatcher.js +8 -0
- package/dist/remote-runtime-session-projection.js +4 -0
- package/dist/server.d.ts +9 -3
- package/dist/server.js +86 -4
- package/dist/session-runtime-index.js +14 -1
- package/package.json +7 -7
- package/dist/control-web/assets/index-0noHpRXD.css +0 -32
- package/dist/control-web/assets/index-D-5t2eCT.js +0 -709
- package/dist/control-web/assets/mermaid-GHXKKRXX-DPZO2Q9W.js +0 -131
package/dist/control-api.js
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* owns that state and exposes its own management application.
|
|
8
8
|
*/
|
|
9
9
|
import { timingSafeEqual } from "node:crypto";
|
|
10
|
+
import { Readable } from "node:stream";
|
|
10
11
|
import Router from "@koa/router";
|
|
11
12
|
import { skillInstallRecipeSchema, } from "@rynx-ai/core";
|
|
12
13
|
import { DAEMON_BROWSER_ARTIFACT_CLEAN_PATH, DAEMON_BROWSER_ARTIFACT_INSTALL_PATH, DAEMON_BROWSER_ARTIFACT_UPDATE_PATH, DAEMON_BROWSER_ARTIFACT_VERSION_PATH, DAEMON_CHROME_INSPECTION_PATH, DAEMON_CLEANUP_SESSIONS_PATH, DAEMON_MAINTENANCE_LEASE_HEADER, DAEMON_MAINTENANCE_LEASE_RELEASE_PATH, DAEMON_SHUTDOWN_IF_IDLE_PATH, parseDaemonBrowserArtifactInstallInput, parseDaemonBrowserArtifactUpdateInput, parseDaemonChromeInspectionConfigureInput, parseDaemonCleanupSessionsInput, } from "@rynx-ai/protocol/control";
|
|
@@ -736,12 +737,15 @@ export function createControlRouter(opts) {
|
|
|
736
737
|
const body = await readRuntimeBody(ctx);
|
|
737
738
|
if (!body)
|
|
738
739
|
return;
|
|
739
|
-
if (!acceptRuntimeBodyKeys(ctx, body, ["model", "reasoningEffort"]))
|
|
740
|
+
if (!acceptRuntimeBodyKeys(ctx, body, ["model", "reasoningEffort", "collaborationMode"]))
|
|
740
741
|
return;
|
|
741
742
|
const outcome = await runtimeCall(ctx, "session.execution.update", {
|
|
742
743
|
sessionId: ctx.params.id,
|
|
743
744
|
model: body.model,
|
|
744
745
|
reasoningEffort: body.reasoningEffort,
|
|
746
|
+
...(body.collaborationMode === undefined
|
|
747
|
+
? {}
|
|
748
|
+
: { collaborationMode: body.collaborationMode }),
|
|
745
749
|
});
|
|
746
750
|
if (outcome.ok)
|
|
747
751
|
ctx.body = outcome.result;
|
|
@@ -856,7 +860,13 @@ export function createControlRouter(opts) {
|
|
|
856
860
|
};
|
|
857
861
|
const runtimeSessionResourceUpload = async (ctx) => {
|
|
858
862
|
const uploadStarted = performance.now();
|
|
859
|
-
const mediaType = ctx.get("content-type").split(";", 1)[0]?.trim();
|
|
863
|
+
const mediaType = ctx.get("content-type").split(";", 1)[0]?.trim().toLowerCase();
|
|
864
|
+
const requestedType = ctx.get("x-rynx-resource-type").trim();
|
|
865
|
+
const resourceType = requestedType === "input_image" || requestedType === "input_file"
|
|
866
|
+
? requestedType
|
|
867
|
+
: SESSION_IMAGE_MEDIA_TYPES.includes(mediaType)
|
|
868
|
+
? "input_image"
|
|
869
|
+
: "input_file";
|
|
860
870
|
const clientUploadId = ctx.get("x-rynx-upload-id").trim();
|
|
861
871
|
const encodedFilename = ctx.get("x-rynx-filename").trim();
|
|
862
872
|
let filename = "";
|
|
@@ -869,7 +879,9 @@ export function createControlRouter(opts) {
|
|
|
869
879
|
return;
|
|
870
880
|
}
|
|
871
881
|
if (!mediaType ||
|
|
872
|
-
!
|
|
882
|
+
!isMediaType(mediaType) ||
|
|
883
|
+
(resourceType === "input_image" &&
|
|
884
|
+
!SESSION_IMAGE_MEDIA_TYPES.includes(mediaType)) ||
|
|
873
885
|
!clientUploadId ||
|
|
874
886
|
!filename ||
|
|
875
887
|
filename.length > SESSION_RESOURCE_MAX_FILENAME_CHARS) {
|
|
@@ -877,23 +889,21 @@ export function createControlRouter(opts) {
|
|
|
877
889
|
ctx.body = { error: "invalid_resource_upload" };
|
|
878
890
|
return;
|
|
879
891
|
}
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
}
|
|
885
|
-
catch (error) {
|
|
886
|
-
ctx.status = error instanceof RequestBodyTooLargeError ? 413 : 400;
|
|
887
|
-
ctx.body = {
|
|
888
|
-
error: error instanceof RequestBodyTooLargeError
|
|
889
|
-
? "request_too_large"
|
|
890
|
-
: "invalid_resource_upload",
|
|
891
|
-
};
|
|
892
|
+
const contentLengthHeader = ctx.get("content-length").trim();
|
|
893
|
+
if (!contentLengthHeader) {
|
|
894
|
+
ctx.status = 411;
|
|
895
|
+
ctx.body = { error: "content_length_required" };
|
|
892
896
|
return;
|
|
893
897
|
}
|
|
894
|
-
|
|
898
|
+
const byteLength = Number(contentLengthHeader);
|
|
899
|
+
if (!Number.isSafeInteger(byteLength) || byteLength <= 0) {
|
|
895
900
|
ctx.status = 400;
|
|
896
|
-
ctx.body = { error: "
|
|
901
|
+
ctx.body = { error: "invalid_content_length" };
|
|
902
|
+
return;
|
|
903
|
+
}
|
|
904
|
+
if (resourceType === "input_image" && byteLength > SESSION_RESOURCE_MAX_IMAGE_BYTES) {
|
|
905
|
+
ctx.status = 413;
|
|
906
|
+
ctx.body = { error: "request_too_large" };
|
|
897
907
|
return;
|
|
898
908
|
}
|
|
899
909
|
const sessionId = ctx.params.id;
|
|
@@ -901,9 +911,7 @@ export function createControlRouter(opts) {
|
|
|
901
911
|
const lease = local ? undefined : await acquireRuntimeLease(ctx);
|
|
902
912
|
if (!local && !lease)
|
|
903
913
|
return;
|
|
904
|
-
const timings = new Map(
|
|
905
|
-
["body", performance.now() - bodyReadStarted],
|
|
906
|
-
]);
|
|
914
|
+
const timings = new Map();
|
|
907
915
|
const timed = async (name, operation) => {
|
|
908
916
|
const started = performance.now();
|
|
909
917
|
try {
|
|
@@ -920,16 +928,18 @@ export function createControlRouter(opts) {
|
|
|
920
928
|
? local.beginResourceUpload({
|
|
921
929
|
sessionId,
|
|
922
930
|
clientUploadId,
|
|
931
|
+
type: resourceType,
|
|
923
932
|
filename,
|
|
924
933
|
mediaType,
|
|
925
|
-
byteLength
|
|
934
|
+
byteLength,
|
|
926
935
|
})
|
|
927
936
|
: lease.call("session.resource.upload.begin", {
|
|
928
937
|
sessionId,
|
|
929
938
|
clientUploadId,
|
|
939
|
+
type: resourceType,
|
|
930
940
|
filename,
|
|
931
941
|
mediaType,
|
|
932
|
-
byteLength
|
|
942
|
+
byteLength,
|
|
933
943
|
}, { timeoutMs: REMOTE_RUNTIME_SESSION_TIMEOUT_MS }));
|
|
934
944
|
const writeChunk = (uploadId, offset, data) => timed("chunks", () => local
|
|
935
945
|
? local.writeResourceUploadChunk({ sessionId, uploadId, offset, data })
|
|
@@ -937,44 +947,72 @@ export function createControlRouter(opts) {
|
|
|
937
947
|
const commit = (uploadId) => timed("commit", () => local
|
|
938
948
|
? local.commitResourceUpload({ sessionId, uploadId })
|
|
939
949
|
: lease.call("session.resource.upload.commit", { sessionId, uploadId }, { timeoutMs: REMOTE_RUNTIME_SESSION_TIMEOUT_MS }));
|
|
950
|
+
const discardPartial = (resourceId) => timed("restart", () => local
|
|
951
|
+
? local.deleteResource({ sessionId, resourceId })
|
|
952
|
+
: lease.call("session.resource.delete", { sessionId, resourceId }, { timeoutMs: REMOTE_RUNTIME_SESSION_TIMEOUT_MS }));
|
|
953
|
+
let requestResourceId;
|
|
954
|
+
let resourceCommitted = false;
|
|
940
955
|
try {
|
|
941
956
|
const resourcePolicy = await policy();
|
|
942
957
|
if (!resourcePolicy.enabled ||
|
|
943
|
-
|
|
944
|
-
|
|
958
|
+
(resourceType === "input_image" &&
|
|
959
|
+
(!resourcePolicy.mediaTypes.includes(mediaType) ||
|
|
960
|
+
byteLength > resourcePolicy.maxImageBytes))) {
|
|
945
961
|
ctx.status = 413;
|
|
946
962
|
ctx.body = { error: "resource_policy_rejected" };
|
|
947
963
|
return;
|
|
948
964
|
}
|
|
949
|
-
|
|
965
|
+
let begun = await begin();
|
|
950
966
|
if (begun.complete && begun.resource) {
|
|
967
|
+
ctx.req.resume();
|
|
951
968
|
ctx.set("Cache-Control", "no-store");
|
|
952
969
|
ctx.body = { resource: begun.resource };
|
|
953
970
|
return;
|
|
954
971
|
}
|
|
955
|
-
if (begun.offset < 0 || begun.offset >
|
|
972
|
+
if (begun.offset < 0 || begun.offset > byteLength) {
|
|
956
973
|
throw runtimeProtocolError("Runtime Session resource upload offset is invalid");
|
|
957
974
|
}
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
975
|
+
// Browser retries send the complete File body again. A target-side
|
|
976
|
+
// partial cannot be blindly combined with the new body's suffix: the
|
|
977
|
+
// caller may have reused an upload id for changed bytes. Restart the
|
|
978
|
+
// incomplete upload so committed content always matches this request.
|
|
979
|
+
if (begun.offset > 0) {
|
|
980
|
+
const discarded = await discardPartial(begun.resourceId);
|
|
981
|
+
if (!discarded.deleted) {
|
|
982
|
+
throw runtimeProtocolError("Runtime Session partial upload could not be restarted");
|
|
983
|
+
}
|
|
984
|
+
begun = await begin();
|
|
985
|
+
if (begun.complete || begun.offset !== 0) {
|
|
986
|
+
throw runtimeProtocolError("Runtime Session resource upload did not restart");
|
|
964
987
|
}
|
|
965
|
-
offset = written.offset;
|
|
966
988
|
}
|
|
989
|
+
requestResourceId = begun.resourceId;
|
|
990
|
+
const bodyStarted = performance.now();
|
|
991
|
+
await forwardResourceUploadBody(ctx, begun.uploadId, begun.offset, byteLength, writeChunk);
|
|
992
|
+
timings.set("body", performance.now() - bodyStarted);
|
|
967
993
|
const committed = await commit(begun.uploadId);
|
|
968
994
|
if (committed.resource.resourceId !== begun.resourceId ||
|
|
995
|
+
committed.resource.type !== resourceType ||
|
|
969
996
|
committed.resource.mediaType !== mediaType ||
|
|
970
|
-
committed.resource.byteLength !==
|
|
997
|
+
committed.resource.byteLength !== byteLength) {
|
|
971
998
|
throw runtimeProtocolError("Runtime Session resource upload identity changed");
|
|
972
999
|
}
|
|
1000
|
+
resourceCommitted = true;
|
|
973
1001
|
ctx.status = 201;
|
|
974
1002
|
ctx.set("Cache-Control", "no-store");
|
|
975
1003
|
ctx.body = committed;
|
|
976
1004
|
}
|
|
977
1005
|
catch (error) {
|
|
1006
|
+
if (requestResourceId && !resourceCommitted) {
|
|
1007
|
+
try {
|
|
1008
|
+
await discardPartial(requestResourceId);
|
|
1009
|
+
}
|
|
1010
|
+
catch {
|
|
1011
|
+
// The original error remains authoritative. Targets also reap stale
|
|
1012
|
+
// uploads, so a disconnected target cannot make cleanup block the
|
|
1013
|
+
// browser response indefinitely.
|
|
1014
|
+
}
|
|
1015
|
+
}
|
|
978
1016
|
runtimeTargetHostError(ctx, error);
|
|
979
1017
|
}
|
|
980
1018
|
finally {
|
|
@@ -990,7 +1028,7 @@ export function createControlRouter(opts) {
|
|
|
990
1028
|
event: "session.resource.upload.slow",
|
|
991
1029
|
selector: ctx.params.selector,
|
|
992
1030
|
sessionId,
|
|
993
|
-
byteLength
|
|
1031
|
+
byteLength,
|
|
994
1032
|
status: ctx.status,
|
|
995
1033
|
timings: Object.fromEntries([...timings.entries()].map(([name, duration]) => [
|
|
996
1034
|
name,
|
|
@@ -1034,16 +1072,32 @@ export function createControlRouter(opts) {
|
|
|
1034
1072
|
const sessionId = ctx.params.id;
|
|
1035
1073
|
const resourceId = ctx.params.resourceId;
|
|
1036
1074
|
const local = ctx.params.selector === "local" ? localSessionResources : undefined;
|
|
1037
|
-
const
|
|
1038
|
-
|
|
1075
|
+
const invocation = downloadInvocationAbortScope(ctx, shutdownSignal);
|
|
1076
|
+
const lease = local ? undefined : await acquireRuntimeLease(ctx, invocation.signal);
|
|
1077
|
+
if (!local && !lease) {
|
|
1078
|
+
invocation.dispose();
|
|
1039
1079
|
return;
|
|
1080
|
+
}
|
|
1081
|
+
let streamOwnsLease = false;
|
|
1082
|
+
let cleanedUp = false;
|
|
1083
|
+
const cleanup = () => {
|
|
1084
|
+
if (cleanedUp)
|
|
1085
|
+
return;
|
|
1086
|
+
cleanedUp = true;
|
|
1087
|
+
lease?.release();
|
|
1088
|
+
invocation.dispose();
|
|
1089
|
+
};
|
|
1040
1090
|
try {
|
|
1041
1091
|
const { resource } = local
|
|
1042
1092
|
? await local.getResource({ sessionId, resourceId })
|
|
1043
|
-
: await lease.call("session.resource.get", { sessionId, resourceId }, { timeoutMs: REMOTE_RUNTIME_SESSION_TIMEOUT_MS });
|
|
1093
|
+
: await lease.call("session.resource.get", { sessionId, resourceId }, { timeoutMs: REMOTE_RUNTIME_SESSION_TIMEOUT_MS, signal: invocation.signal });
|
|
1044
1094
|
if (resource.resourceId !== resourceId) {
|
|
1045
1095
|
throw runtimeProtocolError("Runtime Session resource identity changed");
|
|
1046
1096
|
}
|
|
1097
|
+
const byteLength = resource.byteLength;
|
|
1098
|
+
if (!Number.isSafeInteger(byteLength) || !byteLength || byteLength < 1) {
|
|
1099
|
+
throw runtimeProtocolError("Runtime Session resource length is invalid");
|
|
1100
|
+
}
|
|
1047
1101
|
const etag = `"sha256-${resource.sha256}"`;
|
|
1048
1102
|
ctx.set("Cache-Control", "private, max-age=0, must-revalidate");
|
|
1049
1103
|
ctx.set("ETag", etag);
|
|
@@ -1051,48 +1105,68 @@ export function createControlRouter(opts) {
|
|
|
1051
1105
|
ctx.status = 304;
|
|
1052
1106
|
return;
|
|
1053
1107
|
}
|
|
1054
|
-
const
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
})
|
|
1064
|
-
: await lease.call("session.resource.read", {
|
|
1065
|
-
sessionId,
|
|
1066
|
-
resourceId,
|
|
1067
|
-
offset,
|
|
1068
|
-
length: SESSION_RESOURCE_TRANSFER_CHUNK_BYTES,
|
|
1069
|
-
}, { timeoutMs: REMOTE_RUNTIME_SESSION_TIMEOUT_MS });
|
|
1070
|
-
const chunk = Buffer.from(result.data, "base64");
|
|
1071
|
-
if (result.offset !== offset + chunk.byteLength || (!result.eof && chunk.byteLength === 0)) {
|
|
1072
|
-
throw runtimeProtocolError("Runtime Session resource read did not advance");
|
|
1073
|
-
}
|
|
1074
|
-
chunks.push(chunk);
|
|
1075
|
-
offset = result.offset;
|
|
1076
|
-
if (result.eof)
|
|
1077
|
-
break;
|
|
1078
|
-
}
|
|
1079
|
-
const body = Buffer.concat(chunks);
|
|
1080
|
-
if (body.byteLength !== resource.byteLength) {
|
|
1081
|
-
throw runtimeProtocolError("Runtime Session resource length changed");
|
|
1108
|
+
const requestedRange = ctx.get("range");
|
|
1109
|
+
const ifRange = ctx.get("if-range");
|
|
1110
|
+
const range = ifRange && ifRange !== etag
|
|
1111
|
+
? undefined
|
|
1112
|
+
: parseSingleByteRange(requestedRange, byteLength);
|
|
1113
|
+
if (range === "unsatisfiable") {
|
|
1114
|
+
ctx.status = 416;
|
|
1115
|
+
ctx.set("Content-Range", `bytes */${byteLength}`);
|
|
1116
|
+
return;
|
|
1082
1117
|
}
|
|
1118
|
+
const start = range?.start ?? 0;
|
|
1119
|
+
const end = range?.end ?? byteLength - 1;
|
|
1120
|
+
const responseLength = end - start + 1;
|
|
1083
1121
|
ctx.set("Content-Security-Policy", "default-src 'none'; sandbox");
|
|
1084
1122
|
ctx.set("Cross-Origin-Resource-Policy", "same-origin");
|
|
1085
1123
|
ctx.set("X-Content-Type-Options", "nosniff");
|
|
1086
|
-
ctx.set("
|
|
1124
|
+
ctx.set("Accept-Ranges", "bytes");
|
|
1125
|
+
ctx.set("Content-Disposition", contentDisposition(resource.filename));
|
|
1126
|
+
if (range) {
|
|
1127
|
+
ctx.status = 206;
|
|
1128
|
+
ctx.set("Content-Range", `bytes ${start}-${end}/${byteLength}`);
|
|
1129
|
+
}
|
|
1087
1130
|
ctx.type = resource.mediaType;
|
|
1088
|
-
ctx.length =
|
|
1131
|
+
ctx.length = responseLength;
|
|
1132
|
+
if (ctx.method === "HEAD") {
|
|
1133
|
+
ctx.status = range ? 206 : 200;
|
|
1134
|
+
return;
|
|
1135
|
+
}
|
|
1136
|
+
streamOwnsLease = true;
|
|
1137
|
+
const body = Readable.from((async function* () {
|
|
1138
|
+
let offset = start;
|
|
1139
|
+
try {
|
|
1140
|
+
while (offset <= end) {
|
|
1141
|
+
const length = Math.min(SESSION_RESOURCE_TRANSFER_CHUNK_BYTES, end - offset + 1);
|
|
1142
|
+
const result = local
|
|
1143
|
+
? await local.readResource({ sessionId, resourceId, offset, length })
|
|
1144
|
+
: await lease.call("session.resource.read", { sessionId, resourceId, offset, length }, { timeoutMs: REMOTE_RUNTIME_SESSION_TIMEOUT_MS, signal: invocation.signal });
|
|
1145
|
+
const chunk = Buffer.from(result.data, "base64");
|
|
1146
|
+
if (result.offset !== offset + chunk.byteLength || chunk.byteLength === 0) {
|
|
1147
|
+
throw runtimeProtocolError("Runtime Session resource read did not advance");
|
|
1148
|
+
}
|
|
1149
|
+
offset = result.offset;
|
|
1150
|
+
yield chunk;
|
|
1151
|
+
}
|
|
1152
|
+
if (offset !== end + 1) {
|
|
1153
|
+
throw runtimeProtocolError("Runtime Session resource length changed");
|
|
1154
|
+
}
|
|
1155
|
+
}
|
|
1156
|
+
finally {
|
|
1157
|
+
cleanup();
|
|
1158
|
+
}
|
|
1159
|
+
})());
|
|
1160
|
+
body.once("close", cleanup);
|
|
1089
1161
|
ctx.body = body;
|
|
1090
1162
|
}
|
|
1091
1163
|
catch (error) {
|
|
1092
1164
|
runtimeTargetHostError(ctx, error);
|
|
1093
1165
|
}
|
|
1094
1166
|
finally {
|
|
1095
|
-
|
|
1167
|
+
if (!streamOwnsLease) {
|
|
1168
|
+
cleanup();
|
|
1169
|
+
}
|
|
1096
1170
|
}
|
|
1097
1171
|
};
|
|
1098
1172
|
const runtimeSessionResourceDelete = async (ctx) => {
|
|
@@ -1116,6 +1190,243 @@ export function createControlRouter(opts) {
|
|
|
1116
1190
|
if (outcome.ok)
|
|
1117
1191
|
ctx.body = outcome.result;
|
|
1118
1192
|
};
|
|
1193
|
+
const runtimeSessionItemFileContent = async (ctx) => {
|
|
1194
|
+
const sessionId = ctx.params.id;
|
|
1195
|
+
const itemId = ctx.params.itemId;
|
|
1196
|
+
const partIndex = Number(ctx.params.partIndex);
|
|
1197
|
+
if (!Number.isSafeInteger(partIndex) || partIndex < 0 || partIndex > 1_024) {
|
|
1198
|
+
ctx.status = 400;
|
|
1199
|
+
ctx.body = { error: "invalid_part_index" };
|
|
1200
|
+
return;
|
|
1201
|
+
}
|
|
1202
|
+
const local = ctx.params.selector === "local" ? localMachineSessions : undefined;
|
|
1203
|
+
const invocation = downloadInvocationAbortScope(ctx, shutdownSignal);
|
|
1204
|
+
const lease = local ? undefined : await acquireRuntimeLease(ctx, invocation.signal);
|
|
1205
|
+
if (!local && !lease) {
|
|
1206
|
+
invocation.dispose();
|
|
1207
|
+
return;
|
|
1208
|
+
}
|
|
1209
|
+
let streamOwnsLease = false;
|
|
1210
|
+
let cleanedUp = false;
|
|
1211
|
+
const cleanup = () => {
|
|
1212
|
+
if (cleanedUp)
|
|
1213
|
+
return;
|
|
1214
|
+
cleanedUp = true;
|
|
1215
|
+
lease?.release();
|
|
1216
|
+
invocation.dispose();
|
|
1217
|
+
};
|
|
1218
|
+
try {
|
|
1219
|
+
const { file } = local
|
|
1220
|
+
? await local.getFile({ sessionId, itemId, partIndex })
|
|
1221
|
+
: await lease.call("session.file.get", { sessionId, itemId, partIndex }, { timeoutMs: REMOTE_RUNTIME_SESSION_TIMEOUT_MS, signal: invocation.signal });
|
|
1222
|
+
if (file.itemId !== itemId || file.partIndex !== partIndex) {
|
|
1223
|
+
throw runtimeProtocolError("Runtime Session file identity changed");
|
|
1224
|
+
}
|
|
1225
|
+
const etag = `"file-${file.version}"`;
|
|
1226
|
+
ctx.set("Cache-Control", "private, max-age=0, must-revalidate");
|
|
1227
|
+
ctx.set("ETag", etag);
|
|
1228
|
+
if (ctx.get("if-none-match").split(",").map((value) => value.trim()).includes(etag)) {
|
|
1229
|
+
ctx.status = 304;
|
|
1230
|
+
return;
|
|
1231
|
+
}
|
|
1232
|
+
const requestedRange = ctx.get("range");
|
|
1233
|
+
const ifRange = ctx.get("if-range");
|
|
1234
|
+
const range = ifRange && ifRange !== etag
|
|
1235
|
+
? undefined
|
|
1236
|
+
: parseSingleByteRange(requestedRange, file.byteLength);
|
|
1237
|
+
if (range === "unsatisfiable") {
|
|
1238
|
+
ctx.status = 416;
|
|
1239
|
+
ctx.set("Content-Range", `bytes */${file.byteLength}`);
|
|
1240
|
+
return;
|
|
1241
|
+
}
|
|
1242
|
+
const start = range?.start ?? 0;
|
|
1243
|
+
const end = range?.end ?? file.byteLength - 1;
|
|
1244
|
+
ctx.set("Content-Security-Policy", "default-src 'none'; sandbox");
|
|
1245
|
+
ctx.set("Cross-Origin-Resource-Policy", "same-origin");
|
|
1246
|
+
ctx.set("X-Content-Type-Options", "nosniff");
|
|
1247
|
+
ctx.set("Accept-Ranges", "bytes");
|
|
1248
|
+
ctx.set("Content-Disposition", contentDisposition(file.filename));
|
|
1249
|
+
if (range) {
|
|
1250
|
+
ctx.status = 206;
|
|
1251
|
+
ctx.set("Content-Range", `bytes ${start}-${end}/${file.byteLength}`);
|
|
1252
|
+
}
|
|
1253
|
+
ctx.type = file.mediaType;
|
|
1254
|
+
ctx.length = end - start + 1;
|
|
1255
|
+
if (ctx.method === "HEAD") {
|
|
1256
|
+
ctx.status = range ? 206 : 200;
|
|
1257
|
+
return;
|
|
1258
|
+
}
|
|
1259
|
+
streamOwnsLease = true;
|
|
1260
|
+
const body = Readable.from((async function* () {
|
|
1261
|
+
let offset = start;
|
|
1262
|
+
try {
|
|
1263
|
+
while (offset <= end) {
|
|
1264
|
+
const length = Math.min(SESSION_RESOURCE_TRANSFER_CHUNK_BYTES, end - offset + 1);
|
|
1265
|
+
const result = local
|
|
1266
|
+
? await local.readFile({
|
|
1267
|
+
sessionId,
|
|
1268
|
+
itemId,
|
|
1269
|
+
partIndex,
|
|
1270
|
+
version: file.version,
|
|
1271
|
+
offset,
|
|
1272
|
+
length,
|
|
1273
|
+
})
|
|
1274
|
+
: await lease.call("session.file.read", {
|
|
1275
|
+
sessionId,
|
|
1276
|
+
itemId,
|
|
1277
|
+
partIndex,
|
|
1278
|
+
version: file.version,
|
|
1279
|
+
offset,
|
|
1280
|
+
length,
|
|
1281
|
+
}, { timeoutMs: REMOTE_RUNTIME_SESSION_TIMEOUT_MS, signal: invocation.signal });
|
|
1282
|
+
const chunk = Buffer.from(result.data, "base64");
|
|
1283
|
+
if (result.offset !== offset + chunk.byteLength || chunk.byteLength === 0) {
|
|
1284
|
+
throw runtimeProtocolError("Runtime Session file read did not advance");
|
|
1285
|
+
}
|
|
1286
|
+
offset = result.offset;
|
|
1287
|
+
yield chunk;
|
|
1288
|
+
}
|
|
1289
|
+
}
|
|
1290
|
+
finally {
|
|
1291
|
+
cleanup();
|
|
1292
|
+
}
|
|
1293
|
+
})());
|
|
1294
|
+
body.once("close", cleanup);
|
|
1295
|
+
ctx.body = body;
|
|
1296
|
+
}
|
|
1297
|
+
catch (error) {
|
|
1298
|
+
runtimeTargetHostError(ctx, error);
|
|
1299
|
+
}
|
|
1300
|
+
finally {
|
|
1301
|
+
if (!streamOwnsLease) {
|
|
1302
|
+
cleanup();
|
|
1303
|
+
}
|
|
1304
|
+
}
|
|
1305
|
+
};
|
|
1306
|
+
const runtimeSessionWorkspaceFileContent = async (ctx) => {
|
|
1307
|
+
const sessionId = ctx.params.id;
|
|
1308
|
+
const path = ctx.query.path;
|
|
1309
|
+
if (typeof path !== "string" ||
|
|
1310
|
+
path.length === 0 ||
|
|
1311
|
+
path.length > 4_096 ||
|
|
1312
|
+
path.includes("\0")) {
|
|
1313
|
+
ctx.status = 400;
|
|
1314
|
+
ctx.body = { error: "invalid_workspace_file_path" };
|
|
1315
|
+
return;
|
|
1316
|
+
}
|
|
1317
|
+
const local = ctx.params.selector === "local" ? localMachineSessions : undefined;
|
|
1318
|
+
const invocation = downloadInvocationAbortScope(ctx, shutdownSignal);
|
|
1319
|
+
const lease = local ? undefined : await acquireRuntimeLease(ctx, invocation.signal);
|
|
1320
|
+
if (!local && !lease) {
|
|
1321
|
+
invocation.dispose();
|
|
1322
|
+
return;
|
|
1323
|
+
}
|
|
1324
|
+
let streamOwnsLease = false;
|
|
1325
|
+
let cleanedUp = false;
|
|
1326
|
+
const cleanup = () => {
|
|
1327
|
+
if (cleanedUp)
|
|
1328
|
+
return;
|
|
1329
|
+
cleanedUp = true;
|
|
1330
|
+
lease?.release();
|
|
1331
|
+
invocation.dispose();
|
|
1332
|
+
};
|
|
1333
|
+
try {
|
|
1334
|
+
const { file } = local
|
|
1335
|
+
? await local.getWorkspaceFile({ sessionId, path })
|
|
1336
|
+
: await lease.call("session.workspace.file.get", { sessionId, path }, { timeoutMs: REMOTE_RUNTIME_SESSION_TIMEOUT_MS, signal: invocation.signal });
|
|
1337
|
+
if (file.path !== path) {
|
|
1338
|
+
throw runtimeProtocolError("Runtime Session workspace file identity changed");
|
|
1339
|
+
}
|
|
1340
|
+
const etag = `"workspace-file-${file.version}"`;
|
|
1341
|
+
ctx.set("Cache-Control", "private, max-age=0, must-revalidate");
|
|
1342
|
+
ctx.set("ETag", etag);
|
|
1343
|
+
if (ctx.get("if-none-match").split(",").map((value) => value.trim()).includes(etag)) {
|
|
1344
|
+
ctx.status = 304;
|
|
1345
|
+
return;
|
|
1346
|
+
}
|
|
1347
|
+
ctx.set("Content-Security-Policy", "default-src 'none'; sandbox");
|
|
1348
|
+
ctx.set("Cross-Origin-Resource-Policy", "same-origin");
|
|
1349
|
+
ctx.set("X-Content-Type-Options", "nosniff");
|
|
1350
|
+
ctx.set("Accept-Ranges", "bytes");
|
|
1351
|
+
ctx.set("Content-Disposition", contentDisposition(file.filename));
|
|
1352
|
+
ctx.type = file.mediaType;
|
|
1353
|
+
if (file.byteLength === 0) {
|
|
1354
|
+
if (ctx.get("range")) {
|
|
1355
|
+
ctx.status = 416;
|
|
1356
|
+
ctx.set("Content-Range", "bytes */0");
|
|
1357
|
+
return;
|
|
1358
|
+
}
|
|
1359
|
+
ctx.status = 200;
|
|
1360
|
+
ctx.length = 0;
|
|
1361
|
+
if (ctx.method !== "HEAD")
|
|
1362
|
+
ctx.body = Buffer.alloc(0);
|
|
1363
|
+
return;
|
|
1364
|
+
}
|
|
1365
|
+
const requestedRange = ctx.get("range");
|
|
1366
|
+
const ifRange = ctx.get("if-range");
|
|
1367
|
+
const range = ifRange && ifRange !== etag
|
|
1368
|
+
? undefined
|
|
1369
|
+
: parseSingleByteRange(requestedRange, file.byteLength);
|
|
1370
|
+
if (range === "unsatisfiable") {
|
|
1371
|
+
ctx.status = 416;
|
|
1372
|
+
ctx.set("Content-Range", `bytes */${file.byteLength}`);
|
|
1373
|
+
return;
|
|
1374
|
+
}
|
|
1375
|
+
const start = range?.start ?? 0;
|
|
1376
|
+
const end = range?.end ?? file.byteLength - 1;
|
|
1377
|
+
if (range) {
|
|
1378
|
+
ctx.status = 206;
|
|
1379
|
+
ctx.set("Content-Range", `bytes ${start}-${end}/${file.byteLength}`);
|
|
1380
|
+
}
|
|
1381
|
+
ctx.length = end - start + 1;
|
|
1382
|
+
if (ctx.method === "HEAD") {
|
|
1383
|
+
ctx.status = range ? 206 : 200;
|
|
1384
|
+
return;
|
|
1385
|
+
}
|
|
1386
|
+
streamOwnsLease = true;
|
|
1387
|
+
const body = Readable.from((async function* () {
|
|
1388
|
+
let offset = start;
|
|
1389
|
+
try {
|
|
1390
|
+
while (offset <= end) {
|
|
1391
|
+
const length = Math.min(SESSION_RESOURCE_TRANSFER_CHUNK_BYTES, end - offset + 1);
|
|
1392
|
+
const result = local
|
|
1393
|
+
? await local.readWorkspaceFile({
|
|
1394
|
+
sessionId,
|
|
1395
|
+
path,
|
|
1396
|
+
version: file.version,
|
|
1397
|
+
offset,
|
|
1398
|
+
length,
|
|
1399
|
+
})
|
|
1400
|
+
: await lease.call("session.workspace.file.read", {
|
|
1401
|
+
sessionId,
|
|
1402
|
+
path,
|
|
1403
|
+
version: file.version,
|
|
1404
|
+
offset,
|
|
1405
|
+
length,
|
|
1406
|
+
}, { timeoutMs: REMOTE_RUNTIME_SESSION_TIMEOUT_MS, signal: invocation.signal });
|
|
1407
|
+
const chunk = Buffer.from(result.data, "base64");
|
|
1408
|
+
if (result.offset !== offset + chunk.byteLength || chunk.byteLength === 0) {
|
|
1409
|
+
throw runtimeProtocolError("Runtime Session workspace file read did not advance");
|
|
1410
|
+
}
|
|
1411
|
+
offset = result.offset;
|
|
1412
|
+
yield chunk;
|
|
1413
|
+
}
|
|
1414
|
+
}
|
|
1415
|
+
finally {
|
|
1416
|
+
cleanup();
|
|
1417
|
+
}
|
|
1418
|
+
})());
|
|
1419
|
+
body.once("close", cleanup);
|
|
1420
|
+
ctx.body = body;
|
|
1421
|
+
}
|
|
1422
|
+
catch (error) {
|
|
1423
|
+
runtimeTargetHostError(ctx, error);
|
|
1424
|
+
}
|
|
1425
|
+
finally {
|
|
1426
|
+
if (!streamOwnsLease)
|
|
1427
|
+
cleanup();
|
|
1428
|
+
}
|
|
1429
|
+
};
|
|
1119
1430
|
const runtimeSessionMessageEnqueue = async (ctx) => {
|
|
1120
1431
|
const body = await readRuntimeBody(ctx);
|
|
1121
1432
|
if (!body)
|
|
@@ -1747,6 +2058,11 @@ export function createControlRouter(opts) {
|
|
|
1747
2058
|
router.post("/api/runtimes/:selector/sessions/:id/resources", publicRuntimeMutation(runtimeSessionResourceUpload));
|
|
1748
2059
|
router.get("/api/runtimes/:selector/sessions/:id/resources/:resourceId", publicRuntimeRead(runtimeSessionResourceMetadata));
|
|
1749
2060
|
router.get("/api/runtimes/:selector/sessions/:id/resources/:resourceId/content", publicRuntimeRead(runtimeSessionResourceContent));
|
|
2061
|
+
router.head("/api/runtimes/:selector/sessions/:id/resources/:resourceId/content", publicRuntimeRead(runtimeSessionResourceContent));
|
|
2062
|
+
router.get("/api/runtimes/:selector/sessions/:id/items/:itemId/files/:partIndex/content", publicRuntimeRead(runtimeSessionItemFileContent));
|
|
2063
|
+
router.head("/api/runtimes/:selector/sessions/:id/items/:itemId/files/:partIndex/content", publicRuntimeRead(runtimeSessionItemFileContent));
|
|
2064
|
+
router.get("/api/runtimes/:selector/sessions/:id/workspace/files/content", publicRuntimeRead(runtimeSessionWorkspaceFileContent));
|
|
2065
|
+
router.head("/api/runtimes/:selector/sessions/:id/workspace/files/content", publicRuntimeRead(runtimeSessionWorkspaceFileContent));
|
|
1750
2066
|
router.delete("/api/runtimes/:selector/sessions/:id/resources/:resourceId", publicRuntimeMutation(runtimeSessionResourceDelete));
|
|
1751
2067
|
router.post("/api/runtimes/:selector/sessions/:id/messages/queue", publicRuntimeMutation(runtimeSessionMessageEnqueue));
|
|
1752
2068
|
router.post("/api/runtimes/:selector/sessions/:id/terminal/start", publicRuntimeMutation(runtimeSessionTerminalStart));
|
|
@@ -3706,6 +4022,36 @@ function pluginInstallInvocationAbortScope(ctx, shutdownSignal) {
|
|
|
3706
4022
|
function browserArtifactInvocationAbortScope(ctx, shutdownSignal) {
|
|
3707
4023
|
return managementInvocationAbortScope(ctx, shutdownSignal, BROWSER_ARTIFACT_OPERATION_TIMEOUT_MS, "Browser artifact operation");
|
|
3708
4024
|
}
|
|
4025
|
+
function downloadInvocationAbortScope(ctx, shutdownSignal) {
|
|
4026
|
+
const controller = new AbortController();
|
|
4027
|
+
const abort = (reason) => {
|
|
4028
|
+
if (!controller.signal.aborted)
|
|
4029
|
+
controller.abort(reason);
|
|
4030
|
+
};
|
|
4031
|
+
const onRequestAborted = () => abort(namedError("download request aborted", "AbortError"));
|
|
4032
|
+
const onResponseClose = () => {
|
|
4033
|
+
if (!ctx.res.writableEnded) {
|
|
4034
|
+
abort(namedError("download client disconnected", "AbortError"));
|
|
4035
|
+
}
|
|
4036
|
+
};
|
|
4037
|
+
const onShutdown = () => abort(shutdownSignal?.reason ?? namedError("daemon is shutting down", "AbortError"));
|
|
4038
|
+
ctx.req.once("aborted", onRequestAborted);
|
|
4039
|
+
ctx.res.once("close", onResponseClose);
|
|
4040
|
+
if (shutdownSignal?.aborted)
|
|
4041
|
+
onShutdown();
|
|
4042
|
+
else
|
|
4043
|
+
shutdownSignal?.addEventListener("abort", onShutdown, { once: true });
|
|
4044
|
+
if (ctx.req.aborted)
|
|
4045
|
+
onRequestAborted();
|
|
4046
|
+
return {
|
|
4047
|
+
signal: controller.signal,
|
|
4048
|
+
dispose() {
|
|
4049
|
+
ctx.req.removeListener("aborted", onRequestAborted);
|
|
4050
|
+
ctx.res.removeListener("close", onResponseClose);
|
|
4051
|
+
shutdownSignal?.removeEventListener("abort", onShutdown);
|
|
4052
|
+
},
|
|
4053
|
+
};
|
|
4054
|
+
}
|
|
3709
4055
|
function managementInvocationAbortScope(ctx, shutdownSignal, timeoutMs, label) {
|
|
3710
4056
|
const controller = new AbortController();
|
|
3711
4057
|
const abort = (reason) => {
|
|
@@ -4021,6 +4367,83 @@ function publicRuntimeStreamError(error) {
|
|
|
4021
4367
|
}
|
|
4022
4368
|
class RequestBodyTooLargeError extends Error {
|
|
4023
4369
|
}
|
|
4370
|
+
function isMediaType(value) {
|
|
4371
|
+
return value.length <= 255 && /^[a-z0-9!#$&^_.+-]+\/[a-z0-9!#$&^_.+-]+$/.test(value);
|
|
4372
|
+
}
|
|
4373
|
+
async function forwardResourceUploadBody(ctx, uploadId, resumeOffset, expectedBytes, writeChunk) {
|
|
4374
|
+
let received = 0;
|
|
4375
|
+
let remoteOffset = resumeOffset;
|
|
4376
|
+
let carry = Buffer.alloc(0);
|
|
4377
|
+
for await (const raw of ctx.req) {
|
|
4378
|
+
const incoming = Buffer.isBuffer(raw) ? raw : Buffer.from(raw);
|
|
4379
|
+
if (received + incoming.byteLength > expectedBytes) {
|
|
4380
|
+
throw runtimeProtocolError("Resource upload exceeds Content-Length");
|
|
4381
|
+
}
|
|
4382
|
+
const skip = Math.min(incoming.byteLength, Math.max(0, resumeOffset - received));
|
|
4383
|
+
received += incoming.byteLength;
|
|
4384
|
+
let cursor = skip;
|
|
4385
|
+
while (cursor < incoming.byteLength) {
|
|
4386
|
+
const needed = SESSION_RESOURCE_TRANSFER_CHUNK_BYTES - carry.byteLength;
|
|
4387
|
+
const take = Math.min(needed, incoming.byteLength - cursor);
|
|
4388
|
+
carry = carry.byteLength === 0
|
|
4389
|
+
? incoming.subarray(cursor, cursor + take)
|
|
4390
|
+
: Buffer.concat([carry, incoming.subarray(cursor, cursor + take)]);
|
|
4391
|
+
cursor += take;
|
|
4392
|
+
if (carry.byteLength < SESSION_RESOURCE_TRANSFER_CHUNK_BYTES)
|
|
4393
|
+
continue;
|
|
4394
|
+
const written = await writeChunk(uploadId, remoteOffset, carry.toString("base64"));
|
|
4395
|
+
if (written.offset !== remoteOffset + carry.byteLength) {
|
|
4396
|
+
throw runtimeProtocolError("Runtime Session resource upload did not advance");
|
|
4397
|
+
}
|
|
4398
|
+
remoteOffset = written.offset;
|
|
4399
|
+
carry = Buffer.alloc(0);
|
|
4400
|
+
}
|
|
4401
|
+
}
|
|
4402
|
+
if (received !== expectedBytes) {
|
|
4403
|
+
throw runtimeProtocolError("Resource upload ended before Content-Length");
|
|
4404
|
+
}
|
|
4405
|
+
if (carry.byteLength > 0) {
|
|
4406
|
+
const written = await writeChunk(uploadId, remoteOffset, carry.toString("base64"));
|
|
4407
|
+
if (written.offset !== remoteOffset + carry.byteLength) {
|
|
4408
|
+
throw runtimeProtocolError("Runtime Session resource upload did not advance");
|
|
4409
|
+
}
|
|
4410
|
+
remoteOffset = written.offset;
|
|
4411
|
+
}
|
|
4412
|
+
if (remoteOffset !== expectedBytes) {
|
|
4413
|
+
throw runtimeProtocolError("Runtime Session resource upload length changed");
|
|
4414
|
+
}
|
|
4415
|
+
}
|
|
4416
|
+
function parseSingleByteRange(header, byteLength) {
|
|
4417
|
+
if (!header)
|
|
4418
|
+
return undefined;
|
|
4419
|
+
const match = /^bytes=(\d*)-(\d*)$/.exec(header.trim());
|
|
4420
|
+
if (!match || byteLength <= 0)
|
|
4421
|
+
return "unsatisfiable";
|
|
4422
|
+
const [, startText, endText] = match;
|
|
4423
|
+
if (!startText && !endText)
|
|
4424
|
+
return "unsatisfiable";
|
|
4425
|
+
if (!startText) {
|
|
4426
|
+
const suffix = Number(endText);
|
|
4427
|
+
if (!Number.isSafeInteger(suffix) || suffix <= 0)
|
|
4428
|
+
return "unsatisfiable";
|
|
4429
|
+
return { start: Math.max(0, byteLength - suffix), end: byteLength - 1 };
|
|
4430
|
+
}
|
|
4431
|
+
const start = Number(startText);
|
|
4432
|
+
const requestedEnd = endText ? Number(endText) : byteLength - 1;
|
|
4433
|
+
if (!Number.isSafeInteger(start) ||
|
|
4434
|
+
!Number.isSafeInteger(requestedEnd) ||
|
|
4435
|
+
start < 0 ||
|
|
4436
|
+
requestedEnd < start ||
|
|
4437
|
+
start >= byteLength) {
|
|
4438
|
+
return "unsatisfiable";
|
|
4439
|
+
}
|
|
4440
|
+
return { start, end: Math.min(requestedEnd, byteLength - 1) };
|
|
4441
|
+
}
|
|
4442
|
+
function contentDisposition(filename) {
|
|
4443
|
+
if (!filename)
|
|
4444
|
+
return "inline";
|
|
4445
|
+
return `inline; filename*=UTF-8''${encodeURIComponent(filename)}`;
|
|
4446
|
+
}
|
|
4024
4447
|
async function readBoundedBinary(ctx, maxBytes) {
|
|
4025
4448
|
const declaredLength = Number(ctx.get("content-length"));
|
|
4026
4449
|
if (Number.isFinite(declaredLength) && declaredLength > maxBytes) {
|