minionsai 0.1.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/LICENSE +21 -0
- package/README.md +89 -0
- package/bin/minions.mjs +19 -0
- package/dist/server/client/dist/assets/abap-BdImnpbu.js +1 -0
- package/dist/server/client/dist/assets/actionscript-3-CoDkCxhg.js +1 -0
- package/dist/server/client/dist/assets/ada-bCR0ucgS.js +1 -0
- package/dist/server/client/dist/assets/andromeeda-C4gqWexZ.js +1 -0
- package/dist/server/client/dist/assets/angular-html-CU67Zn6k.js +1 -0
- package/dist/server/client/dist/assets/angular-ts-BwZT4LLn.js +1 -0
- package/dist/server/client/dist/assets/apache-Pmp26Uib.js +1 -0
- package/dist/server/client/dist/assets/apex-D8_7TLub.js +1 -0
- package/dist/server/client/dist/assets/apl-dKokRX4l.js +1 -0
- package/dist/server/client/dist/assets/applescript-Co6uUVPk.js +1 -0
- package/dist/server/client/dist/assets/ara-BRHolxvo.js +1 -0
- package/dist/server/client/dist/assets/asciidoc-Ve4PFQV2.js +1 -0
- package/dist/server/client/dist/assets/asm-D_Q5rh1f.js +1 -0
- package/dist/server/client/dist/assets/astro-CbQHKStN.js +1 -0
- package/dist/server/client/dist/assets/aurora-x-D-2ljcwZ.js +1 -0
- package/dist/server/client/dist/assets/awk-DMzUqQB5.js +1 -0
- package/dist/server/client/dist/assets/ayu-dark-DYE7WIF3.js +1 -0
- package/dist/server/client/dist/assets/ayu-light-BA47KaF1.js +1 -0
- package/dist/server/client/dist/assets/ayu-mirage-32ctXXKs.js +1 -0
- package/dist/server/client/dist/assets/ballerina-BFfxhgS-.js +1 -0
- package/dist/server/client/dist/assets/bat-BkioyH1T.js +1 -0
- package/dist/server/client/dist/assets/beancount-k_qm7-4y.js +1 -0
- package/dist/server/client/dist/assets/berry-uYugtg8r.js +1 -0
- package/dist/server/client/dist/assets/bibtex-CHM0blh-.js +1 -0
- package/dist/server/client/dist/assets/bicep-Bmn6On1c.js +1 -0
- package/dist/server/client/dist/assets/bird2-DPOp833l.js +1 -0
- package/dist/server/client/dist/assets/blade-D4QpJJKB.js +1 -0
- package/dist/server/client/dist/assets/bsl-BO_Y6i37.js +1 -0
- package/dist/server/client/dist/assets/c-BIGW1oBm.js +1 -0
- package/dist/server/client/dist/assets/c3-eo99z4R2.js +1 -0
- package/dist/server/client/dist/assets/cadence-Bv_4Rxtq.js +1 -0
- package/dist/server/client/dist/assets/cairo-KRGpt6FW.js +1 -0
- package/dist/server/client/dist/assets/catppuccin-frappe-DFWUc33u.js +1 -0
- package/dist/server/client/dist/assets/catppuccin-latte-C9dUb6Cb.js +1 -0
- package/dist/server/client/dist/assets/catppuccin-macchiato-DQyhUUbL.js +1 -0
- package/dist/server/client/dist/assets/catppuccin-mocha-D87Tk5Gz.js +1 -0
- package/dist/server/client/dist/assets/clarity-D53aC0YG.js +1 -0
- package/dist/server/client/dist/assets/clojure-P80f7IUj.js +1 -0
- package/dist/server/client/dist/assets/cmake-D1j8_8rp.js +1 -0
- package/dist/server/client/dist/assets/cobol-nwyudZeR.js +1 -0
- package/dist/server/client/dist/assets/codeowners-Bp6g37R7.js +1 -0
- package/dist/server/client/dist/assets/codeql-DsOJ9woJ.js +1 -0
- package/dist/server/client/dist/assets/coffee-Ch7k5sss.js +1 -0
- package/dist/server/client/dist/assets/common-lisp-Cg-RD9OK.js +1 -0
- package/dist/server/client/dist/assets/coq-DkFqJrB1.js +1 -0
- package/dist/server/client/dist/assets/cpp-CofmeUqb.js +1 -0
- package/dist/server/client/dist/assets/crystal-tKQVLTB8.js +1 -0
- package/dist/server/client/dist/assets/csharp-COcwbKMJ.js +1 -0
- package/dist/server/client/dist/assets/css-DPfMkruS.js +1 -0
- package/dist/server/client/dist/assets/csv-fuZLfV_i.js +1 -0
- package/dist/server/client/dist/assets/cue-D82EKSYY.js +1 -0
- package/dist/server/client/dist/assets/cypher-COkxafJQ.js +1 -0
- package/dist/server/client/dist/assets/d-85-TOEBH.js +1 -0
- package/dist/server/client/dist/assets/dark-plus-C3mMm8J8.js +1 -0
- package/dist/server/client/dist/assets/dart-CF10PKvl.js +1 -0
- package/dist/server/client/dist/assets/dax-CEL-wOlO.js +1 -0
- package/dist/server/client/dist/assets/desktop-BmXAJ9_W.js +1 -0
- package/dist/server/client/dist/assets/diff-D97Zzqfu.js +1 -0
- package/dist/server/client/dist/assets/docker-BcOcwvcX.js +1 -0
- package/dist/server/client/dist/assets/dotenv-Da5cRb03.js +1 -0
- package/dist/server/client/dist/assets/dracula-BzJJZx-M.js +1 -0
- package/dist/server/client/dist/assets/dracula-soft-BXkSAIEj.js +1 -0
- package/dist/server/client/dist/assets/dream-maker-BtqSS_iP.js +1 -0
- package/dist/server/client/dist/assets/edge-BkV0erSs.js +1 -0
- package/dist/server/client/dist/assets/elixir-CDX3lj18.js +1 -0
- package/dist/server/client/dist/assets/elm-DbKCFpqz.js +1 -0
- package/dist/server/client/dist/assets/emacs-lisp-C9XAeP06.js +1 -0
- package/dist/server/client/dist/assets/erb-B12qg9BL.js +1 -0
- package/dist/server/client/dist/assets/erlang-DsQrWhSR.js +1 -0
- package/dist/server/client/dist/assets/everforest-dark-BgDCqdQA.js +1 -0
- package/dist/server/client/dist/assets/everforest-light-C8M2exoo.js +1 -0
- package/dist/server/client/dist/assets/fennel-BYunw83y.js +1 -0
- package/dist/server/client/dist/assets/fish-BvzEVeQv.js +1 -0
- package/dist/server/client/dist/assets/fluent-C4IJs8-o.js +1 -0
- package/dist/server/client/dist/assets/fortran-fixed-form-CkoXwp7k.js +1 -0
- package/dist/server/client/dist/assets/fortran-free-form-BxgE0vQu.js +1 -0
- package/dist/server/client/dist/assets/fsharp-CXgrBDvD.js +1 -0
- package/dist/server/client/dist/assets/gdresource-BOOCDP_w.js +1 -0
- package/dist/server/client/dist/assets/gdscript-C5YyOfLZ.js +1 -0
- package/dist/server/client/dist/assets/gdshader-DkwncUOv.js +1 -0
- package/dist/server/client/dist/assets/genie-D0YGMca9.js +1 -0
- package/dist/server/client/dist/assets/gherkin-DyxjwDmM.js +1 -0
- package/dist/server/client/dist/assets/git-commit-F4YmCXRG.js +1 -0
- package/dist/server/client/dist/assets/git-rebase-r7XF79zn.js +1 -0
- package/dist/server/client/dist/assets/github-dark-DHJKELXO.js +1 -0
- package/dist/server/client/dist/assets/github-dark-default-Cuk6v7N8.js +1 -0
- package/dist/server/client/dist/assets/github-dark-dimmed-DH5Ifo-i.js +1 -0
- package/dist/server/client/dist/assets/github-dark-high-contrast-E3gJ1_iC.js +1 -0
- package/dist/server/client/dist/assets/github-light-DAi9KRSo.js +1 -0
- package/dist/server/client/dist/assets/github-light-default-D7oLnXFd.js +1 -0
- package/dist/server/client/dist/assets/github-light-high-contrast-BfjtVDDH.js +1 -0
- package/dist/server/client/dist/assets/gleam-BspZqrRM.js +1 -0
- package/dist/server/client/dist/assets/glimmer-js-Rg0-pVw9.js +1 -0
- package/dist/server/client/dist/assets/glimmer-ts-U6CK756n.js +1 -0
- package/dist/server/client/dist/assets/glsl-DplSGwfg.js +1 -0
- package/dist/server/client/dist/assets/gn-n2N0HUVH.js +1 -0
- package/dist/server/client/dist/assets/gnuplot-DdkO51Og.js +1 -0
- package/dist/server/client/dist/assets/go-CxLEBnE3.js +1 -0
- package/dist/server/client/dist/assets/graphql-ChdNCCLP.js +1 -0
- package/dist/server/client/dist/assets/groovy-gcz8RCvz.js +1 -0
- package/dist/server/client/dist/assets/gruvbox-dark-hard-CFHQjOhq.js +1 -0
- package/dist/server/client/dist/assets/gruvbox-dark-medium-GsRaNv29.js +1 -0
- package/dist/server/client/dist/assets/gruvbox-dark-soft-CVdnzihN.js +1 -0
- package/dist/server/client/dist/assets/gruvbox-light-hard-CH1njM8p.js +1 -0
- package/dist/server/client/dist/assets/gruvbox-light-medium-DRw_LuNl.js +1 -0
- package/dist/server/client/dist/assets/gruvbox-light-soft-hJgmCMqR.js +1 -0
- package/dist/server/client/dist/assets/hack-CaT9iCJl.js +1 -0
- package/dist/server/client/dist/assets/haml-B8DHNrY2.js +1 -0
- package/dist/server/client/dist/assets/handlebars-BL8al0AC.js +1 -0
- package/dist/server/client/dist/assets/haskell-Df6bDoY_.js +1 -0
- package/dist/server/client/dist/assets/haxe-CzTSHFRz.js +1 -0
- package/dist/server/client/dist/assets/hcl-BWvSN4gD.js +1 -0
- package/dist/server/client/dist/assets/highlighted-body-TPN3WLV5-Dmyr2DoJ.js +1 -0
- package/dist/server/client/dist/assets/hjson-D5-asLiD.js +1 -0
- package/dist/server/client/dist/assets/hlsl-D3lLCCz7.js +1 -0
- package/dist/server/client/dist/assets/horizon-BUw7H-hv.js +1 -0
- package/dist/server/client/dist/assets/horizon-bright-Cn-bp-IR.js +1 -0
- package/dist/server/client/dist/assets/houston-DnULxvSX.js +1 -0
- package/dist/server/client/dist/assets/html-GMplVEZG.js +1 -0
- package/dist/server/client/dist/assets/html-derivative-BFtXZ54Q.js +1 -0
- package/dist/server/client/dist/assets/http-jrhK8wxY.js +1 -0
- package/dist/server/client/dist/assets/hurl-irOxFIW8.js +1 -0
- package/dist/server/client/dist/assets/hxml-Bvhsp5Yf.js +1 -0
- package/dist/server/client/dist/assets/hy-DFXneXwc.js +1 -0
- package/dist/server/client/dist/assets/imba-DGztddWO.js +1 -0
- package/dist/server/client/dist/assets/index-BB7507W7.css +1 -0
- package/dist/server/client/dist/assets/index-hLQDnL9J.js +694 -0
- package/dist/server/client/dist/assets/ini-BEwlwnbL.js +1 -0
- package/dist/server/client/dist/assets/java-CylS5w8V.js +1 -0
- package/dist/server/client/dist/assets/javascript-wDzz0qaB.js +1 -0
- package/dist/server/client/dist/assets/jinja-4LBKfQ-Z.js +1 -0
- package/dist/server/client/dist/assets/jison-wvAkD_A8.js +1 -0
- package/dist/server/client/dist/assets/json-Cp-IABpG.js +1 -0
- package/dist/server/client/dist/assets/json5-C9tS-k6U.js +1 -0
- package/dist/server/client/dist/assets/jsonc-Des-eS-w.js +1 -0
- package/dist/server/client/dist/assets/jsonl-DcaNXYhu.js +1 -0
- package/dist/server/client/dist/assets/jsonnet-DFQXde-d.js +1 -0
- package/dist/server/client/dist/assets/jssm-C2t-YnRu.js +1 -0
- package/dist/server/client/dist/assets/jsx-g9-lgVsj.js +1 -0
- package/dist/server/client/dist/assets/julia-CxzCAyBv.js +1 -0
- package/dist/server/client/dist/assets/just-Cw27pwNe.js +1 -0
- package/dist/server/client/dist/assets/kanagawa-dragon-CkXjmgJE.js +1 -0
- package/dist/server/client/dist/assets/kanagawa-lotus-CfQXZHmo.js +1 -0
- package/dist/server/client/dist/assets/kanagawa-wave-DWedfzmr.js +1 -0
- package/dist/server/client/dist/assets/kdl-DV7GczEv.js +1 -0
- package/dist/server/client/dist/assets/kotlin-BdnUsdx6.js +1 -0
- package/dist/server/client/dist/assets/kusto-DZf3V79B.js +1 -0
- package/dist/server/client/dist/assets/laserwave-DUszq2jm.js +1 -0
- package/dist/server/client/dist/assets/latex-CWtU0Tv5.js +1 -0
- package/dist/server/client/dist/assets/lean-BZvkOJ9d.js +1 -0
- package/dist/server/client/dist/assets/less-B1dDrJ26.js +1 -0
- package/dist/server/client/dist/assets/light-plus-B7mTdjB0.js +1 -0
- package/dist/server/client/dist/assets/liquid-DYVedYrR.js +1 -0
- package/dist/server/client/dist/assets/llvm-DjAJT7YJ.js +1 -0
- package/dist/server/client/dist/assets/log-2UxHyX5q.js +1 -0
- package/dist/server/client/dist/assets/logo-BtOb2qkB.js +1 -0
- package/dist/server/client/dist/assets/lua-BaeVxFsk.js +1 -0
- package/dist/server/client/dist/assets/luau-C-HG3fhB.js +1 -0
- package/dist/server/client/dist/assets/make-CHLpvVh8.js +1 -0
- package/dist/server/client/dist/assets/markdown-Cvjx9yec.js +1 -0
- package/dist/server/client/dist/assets/marko-CnJfTvn9.js +1 -0
- package/dist/server/client/dist/assets/material-theme-D5KoaKCx.js +1 -0
- package/dist/server/client/dist/assets/material-theme-darker-BfHTSMKl.js +1 -0
- package/dist/server/client/dist/assets/material-theme-lighter-B0m2ddpp.js +1 -0
- package/dist/server/client/dist/assets/material-theme-ocean-CyktbL80.js +1 -0
- package/dist/server/client/dist/assets/material-theme-palenight-Csfq5Kiy.js +1 -0
- package/dist/server/client/dist/assets/matlab-D7o27uSR.js +1 -0
- package/dist/server/client/dist/assets/mdc-BMNejdWA.js +1 -0
- package/dist/server/client/dist/assets/mdx-Cmh6b_Ma.js +1 -0
- package/dist/server/client/dist/assets/mermaid-mWjccvbQ.js +1 -0
- package/dist/server/client/dist/assets/min-dark-CafNBF8u.js +1 -0
- package/dist/server/client/dist/assets/min-light-CTRr51gU.js +1 -0
- package/dist/server/client/dist/assets/mipsasm-CKIfxQSi.js +1 -0
- package/dist/server/client/dist/assets/mojo-rZm6bMo-.js +1 -0
- package/dist/server/client/dist/assets/monokai-D4h5O-jR.js +1 -0
- package/dist/server/client/dist/assets/moonbit-_H4v1dQx.js +1 -0
- package/dist/server/client/dist/assets/move-IF9eRakj.js +1 -0
- package/dist/server/client/dist/assets/narrat-DRg8JJMk.js +1 -0
- package/dist/server/client/dist/assets/nextflow-Zz6hmt5N.js +1 -0
- package/dist/server/client/dist/assets/nextflow-groovy-BeH2EWoN.js +1 -0
- package/dist/server/client/dist/assets/nginx-BpAMiNFr.js +1 -0
- package/dist/server/client/dist/assets/night-owl-C39BiMTA.js +1 -0
- package/dist/server/client/dist/assets/night-owl-light-CMTm3GFP.js +1 -0
- package/dist/server/client/dist/assets/nim-CVrawwO9.js +1 -0
- package/dist/server/client/dist/assets/nix-CwoSXNpI.js +1 -0
- package/dist/server/client/dist/assets/nord-Ddv68eIx.js +1 -0
- package/dist/server/client/dist/assets/nushell-Cz2AlsmD.js +1 -0
- package/dist/server/client/dist/assets/objective-c-DXmwc3jG.js +1 -0
- package/dist/server/client/dist/assets/objective-cpp-CLxacb5B.js +1 -0
- package/dist/server/client/dist/assets/ocaml-C0hk2d4L.js +1 -0
- package/dist/server/client/dist/assets/odin-BBf5iR-q.js +1 -0
- package/dist/server/client/dist/assets/one-dark-pro-DVMEJ2y_.js +1 -0
- package/dist/server/client/dist/assets/one-light-C3Wv6jpd.js +1 -0
- package/dist/server/client/dist/assets/openscad-C4EeE6gA.js +1 -0
- package/dist/server/client/dist/assets/pascal-D93ZcfNL.js +1 -0
- package/dist/server/client/dist/assets/perl-C0TMdlhV.js +1 -0
- package/dist/server/client/dist/assets/php-Dhbhpdrm.js +1 -0
- package/dist/server/client/dist/assets/pkl-u5AG7uiY.js +1 -0
- package/dist/server/client/dist/assets/plastic-3e1v2bzS.js +1 -0
- package/dist/server/client/dist/assets/plsql-ChMvpjG-.js +1 -0
- package/dist/server/client/dist/assets/po-BTJTHyun.js +1 -0
- package/dist/server/client/dist/assets/poimandres-CS3Unz2-.js +1 -0
- package/dist/server/client/dist/assets/polar-C0HS_06l.js +1 -0
- package/dist/server/client/dist/assets/postcss-CXtECtnM.js +1 -0
- package/dist/server/client/dist/assets/powerquery-CEu0bR-o.js +1 -0
- package/dist/server/client/dist/assets/powershell-Dpen1YoG.js +1 -0
- package/dist/server/client/dist/assets/prisma-Dd19v3D-.js +1 -0
- package/dist/server/client/dist/assets/prolog-CbFg5uaA.js +1 -0
- package/dist/server/client/dist/assets/proto-C7zT0LnQ.js +1 -0
- package/dist/server/client/dist/assets/pug-CGlum2m_.js +1 -0
- package/dist/server/client/dist/assets/puppet-BMWR74SV.js +1 -0
- package/dist/server/client/dist/assets/purescript-CklMAg4u.js +1 -0
- package/dist/server/client/dist/assets/python-B6aJPvgy.js +1 -0
- package/dist/server/client/dist/assets/qml-3beO22l8.js +1 -0
- package/dist/server/client/dist/assets/qmldir-C8lEn-DE.js +1 -0
- package/dist/server/client/dist/assets/qss-IeuSbFQv.js +1 -0
- package/dist/server/client/dist/assets/r-Dspwwk_N.js +1 -0
- package/dist/server/client/dist/assets/racket-BqYA7rlc.js +1 -0
- package/dist/server/client/dist/assets/raku-DXvB9xmW.js +1 -0
- package/dist/server/client/dist/assets/razor-Uh8Bk_45.js +1 -0
- package/dist/server/client/dist/assets/red-bN70gL4F.js +1 -0
- package/dist/server/client/dist/assets/reg-C-SQnVFl.js +1 -0
- package/dist/server/client/dist/assets/regexp-CDVJQ6XC.js +1 -0
- package/dist/server/client/dist/assets/rel-C3B-1QV4.js +1 -0
- package/dist/server/client/dist/assets/riscv-BM1_JUlF.js +1 -0
- package/dist/server/client/dist/assets/ron-D8l8udqQ.js +1 -0
- package/dist/server/client/dist/assets/rose-pine-dawn-DHQR4-dF.js +1 -0
- package/dist/server/client/dist/assets/rose-pine-moon-D4_iv3hh.js +1 -0
- package/dist/server/client/dist/assets/rose-pine-qdsjHGoJ.js +1 -0
- package/dist/server/client/dist/assets/rosmsg-BJDFO7_C.js +1 -0
- package/dist/server/client/dist/assets/rst-BrH8l1NY.js +1 -0
- package/dist/server/client/dist/assets/ruby-Dw2BHqvy.js +1 -0
- package/dist/server/client/dist/assets/rust-B1yitclQ.js +1 -0
- package/dist/server/client/dist/assets/sas-cz2c8ADy.js +1 -0
- package/dist/server/client/dist/assets/sass-Cj5Yp3dK.js +1 -0
- package/dist/server/client/dist/assets/scala-C151Ov-r.js +1 -0
- package/dist/server/client/dist/assets/scheme-C98Dy4si.js +1 -0
- package/dist/server/client/dist/assets/scss-OYdSNvt2.js +1 -0
- package/dist/server/client/dist/assets/sdbl-DVxCFoDh.js +1 -0
- package/dist/server/client/dist/assets/shaderlab-Dg9Lc6iA.js +1 -0
- package/dist/server/client/dist/assets/shellscript-Yzrsuije.js +1 -0
- package/dist/server/client/dist/assets/shellsession-BADoaaVG.js +1 -0
- package/dist/server/client/dist/assets/slack-dark-BthQWCQV.js +1 -0
- package/dist/server/client/dist/assets/slack-ochin-DqwNpetd.js +1 -0
- package/dist/server/client/dist/assets/smalltalk-BERRCDM3.js +1 -0
- package/dist/server/client/dist/assets/snazzy-light-Bw305WKR.js +1 -0
- package/dist/server/client/dist/assets/solarized-dark-DXbdFlpD.js +1 -0
- package/dist/server/client/dist/assets/solarized-light-L9t79GZl.js +1 -0
- package/dist/server/client/dist/assets/solidity-rGO070M0.js +1 -0
- package/dist/server/client/dist/assets/soy-Brmx7dQM.js +1 -0
- package/dist/server/client/dist/assets/sparql-rVzFXLq3.js +1 -0
- package/dist/server/client/dist/assets/splunk-BtCnVYZw.js +1 -0
- package/dist/server/client/dist/assets/sql-BLtJtn59.js +1 -0
- package/dist/server/client/dist/assets/ssh-config-_ykCGR6B.js +1 -0
- package/dist/server/client/dist/assets/stata-BH5u7GGu.js +1 -0
- package/dist/server/client/dist/assets/stylus-BEDo0Tqx.js +1 -0
- package/dist/server/client/dist/assets/surrealql-Bq5Q-fJD.js +1 -0
- package/dist/server/client/dist/assets/svelte-C_ipcX3V.js +1 -0
- package/dist/server/client/dist/assets/swift-D82vCrfD.js +1 -0
- package/dist/server/client/dist/assets/synthwave-84-CbfX1IO0.js +1 -0
- package/dist/server/client/dist/assets/system-verilog-CnnmHF94.js +1 -0
- package/dist/server/client/dist/assets/systemd-4A_iFExJ.js +1 -0
- package/dist/server/client/dist/assets/talonscript-CkByrt1z.js +1 -0
- package/dist/server/client/dist/assets/tasl-QIJgUcNo.js +1 -0
- package/dist/server/client/dist/assets/tcl-dwOrl1Do.js +1 -0
- package/dist/server/client/dist/assets/templ-P3uqSqPl.js +1 -0
- package/dist/server/client/dist/assets/terraform-BETggiCN.js +1 -0
- package/dist/server/client/dist/assets/tex-idrVyKtj.js +1 -0
- package/dist/server/client/dist/assets/tokyo-night-hegEt444.js +1 -0
- package/dist/server/client/dist/assets/toml-vGWfd6FD.js +1 -0
- package/dist/server/client/dist/assets/ts-tags-zn1MmPIZ.js +1 -0
- package/dist/server/client/dist/assets/tsv-B_m7g4N7.js +1 -0
- package/dist/server/client/dist/assets/tsx-COt5Ahok.js +1 -0
- package/dist/server/client/dist/assets/turtle-BsS91CYL.js +1 -0
- package/dist/server/client/dist/assets/twig-DNn4PbVi.js +1 -0
- package/dist/server/client/dist/assets/typescript-BPQ3VLAy.js +1 -0
- package/dist/server/client/dist/assets/typespec-BGHnOYBU.js +1 -0
- package/dist/server/client/dist/assets/typst-DHCkPAjA.js +1 -0
- package/dist/server/client/dist/assets/v-BcVCzyr7.js +1 -0
- package/dist/server/client/dist/assets/vala-CsfeWuGM.js +1 -0
- package/dist/server/client/dist/assets/vb-D17OF-Vu.js +1 -0
- package/dist/server/client/dist/assets/verilog-BQ8w6xss.js +1 -0
- package/dist/server/client/dist/assets/vesper-DU1UobuO.js +1 -0
- package/dist/server/client/dist/assets/vhdl-CeAyd5Ju.js +1 -0
- package/dist/server/client/dist/assets/viml-CJc9bBzg.js +1 -0
- package/dist/server/client/dist/assets/vitesse-black-Bkuqu6BP.js +1 -0
- package/dist/server/client/dist/assets/vitesse-dark-D0r3Knsf.js +1 -0
- package/dist/server/client/dist/assets/vitesse-light-CVO1_9PV.js +1 -0
- package/dist/server/client/dist/assets/vue-DN_0RTcg.js +1 -0
- package/dist/server/client/dist/assets/vue-html-AaS7Mt5G.js +1 -0
- package/dist/server/client/dist/assets/vue-vine-CQOfvN7w.js +1 -0
- package/dist/server/client/dist/assets/vyper-CDx5xZoG.js +1 -0
- package/dist/server/client/dist/assets/wasm-CG6Dc4jp.js +1 -0
- package/dist/server/client/dist/assets/wasm-MzD3tlZU.js +1 -0
- package/dist/server/client/dist/assets/wenyan-BV7otONQ.js +1 -0
- package/dist/server/client/dist/assets/wgsl-Dx-B1_4e.js +1 -0
- package/dist/server/client/dist/assets/wikitext-BhOHFoWU.js +1 -0
- package/dist/server/client/dist/assets/wit-5i3qLPDT.js +1 -0
- package/dist/server/client/dist/assets/wolfram-lXgVvXCa.js +1 -0
- package/dist/server/client/dist/assets/xml-sdJ4AIDG.js +1 -0
- package/dist/server/client/dist/assets/xsl-CtQFsRM5.js +1 -0
- package/dist/server/client/dist/assets/yaml-Buea-lGh.js +1 -0
- package/dist/server/client/dist/assets/zenscript-DVFEvuxE.js +1 -0
- package/dist/server/client/dist/assets/zig-VOosw3JB.js +1 -0
- package/dist/server/client/dist/favicon.ico +0 -0
- package/dist/server/client/dist/index.html +17 -0
- package/dist/server/client/dist/logo.png +0 -0
- package/dist/server/server/adapters/hermes-worker.d.ts +37 -0
- package/dist/server/server/adapters/hermes-worker.js +525 -0
- package/dist/server/server/adapters/types.d.ts +39 -0
- package/dist/server/server/adapters/types.js +1 -0
- package/dist/server/server/adapters/worker-protocol.d.ts +141 -0
- package/dist/server/server/adapters/worker-protocol.js +1 -0
- package/dist/server/server/agent-settings.d.ts +12 -0
- package/dist/server/server/agent-settings.js +56 -0
- package/dist/server/server/app.d.ts +5 -0
- package/dist/server/server/app.js +41 -0
- package/dist/server/server/db/index.d.ts +2 -0
- package/dist/server/server/db/index.js +14 -0
- package/dist/server/server/db/queries.d.ts +22 -0
- package/dist/server/server/db/queries.js +116 -0
- package/dist/server/server/db/schema.sql +16 -0
- package/dist/server/server/errors.d.ts +3 -0
- package/dist/server/server/errors.js +12 -0
- package/dist/server/server/events.d.ts +7 -0
- package/dist/server/server/events.js +50 -0
- package/dist/server/server/frontend.d.ts +4 -0
- package/dist/server/server/frontend.js +32 -0
- package/dist/server/server/index.d.ts +2 -0
- package/dist/server/server/index.js +63 -0
- package/dist/server/server/live-chat.d.ts +17 -0
- package/dist/server/server/live-chat.js +217 -0
- package/dist/server/server/paths.d.ts +7 -0
- package/dist/server/server/paths.js +39 -0
- package/dist/server/server/prompts/task-agent.d.ts +1 -0
- package/dist/server/server/prompts/task-agent.js +26 -0
- package/dist/server/server/routes/agent.d.ts +4 -0
- package/dist/server/server/routes/agent.js +94 -0
- package/dist/server/server/routes/chat.d.ts +1 -0
- package/dist/server/server/routes/chat.js +177 -0
- package/dist/server/server/routes/cron.d.ts +4 -0
- package/dist/server/server/routes/cron.js +109 -0
- package/dist/server/server/routes/files.d.ts +1 -0
- package/dist/server/server/routes/files.js +543 -0
- package/dist/server/server/routes/skills.d.ts +1 -0
- package/dist/server/server/routes/skills.js +13 -0
- package/dist/server/server/routes/tasks.d.ts +1 -0
- package/dist/server/server/routes/tasks.js +107 -0
- package/dist/server/server/skills/catalog.d.ts +21 -0
- package/dist/server/server/skills/catalog.js +160 -0
- package/dist/server/server/workers/hermes_cron.py +241 -0
- package/dist/server/server/workers/hermes_sessions.py +264 -0
- package/dist/server/server/workers/hermes_worker.py +1270 -0
- package/dist/server/server/workers/hermes_worker_utils.py +39 -0
- package/dist/server/shared/types.d.ts +211 -0
- package/dist/server/shared/types.js +2 -0
- package/package.json +74 -0
- package/skills/lead-generation/SKILL.md +41 -0
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import { v4 as uuid } from 'uuid';
|
|
2
|
+
const runs = new Map();
|
|
3
|
+
const subscribers = new Map();
|
|
4
|
+
const expiryTimers = new Map();
|
|
5
|
+
const KEEPALIVE_INTERVAL_MS = 30_000;
|
|
6
|
+
let keepaliveTimer = null;
|
|
7
|
+
function cloneRun(run) {
|
|
8
|
+
return {
|
|
9
|
+
...run,
|
|
10
|
+
messages: run.messages.map((message) => ({
|
|
11
|
+
...message,
|
|
12
|
+
tools: message.tools ? message.tools.map((tool) => ({ ...tool })) : undefined,
|
|
13
|
+
})),
|
|
14
|
+
context: run.context ? { ...run.context } : null,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
function runState(run) {
|
|
18
|
+
return {
|
|
19
|
+
taskId: run.taskId,
|
|
20
|
+
runId: run.runId,
|
|
21
|
+
status: run.status,
|
|
22
|
+
startedAt: run.startedAt,
|
|
23
|
+
updatedAt: run.updatedAt,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
function assistantMessage(run) {
|
|
27
|
+
for (let i = run.messages.length - 1; i >= 0; i--) {
|
|
28
|
+
if (run.messages[i].role === 'assistant')
|
|
29
|
+
return run.messages[i];
|
|
30
|
+
}
|
|
31
|
+
const message = {
|
|
32
|
+
id: uuid(),
|
|
33
|
+
task_id: run.taskId,
|
|
34
|
+
role: 'assistant',
|
|
35
|
+
content: '',
|
|
36
|
+
created_at: Date.now(),
|
|
37
|
+
};
|
|
38
|
+
run.messages.push(message);
|
|
39
|
+
return message;
|
|
40
|
+
}
|
|
41
|
+
function mergeToolProgress(tools, event) {
|
|
42
|
+
const tool = {
|
|
43
|
+
tool: event.tool ?? 'tool',
|
|
44
|
+
status: event.status ?? 'running',
|
|
45
|
+
duration: event.duration,
|
|
46
|
+
label: event.label,
|
|
47
|
+
};
|
|
48
|
+
if (tool.status === 'running') {
|
|
49
|
+
tools.push(tool);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
for (let i = tools.length - 1; i >= 0; i--) {
|
|
53
|
+
if (tools[i].tool === tool.tool && tools[i].status === 'running') {
|
|
54
|
+
tools[i] = { ...tools[i], ...tool, label: tool.label ?? tools[i].label };
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
tools.push(tool);
|
|
59
|
+
}
|
|
60
|
+
function writeEvent(res, event) {
|
|
61
|
+
try {
|
|
62
|
+
return res.write(`data: ${JSON.stringify(event)}\n\n`);
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
function startKeepalive() {
|
|
69
|
+
if (keepaliveTimer)
|
|
70
|
+
return;
|
|
71
|
+
keepaliveTimer = setInterval(() => {
|
|
72
|
+
for (const [taskId, taskSubscribers] of subscribers) {
|
|
73
|
+
for (const subscriber of taskSubscribers) {
|
|
74
|
+
try {
|
|
75
|
+
subscriber.write(':keepalive\n\n');
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
taskSubscribers.delete(subscriber);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
if (taskSubscribers.size === 0)
|
|
82
|
+
subscribers.delete(taskId);
|
|
83
|
+
}
|
|
84
|
+
if (subscribers.size === 0 && keepaliveTimer) {
|
|
85
|
+
clearInterval(keepaliveTimer);
|
|
86
|
+
keepaliveTimer = null;
|
|
87
|
+
}
|
|
88
|
+
}, KEEPALIVE_INTERVAL_MS);
|
|
89
|
+
}
|
|
90
|
+
export function startRun(taskId, sessionId, userContent) {
|
|
91
|
+
const expiryTimer = expiryTimers.get(taskId);
|
|
92
|
+
if (expiryTimer) {
|
|
93
|
+
clearTimeout(expiryTimer);
|
|
94
|
+
expiryTimers.delete(taskId);
|
|
95
|
+
}
|
|
96
|
+
const now = Date.now();
|
|
97
|
+
const run = {
|
|
98
|
+
taskId,
|
|
99
|
+
runId: uuid(),
|
|
100
|
+
sessionId,
|
|
101
|
+
status: 'streaming',
|
|
102
|
+
startedAt: now,
|
|
103
|
+
updatedAt: now,
|
|
104
|
+
messages: [
|
|
105
|
+
{
|
|
106
|
+
id: uuid(),
|
|
107
|
+
task_id: taskId,
|
|
108
|
+
role: 'user',
|
|
109
|
+
content: userContent,
|
|
110
|
+
created_at: now,
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
id: uuid(),
|
|
114
|
+
task_id: taskId,
|
|
115
|
+
role: 'assistant',
|
|
116
|
+
content: '',
|
|
117
|
+
created_at: now,
|
|
118
|
+
tools: [],
|
|
119
|
+
},
|
|
120
|
+
],
|
|
121
|
+
};
|
|
122
|
+
runs.set(taskId, run);
|
|
123
|
+
return cloneRun(run);
|
|
124
|
+
}
|
|
125
|
+
export function applyEvent(taskId, event) {
|
|
126
|
+
const run = runs.get(taskId);
|
|
127
|
+
if (!run)
|
|
128
|
+
return;
|
|
129
|
+
const assistant = assistantMessage(run);
|
|
130
|
+
if (event.type === 'text_delta' && event.content) {
|
|
131
|
+
assistant.content += event.content;
|
|
132
|
+
}
|
|
133
|
+
else if (event.type === 'thinking_delta' && event.content) {
|
|
134
|
+
assistant.thinking = `${assistant.thinking ?? ''}${event.content}`;
|
|
135
|
+
}
|
|
136
|
+
else if (event.type === 'tool_progress') {
|
|
137
|
+
if (!assistant.tools)
|
|
138
|
+
assistant.tools = [];
|
|
139
|
+
mergeToolProgress(assistant.tools, event);
|
|
140
|
+
}
|
|
141
|
+
else if (event.type === 'done') {
|
|
142
|
+
if (run.status !== 'error')
|
|
143
|
+
run.status = 'done';
|
|
144
|
+
if (event.sessionId)
|
|
145
|
+
run.sessionId = event.sessionId;
|
|
146
|
+
if (event.context !== undefined) {
|
|
147
|
+
run.context = event.context;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
else if (event.type === 'error') {
|
|
151
|
+
const error = event.error || 'Unknown error';
|
|
152
|
+
run.status = 'error';
|
|
153
|
+
run.error = error;
|
|
154
|
+
if (!assistant.content.includes(`[Error: ${error}]`)) {
|
|
155
|
+
assistant.content = assistant.content
|
|
156
|
+
? `${assistant.content}\n[Error: ${error}]`
|
|
157
|
+
: `[Error: ${error}]`;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
run.updatedAt = Date.now();
|
|
161
|
+
}
|
|
162
|
+
export function getRun(taskId) {
|
|
163
|
+
const run = runs.get(taskId);
|
|
164
|
+
return run ? cloneRun(run) : undefined;
|
|
165
|
+
}
|
|
166
|
+
export function getRunContext(taskId) {
|
|
167
|
+
return runs.get(taskId)?.context;
|
|
168
|
+
}
|
|
169
|
+
export function getRunStatus(taskId) {
|
|
170
|
+
const run = runs.get(taskId);
|
|
171
|
+
return run ? runState(run) : undefined;
|
|
172
|
+
}
|
|
173
|
+
export function getRunStatuses() {
|
|
174
|
+
return Array.from(runs.values()).map(runState);
|
|
175
|
+
}
|
|
176
|
+
export function subscribe(taskId, res) {
|
|
177
|
+
let taskSubscribers = subscribers.get(taskId);
|
|
178
|
+
if (!taskSubscribers) {
|
|
179
|
+
taskSubscribers = new Set();
|
|
180
|
+
subscribers.set(taskId, taskSubscribers);
|
|
181
|
+
}
|
|
182
|
+
taskSubscribers.add(res);
|
|
183
|
+
res.on('close', () => {
|
|
184
|
+
taskSubscribers.delete(res);
|
|
185
|
+
if (taskSubscribers.size === 0)
|
|
186
|
+
subscribers.delete(taskId);
|
|
187
|
+
});
|
|
188
|
+
startKeepalive();
|
|
189
|
+
}
|
|
190
|
+
export function sendSnapshot(res, run) {
|
|
191
|
+
writeEvent(res, { type: 'snapshot', run });
|
|
192
|
+
}
|
|
193
|
+
export function broadcast(taskId, event) {
|
|
194
|
+
const taskSubscribers = subscribers.get(taskId);
|
|
195
|
+
if (!taskSubscribers)
|
|
196
|
+
return;
|
|
197
|
+
for (const subscriber of taskSubscribers) {
|
|
198
|
+
if (!writeEvent(subscriber, event))
|
|
199
|
+
taskSubscribers.delete(subscriber);
|
|
200
|
+
}
|
|
201
|
+
if (taskSubscribers.size === 0)
|
|
202
|
+
subscribers.delete(taskId);
|
|
203
|
+
}
|
|
204
|
+
export function finishRun(taskId, ttlMs, runId) {
|
|
205
|
+
if (!runs.has(taskId))
|
|
206
|
+
return;
|
|
207
|
+
const expiryTimer = expiryTimers.get(taskId);
|
|
208
|
+
if (expiryTimer)
|
|
209
|
+
clearTimeout(expiryTimer);
|
|
210
|
+
const timer = setTimeout(() => {
|
|
211
|
+
if (runs.get(taskId)?.runId === runId)
|
|
212
|
+
runs.delete(taskId);
|
|
213
|
+
expiryTimers.delete(taskId);
|
|
214
|
+
}, ttlMs);
|
|
215
|
+
timer.unref();
|
|
216
|
+
expiryTimers.set(taskId, timer);
|
|
217
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare function expandHomePrefix(value: string): string;
|
|
2
|
+
export declare function resolveMinionsHome(): string;
|
|
3
|
+
export declare function resolveMinionsDataDir(): string;
|
|
4
|
+
export declare function resolveMinionsLogsDir(): string;
|
|
5
|
+
export declare function resolveMinionsWorkspaceDir(): string;
|
|
6
|
+
export declare function resolveMinionsDbPath(): string;
|
|
7
|
+
export declare function ensureMinionsStateDirs(): void;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { mkdirSync } from 'node:fs';
|
|
2
|
+
import { dirname, join, resolve } from 'node:path';
|
|
3
|
+
import { homedir } from 'node:os';
|
|
4
|
+
export function expandHomePrefix(value) {
|
|
5
|
+
if (value === '~')
|
|
6
|
+
return homedir();
|
|
7
|
+
if (value.startsWith('~/'))
|
|
8
|
+
return join(homedir(), value.slice(2));
|
|
9
|
+
return value;
|
|
10
|
+
}
|
|
11
|
+
function resolveHomeAwarePath(value) {
|
|
12
|
+
return resolve(expandHomePrefix(value));
|
|
13
|
+
}
|
|
14
|
+
export function resolveMinionsHome() {
|
|
15
|
+
const configured = process.env.MINIONS_HOME?.trim();
|
|
16
|
+
return resolveHomeAwarePath(configured || '~/.minions');
|
|
17
|
+
}
|
|
18
|
+
export function resolveMinionsDataDir() {
|
|
19
|
+
return join(resolveMinionsHome(), 'data');
|
|
20
|
+
}
|
|
21
|
+
export function resolveMinionsLogsDir() {
|
|
22
|
+
return join(resolveMinionsHome(), 'logs');
|
|
23
|
+
}
|
|
24
|
+
export function resolveMinionsWorkspaceDir() {
|
|
25
|
+
return join(resolveMinionsHome(), 'workspace');
|
|
26
|
+
}
|
|
27
|
+
export function resolveMinionsDbPath() {
|
|
28
|
+
const configured = process.env.DB_PATH?.trim();
|
|
29
|
+
if (configured)
|
|
30
|
+
return resolveHomeAwarePath(configured);
|
|
31
|
+
return join(resolveMinionsDataDir(), 'minions.db');
|
|
32
|
+
}
|
|
33
|
+
export function ensureMinionsStateDirs() {
|
|
34
|
+
const dbPath = resolveMinionsDbPath();
|
|
35
|
+
mkdirSync(resolveMinionsDataDir(), { recursive: true });
|
|
36
|
+
mkdirSync(resolveMinionsLogsDir(), { recursive: true });
|
|
37
|
+
mkdirSync(resolveMinionsWorkspaceDir(), { recursive: true });
|
|
38
|
+
mkdirSync(dirname(dbPath), { recursive: true });
|
|
39
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const TASK_AGENT_SYSTEM_PROMPT = "<task_agent>\n <role>\n You are an autonomous task agent. A user has given you a task to accomplish.\n </role>\n\n <responsibilities>\n <responsibility name=\"understand\">\n Read the task carefully. Identify anything unclear, ambiguous, or underspecified.\n </responsibility>\n <responsibility name=\"clarify\">\n Before doing work, make sure you fully understand what the user wants. Ask focused clarifying questions about scope, constraints, expected outcomes, edge cases, or anything else you are uncertain about. Do not assume when the uncertainty matters. The user is available to answer. Keep asking until you are confident you understand the task correctly.\n </responsibility>\n <responsibility name=\"execute\">\n Once you and the user are aligned, choose the best execution strategy. Do the work yourself in this session if it is straightforward. Create a child session if you need a dedicated sub-agent for complex sub-work. Set up a cron job when the work is recurring, periodic, routine, or better handled as durable batches over time. You have full autonomy to use the tools and approach that best accomplish the task.\n </responsibility>\n </responsibilities>\n\n <guidelines>\n <guideline>Understand first, act second. Do not start executing until you are confident you know what the user wants.</guideline>\n <guideline>When clarifying, ask focused questions rather than a long wall of questions. A natural back-and-forth conversation is ideal.</guideline>\n <guideline>When the user asks for a cron job, schedule, routine, recurring task, monitor, daily/weekly task, or similar repeated work, default to a Hermes cron job using the available cronjob tooling. Do not use Linux cron, systemd timers, or host OS schedulers unless the user explicitly asks for them.</guideline>\n <guideline>For lead generation, prospecting, and large list processing, prefer a small sample or validation run first. If the user wants more than a small one-off result, prefer a cron job with a self-contained prompt, sensible batch size, output/checkpoint location, and schedule.</guideline>\n <guideline>Keep the user informed of meaningful progress in your responses.</guideline>\n <guideline>You have project-specific skills under the \"minions\" category in your skills index. Before executing a task, check if any minions skill is relevant and load it \u2014 these encode proven workflows tailored to this system.</guideline>\n </guidelines>\n</task_agent>";
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export const TASK_AGENT_SYSTEM_PROMPT = `<task_agent>
|
|
2
|
+
<role>
|
|
3
|
+
You are an autonomous task agent. A user has given you a task to accomplish.
|
|
4
|
+
</role>
|
|
5
|
+
|
|
6
|
+
<responsibilities>
|
|
7
|
+
<responsibility name="understand">
|
|
8
|
+
Read the task carefully. Identify anything unclear, ambiguous, or underspecified.
|
|
9
|
+
</responsibility>
|
|
10
|
+
<responsibility name="clarify">
|
|
11
|
+
Before doing work, make sure you fully understand what the user wants. Ask focused clarifying questions about scope, constraints, expected outcomes, edge cases, or anything else you are uncertain about. Do not assume when the uncertainty matters. The user is available to answer. Keep asking until you are confident you understand the task correctly.
|
|
12
|
+
</responsibility>
|
|
13
|
+
<responsibility name="execute">
|
|
14
|
+
Once you and the user are aligned, choose the best execution strategy. Do the work yourself in this session if it is straightforward. Create a child session if you need a dedicated sub-agent for complex sub-work. Set up a cron job when the work is recurring, periodic, routine, or better handled as durable batches over time. You have full autonomy to use the tools and approach that best accomplish the task.
|
|
15
|
+
</responsibility>
|
|
16
|
+
</responsibilities>
|
|
17
|
+
|
|
18
|
+
<guidelines>
|
|
19
|
+
<guideline>Understand first, act second. Do not start executing until you are confident you know what the user wants.</guideline>
|
|
20
|
+
<guideline>When clarifying, ask focused questions rather than a long wall of questions. A natural back-and-forth conversation is ideal.</guideline>
|
|
21
|
+
<guideline>When the user asks for a cron job, schedule, routine, recurring task, monitor, daily/weekly task, or similar repeated work, default to a Hermes cron job using the available cronjob tooling. Do not use Linux cron, systemd timers, or host OS schedulers unless the user explicitly asks for them.</guideline>
|
|
22
|
+
<guideline>For lead generation, prospecting, and large list processing, prefer a small sample or validation run first. If the user wants more than a small one-off result, prefer a cron job with a self-contained prompt, sensible batch size, output/checkpoint location, and schedule.</guideline>
|
|
23
|
+
<guideline>Keep the user informed of meaningful progress in your responses.</guideline>
|
|
24
|
+
<guideline>You have project-specific skills under the "minions" category in your skills index. Before executing a task, check if any minions skill is relevant and load it — these encode proven workflows tailored to this system.</guideline>
|
|
25
|
+
</guidelines>
|
|
26
|
+
</task_agent>`;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { Router } from 'express';
|
|
2
|
+
import type { HermesWorkerAdapter } from '../adapters/hermes-worker.js';
|
|
3
|
+
export declare function createAgentRouter(adapter: HermesWorkerAdapter): Router;
|
|
4
|
+
export declare function createTaskAgentSettingsRouter(adapter: HermesWorkerAdapter): Router;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { Router } from 'express';
|
|
2
|
+
import { getTask } from '../db/queries.js';
|
|
3
|
+
import { isRecord, toErrorMessage } from '../errors.js';
|
|
4
|
+
import { taskRunSettings } from '../agent-settings.js';
|
|
5
|
+
import { REASONING_EFFORTS } from '../../shared/types.js';
|
|
6
|
+
const FALLBACK_DEFAULTS = {
|
|
7
|
+
provider: null,
|
|
8
|
+
model: null,
|
|
9
|
+
baseUrl: null,
|
|
10
|
+
apiMode: null,
|
|
11
|
+
reasoningEffort: 'medium',
|
|
12
|
+
showReasoning: true,
|
|
13
|
+
};
|
|
14
|
+
async function defaultsForSettings(adapter) {
|
|
15
|
+
try {
|
|
16
|
+
return await adapter.getDefaults();
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return FALLBACK_DEFAULTS;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function buildTaskSettings(task, defaults) {
|
|
23
|
+
const overrides = taskRunSettings(task);
|
|
24
|
+
return {
|
|
25
|
+
task: {
|
|
26
|
+
model: overrides.model ?? null,
|
|
27
|
+
reasoningEffort: overrides.reasoningEffort ?? null,
|
|
28
|
+
},
|
|
29
|
+
defaults,
|
|
30
|
+
effective: {
|
|
31
|
+
model: overrides.model ?? defaults.model,
|
|
32
|
+
provider: defaults.provider,
|
|
33
|
+
reasoningEffort: overrides.reasoningEffort ?? defaults.reasoningEffort,
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
export function createAgentRouter(adapter) {
|
|
38
|
+
const router = Router();
|
|
39
|
+
router.get('/defaults', async (_req, res) => {
|
|
40
|
+
try {
|
|
41
|
+
res.json(await adapter.getDefaults());
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
res.status(503).json({ error: toErrorMessage(error, 'Hermes worker unavailable') });
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
router.patch('/defaults', async (req, res) => {
|
|
48
|
+
if (!isRecord(req.body)) {
|
|
49
|
+
return res.status(400).json({ error: 'Request body is required' });
|
|
50
|
+
}
|
|
51
|
+
const updates = {};
|
|
52
|
+
if ('model' in req.body) {
|
|
53
|
+
const model = req.body.model;
|
|
54
|
+
if (model !== null && typeof model !== 'string') {
|
|
55
|
+
return res.status(400).json({ error: 'model must be a string or null' });
|
|
56
|
+
}
|
|
57
|
+
updates.model = typeof model === 'string' ? model.trim() || null : null;
|
|
58
|
+
}
|
|
59
|
+
if ('reasoningEffort' in req.body) {
|
|
60
|
+
const effort = req.body.reasoningEffort;
|
|
61
|
+
if (effort !== null && (typeof effort !== 'string' || !REASONING_EFFORTS.includes(effort))) {
|
|
62
|
+
return res.status(400).json({ error: `reasoningEffort must be one of: ${REASONING_EFFORTS.join(', ')}` });
|
|
63
|
+
}
|
|
64
|
+
updates.reasoningEffort = effort;
|
|
65
|
+
}
|
|
66
|
+
try {
|
|
67
|
+
const defaults = await adapter.setDefaults(updates);
|
|
68
|
+
res.json(defaults);
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
res.status(503).json({ error: toErrorMessage(error, 'Failed to update defaults') });
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
router.get('/models', async (_req, res) => {
|
|
75
|
+
try {
|
|
76
|
+
res.json(await adapter.getModels());
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
res.status(503).json({ error: toErrorMessage(error, 'Hermes worker unavailable') });
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
return router;
|
|
83
|
+
}
|
|
84
|
+
export function createTaskAgentSettingsRouter(adapter) {
|
|
85
|
+
const router = Router();
|
|
86
|
+
router.get('/:id/agent-settings', async (req, res) => {
|
|
87
|
+
const task = getTask(req.params.id);
|
|
88
|
+
if (!task)
|
|
89
|
+
return res.status(404).json({ error: 'Task not found' });
|
|
90
|
+
const defaults = await defaultsForSettings(adapter);
|
|
91
|
+
res.json(buildTaskSettings(task, defaults));
|
|
92
|
+
});
|
|
93
|
+
return router;
|
|
94
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const chatRouter: import("express-serve-static-core").Router;
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { Router } from 'express';
|
|
2
|
+
import { contextFromTask, getTask, updateTask, touchTask, recordAgentResponse } from '../db/queries.js';
|
|
3
|
+
import { adapter } from '../app.js';
|
|
4
|
+
import { broadcast, initSSE } from '../events.js';
|
|
5
|
+
import { applyEvent, broadcast as broadcastLive, finishRun, getRun, getRunContext, getRunStatus, sendSnapshot, startRun, subscribe, } from '../live-chat.js';
|
|
6
|
+
import { taskRunSettings, parseRunSettingsBody } from '../agent-settings.js';
|
|
7
|
+
import { TASK_AGENT_SYSTEM_PROMPT } from '../prompts/task-agent.js';
|
|
8
|
+
import { toErrorMessage } from '../errors.js';
|
|
9
|
+
export const chatRouter = Router();
|
|
10
|
+
function hasNoSession(task) {
|
|
11
|
+
if (task.last_agent_response_at !== null)
|
|
12
|
+
return false;
|
|
13
|
+
return getRunStatus(task.id)?.status !== 'streaming';
|
|
14
|
+
}
|
|
15
|
+
chatRouter.get('/:id/messages', async (req, res) => {
|
|
16
|
+
const task = getTask(req.params.id);
|
|
17
|
+
if (!task)
|
|
18
|
+
return res.status(404).json({ error: 'Task not found' });
|
|
19
|
+
const liveContext = getRunContext(task.id);
|
|
20
|
+
const context = liveContext !== undefined ? liveContext : contextFromTask(task);
|
|
21
|
+
if (hasNoSession(task))
|
|
22
|
+
return res.json({ messages: [], context });
|
|
23
|
+
try {
|
|
24
|
+
const messages = await adapter.getMessages(task.id, task.id);
|
|
25
|
+
res.json({ messages, context });
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
res.status(503).json({ error: toErrorMessage(error, 'Hermes session history unavailable') });
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
chatRouter.get('/:id/session', async (req, res) => {
|
|
32
|
+
const task = getTask(req.params.id);
|
|
33
|
+
if (!task)
|
|
34
|
+
return res.status(404).json({ error: 'Task not found' });
|
|
35
|
+
if (hasNoSession(task))
|
|
36
|
+
return res.json({ session: null });
|
|
37
|
+
try {
|
|
38
|
+
const session = await adapter.getSessionMetadata(task.id);
|
|
39
|
+
res.json({ session });
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
res.status(503).json({ error: toErrorMessage(error, 'Hermes session metadata unavailable') });
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
const DONE_SNAPSHOT_TTL_MS = 30_000;
|
|
46
|
+
const ERROR_SNAPSHOT_TTL_MS = 5 * 60_000;
|
|
47
|
+
async function judgeTaskCompletion(task, responseText, responseAt) {
|
|
48
|
+
if (!responseText.trim() || task.status !== 'in_progress')
|
|
49
|
+
return;
|
|
50
|
+
try {
|
|
51
|
+
const result = await adapter.judgeCompletion(task.title, task.description, responseText);
|
|
52
|
+
if (result.done) {
|
|
53
|
+
const current = getTask(task.id);
|
|
54
|
+
if (!current ||
|
|
55
|
+
current.status !== 'in_progress' ||
|
|
56
|
+
current.last_agent_response_at !== responseAt) {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
const updated = updateTask(task.id, { status: 'in_review' });
|
|
60
|
+
if (updated)
|
|
61
|
+
broadcast({ type: 'task_updated', task: updated });
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
// Judge failure is non-critical — leave task as-is
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
async function consumeChatRun(runTask, sessionId, content, runId) {
|
|
69
|
+
let sawDone = false;
|
|
70
|
+
let doneContext;
|
|
71
|
+
let responseText = '';
|
|
72
|
+
try {
|
|
73
|
+
const stream = adapter.chatStream(sessionId, content, {
|
|
74
|
+
systemMessage: TASK_AGENT_SYSTEM_PROMPT,
|
|
75
|
+
settings: taskRunSettings(runTask),
|
|
76
|
+
task: { id: runTask.id, title: runTask.title },
|
|
77
|
+
});
|
|
78
|
+
for await (const event of stream) {
|
|
79
|
+
if (event.type === 'text_delta' && responseText.length < 4200)
|
|
80
|
+
responseText += event.content ?? '';
|
|
81
|
+
if (event.type === 'done') {
|
|
82
|
+
sawDone = true;
|
|
83
|
+
doneContext = event.context;
|
|
84
|
+
}
|
|
85
|
+
applyEvent(runTask.id, event);
|
|
86
|
+
broadcastLive(runTask.id, event);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
const event = { type: 'error', error: toErrorMessage(error, 'Hermes chat stream failed') };
|
|
91
|
+
applyEvent(runTask.id, event);
|
|
92
|
+
broadcastLive(runTask.id, event);
|
|
93
|
+
}
|
|
94
|
+
finally {
|
|
95
|
+
const currentRun = getRunStatus(runTask.id);
|
|
96
|
+
if (!sawDone && currentRun?.status === 'streaming') {
|
|
97
|
+
const event = { type: 'done', sessionId };
|
|
98
|
+
sawDone = true;
|
|
99
|
+
applyEvent(runTask.id, event);
|
|
100
|
+
broadcastLive(runTask.id, event);
|
|
101
|
+
}
|
|
102
|
+
const finishedRun = getRunStatus(runTask.id);
|
|
103
|
+
if (finishedRun)
|
|
104
|
+
broadcast({ type: 'task_run_updated', run: finishedRun });
|
|
105
|
+
if (sawDone && finishedRun?.status === 'done') {
|
|
106
|
+
const responseAt = Date.now();
|
|
107
|
+
const updated = recordAgentResponse(runTask.id, responseAt, doneContext ?? null);
|
|
108
|
+
if (updated)
|
|
109
|
+
broadcast({ type: 'task_updated', task: updated });
|
|
110
|
+
void judgeTaskCompletion(runTask, responseText, responseAt);
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
touchTask(runTask.id);
|
|
114
|
+
}
|
|
115
|
+
const ttl = finishedRun?.status === 'error' ? ERROR_SNAPSHOT_TTL_MS : DONE_SNAPSHOT_TTL_MS;
|
|
116
|
+
finishRun(runTask.id, ttl, runId);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
chatRouter.post('/:id/messages', async (req, res) => {
|
|
120
|
+
const task = getTask(req.params.id);
|
|
121
|
+
if (!task)
|
|
122
|
+
return res.status(404).json({ error: 'Task not found' });
|
|
123
|
+
const { content } = req.body;
|
|
124
|
+
if (!content || typeof content !== 'string') {
|
|
125
|
+
return res.status(400).json({ error: 'content is required' });
|
|
126
|
+
}
|
|
127
|
+
let runSettings;
|
|
128
|
+
try {
|
|
129
|
+
runSettings = parseRunSettingsBody(req.body);
|
|
130
|
+
}
|
|
131
|
+
catch (error) {
|
|
132
|
+
return res.status(400).json({ error: toErrorMessage(error, 'Invalid run settings') });
|
|
133
|
+
}
|
|
134
|
+
const activeRun = getRunStatus(task.id);
|
|
135
|
+
if (activeRun?.status === 'streaming') {
|
|
136
|
+
return res.status(409).json({ error: 'This task already has a message in progress' });
|
|
137
|
+
}
|
|
138
|
+
let runTask = task;
|
|
139
|
+
const taskUpdates = {};
|
|
140
|
+
if (runSettings.hasFields) {
|
|
141
|
+
const { taskFields } = runSettings;
|
|
142
|
+
if (taskFields.agent_model !== undefined && taskFields.agent_model !== task.agent_model) {
|
|
143
|
+
taskUpdates.agent_model = taskFields.agent_model;
|
|
144
|
+
}
|
|
145
|
+
if (taskFields.reasoning_effort !== undefined && taskFields.reasoning_effort !== task.reasoning_effort) {
|
|
146
|
+
taskUpdates.reasoning_effort = taskFields.reasoning_effort;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
if (task.status === 'in_review') {
|
|
150
|
+
taskUpdates.status = 'in_progress';
|
|
151
|
+
}
|
|
152
|
+
if (Object.keys(taskUpdates).length > 0) {
|
|
153
|
+
const updated = updateTask(task.id, taskUpdates);
|
|
154
|
+
if (!updated)
|
|
155
|
+
return res.status(404).json({ error: 'Task not found' });
|
|
156
|
+
runTask = updated;
|
|
157
|
+
broadcast({ type: 'task_updated', task: updated });
|
|
158
|
+
}
|
|
159
|
+
const sessionId = runTask.id;
|
|
160
|
+
const run = startRun(runTask.id, sessionId, content);
|
|
161
|
+
const startedRun = getRunStatus(runTask.id);
|
|
162
|
+
if (startedRun)
|
|
163
|
+
broadcast({ type: 'task_run_updated', run: startedRun });
|
|
164
|
+
broadcastLive(runTask.id, { type: 'snapshot', run });
|
|
165
|
+
void consumeChatRun(runTask, sessionId, content, run.runId);
|
|
166
|
+
res.status(202).json({ runId: run.runId, run });
|
|
167
|
+
});
|
|
168
|
+
chatRouter.get('/:id/live', (req, res) => {
|
|
169
|
+
const task = getTask(req.params.id);
|
|
170
|
+
if (!task)
|
|
171
|
+
return res.status(404).json({ error: 'Task not found' });
|
|
172
|
+
initSSE(res);
|
|
173
|
+
subscribe(task.id, res);
|
|
174
|
+
const run = getRun(task.id);
|
|
175
|
+
if (run)
|
|
176
|
+
sendSnapshot(res, run);
|
|
177
|
+
});
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { Router } from 'express';
|
|
2
|
+
import type { HermesWorkerAdapter } from '../adapters/hermes-worker.js';
|
|
3
|
+
export declare function createCronRouter(adapter: HermesWorkerAdapter): Router;
|
|
4
|
+
export declare function createTaskCronRouter(adapter: HermesWorkerAdapter): Router;
|