@poe-platform/safe-bash 0.1.788 → 0.1.790
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/image-ast/index.browser.js +147 -80
- package/dist/image-ast/index.js +147 -80
- package/dist/mp4-ast/mp4.d.ts +2 -0
- package/dist/pdf-ast/cos/parser.d.ts +1 -0
- package/dist/pdf-ast/cos/security.d.ts +2 -0
- package/dist/pdf-ast/cos/writer.d.ts +1 -0
- package/dist/pdf-ast/document.d.ts +3 -0
- package/dist/pdf-ast/edit/forms.d.ts +1 -0
- package/dist/pdf-ast/index.js +171 -82
- package/dist/safe-bash/chunks/{chunk-L5QQLNTO.js → chunk-22PI65AH.js} +2 -2
- package/dist/safe-bash/chunks/{chunk-Q3E6C3DX.js → chunk-2TAGYMPK.js} +49 -34
- package/dist/safe-bash/chunks/{chunk-Z3HX3ZBA.js → chunk-2W4HTMEK.js} +52 -48
- package/dist/safe-bash/chunks/{chunk-FFZXP6ZC.js → chunk-3M7L7XU2.js} +2 -2
- package/dist/safe-bash/chunks/{chunk-XNODZRVD.js → chunk-3QAO6UYS.js} +2 -2
- package/dist/safe-bash/chunks/{chunk-YPETOVQU.js → chunk-3VKFK3NF.js} +2 -2
- package/dist/safe-bash/chunks/chunk-5OST7NOX.js +42 -0
- package/dist/safe-bash/chunks/{chunk-KEBSX2AX.js → chunk-6HLURHVU.js} +2 -2
- package/dist/safe-bash/chunks/chunk-DYEUZE6Z.js +19 -0
- package/dist/safe-bash/chunks/{chunk-T2TGCHKE.js → chunk-FM3WBSZT.js} +2 -2
- package/dist/safe-bash/chunks/chunk-GAYRKQM6.js +22 -0
- package/dist/safe-bash/chunks/{chunk-Q45QCA4J.js → chunk-I3KSESCR.js} +0 -7
- package/dist/safe-bash/chunks/{chunk-OSKDIBQS.js → chunk-JLIMK5TD.js} +1 -1
- package/dist/safe-bash/chunks/{chunk-2AYZCT5X.js → chunk-JQ2FAJJT.js} +27 -23
- package/dist/safe-bash/chunks/{chunk-QA3NVP43.js → chunk-JRE6Z3T7.js} +2 -2
- package/dist/safe-bash/chunks/{chunk-DC5EHLKS.js → chunk-NDIL6T7Y.js} +5 -5
- package/dist/safe-bash/chunks/{chunk-747G42FY.js → chunk-OPR4UAIT.js} +2 -2
- package/dist/safe-bash/chunks/chunk-OSMQCYSP.js +19 -0
- package/dist/safe-bash/chunks/chunk-OYB332PQ.js +17 -0
- package/dist/safe-bash/chunks/{chunk-ZMYVCRAF.js → chunk-QTIH2AFE.js} +77 -69
- package/dist/safe-bash/chunks/{chunk-PYTLIUST.js → chunk-SBESXWT2.js} +43 -44
- package/dist/safe-bash/chunks/{chunk-4FDQJUFW.js → chunk-SDEPGTOF.js} +1 -1
- package/dist/safe-bash/chunks/chunk-UZU5BIJI.js +32 -0
- package/dist/safe-bash/chunks/{chunk-BI6JV62X.js → chunk-VCCMROTL.js} +7 -10
- package/dist/safe-bash/chunks/chunk-W47GHRRF.js +13 -0
- package/dist/safe-bash/chunks/{chunk-NPMQWZUZ.js → chunk-WS7KZIUM.js} +2 -2
- package/dist/safe-bash/chunks/{chunk-3PZYHMGM.js → chunk-YYAERCWS.js} +7 -7
- package/dist/safe-bash/chunks/{chunk-5U7JECDB.js → chunk-ZPGVEUKF.js} +8 -7
- package/dist/safe-bash/chunks/{csvkit-K55OYAQC.js → csvkit-USUJG62I.js} +65 -11
- package/dist/safe-bash/chunks/{ffmpeg-BEFTQ6DZ.js → ffmpeg-KRGG5DLH.js} +21 -10
- package/dist/safe-bash/chunks/{gh-HQWOWLWE.js → gh-UCFDUZCX.js} +16 -8
- package/dist/safe-bash/chunks/{git-UFNPAOYZ.js → git-LPAF6KDG.js} +7 -9
- package/dist/safe-bash/chunks/{imagemagick-53BMHH6D.js → imagemagick-KGREKK4G.js} +38 -7
- package/dist/safe-bash/chunks/{implementation-QUTAAYMT.js → implementation-FXDRYS5A.js} +34 -8
- package/dist/safe-bash/chunks/{pdfimages-4OYI6FLG.js → pdfimages-UADCF4G4.js} +12 -8
- package/dist/safe-bash/chunks/{pdfinfo-I7U6TQPP.js → pdfinfo-O7UWPF4W.js} +38 -13
- package/dist/safe-bash/chunks/{pdftk-SUA6FMHI.js → pdftk-AERXIJTN.js} +13 -8
- package/dist/safe-bash/chunks/{pdftoppm-4C5DGEWX.js → pdftoppm-L466JQKI.js} +17 -10
- package/dist/safe-bash/chunks/{pdftotext-Y4WI225Y.js → pdftotext-SUSI4WXS.js} +19 -9
- package/dist/safe-bash/chunks/{qpdf-IORB4RV5.js → qpdf-YL24KVRH.js} +14 -8
- package/dist/safe-bash/chunks/{sips-WHAMJFEU.js → sips-QXEQZERX.js} +14 -7
- package/dist/safe-bash/chunks/{soffice-SYEK6WJS.js → soffice-TBITRML3.js} +16 -8
- package/dist/safe-bash/chunks/{wkhtmltopdf-ZIICWJLF.js → wkhtmltopdf-NJA2THRC.js} +27 -7
- package/dist/safe-bash/command-chunks/chunk-2C5BEBPY.js +1388 -0
- package/dist/safe-bash/command-chunks/{chunk-FXYWQ6S4.js → chunk-2EXV2ZLV.js} +2 -2
- package/dist/safe-bash/command-chunks/{chunk-PFBJR2PY.js → chunk-2KRKKW5S.js} +2 -2
- package/dist/safe-bash/command-chunks/{chunk-4DSJDVBM.js → chunk-32F3RBUW.js} +10 -749
- package/dist/safe-bash/command-chunks/{chunk-L3MLMXL4.js → chunk-3ZK5F23O.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-4QX6XCDD.js → chunk-4RNIZ3RT.js} +79 -0
- package/dist/safe-bash/command-chunks/{chunk-D7TADAYG.js → chunk-64LG3EVJ.js} +17 -0
- package/dist/safe-bash/command-chunks/{chunk-TOSM3T3A.js → chunk-6EASC5EC.js} +20 -9
- package/dist/safe-bash/command-chunks/{chunk-ZF3ZVGQC.js → chunk-7JRITHKW.js} +150 -80
- package/dist/safe-bash/command-chunks/{chunk-IJ3FXP4Q.js → chunk-A3ZX6SCY.js} +1 -1
- package/dist/safe-bash/{chunks/chunk-LD76P7AG.js → command-chunks/chunk-AKDMCNX4.js} +74 -39
- package/dist/safe-bash/command-chunks/{chunk-KSIGF4AG.js → chunk-BK4CMEE6.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-JUDOV5MJ.js → chunk-CBDVLMJB.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-XGMWWUHV.js → chunk-CZ5DAK4K.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-Z57TV6TC.js → chunk-EZ2DTOLI.js} +4 -2
- package/dist/safe-bash/command-chunks/{chunk-ADCGH6A7.js → chunk-FH3D75FC.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-WYJTWJZ5.js → chunk-G3G6W5ZE.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-3HDIDEUJ.js → chunk-GF54KE2M.js} +1 -1
- package/dist/safe-bash/command-chunks/chunk-H4LWTITX.js +169 -0
- package/dist/safe-bash/command-chunks/chunk-I2MQNBGR.js +145 -0
- package/dist/safe-bash/command-chunks/{chunk-Z7TYZG3A.js → chunk-IHHTTQX6.js} +5 -3
- package/dist/safe-bash/command-chunks/{chunk-5GRLAARV.js → chunk-IOXI5ZAJ.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-INDIFLBW.js → chunk-JTAGNROA.js} +4 -0
- package/dist/safe-bash/command-chunks/{chunk-Y5IHIAY3.js → chunk-MDPIOQUD.js} +12 -8
- package/dist/safe-bash/command-chunks/chunk-PGEYORBZ.js +25 -0
- package/dist/safe-bash/command-chunks/chunk-QI4MGIN6.js +6 -0
- package/dist/safe-bash/command-chunks/chunk-QM4UZF3C.js +753 -0
- package/dist/safe-bash/command-chunks/chunk-QTYZAWSB.js +91 -0
- package/dist/safe-bash/command-chunks/chunk-SNK7K3XW.js +90 -0
- package/dist/safe-bash/command-chunks/chunk-T5OLGM43.js +314 -0
- package/dist/safe-bash/command-chunks/chunk-TB7IFMUZ.js +802 -0
- package/dist/safe-bash/command-chunks/{chunk-YNT4ZJHW.js → chunk-TPPBPIWL.js} +3 -3
- package/dist/safe-bash/command-chunks/chunk-VMK4XVKO.js +82 -0
- package/dist/safe-bash/command-chunks/chunk-VNSJKXDU.js +130 -0
- package/dist/safe-bash/command-chunks/{chunk-2LP3VMPA.js → chunk-WFDW4XXD.js} +1 -17
- package/dist/safe-bash/command-chunks/chunk-WR37IS4O.js +318 -0
- package/dist/safe-bash/command-chunks/chunk-YFNTMH6Z.js +6 -0
- package/dist/safe-bash/commands/basic.js +148 -48
- package/dist/safe-bash/commands/bytes/compression/index.js +5 -6
- package/dist/safe-bash/commands/cmp.d.ts +2 -3
- package/dist/safe-bash/commands/cmp.js +2 -689
- package/dist/safe-bash/commands/csplit/index.browser.js +2 -2
- package/dist/safe-bash/commands/docx/index.browser.js +4 -47
- package/dist/safe-bash/commands/docx/index.d.ts +2 -24
- package/dist/safe-bash/commands/docx/index.js +2 -41
- package/dist/safe-bash/commands/docx/io.d.ts +1 -14
- package/dist/safe-bash/commands/docx/io.js +1 -15
- package/dist/safe-bash/commands/factor/index.browser.js +2 -2
- package/dist/safe-bash/commands/getopt/index.browser.js +2 -2
- package/dist/safe-bash/commands/hexdump/index.browser.js +2 -2
- package/dist/safe-bash/commands/iconv/index.browser.js +2 -2
- package/dist/safe-bash/commands/line-endings/index.browser.js +2 -2
- package/dist/safe-bash/commands/llm/command.d.ts +1 -4
- package/dist/safe-bash/commands/llm/command.js +1 -248
- package/dist/safe-bash/commands/llm/elevenlabs-stream.d.ts +1 -2
- package/dist/safe-bash/commands/llm/elevenlabs-stream.js +1 -117
- package/dist/safe-bash/commands/llm/elevenlabs.d.ts +1 -15
- package/dist/safe-bash/commands/llm/elevenlabs.js +1 -123
- package/dist/safe-bash/commands/llm/index.browser.js +20 -15
- package/dist/safe-bash/commands/llm/index.d.ts +1 -6
- package/dist/safe-bash/commands/llm/index.js +1 -4
- package/dist/safe-bash/commands/llm/mime.d.ts +1 -2
- package/dist/safe-bash/commands/llm/mime.js +1 -136
- package/dist/safe-bash/commands/llm/openai-http.d.ts +1 -8
- package/dist/safe-bash/commands/llm/openai-http.js +1 -143
- package/dist/safe-bash/commands/llm/openai-sse.d.ts +1 -3
- package/dist/safe-bash/commands/llm/openai-sse.js +1 -78
- package/dist/safe-bash/commands/llm/openai.d.ts +1 -14
- package/dist/safe-bash/commands/llm/openai.js +1 -288
- package/dist/safe-bash/commands/llm/providers/elevenlabs.d.ts +1 -1
- package/dist/safe-bash/commands/llm/providers/elevenlabs.js +1 -1
- package/dist/safe-bash/commands/llm/providers/index.browser.js +6 -6
- package/dist/safe-bash/commands/llm/providers/index.d.ts +1 -3
- package/dist/safe-bash/commands/llm/providers/index.js +1 -2
- package/dist/safe-bash/commands/llm/providers/openai.d.ts +1 -1
- package/dist/safe-bash/commands/llm/providers/openai.js +1 -1
- package/dist/safe-bash/commands/llm/providers/shared.d.ts +1 -23
- package/dist/safe-bash/commands/llm/providers/shared.js +1 -65
- package/dist/safe-bash/commands/llm/service.d.ts +1 -37
- package/dist/safe-bash/commands/llm/service.js +1 -151
- package/dist/safe-bash/commands/llm/types.d.ts +1 -52
- package/dist/safe-bash/commands/llm/types.js +1 -1
- package/dist/safe-bash/commands/mdq/index.browser.js +3 -3
- package/dist/safe-bash/commands/media/index.browser.js +1 -1
- package/dist/safe-bash/commands/network/index.browser.js +9 -9
- package/dist/safe-bash/commands/network/types.d.ts +2 -40
- package/dist/safe-bash/commands/node/index.browser.js +6 -8
- package/dist/safe-bash/commands/op/index.browser.js +3 -3
- package/dist/safe-bash/commands/op/index.js +12 -28
- package/dist/safe-bash/commands/pptx/index.d.ts +2 -28
- package/dist/safe-bash/commands/pptx/index.js +2 -152
- package/dist/safe-bash/commands/pr/index.browser.js +2 -2
- package/dist/safe-bash/commands/printf-float.d.ts +1 -0
- package/dist/safe-bash/commands/printf-float.js +48 -38
- package/dist/safe-bash/commands/printf-format.js +9 -6
- package/dist/safe-bash/commands/printf-quote.d.ts +3 -0
- package/dist/safe-bash/commands/printf-quote.js +62 -0
- package/dist/safe-bash/commands/printf-wide.d.ts +5 -0
- package/dist/safe-bash/commands/printf-wide.js +41 -0
- package/dist/safe-bash/commands/python/index.browser.js +8 -8
- package/dist/safe-bash/commands/python/worker.browser.js +2 -2
- package/dist/safe-bash/commands/truncate.d.ts +2 -3
- package/dist/safe-bash/commands/truncate.js +2 -686
- package/dist/safe-bash/commands/tsort/index.browser.js +2 -2
- package/dist/safe-bash/commands/xml/index.browser.js +2 -2
- package/dist/safe-bash/commands/yq/index.browser.js +3 -3
- package/dist/safe-bash/contracts/diagnostics.d.ts +2 -0
- package/dist/safe-bash/contracts/diagnostics.js +2 -0
- package/dist/safe-bash/contracts/runtime-control.d.ts +2 -0
- package/dist/safe-bash/contracts/runtime-control.js +2 -0
- package/dist/safe-bash/core.browser.d.ts +1 -1
- package/dist/safe-bash/core.browser.js +10645 -14065
- package/dist/safe-bash/core.d.ts +10 -1
- package/dist/safe-bash/core.js +0 -1
- package/dist/safe-bash/jobs.browser.js +5 -4
- package/dist/safe-bash/opt-in/commands/cmp/index.d.ts +6 -2
- package/dist/safe-bash/opt-in/commands/cmp/index.js +776 -79
- package/dist/safe-bash/opt-in/commands/cmp/options.d.ts +0 -12
- package/dist/safe-bash/opt-in/commands/cmp/options.js +0 -153
- package/dist/safe-bash/opt-in/commands/truncate/index.d.ts +8 -3
- package/dist/safe-bash/opt-in/commands/truncate/index.js +790 -272
- package/dist/safe-bash/opt-in/commands/truncate/sync.d.ts +1 -0
- package/dist/safe-bash/opt-in/commands/truncate/sync.js +60 -0
- package/dist/safe-bash/optional-host.browser.js +61 -80
- package/dist/safe-bash/optional-host.d.ts +3 -1
- package/dist/safe-bash/optional-host.js +3 -1
- package/dist/safe-bash/shell/runtime.js +44 -18
- package/dist/safe-bash/yq-browser/index.js +1 -1
- package/dist/safe-bash-checksum-engine/index.d.ts +1 -1
- package/dist/safe-bash-checksum-engine/index.js +14 -2
- package/dist/safe-bash-command-bzip2/index.js +2 -1
- package/dist/safe-bash-command-cmp/index.d.ts +10 -0
- package/dist/safe-bash-command-cmp/index.js +796 -0
- package/dist/safe-bash-command-cmp/options.d.ts +12 -0
- package/dist/safe-bash-command-cmp/options.js +42 -0
- package/dist/safe-bash-command-csvcut/index.js +11 -8
- package/dist/safe-bash-command-csvgrep/index.js +35 -7
- package/dist/safe-bash-command-csvkit/codecs/python.js +4 -3
- package/dist/safe-bash-command-csvkit/codecs/utf8.js +3 -2
- package/dist/safe-bash-command-csvkit/index.js +80 -324
- package/dist/safe-bash-command-csvkit/python-regex.d.ts +5 -0
- package/dist/safe-bash-command-csvkit/python-regex.js +14 -0
- package/dist/safe-bash-command-csvkit/runtime.d.ts +1 -0
- package/dist/safe-bash-command-csvkit/sync-support.js +4 -2
- package/dist/safe-bash-command-diff3/index.js +3 -0
- package/dist/safe-bash-command-docx/LICENSE +21 -0
- package/dist/safe-bash-command-docx/index.d.ts +30 -0
- package/dist/safe-bash-command-docx/index.js +67 -0
- package/dist/safe-bash-command-docx/io.d.ts +14 -0
- package/dist/safe-bash-command-docx/io.js +26 -0
- package/dist/safe-bash-command-envsubst/index.js +34 -3
- package/dist/safe-bash-command-exiftool/index.js +3 -0
- package/dist/safe-bash-command-ffmpeg/index.js +8073 -7940
- package/dist/safe-bash-command-fold/family.js +1 -1
- package/dist/safe-bash-command-fold/index.js +1 -1
- package/dist/safe-bash-command-git/git_rust.wasm +0 -0
- package/dist/safe-bash-command-git/wasm.generated.js +1 -1
- package/dist/safe-bash-command-htmlq/index.js +5 -0
- package/dist/safe-bash-command-imagemagick/index.d.ts +25 -21
- package/dist/safe-bash-command-imagemagick/index.js +671 -273
- package/dist/safe-bash-command-llm/LICENSE +21 -0
- package/dist/safe-bash-command-llm/command.d.ts +5 -0
- package/dist/safe-bash-command-llm/command.js +14 -0
- package/dist/safe-bash-command-llm/configuration.d.ts +18 -0
- package/dist/safe-bash-command-llm/elevenlabs-stream.d.ts +2 -0
- package/dist/safe-bash-command-llm/elevenlabs-stream.js +7 -0
- package/dist/safe-bash-command-llm/elevenlabs.d.ts +15 -0
- package/dist/safe-bash-command-llm/elevenlabs.js +10 -0
- package/dist/safe-bash-command-llm/index.d.ts +10 -0
- package/dist/safe-bash-command-llm/index.js +46 -0
- package/dist/safe-bash-command-llm/mime.d.ts +2 -0
- package/dist/safe-bash-command-llm/mime.js +9 -0
- package/dist/safe-bash-command-llm/model-options.d.ts +3 -0
- package/dist/safe-bash-command-llm/openai-http.d.ts +8 -0
- package/dist/safe-bash-command-llm/openai-http.js +17 -0
- package/dist/safe-bash-command-llm/openai-sse.d.ts +3 -0
- package/dist/safe-bash-command-llm/openai-sse.js +8 -0
- package/dist/safe-bash-command-llm/openai.d.ts +14 -0
- package/dist/safe-bash-command-llm/openai.js +12 -0
- package/dist/safe-bash-command-llm/providers/elevenlabs.d.ts +1 -0
- package/dist/safe-bash-command-llm/providers/elevenlabs.js +11 -0
- package/dist/safe-bash-command-llm/providers/index.d.ts +3 -0
- package/dist/safe-bash-command-llm/providers/index.js +24 -0
- package/dist/safe-bash-command-llm/providers/openai.d.ts +1 -0
- package/dist/safe-bash-command-llm/providers/openai.js +13 -0
- package/dist/safe-bash-command-llm/providers/shared.d.ts +23 -0
- package/dist/safe-bash-command-llm/providers/shared.js +13 -0
- package/dist/safe-bash-command-llm/schemas.d.ts +2 -0
- package/dist/safe-bash-command-llm/service.d.ts +42 -0
- package/dist/safe-bash-command-llm/service.js +9 -0
- package/dist/safe-bash-command-llm/templates.d.ts +27 -0
- package/dist/safe-bash-command-llm/types.d.ts +87 -0
- package/dist/safe-bash-command-llm/types.js +6 -0
- package/dist/safe-bash-command-mmdc/command.d.ts +4 -0
- package/dist/safe-bash-command-mmdc/index.d.ts +1 -1
- package/dist/safe-bash-command-mmdc/index.js +7134 -6699
- package/dist/safe-bash-command-mmdc/layout.d.ts +1 -0
- package/dist/safe-bash-command-mmdc/parser.d.ts +1 -0
- package/dist/safe-bash-command-mmdc/png.d.ts +3 -0
- package/dist/safe-bash-command-mmdc/raster.d.ts +1 -0
- package/dist/safe-bash-command-mmdc/svg.d.ts +1 -0
- package/dist/safe-bash-command-op/index.js +19 -14
- package/dist/safe-bash-command-pandoc/command.js +3 -3
- package/dist/safe-bash-command-pandoc/index.js +3 -3
- package/dist/safe-bash-command-pdfimages/index.d.ts +7 -1
- package/dist/safe-bash-command-pdfimages/index.js +210 -113
- package/dist/safe-bash-command-pdfinfo/index.d.ts +24 -20
- package/dist/safe-bash-command-pdfinfo/index.js +517 -241
- package/dist/safe-bash-command-pdftk/index.d.ts +7 -3
- package/dist/safe-bash-command-pdftk/index.js +261 -125
- package/dist/safe-bash-command-pdftoppm/index.d.ts +15 -7
- package/dist/safe-bash-command-pdftoppm/index.js +326 -189
- package/dist/safe-bash-command-pdftotext/index.d.ts +9 -5
- package/dist/safe-bash-command-pdftotext/index.js +237 -107
- package/dist/safe-bash-command-pptx/LICENSE +21 -0
- package/dist/safe-bash-command-pptx/index.d.ts +33 -0
- package/dist/safe-bash-command-pptx/index.js +168 -0
- package/dist/safe-bash-command-qpdf/index.d.ts +9 -3
- package/dist/safe-bash-command-qpdf/index.js +254 -130
- package/dist/safe-bash-command-sha512sum/index.js +12 -475
- package/dist/safe-bash-command-sips/index.d.ts +9 -5
- package/dist/safe-bash-command-sips/index.js +65 -46
- package/dist/safe-bash-command-soffice/index.d.ts +9 -3
- package/dist/safe-bash-command-soffice/index.js +66 -25
- package/dist/safe-bash-command-sqlite3/engine.d.ts +9 -0
- package/dist/safe-bash-command-sqlite3/index.d.ts +1 -0
- package/dist/safe-bash-command-sqlite3/index.js +851 -352
- package/dist/safe-bash-command-ssconvert/formats/xls.js +3 -3
- package/dist/safe-bash-command-ssconvert/index.js +147 -80
- package/dist/safe-bash-command-timeout/index.js +3 -3
- package/dist/safe-bash-command-truncate/index.d.ts +8 -3
- package/dist/safe-bash-command-truncate/index.js +790 -272
- package/dist/safe-bash-command-truncate/sync.d.ts +1 -0
- package/dist/safe-bash-command-truncate/sync.js +60 -0
- package/dist/safe-bash-command-wkhtmltopdf/index.js +239 -118
- package/dist/safe-bash-command-wkhtmltopdf/pdf-renderer.d.ts +1 -1
- package/dist/safe-bash-command-xxd/index.js +78 -20
- package/dist/safe-bash-command-xz/command.d.ts +4 -0
- package/dist/safe-bash-command-xz/index.d.ts +1 -1
- package/dist/safe-bash-command-xz/index.js +1 -1
- package/dist/safe-bash-compression-engine/bounded-codec.js +3 -3
- package/dist/safe-bash-compression-engine/codec-loader.js +2 -2
- package/dist/safe-bash-compression-engine/files.js +6 -6
- package/dist/safe-bash-compression-engine/index.js +5 -5
- package/dist/safe-bash-compression-engine/operand.js +6 -6
- package/dist/safe-bash-compression-engine/stream.js +5 -5
- package/dist/safe-bash-compression-engine/zstd-decode.js +4 -4
- package/dist/safe-bash-contracts/command.js +3 -3
- package/dist/safe-bash-contracts/default-executor.d.ts +5 -0
- package/dist/safe-bash-contracts/default-executor.js +37 -0
- package/dist/safe-bash-contracts/diagnostics.js +3 -3
- package/dist/safe-bash-contracts/escaping.js +9 -9
- package/dist/safe-bash-contracts/filesystem-descriptor.js +3 -3
- package/dist/safe-bash-contracts/filesystem-output.js +8 -8
- package/dist/safe-bash-contracts/http.d.ts +41 -0
- package/dist/safe-bash-contracts/http.js +6 -0
- package/dist/safe-bash-contracts/index.js +21 -19
- package/dist/safe-bash-contracts/io.d.ts +12 -0
- package/dist/safe-bash-contracts/io.js +4 -1
- package/dist/safe-bash-contracts/output.js +3 -2
- package/dist/safe-bash-contracts/runtime-control.js +2 -2
- package/dist/safe-bash-contracts/signals.js +1 -1
- package/dist/safe-bash-contracts/yield.d.ts +1 -0
- package/dist/safe-bash-contracts/yield.js +3 -1
- package/dist/safe-bash-csv-engine/index.d.ts +10 -1
- package/dist/safe-bash-csv-engine/index.js +78 -6
- package/dist/safe-bash-io-engine/commands/search/requirements.js +3 -3
- package/dist/safe-bash-io-engine/commands/text-programs/shared.js +3 -3
- package/dist/safe-bash-io-engine/gnu-information.d.ts +1 -1
- package/dist/safe-bash-io-engine/gnu-information.js +1 -1
- package/dist/safe-bash-io-engine/internal.d.ts +1 -1
- package/dist/safe-bash-io-engine/internal.js +2 -2
- package/dist/safe-bash-query-engine/index.js +5 -5
- package/dist/safe-bash-query-engine/interpreter.js +3 -3
- package/dist/safe-bash-query-engine/query-core.js +5 -5
- package/package.json +2 -2
- package/dist/safe-bash/chunks/chunk-2G2T5MEM.js +0 -14
- package/dist/safe-bash/chunks/chunk-FJZNUUOQ.js +0 -81
- package/dist/safe-bash/chunks/chunk-GJWUEOT6.js +0 -14
- package/dist/safe-bash/chunks/chunk-LAPF2XE6.js +0 -14
- package/dist/safe-bash/chunks/chunk-O6356Z27.js +0 -37
- package/dist/safe-bash/chunks/chunk-S2LSZFZ6.js +0 -758
- package/dist/safe-bash/chunks/chunk-T3VDYWKZ.js +0 -21
- package/dist/safe-bash/chunks/chunk-VYW4Q6KF.js +0 -12
- package/dist/safe-bash/chunks/chunk-WHURJBET.js +0 -409
- package/dist/safe-bash/opt-in/commands/cmp/compare.js +0 -95
- package/dist/safe-bash/opt-in/commands/cmp/io.js +0 -218
- package/dist/safe-bash/command-chunks/{chunk-RTOJNFFL.js → chunk-KNI4GRXF.js} +7 -7
- package/dist/safe-bash/command-chunks/{chunk-DEH3CMGL.js → chunk-QJ3ONEBI.js} +3 -3
|
@@ -0,0 +1,1388 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createLlmService,
|
|
3
|
+
validateModelOptions
|
|
4
|
+
} from "./chunk-T5OLGM43.js";
|
|
5
|
+
import {
|
|
6
|
+
acceptsMimeType,
|
|
7
|
+
sniffMimeType
|
|
8
|
+
} from "./chunk-AKDMCNX4.js";
|
|
9
|
+
import {
|
|
10
|
+
init_buffer
|
|
11
|
+
} from "./chunk-HX3SHTCE.js";
|
|
12
|
+
|
|
13
|
+
// packages/safe-bash-command-llm/dist/command.js
|
|
14
|
+
init_buffer();
|
|
15
|
+
import { createOutputOperation, getCommandArguments, FsError as FsError6 } from "../../safe-bash-contracts/index.js";
|
|
16
|
+
import { inheritYieldCheckpoint, yieldTurn } from "../../safe-bash-contracts/yield.js";
|
|
17
|
+
import { writeDiagnostic } from "../../safe-bash-contracts/escaping.js";
|
|
18
|
+
import { pathOf as pathOf2 } from "../../safe-bash-contracts/path.js";
|
|
19
|
+
|
|
20
|
+
// packages/safe-bash-command-llm/dist/configuration.js
|
|
21
|
+
init_buffer();
|
|
22
|
+
import { FsError as FsError2, toByteSource as toByteSource2 } from "../../safe-bash-contracts/index.js";
|
|
23
|
+
import { pathOf } from "../../safe-bash-contracts/path.js";
|
|
24
|
+
|
|
25
|
+
// packages/safe-bash-command-llm/dist/configuration-publication.js
|
|
26
|
+
init_buffer();
|
|
27
|
+
import { retainFileSystemCleanup } from "@poe-platform/safe-fs/core";
|
|
28
|
+
import { FsError, toByteSource } from "../../safe-bash-contracts/index.js";
|
|
29
|
+
var stagingSerial = 0;
|
|
30
|
+
async function publishConfiguration(fs, directory, path, bytes, parent, expected, signal) {
|
|
31
|
+
const capabilities = await fs.capabilitiesFor?.(path, { signal, create: expected === null }) ?? fs.capabilities;
|
|
32
|
+
if (capabilities.atomicFilePublication === true && fs.publishFileConditional) {
|
|
33
|
+
await fs.publishFileConditional(path, toByteSource(bytes), { parent, expected, mode: 384, signal, maxBytes: bytes.byteLength });
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
if ((capabilities.atomicFileMutation === true || capabilities.trustedOwnedStaging === true) && fs.writeFileConditional) {
|
|
37
|
+
await fs.writeFileConditional(path, bytes, { parent, expected, mode: 384, signal });
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
if (capabilities.atomicFileStaging !== true || !fs.createStagedFile || !fs.publishStagedFile || !fs.removeStagedFile) {
|
|
41
|
+
throw new FsError("ENOTSUP", { path, message: "LLM configuration requires atomic conditional publication" });
|
|
42
|
+
}
|
|
43
|
+
const ancestors = [];
|
|
44
|
+
let current = "/";
|
|
45
|
+
for (const component of ["", ...directory.split("/").filter(Boolean)]) {
|
|
46
|
+
if (component)
|
|
47
|
+
current = `${current === "/" ? "" : current}/${component}`;
|
|
48
|
+
const stat = await fs.lstat(current, { signal });
|
|
49
|
+
if (stat.type !== "directory")
|
|
50
|
+
throw new FsError("ENOTDIR", { path: current });
|
|
51
|
+
ancestors.push({ path: current, stat });
|
|
52
|
+
}
|
|
53
|
+
let staging;
|
|
54
|
+
const cleanup = retainFileSystemCleanup(fs, async (view) => {
|
|
55
|
+
if (staging)
|
|
56
|
+
await view.removeStagedFile(staging);
|
|
57
|
+
}, { maxOperations: 1 });
|
|
58
|
+
try {
|
|
59
|
+
for (let attempt = 0; attempt < 16; attempt++) {
|
|
60
|
+
try {
|
|
61
|
+
staging = await fs.createStagedFile(`${directory}/.llm-config-${++stagingSerial}`, "entry", { type: "file", data: bytes }, { parent, mode: 384, signal });
|
|
62
|
+
break;
|
|
63
|
+
} catch (error) {
|
|
64
|
+
signal.throwIfAborted();
|
|
65
|
+
if (!(error instanceof FsError) || error.code !== "EEXIST")
|
|
66
|
+
throw error;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
if (!staging)
|
|
70
|
+
throw new FsError("EEXIST", { path: directory, message: "LLM configuration staging names exhausted" });
|
|
71
|
+
await fs.publishStagedFile(staging, path, { parent, destination: expected, ancestors, signal });
|
|
72
|
+
} finally {
|
|
73
|
+
await cleanup();
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// packages/safe-bash-command-llm/dist/configuration.js
|
|
78
|
+
var maxConfigurationBytes = 1024 * 1024;
|
|
79
|
+
var locks = /* @__PURE__ */ new WeakMap();
|
|
80
|
+
function record(value) {
|
|
81
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
82
|
+
}
|
|
83
|
+
function stringRecord(value) {
|
|
84
|
+
return record(value) && Object.values(value).every((item) => typeof item === "string");
|
|
85
|
+
}
|
|
86
|
+
function createLlmConfiguration(context) {
|
|
87
|
+
const { fs, signal } = context;
|
|
88
|
+
const base = context.env.XDG_CONFIG_HOME ?? `${context.env.HOME ?? "/"}/.config`;
|
|
89
|
+
const directory = pathOf(context, context.env.LLM_USER_PATH ?? `${base}/io.datasette.llm`);
|
|
90
|
+
const filename = (name) => `${directory}/${name}`;
|
|
91
|
+
const stat = async (path) => {
|
|
92
|
+
try {
|
|
93
|
+
const result = await fs.lstat(path, { signal });
|
|
94
|
+
if (result.type !== "file")
|
|
95
|
+
throw new FsError2("EINVAL", { path, message: "LLM configuration must be a regular file" });
|
|
96
|
+
return result;
|
|
97
|
+
} catch (error) {
|
|
98
|
+
if (error instanceof FsError2 && error.code === "ENOENT")
|
|
99
|
+
return null;
|
|
100
|
+
throw error;
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
const read = async (name) => {
|
|
104
|
+
const path = filename(name);
|
|
105
|
+
if (!await stat(path))
|
|
106
|
+
return void 0;
|
|
107
|
+
const decoder = new TextDecoder("utf-8", { fatal: true });
|
|
108
|
+
let bytes = 0, text = "";
|
|
109
|
+
const source = fs.readStream?.(path, { signal, chunkSize: 16384 }) ?? toByteSource2(await fs.readFile(path, { signal, maxBytes: maxConfigurationBytes }));
|
|
110
|
+
for await (const chunk of source) {
|
|
111
|
+
signal.throwIfAborted();
|
|
112
|
+
if (chunk.byteLength > maxConfigurationBytes - bytes)
|
|
113
|
+
throw new FsError2("EFBIG", { path, message: "LLM configuration byte limit exceeded" });
|
|
114
|
+
bytes += chunk.byteLength;
|
|
115
|
+
text += decoder.decode(chunk, { stream: true });
|
|
116
|
+
}
|
|
117
|
+
return text + decoder.decode();
|
|
118
|
+
};
|
|
119
|
+
const write = async (name, text, observed) => {
|
|
120
|
+
signal.throwIfAborted();
|
|
121
|
+
if (!fs.publishFileConditional && !fs.writeFileConditional && !fs.createStagedFile)
|
|
122
|
+
throw new FsError2("ENOTSUP", { message: "LLM configuration requires atomic conditional publication" });
|
|
123
|
+
const bytes = new TextEncoder().encode(text);
|
|
124
|
+
if (bytes.byteLength > maxConfigurationBytes)
|
|
125
|
+
throw new FsError2("EFBIG", { message: "LLM configuration byte limit exceeded" });
|
|
126
|
+
await fs.mkdir(directory, { recursive: true, signal });
|
|
127
|
+
const parent = await fs.stat(directory, { signal });
|
|
128
|
+
const path = filename(name), expected = observed === void 0 ? await stat(path) : observed;
|
|
129
|
+
await publishConfiguration(fs, directory, path, bytes, parent, expected, signal);
|
|
130
|
+
};
|
|
131
|
+
const serialized = async (operation) => {
|
|
132
|
+
let entries = locks.get(fs);
|
|
133
|
+
if (!entries) {
|
|
134
|
+
entries = /* @__PURE__ */ new Map();
|
|
135
|
+
locks.set(fs, entries);
|
|
136
|
+
}
|
|
137
|
+
const previous = entries.get(directory) ?? Promise.resolve();
|
|
138
|
+
const current = previous.catch(() => {
|
|
139
|
+
}).then(() => {
|
|
140
|
+
signal.throwIfAborted();
|
|
141
|
+
return operation();
|
|
142
|
+
});
|
|
143
|
+
entries.set(directory, current);
|
|
144
|
+
try {
|
|
145
|
+
await current;
|
|
146
|
+
} finally {
|
|
147
|
+
if (entries.get(directory) === current)
|
|
148
|
+
entries.delete(directory);
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
const json = async (name) => {
|
|
152
|
+
const text = await read(name);
|
|
153
|
+
return text === void 0 ? {} : JSON.parse(text);
|
|
154
|
+
};
|
|
155
|
+
const aliases = async () => {
|
|
156
|
+
const value = await json("aliases.json");
|
|
157
|
+
if (!stringRecord(value))
|
|
158
|
+
throw new Error("Invalid aliases.json: expected string values");
|
|
159
|
+
return value;
|
|
160
|
+
};
|
|
161
|
+
const options = async () => {
|
|
162
|
+
const value = await json("model_options.json");
|
|
163
|
+
if (!record(value) || !Object.values(value).every(stringRecord))
|
|
164
|
+
throw new Error("Invalid model_options.json: expected model option objects");
|
|
165
|
+
return value;
|
|
166
|
+
};
|
|
167
|
+
const resolveAlias = async (name) => {
|
|
168
|
+
const values = await aliases(), seen = /* @__PURE__ */ new Set();
|
|
169
|
+
while (Object.hasOwn(values, name)) {
|
|
170
|
+
if (seen.has(name))
|
|
171
|
+
throw new Error(`Alias cycle: ${name}`);
|
|
172
|
+
seen.add(name);
|
|
173
|
+
name = values[name];
|
|
174
|
+
}
|
|
175
|
+
return name;
|
|
176
|
+
};
|
|
177
|
+
const setModelOption = (model, name, value) => serialized(async () => {
|
|
178
|
+
const expected = await stat(filename("model_options.json"));
|
|
179
|
+
const values = await options();
|
|
180
|
+
const previous = Object.hasOwn(values, model) ? values[model] : {};
|
|
181
|
+
const next = { ...values, [model]: { ...previous, [name]: value } };
|
|
182
|
+
await write("model_options.json", JSON.stringify(next, null, 2), expected);
|
|
183
|
+
});
|
|
184
|
+
return {
|
|
185
|
+
directory,
|
|
186
|
+
aliases,
|
|
187
|
+
resolveAlias,
|
|
188
|
+
allModelOptions: options,
|
|
189
|
+
setAlias: (name, model) => serialized(async () => {
|
|
190
|
+
const expected = await stat(filename("aliases.json"));
|
|
191
|
+
const values = await aliases();
|
|
192
|
+
const canonical = await resolveAlias(model);
|
|
193
|
+
await write("aliases.json", JSON.stringify({ ...values, [name]: canonical }, null, 4) + "\n", expected);
|
|
194
|
+
}),
|
|
195
|
+
removeAlias: (name) => serialized(async () => {
|
|
196
|
+
const expected = await stat(filename("aliases.json"));
|
|
197
|
+
const values = await aliases();
|
|
198
|
+
if (!Object.hasOwn(values, name))
|
|
199
|
+
throw new Error(`No such alias: ${name}`);
|
|
200
|
+
delete values[name];
|
|
201
|
+
await write("aliases.json", JSON.stringify(values, null, 4) + "\n", expected);
|
|
202
|
+
}),
|
|
203
|
+
defaultModel: () => read("default_model.txt"),
|
|
204
|
+
setDefaultModel: (model) => serialized(() => write("default_model.txt", model)),
|
|
205
|
+
modelOptions: async (model) => {
|
|
206
|
+
const values = await options();
|
|
207
|
+
return Object.hasOwn(values, model) ? values[model] : {};
|
|
208
|
+
},
|
|
209
|
+
setModelOption,
|
|
210
|
+
clearModelOption: (model, name) => serialized(async () => {
|
|
211
|
+
const expected = await stat(filename("model_options.json"));
|
|
212
|
+
const values = await options();
|
|
213
|
+
if (!Object.hasOwn(values, model))
|
|
214
|
+
return;
|
|
215
|
+
if (name === void 0)
|
|
216
|
+
delete values[model];
|
|
217
|
+
else {
|
|
218
|
+
delete values[model][name];
|
|
219
|
+
if (!Object.keys(values[model]).length)
|
|
220
|
+
delete values[model];
|
|
221
|
+
}
|
|
222
|
+
await write("model_options.json", JSON.stringify(values, null, 2), expected);
|
|
223
|
+
})
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// packages/safe-bash-command-llm/dist/templates.js
|
|
228
|
+
init_buffer();
|
|
229
|
+
import { FsError as FsError3 } from "../../safe-bash-contracts/index.js";
|
|
230
|
+
var templateFields = ["name", "prompt", "system", "model", "defaults", "options", "attachments", "attachment_types"];
|
|
231
|
+
function template(value, name) {
|
|
232
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
233
|
+
throw new Error(`Invalid template: ${name}`);
|
|
234
|
+
const fields = value;
|
|
235
|
+
for (const [key, item] of Object.entries(fields)) {
|
|
236
|
+
if (!templateFields.includes(key))
|
|
237
|
+
throw new Error(`Unsupported template field: ${key}`);
|
|
238
|
+
if (key === "attachments") {
|
|
239
|
+
if (!Array.isArray(item) || item.some((value2) => typeof value2 !== "string"))
|
|
240
|
+
throw new Error(`Invalid template: ${name}`);
|
|
241
|
+
} else if (key === "attachment_types") {
|
|
242
|
+
if (!Array.isArray(item) || item.some((value2) => !value2 || typeof value2 !== "object" || Array.isArray(value2) || typeof value2.type !== "string" || typeof value2.value !== "string"))
|
|
243
|
+
throw new Error(`Invalid template: ${name}`);
|
|
244
|
+
fields[key] = item.map(({ type, value: value2 }) => ({ type, value: value2 }));
|
|
245
|
+
} else if (["defaults", "options"].includes(key)) {
|
|
246
|
+
if (!item || typeof item !== "object" || Array.isArray(item) || Object.values(item).some((value2) => typeof value2 !== "string" && typeof value2 !== "number" && typeof value2 !== "boolean"))
|
|
247
|
+
throw new Error(`Invalid template: ${name}`);
|
|
248
|
+
} else if (typeof item !== "string")
|
|
249
|
+
throw new Error(`Invalid template: ${name}`);
|
|
250
|
+
}
|
|
251
|
+
return { ...fields, name };
|
|
252
|
+
}
|
|
253
|
+
function interpolate(text, params, validateOnly = false) {
|
|
254
|
+
if (!text)
|
|
255
|
+
return text;
|
|
256
|
+
let result = "";
|
|
257
|
+
const missing = [];
|
|
258
|
+
for (let index = 0; index < text.length; index++) {
|
|
259
|
+
if (text[index] !== "$") {
|
|
260
|
+
if (!validateOnly)
|
|
261
|
+
result += text[index];
|
|
262
|
+
continue;
|
|
263
|
+
}
|
|
264
|
+
if (text[index + 1] === "$") {
|
|
265
|
+
if (!validateOnly)
|
|
266
|
+
result += "$";
|
|
267
|
+
index++;
|
|
268
|
+
continue;
|
|
269
|
+
}
|
|
270
|
+
const start = index, braced = text[index + 1] === "{";
|
|
271
|
+
if (braced)
|
|
272
|
+
index++;
|
|
273
|
+
let name = "";
|
|
274
|
+
while (index + 1 < text.length && "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_".includes(text[index + 1]))
|
|
275
|
+
name += text[++index];
|
|
276
|
+
if (!name || "0123456789".includes(name[0]) || braced && text[index + 1] !== "}")
|
|
277
|
+
throw new Error(`Invalid placeholder in template at position ${start}`);
|
|
278
|
+
if (braced)
|
|
279
|
+
index++;
|
|
280
|
+
if (!Object.hasOwn(params, name)) {
|
|
281
|
+
if (!missing.includes(name))
|
|
282
|
+
missing.push(name);
|
|
283
|
+
} else if (!validateOnly)
|
|
284
|
+
result += String(params[name]);
|
|
285
|
+
}
|
|
286
|
+
if (missing.length)
|
|
287
|
+
throw new Error(`Missing variables: ${missing.join(", ")}`);
|
|
288
|
+
return result;
|
|
289
|
+
}
|
|
290
|
+
function validateLlmTemplateParameters(value, params) {
|
|
291
|
+
const variables = { ...value.defaults, ...params, input: "" };
|
|
292
|
+
for (const text of [value.prompt, value.system])
|
|
293
|
+
interpolate(text, variables, true);
|
|
294
|
+
}
|
|
295
|
+
function llmTemplateUsesInput(value) {
|
|
296
|
+
for (const text of [value.prompt, value.system]) {
|
|
297
|
+
if (!text)
|
|
298
|
+
continue;
|
|
299
|
+
for (let index = 0; index < text.length; index++) {
|
|
300
|
+
if (text[index] !== "$")
|
|
301
|
+
continue;
|
|
302
|
+
if (text[index + 1] === "$") {
|
|
303
|
+
index++;
|
|
304
|
+
continue;
|
|
305
|
+
}
|
|
306
|
+
let name = "";
|
|
307
|
+
while (index + 1 < text.length && "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_".includes(text[index + 1]))
|
|
308
|
+
name += text[++index];
|
|
309
|
+
if (name === "input")
|
|
310
|
+
return true;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
return false;
|
|
314
|
+
}
|
|
315
|
+
function evaluateLlmTemplate(value, input, params) {
|
|
316
|
+
const variables = { ...value.defaults, ...params, input };
|
|
317
|
+
return { prompt: value.prompt ? interpolate(value.prompt, variables) : input, ...value.system === void 0 ? {} : { system: interpolate(value.system, variables) } };
|
|
318
|
+
}
|
|
319
|
+
function createLlmTemplateStore(context) {
|
|
320
|
+
const directory = `${createLlmConfiguration(context).directory}/templates`;
|
|
321
|
+
const filename = (name) => {
|
|
322
|
+
if (!name || name.includes("/") || name.includes("\\") || name === "." || name === "..")
|
|
323
|
+
throw new Error(`Invalid template name: ${name}`);
|
|
324
|
+
return `${directory}/${name}.yaml`;
|
|
325
|
+
};
|
|
326
|
+
const load = async (name) => {
|
|
327
|
+
try {
|
|
328
|
+
const { parse: parse2 } = await import("../bundled-yaml/index.js");
|
|
329
|
+
const bytes = await context.fs.readFile(filename(name), { signal: context.signal });
|
|
330
|
+
return template(parse2(new TextDecoder("utf-8", { fatal: true }).decode(bytes)), name);
|
|
331
|
+
} catch (error) {
|
|
332
|
+
if (error instanceof FsError3 && error.code === "ENOENT")
|
|
333
|
+
throw new Error(`Invalid template: ${name}`);
|
|
334
|
+
throw error;
|
|
335
|
+
}
|
|
336
|
+
};
|
|
337
|
+
return {
|
|
338
|
+
directory,
|
|
339
|
+
load,
|
|
340
|
+
async save(name, value) {
|
|
341
|
+
const { stringify } = await import("../bundled-yaml/index.js");
|
|
342
|
+
const path = filename(name);
|
|
343
|
+
await context.fs.mkdir(directory, { recursive: true, signal: context.signal });
|
|
344
|
+
const parent = await context.fs.stat(directory, { signal: context.signal });
|
|
345
|
+
let expected;
|
|
346
|
+
try {
|
|
347
|
+
expected = await context.fs.lstat(path, { signal: context.signal });
|
|
348
|
+
} catch (error) {
|
|
349
|
+
if (!(error instanceof FsError3) || error.code !== "ENOENT")
|
|
350
|
+
throw error;
|
|
351
|
+
expected = null;
|
|
352
|
+
}
|
|
353
|
+
const bytes = new TextEncoder().encode(stringify(value, { indent: 4, lineWidth: 0 }));
|
|
354
|
+
await publishConfiguration(context.fs, directory, path, bytes, parent, expected, context.signal);
|
|
355
|
+
},
|
|
356
|
+
async command(args, output) {
|
|
357
|
+
const [command, name] = args;
|
|
358
|
+
if (command === "path" && args.length === 1) {
|
|
359
|
+
await output(directory + "\n");
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
362
|
+
if (command === "show" && name && args.length === 2) {
|
|
363
|
+
let value;
|
|
364
|
+
try {
|
|
365
|
+
value = await load(name);
|
|
366
|
+
} catch {
|
|
367
|
+
throw new Error(`Template '${name}' not found or invalid`);
|
|
368
|
+
}
|
|
369
|
+
const { stringify } = await import("../bundled-yaml/index.js");
|
|
370
|
+
const sorted = Object.fromEntries(Object.entries(value).sort(([a], [b]) => a.localeCompare(b)));
|
|
371
|
+
await output(stringify(sorted, { indent: 4, lineWidth: 0 }) + "\n");
|
|
372
|
+
return;
|
|
373
|
+
}
|
|
374
|
+
if (command !== void 0 && command !== "list" || args.length > 1)
|
|
375
|
+
throw new Error("Invalid templates command");
|
|
376
|
+
let files;
|
|
377
|
+
try {
|
|
378
|
+
files = await context.fs.readdir(directory, { signal: context.signal });
|
|
379
|
+
} catch (error) {
|
|
380
|
+
if (error instanceof FsError3 && error.code === "ENOENT")
|
|
381
|
+
return;
|
|
382
|
+
throw error;
|
|
383
|
+
}
|
|
384
|
+
const values = [];
|
|
385
|
+
for (const file of files) {
|
|
386
|
+
if (file.type !== "file" || !file.name.endsWith(".yaml"))
|
|
387
|
+
continue;
|
|
388
|
+
try {
|
|
389
|
+
values.push(await load(file.name.slice(0, -5)));
|
|
390
|
+
} catch {
|
|
391
|
+
context.signal.throwIfAborted();
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
const width = Math.max(0, ...values.map((value) => [...value.name].length));
|
|
395
|
+
for (const value of values.sort((a, b) => a.name.localeCompare(b.name))) {
|
|
396
|
+
const description = (value.system ? `system: ${value.system}${value.prompt ? ` prompt: ${value.prompt}` : ""}` : value.prompt ?? "").split("\n").join(" ");
|
|
397
|
+
await output(`${value.name}${" ".repeat(width - [...value.name].length)} : ${description}
|
|
398
|
+
`);
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
};
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
// packages/safe-bash-command-llm/dist/retained-spool.js
|
|
405
|
+
init_buffer();
|
|
406
|
+
import { FsError as FsError4 } from "../../safe-bash-contracts/index.js";
|
|
407
|
+
var serial = 0;
|
|
408
|
+
function verifyRetainedFile(actual, expected) {
|
|
409
|
+
const sameOwner = expected.identityScope !== void 0 && expected.identityScope === actual.identityScope;
|
|
410
|
+
const sameIdentity = expected.opaqueIdentity !== void 0 ? expected.opaqueIdentity === actual.opaqueIdentity : expected.dev !== void 0 && expected.ino !== void 0 && expected.dev === actual.dev && expected.ino === actual.ino;
|
|
411
|
+
if (!sameOwner || !sameIdentity || actual.type !== "file" || actual.size !== expected.size || actual.revision !== expected.revision || actual.opaqueVersion !== expected.opaqueVersion || actual.mtimeMs !== expected.mtimeMs || actual.ctimeMs !== expected.ctimeMs)
|
|
412
|
+
throw new FsError4("EBUSY", { message: "LLM spool changed" });
|
|
413
|
+
}
|
|
414
|
+
async function createLlmSpool(fs, directory, signal, purpose = "output") {
|
|
415
|
+
const parent = await fs.stat(directory, { signal });
|
|
416
|
+
if (parent.type !== "directory")
|
|
417
|
+
throw new FsError4("ENOTDIR", { path: directory });
|
|
418
|
+
const caps = await fs.capabilitiesFor?.(directory, { signal }) ?? fs.capabilities;
|
|
419
|
+
if (!caps.retainedStagingCleanup || !caps.retainedStagingWrite || !caps.retainedRead || !fs.createStagedFile || !fs.openReadFile)
|
|
420
|
+
throw new FsError4("ENOTSUP", { message: "LLM staging requires caller filesystem retained staging and reads" });
|
|
421
|
+
let staging;
|
|
422
|
+
for (let attempt = 0; attempt < 16; attempt++) {
|
|
423
|
+
try {
|
|
424
|
+
staging = await fs.createStagedFile(`${directory === "/" ? "" : directory}/.llm-${purpose}-${++serial}`, purpose, { type: "file", data: new Uint8Array(0) }, { parent, mode: 384, retainCleanup: true, signal });
|
|
425
|
+
break;
|
|
426
|
+
} catch (error) {
|
|
427
|
+
signal.throwIfAborted();
|
|
428
|
+
if (!(error instanceof FsError4) || error.code !== "EEXIST")
|
|
429
|
+
throw error;
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
if (!staging)
|
|
433
|
+
throw new FsError4("EEXIST", { message: "LLM output staging names exhausted" });
|
|
434
|
+
const owner = staging;
|
|
435
|
+
const cleanup = owner.cleanup;
|
|
436
|
+
const writer = owner.writer;
|
|
437
|
+
if (!cleanup || !writer) {
|
|
438
|
+
try {
|
|
439
|
+
await cleanup?.remove();
|
|
440
|
+
} finally {
|
|
441
|
+
await cleanup?.close();
|
|
442
|
+
}
|
|
443
|
+
throw new FsError4("EIO", { message: "Caller filesystem omitted its retained staging handles" });
|
|
444
|
+
}
|
|
445
|
+
let reader;
|
|
446
|
+
let sealed;
|
|
447
|
+
let written = 0;
|
|
448
|
+
let closing;
|
|
449
|
+
return {
|
|
450
|
+
async write(bytes) {
|
|
451
|
+
signal.throwIfAborted();
|
|
452
|
+
if (sealed || closing)
|
|
453
|
+
throw new FsError4("EBADF", { message: "LLM spool is closed" });
|
|
454
|
+
for (let offset = 0; offset < bytes.byteLength; offset += 16384) {
|
|
455
|
+
const chunk = bytes.subarray(offset, offset + 16384);
|
|
456
|
+
await writer.write(chunk, { signal });
|
|
457
|
+
written += chunk.byteLength;
|
|
458
|
+
}
|
|
459
|
+
},
|
|
460
|
+
async *replay() {
|
|
461
|
+
signal.throwIfAborted();
|
|
462
|
+
if (sealed || closing)
|
|
463
|
+
throw new FsError4("EBADF", { message: "LLM spool is closed" });
|
|
464
|
+
sealed = await writer.finish({ signal });
|
|
465
|
+
if (sealed.size !== written)
|
|
466
|
+
throw new FsError4("EIO", { message: "LLM spool size mismatch" });
|
|
467
|
+
signal.throwIfAborted();
|
|
468
|
+
if (closing)
|
|
469
|
+
throw new FsError4("EBADF", { message: "LLM spool is closed" });
|
|
470
|
+
const opened = await fs.openReadFile(owner.file.path, { signal });
|
|
471
|
+
if (closing || signal.aborted) {
|
|
472
|
+
await opened.close();
|
|
473
|
+
signal.throwIfAborted();
|
|
474
|
+
throw new FsError4("EBADF", { message: "LLM spool is closed" });
|
|
475
|
+
}
|
|
476
|
+
reader = opened;
|
|
477
|
+
verifyRetainedFile(await reader.stat({ signal }), sealed);
|
|
478
|
+
let position = 0;
|
|
479
|
+
while (position < written) {
|
|
480
|
+
const bytes = await reader.read(position, Math.min(16384, written - position), { signal });
|
|
481
|
+
if (!bytes.byteLength || bytes.byteLength > Math.min(16384, written - position))
|
|
482
|
+
throw new FsError4("EIO", { message: "Invalid LLM spool read" });
|
|
483
|
+
verifyRetainedFile(await reader.stat({ signal }), sealed);
|
|
484
|
+
position += bytes.byteLength;
|
|
485
|
+
yield bytes;
|
|
486
|
+
}
|
|
487
|
+
},
|
|
488
|
+
close() {
|
|
489
|
+
closing ??= (async () => {
|
|
490
|
+
try {
|
|
491
|
+
await reader?.close();
|
|
492
|
+
} finally {
|
|
493
|
+
try {
|
|
494
|
+
await cleanup.remove();
|
|
495
|
+
} finally {
|
|
496
|
+
await cleanup.close();
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
})();
|
|
500
|
+
return closing;
|
|
501
|
+
}
|
|
502
|
+
};
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
// packages/safe-bash-command-llm/dist/file-source.js
|
|
506
|
+
init_buffer();
|
|
507
|
+
import { FsError as FsError5 } from "../../safe-bash-contracts/index.js";
|
|
508
|
+
function sameFile(actual, expected) {
|
|
509
|
+
const identified = expected.opaqueIdentity !== void 0 ? expected.opaqueIdentity === actual.opaqueIdentity : expected.dev !== void 0 && expected.ino !== void 0 && expected.dev === actual.dev && expected.ino === actual.ino;
|
|
510
|
+
if (!identified || expected.identityScope === void 0 || expected.identityScope !== actual.identityScope || actual.type !== "file" || actual.size !== expected.size || actual.revision !== expected.revision || actual.opaqueVersion !== expected.opaqueVersion || actual.mtimeMs !== expected.mtimeMs || actual.ctimeMs !== expected.ctimeMs)
|
|
511
|
+
throw new FsError5("EBUSY", { message: "LLM attachment changed" });
|
|
512
|
+
}
|
|
513
|
+
async function fileSource({ fs, path, signal, maxBytes = Infinity, expectedStat }) {
|
|
514
|
+
signal.throwIfAborted();
|
|
515
|
+
const capabilities = await fs.capabilitiesFor?.(path, { signal }) ?? fs.capabilities;
|
|
516
|
+
if (!capabilities.retainedRead || !fs.openReadFile)
|
|
517
|
+
throw new FsError5("ENOTSUP", { message: "LLM attachment sources require retained reads" });
|
|
518
|
+
const expected = await fs.stat(path, { signal });
|
|
519
|
+
if (expectedStat)
|
|
520
|
+
sameFile(expected, expectedStat);
|
|
521
|
+
if (expected.type !== "file")
|
|
522
|
+
throw new FsError5("EINVAL", { path });
|
|
523
|
+
if (expected.size > maxBytes)
|
|
524
|
+
throw new FsError5("EFBIG", { message: "LLM attachment input byte limit exceeded" });
|
|
525
|
+
const reader = await fs.openReadFile(path, { signal });
|
|
526
|
+
let closing;
|
|
527
|
+
const dispose = () => closing ??= reader.close();
|
|
528
|
+
try {
|
|
529
|
+
sameFile(await reader.stat({ signal }), expected);
|
|
530
|
+
} catch (error) {
|
|
531
|
+
await dispose();
|
|
532
|
+
throw error;
|
|
533
|
+
}
|
|
534
|
+
let consumed = false;
|
|
535
|
+
return {
|
|
536
|
+
dispose,
|
|
537
|
+
bytes: { async *[Symbol.asyncIterator]() {
|
|
538
|
+
if (consumed || closing)
|
|
539
|
+
throw new FsError5("EBADF", { message: "LLM attachment source is closed" });
|
|
540
|
+
consumed = true;
|
|
541
|
+
let position = 0;
|
|
542
|
+
while (position < expected.size) {
|
|
543
|
+
signal.throwIfAborted();
|
|
544
|
+
if (closing)
|
|
545
|
+
throw new FsError5("EBADF", { message: "LLM attachment source is closed" });
|
|
546
|
+
sameFile(await reader.stat({ signal }), expected);
|
|
547
|
+
const length = Math.min(16384, expected.size - position);
|
|
548
|
+
const bytes = await reader.read(position, length, { signal });
|
|
549
|
+
if (closing)
|
|
550
|
+
throw new FsError5("EBADF", { message: "LLM attachment source is closed" });
|
|
551
|
+
signal.throwIfAborted();
|
|
552
|
+
if (!bytes.byteLength || bytes.byteLength > length)
|
|
553
|
+
throw new FsError5("EIO", { message: "Invalid LLM attachment read" });
|
|
554
|
+
sameFile(await reader.stat({ signal }), expected);
|
|
555
|
+
position += bytes.byteLength;
|
|
556
|
+
yield bytes;
|
|
557
|
+
}
|
|
558
|
+
sameFile(await reader.stat({ signal }), expected);
|
|
559
|
+
} }
|
|
560
|
+
};
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
// packages/safe-bash-command-llm/dist/schemas.js
|
|
564
|
+
init_buffer();
|
|
565
|
+
function parseLlmSchemaDsl(input, multi = false) {
|
|
566
|
+
const properties = /* @__PURE__ */ Object.create(null);
|
|
567
|
+
const required = [];
|
|
568
|
+
const types = { int: "integer", float: "number", bool: "boolean", str: "string" };
|
|
569
|
+
for (const field of input.split(input.includes("\n") ? "\n" : ",").map((value) => value.trim()).filter(Boolean)) {
|
|
570
|
+
const colon = field.indexOf(":");
|
|
571
|
+
const info = (colon < 0 ? field : field.slice(0, colon)).trim();
|
|
572
|
+
const description = colon < 0 ? "" : field.slice(colon + 1).trim();
|
|
573
|
+
const parts = [];
|
|
574
|
+
let word = "";
|
|
575
|
+
for (const character of info) {
|
|
576
|
+
if (character.trim() === "") {
|
|
577
|
+
if (word)
|
|
578
|
+
parts.push(word);
|
|
579
|
+
word = "";
|
|
580
|
+
} else
|
|
581
|
+
word += character;
|
|
582
|
+
}
|
|
583
|
+
if (word)
|
|
584
|
+
parts.push(word);
|
|
585
|
+
const name = parts[0];
|
|
586
|
+
if (!name)
|
|
587
|
+
throw new Error("Schema field requires a name");
|
|
588
|
+
const indicator = parts[1] ?? "str";
|
|
589
|
+
const type = Object.hasOwn(types, indicator) ? types[indicator] : "string";
|
|
590
|
+
properties[name] = { type, ...description ? { description } : {} };
|
|
591
|
+
required.push(name);
|
|
592
|
+
}
|
|
593
|
+
const schema = { type: "object", properties, required };
|
|
594
|
+
return multi ? { type: "object", properties: { items: { type: "array", items: schema } }, required: ["items"] } : schema;
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
// packages/safe-bash-command-llm/dist/configuration-command.js
|
|
598
|
+
init_buffer();
|
|
599
|
+
async function configurationCommand(context, service, args, output, diagnostic) {
|
|
600
|
+
if (args.length === 1 && args[0] === "--version") {
|
|
601
|
+
await output("llm, version 0.27.1\n");
|
|
602
|
+
return true;
|
|
603
|
+
}
|
|
604
|
+
const aliases = args[0] === "aliases";
|
|
605
|
+
const defaults = args[0] === "models" && args[1] === "default";
|
|
606
|
+
const options = args[0] === "models" && args[1] === "options";
|
|
607
|
+
if (!aliases && !defaults && !options)
|
|
608
|
+
return false;
|
|
609
|
+
const configuration = createLlmConfiguration(context);
|
|
610
|
+
const canonical = async (model) => {
|
|
611
|
+
const resolved = await configuration.resolveAlias(model);
|
|
612
|
+
try {
|
|
613
|
+
return service.resolve(resolved).model.id;
|
|
614
|
+
} catch {
|
|
615
|
+
return resolved;
|
|
616
|
+
}
|
|
617
|
+
};
|
|
618
|
+
const tokens = args.slice(aliases ? 1 : 2), command = tokens[0];
|
|
619
|
+
if (defaults) {
|
|
620
|
+
if (tokens.length > 1)
|
|
621
|
+
throw new Error("Unexpected extra arguments");
|
|
622
|
+
if (command === void 0)
|
|
623
|
+
await output(`${await configuration.defaultModel() ?? service.resolve().model.id}
|
|
624
|
+
`);
|
|
625
|
+
else {
|
|
626
|
+
const model = service.resolve(await canonical(command)).model.id;
|
|
627
|
+
await configuration.setDefaultModel(model);
|
|
628
|
+
}
|
|
629
|
+
return true;
|
|
630
|
+
}
|
|
631
|
+
if (aliases) {
|
|
632
|
+
if (command === "path" && tokens.length === 1)
|
|
633
|
+
await output(`${configuration.directory}/aliases.json
|
|
634
|
+
`);
|
|
635
|
+
else if (command === "set") {
|
|
636
|
+
const operands = [], queries = [];
|
|
637
|
+
for (let index = 1; index < tokens.length; index++) {
|
|
638
|
+
const token = tokens[index];
|
|
639
|
+
if (token === "-q" || token === "--query") {
|
|
640
|
+
const query = tokens[++index];
|
|
641
|
+
if (query === void 0)
|
|
642
|
+
throw new Error(`Option '${token}' requires an argument`);
|
|
643
|
+
queries.push(query);
|
|
644
|
+
} else if (token.startsWith("--query="))
|
|
645
|
+
queries.push(token.slice(8));
|
|
646
|
+
else if (token.startsWith("-q") && token.length > 2)
|
|
647
|
+
queries.push(token.slice(2));
|
|
648
|
+
else if (token.startsWith("-"))
|
|
649
|
+
throw new Error(`No such option: ${token}`);
|
|
650
|
+
else
|
|
651
|
+
operands.push(token);
|
|
652
|
+
}
|
|
653
|
+
if (!operands.length || operands.length > 2)
|
|
654
|
+
throw new Error("Invalid aliases set arguments");
|
|
655
|
+
let model = operands[1];
|
|
656
|
+
const queried = model === void 0;
|
|
657
|
+
if (model === void 0) {
|
|
658
|
+
if (!queries.length)
|
|
659
|
+
throw new Error("You must provide a model_id or at least one -q option");
|
|
660
|
+
const persisted = await configuration.aliases();
|
|
661
|
+
const found = service.models.find((entry) => queries.every((query) => [entry.provider.name, entry.model.id, ...entry.model.aliases ?? [], ...Object.entries(persisted).filter(([, id]) => id === entry.model.id).map(([alias]) => alias)].some((text) => text.toLowerCase().includes(query.toLowerCase()))));
|
|
662
|
+
if (!found)
|
|
663
|
+
throw new Error(`No model found matching query: ${queries.join(", ")}`);
|
|
664
|
+
model = found.model.id;
|
|
665
|
+
}
|
|
666
|
+
await configuration.setAlias(operands[0], await canonical(model));
|
|
667
|
+
if (queried)
|
|
668
|
+
await diagnostic(`Alias '${operands[0]}' set to model '${model}'
|
|
669
|
+
`);
|
|
670
|
+
} else if (command === "remove" && tokens.length === 2)
|
|
671
|
+
await configuration.removeAlias(tokens[1]);
|
|
672
|
+
else if ((command === void 0 || command === "list" || command === "--json") && tokens.slice(command === void 0 ? 0 : 1).every((token) => token === "--json")) {
|
|
673
|
+
const values = {};
|
|
674
|
+
for (const { model } of service.models)
|
|
675
|
+
for (const alias of model.aliases ?? [])
|
|
676
|
+
if (alias !== model.id)
|
|
677
|
+
Object.defineProperty(values, alias, { value: model.id, enumerable: true, configurable: true, writable: true });
|
|
678
|
+
const entries = Object.entries({ ...values, ...await configuration.aliases() });
|
|
679
|
+
if (tokens.includes("--json"))
|
|
680
|
+
await output(JSON.stringify(Object.fromEntries(entries), null, 4) + "\n");
|
|
681
|
+
else {
|
|
682
|
+
const width = Math.max(0, ...entries.map(([alias]) => [...alias].length));
|
|
683
|
+
for (const [alias, model] of entries)
|
|
684
|
+
await output(`${alias}${" ".repeat(width - [...alias].length)} : ${model}
|
|
685
|
+
`);
|
|
686
|
+
}
|
|
687
|
+
} else
|
|
688
|
+
throw new Error("Invalid aliases command");
|
|
689
|
+
return true;
|
|
690
|
+
}
|
|
691
|
+
if (command === "set" && tokens.length === 4) {
|
|
692
|
+
const model = await canonical(tokens[1]);
|
|
693
|
+
const entry = service.models.find((entry2) => entry2.model.id === model);
|
|
694
|
+
if (entry)
|
|
695
|
+
validateModelOptions(entry.model, { [tokens[2]]: tokens[3] });
|
|
696
|
+
await configuration.setModelOption(model, tokens[2], tokens[3]);
|
|
697
|
+
await diagnostic(`Set default option ${tokens[2]}=${tokens[3]} for model ${model}
|
|
698
|
+
`);
|
|
699
|
+
} else if (command === "show" && tokens.length === 2) {
|
|
700
|
+
const model = await canonical(tokens[1]), values = await configuration.modelOptions(model);
|
|
701
|
+
if (!Object.keys(values).length)
|
|
702
|
+
await diagnostic(`No default options set for model '${model}'.
|
|
703
|
+
`);
|
|
704
|
+
else
|
|
705
|
+
for (const [key, value] of Object.entries(values))
|
|
706
|
+
await output(`${key}: ${value}
|
|
707
|
+
`);
|
|
708
|
+
} else if (command === "clear" && (tokens.length === 2 || tokens.length === 3)) {
|
|
709
|
+
const model = await canonical(tokens[1]);
|
|
710
|
+
const keys = tokens[2] === void 0 ? Object.keys(await configuration.modelOptions(model)) : [tokens[2]];
|
|
711
|
+
await configuration.clearModelOption(model, tokens[2]);
|
|
712
|
+
if (keys.length === 1)
|
|
713
|
+
await output(`Cleared option '${keys[0]}' for model ${model}
|
|
714
|
+
`);
|
|
715
|
+
else if (keys.length > 1)
|
|
716
|
+
await output(`Cleared ${keys.join(", ")} options for model ${model}
|
|
717
|
+
`);
|
|
718
|
+
} else if (command === "list" && tokens.length === 1 || command === void 0) {
|
|
719
|
+
await listOptions(configuration, output, diagnostic);
|
|
720
|
+
} else
|
|
721
|
+
throw new Error("Invalid models options command");
|
|
722
|
+
return true;
|
|
723
|
+
}
|
|
724
|
+
async function listOptions(configuration, output, diagnostic) {
|
|
725
|
+
const entries = Object.entries(await configuration.allModelOptions());
|
|
726
|
+
if (!entries.length)
|
|
727
|
+
await diagnostic("No default options set for any models.\n");
|
|
728
|
+
for (const [model, values] of entries) {
|
|
729
|
+
await output(`${model}:
|
|
730
|
+
`);
|
|
731
|
+
for (const [key, value] of Object.entries(values))
|
|
732
|
+
await output(` ${key}: ${value}
|
|
733
|
+
`);
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
// packages/safe-bash-command-llm/dist/models-list.js
|
|
738
|
+
init_buffer();
|
|
739
|
+
var modelsGroupHelp = "Usage: llm models [OPTIONS] COMMAND [ARGS]...\n\n Manage available models\n\nOptions:\n -h, --help Show this message and exit.\n\nCommands:\n list* List available models\n default Show or set the default model\n options Manage default options for models\n";
|
|
740
|
+
var LlmModelsUsageError = class extends Error {
|
|
741
|
+
constructor(message, usage = true) {
|
|
742
|
+
super((usage ? "Usage: llm models list [OPTIONS]\nTry 'llm models list -h' for help.\n\n" : "") + `Error: ${message}`);
|
|
743
|
+
}
|
|
744
|
+
};
|
|
745
|
+
function wrapDescription(description) {
|
|
746
|
+
const lines = [];
|
|
747
|
+
let line = "";
|
|
748
|
+
for (const word of description.split(" ")) {
|
|
749
|
+
if (!word)
|
|
750
|
+
continue;
|
|
751
|
+
if (line && line.length + word.length + 1 > 70) {
|
|
752
|
+
lines.push(line);
|
|
753
|
+
line = "";
|
|
754
|
+
}
|
|
755
|
+
line += (line ? " " : "") + word;
|
|
756
|
+
}
|
|
757
|
+
if (line)
|
|
758
|
+
lines.push(line);
|
|
759
|
+
return lines.join("\n ");
|
|
760
|
+
}
|
|
761
|
+
async function listLlmModels(context, service, tokens, emit, step) {
|
|
762
|
+
const explicit = tokens[0] === "list";
|
|
763
|
+
const terminator = tokens.indexOf("--");
|
|
764
|
+
const groupFlags = terminator < 0 ? tokens : tokens.slice(0, terminator);
|
|
765
|
+
if (!explicit && groupFlags.some((token) => token === "--help" || token.startsWith("-") && !token.startsWith("--") && token.slice(1).includes("h"))) {
|
|
766
|
+
await emit(modelsGroupHelp);
|
|
767
|
+
return;
|
|
768
|
+
}
|
|
769
|
+
const queries = [], selected = [];
|
|
770
|
+
let schemas = false, tools = false, asyncModels = false, options = false, help = false, ended = false;
|
|
771
|
+
const unexpected = [];
|
|
772
|
+
const args = explicit ? tokens.slice(1) : tokens.filter((_, index) => index !== terminator);
|
|
773
|
+
for (let index = 0; index < args.length; index++) {
|
|
774
|
+
await step();
|
|
775
|
+
const argument = args[index];
|
|
776
|
+
if (ended) {
|
|
777
|
+
unexpected.push(argument);
|
|
778
|
+
continue;
|
|
779
|
+
}
|
|
780
|
+
if (argument === "--") {
|
|
781
|
+
ended = true;
|
|
782
|
+
continue;
|
|
783
|
+
}
|
|
784
|
+
if (argument === "--help" || argument === "-h") {
|
|
785
|
+
help = true;
|
|
786
|
+
continue;
|
|
787
|
+
}
|
|
788
|
+
if (argument === "--options") {
|
|
789
|
+
options = true;
|
|
790
|
+
continue;
|
|
791
|
+
}
|
|
792
|
+
if (argument === "--schemas") {
|
|
793
|
+
schemas = true;
|
|
794
|
+
continue;
|
|
795
|
+
}
|
|
796
|
+
if (argument === "--tools") {
|
|
797
|
+
tools = true;
|
|
798
|
+
continue;
|
|
799
|
+
}
|
|
800
|
+
if (argument === "--async") {
|
|
801
|
+
asyncModels = true;
|
|
802
|
+
continue;
|
|
803
|
+
}
|
|
804
|
+
if (!argument.startsWith("-") || argument === "-") {
|
|
805
|
+
unexpected.push(argument);
|
|
806
|
+
continue;
|
|
807
|
+
}
|
|
808
|
+
const equals = argument.indexOf("=");
|
|
809
|
+
const long = argument.startsWith("--");
|
|
810
|
+
const flag = long ? argument.slice(0, equals < 0 ? void 0 : equals) : argument.slice(0, 2);
|
|
811
|
+
const attached = long ? equals < 0 ? void 0 : argument.slice(equals + 1) : argument.length > 2 ? argument.slice(2) : void 0;
|
|
812
|
+
if (equals >= 0 && ["--schemas", "--tools", "--async", "--options", "--help", "-h"].includes(flag))
|
|
813
|
+
throw new LlmModelsUsageError(`Option '${flag}' does not take a value.`, false);
|
|
814
|
+
if (!["-q", "--query", "-m", "--model"].includes(flag))
|
|
815
|
+
throw new LlmModelsUsageError(`No such option: ${flag}`);
|
|
816
|
+
const value = attached ?? args[++index];
|
|
817
|
+
if (value === void 0)
|
|
818
|
+
throw new LlmModelsUsageError(`Option '${flag}' requires an argument.`, false);
|
|
819
|
+
(flag === "-q" || flag === "--query" ? queries : selected).push(value);
|
|
820
|
+
}
|
|
821
|
+
if (help) {
|
|
822
|
+
await emit("Usage: llm models list [OPTIONS]\n\n List available models\n\nOptions:\n --options Show options for each model, if available\n --async List async models\n --schemas List models that support schemas\n --tools List models that support tools\n -q, --query TEXT Search for models matching these strings\n -m, --model TEXT Specific model IDs\n -h, --help Show this message and exit.\n");
|
|
823
|
+
return;
|
|
824
|
+
}
|
|
825
|
+
if (unexpected.length)
|
|
826
|
+
throw new LlmModelsUsageError(`Got unexpected extra argument${unexpected.length === 1 ? "" : "s"} (${unexpected.join(" ")})`);
|
|
827
|
+
const configuration = createLlmConfiguration(context);
|
|
828
|
+
const configuredAliases = await configuration.aliases();
|
|
829
|
+
const shownDescriptions = /* @__PURE__ */ new Set();
|
|
830
|
+
for (const { provider, model } of service.models) {
|
|
831
|
+
await step();
|
|
832
|
+
const aliases = new Set(model.aliases);
|
|
833
|
+
for (const [alias, target] of Object.entries(configuredAliases)) {
|
|
834
|
+
if (target === model.id || target === `${provider.name}/${model.id}` || model.aliases?.includes(target))
|
|
835
|
+
aliases.add(alias);
|
|
836
|
+
}
|
|
837
|
+
const description = `${provider.name}: ${model.id}`;
|
|
838
|
+
const terms = [description, ...aliases].map((value) => value.toLowerCase());
|
|
839
|
+
if (!queries.every((query) => terms.some((term) => term.includes(query.toLowerCase()))))
|
|
840
|
+
continue;
|
|
841
|
+
if (selected.length && !selected.some((value) => value === model.id || aliases.has(value)))
|
|
842
|
+
continue;
|
|
843
|
+
if (schemas && !model.capabilities?.includes("schema") || tools || asyncModels)
|
|
844
|
+
continue;
|
|
845
|
+
let output = description + (aliases.size ? ` (aliases: ${[...aliases].join(", ")})` : "");
|
|
846
|
+
if (options && Object.keys(model.options ?? {}).length) {
|
|
847
|
+
output += "\n Options:";
|
|
848
|
+
for (const [name, rule] of Object.entries(model.options)) {
|
|
849
|
+
const type = { number: "float", integer: "int", boolean: "boolean", string: "str" }[rule.type];
|
|
850
|
+
output += `
|
|
851
|
+
${name}: ${type}`;
|
|
852
|
+
if (rule.description && !shownDescriptions.has(provider.name))
|
|
853
|
+
output += `
|
|
854
|
+
${wrapDescription(rule.description)}`;
|
|
855
|
+
}
|
|
856
|
+
shownDescriptions.add(provider.name);
|
|
857
|
+
}
|
|
858
|
+
if (options && model.attachmentTypes?.length)
|
|
859
|
+
output += `
|
|
860
|
+
Attachment types:
|
|
861
|
+
${[...model.attachmentTypes].sort().join(", ")}`;
|
|
862
|
+
if (options && model.capabilities?.includes("schema"))
|
|
863
|
+
output += "\n Features:\n - schemas";
|
|
864
|
+
await emit(output + "\n");
|
|
865
|
+
}
|
|
866
|
+
if (!queries.length && !selected.length && !schemas && !options) {
|
|
867
|
+
const configured = await configuration.defaultModel();
|
|
868
|
+
let model = configured;
|
|
869
|
+
if (model === void 0) {
|
|
870
|
+
try {
|
|
871
|
+
model = service.resolve().model.id;
|
|
872
|
+
} catch {
|
|
873
|
+
}
|
|
874
|
+
}
|
|
875
|
+
if (model !== void 0)
|
|
876
|
+
await emit(`Default: ${model}
|
|
877
|
+
`);
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
|
|
881
|
+
// packages/safe-bash-command-llm/dist/command.js
|
|
882
|
+
async function parse(length, text, step) {
|
|
883
|
+
const parsed = { prompt: "", params: {}, options: /* @__PURE__ */ Object.create(null), attachments: [] };
|
|
884
|
+
const operands = [];
|
|
885
|
+
let ended = false;
|
|
886
|
+
for (let index = 0; index < length; index++) {
|
|
887
|
+
await step();
|
|
888
|
+
const argument = text(index);
|
|
889
|
+
if (!ended && ["--no-log", "-n"].includes(argument))
|
|
890
|
+
continue;
|
|
891
|
+
if (!ended && argument === "--no-stream") {
|
|
892
|
+
parsed.noStream = true;
|
|
893
|
+
continue;
|
|
894
|
+
}
|
|
895
|
+
if (ended || !argument.startsWith("-") || argument === "-") {
|
|
896
|
+
operands.push(argument);
|
|
897
|
+
continue;
|
|
898
|
+
}
|
|
899
|
+
if (argument === "--") {
|
|
900
|
+
ended = true;
|
|
901
|
+
continue;
|
|
902
|
+
}
|
|
903
|
+
const equals = argument.indexOf("=");
|
|
904
|
+
const long = argument.startsWith("--");
|
|
905
|
+
const flag = long ? argument.slice(0, equals < 0 ? void 0 : equals) : argument.slice(0, 2);
|
|
906
|
+
const attached = long ? equals < 0 ? void 0 : argument.slice(equals + 1) : argument.length > 2 ? argument.slice(2) : void 0;
|
|
907
|
+
const take = () => {
|
|
908
|
+
if (++index >= length)
|
|
909
|
+
throw new Error(`Option ${flag} requires an argument`);
|
|
910
|
+
return text(index);
|
|
911
|
+
};
|
|
912
|
+
if (!["-m", "--model", "-s", "--system", "-o", "--option", "-a", "--attachment", "--at", "--attachment-type", "-t", "--template", "--save", "-p", "--param"].includes(flag))
|
|
913
|
+
throw new Error(`Unknown option: ${flag}`);
|
|
914
|
+
const value = attached ?? take();
|
|
915
|
+
if (flag === "-t" || flag === "--template")
|
|
916
|
+
parsed.template = value;
|
|
917
|
+
else if (flag === "--save")
|
|
918
|
+
parsed.save = value;
|
|
919
|
+
else if (flag === "-p" || flag === "--param")
|
|
920
|
+
Object.defineProperty(parsed.params, value, { value: take(), enumerable: true, configurable: true, writable: true });
|
|
921
|
+
else if (flag === "-m" || flag === "--model")
|
|
922
|
+
parsed.model = value;
|
|
923
|
+
else if (flag === "-s" || flag === "--system")
|
|
924
|
+
parsed.system = value;
|
|
925
|
+
else if (flag === "-o" || flag === "--option")
|
|
926
|
+
parsed.options[value] = take();
|
|
927
|
+
else if (flag === "--at" || flag === "--attachment-type")
|
|
928
|
+
parsed.attachments.push({ path: value, mimeType: take() });
|
|
929
|
+
else
|
|
930
|
+
parsed.attachments.push({ path: value });
|
|
931
|
+
}
|
|
932
|
+
parsed.prompt = operands.join(" ");
|
|
933
|
+
return parsed;
|
|
934
|
+
}
|
|
935
|
+
async function interrupted(start, signal) {
|
|
936
|
+
signal.throwIfAborted();
|
|
937
|
+
return new Promise((resolve, reject) => {
|
|
938
|
+
const aborted = () => reject(signal.reason);
|
|
939
|
+
signal.addEventListener("abort", aborted, { once: true });
|
|
940
|
+
Promise.resolve().then(() => {
|
|
941
|
+
signal.throwIfAborted();
|
|
942
|
+
return start();
|
|
943
|
+
}).then((value) => {
|
|
944
|
+
signal.removeEventListener("abort", aborted);
|
|
945
|
+
resolve(value);
|
|
946
|
+
}, (error) => {
|
|
947
|
+
signal.removeEventListener("abort", aborted);
|
|
948
|
+
reject(error);
|
|
949
|
+
});
|
|
950
|
+
});
|
|
951
|
+
}
|
|
952
|
+
async function execute(context, service, limits) {
|
|
953
|
+
context.signal.throwIfAborted();
|
|
954
|
+
const controller = new AbortController();
|
|
955
|
+
const operation = createOutputOperation(context, context.stdout);
|
|
956
|
+
const signal = AbortSignal.any([operation.signal, controller.signal]);
|
|
957
|
+
inheritYieldCheckpoint(context.signal, signal);
|
|
958
|
+
let iterator;
|
|
959
|
+
let closed = false;
|
|
960
|
+
let ended = false;
|
|
961
|
+
operation.registerCleanup(() => {
|
|
962
|
+
if (closed)
|
|
963
|
+
return;
|
|
964
|
+
closed = true;
|
|
965
|
+
controller.abort(new Error("llm request closed"));
|
|
966
|
+
if (!ended && iterator) {
|
|
967
|
+
const resource = iterator;
|
|
968
|
+
void Promise.resolve().then(() => resource.return?.()).catch(() => {
|
|
969
|
+
});
|
|
970
|
+
}
|
|
971
|
+
});
|
|
972
|
+
let work = 0;
|
|
973
|
+
const step = async () => {
|
|
974
|
+
signal.throwIfAborted();
|
|
975
|
+
if (closed)
|
|
976
|
+
throw new Error("LLM invocation is closed");
|
|
977
|
+
work++;
|
|
978
|
+
if (work % 256 === 0)
|
|
979
|
+
await yieldTurn(signal);
|
|
980
|
+
};
|
|
981
|
+
let outputSpool;
|
|
982
|
+
let outputBytes = 0;
|
|
983
|
+
let writing = false;
|
|
984
|
+
const write = async (chunk) => {
|
|
985
|
+
if (chunk.byteLength > (limits?.maxOutputBytes ?? Infinity) - outputBytes)
|
|
986
|
+
throw new FsError6("EFBIG", { message: "llm output byte limit exceeded" });
|
|
987
|
+
outputBytes += chunk.byteLength;
|
|
988
|
+
if (outputSpool) {
|
|
989
|
+
await outputSpool.write(chunk);
|
|
990
|
+
return;
|
|
991
|
+
}
|
|
992
|
+
writing = true;
|
|
993
|
+
await operation.output.write(chunk);
|
|
994
|
+
writing = false;
|
|
995
|
+
};
|
|
996
|
+
const emitText = async (text) => {
|
|
997
|
+
for (let offset = 0; offset < text.length; ) {
|
|
998
|
+
await step();
|
|
999
|
+
let end = Math.min(text.length, offset + 16384);
|
|
1000
|
+
const last = text.charCodeAt(end - 1);
|
|
1001
|
+
if (end < text.length && last >= 55296 && last <= 56319)
|
|
1002
|
+
end--;
|
|
1003
|
+
await write(new TextEncoder().encode(text.slice(offset, end)));
|
|
1004
|
+
offset = end;
|
|
1005
|
+
}
|
|
1006
|
+
};
|
|
1007
|
+
let inputBytes = 0;
|
|
1008
|
+
const inputLimit = Math.min(context.inputBudget?.maxBytes ?? Infinity, limits?.maxInputBytes ?? Infinity);
|
|
1009
|
+
const checkInput = (size) => {
|
|
1010
|
+
context.inputBudget?.check(inputBytes + size);
|
|
1011
|
+
if (size > inputLimit - inputBytes)
|
|
1012
|
+
throw new FsError6("EFBIG", { message: "llm input byte limit exceeded" });
|
|
1013
|
+
};
|
|
1014
|
+
const admitInput = (size) => {
|
|
1015
|
+
checkInput(size);
|
|
1016
|
+
inputBytes += size;
|
|
1017
|
+
};
|
|
1018
|
+
try {
|
|
1019
|
+
const argumentsValue = getCommandArguments(context);
|
|
1020
|
+
const argumentText = (index) => {
|
|
1021
|
+
const bytes = argumentsValue.bytes(index);
|
|
1022
|
+
if (!bytes)
|
|
1023
|
+
throw new Error("Missing option argument");
|
|
1024
|
+
return new TextDecoder("utf-8", { fatal: true }).decode(bytes);
|
|
1025
|
+
};
|
|
1026
|
+
if (argumentsValue.args.length === 1 && ["--help", "-h"].includes(argumentsValue.args[0])) {
|
|
1027
|
+
argumentText(0);
|
|
1028
|
+
await emitText("Usage: llm [prompt] [-m MODEL] [-s SYSTEM] [-o KEY VALUE] [-a PATH] [--at PATH MIMETYPE]\n llm models\nOptions: --model, --system, --option, --attachment; -- ends options\n");
|
|
1029
|
+
return { exitCode: 0 };
|
|
1030
|
+
}
|
|
1031
|
+
if (argumentsValue.args.length === 2 && argumentsValue.args[0] === "models" && ["--help", "-h"].includes(argumentsValue.args[1])) {
|
|
1032
|
+
argumentText(0);
|
|
1033
|
+
argumentText(1);
|
|
1034
|
+
await emitText(modelsGroupHelp);
|
|
1035
|
+
return { exitCode: 0 };
|
|
1036
|
+
}
|
|
1037
|
+
if (argumentsValue.args[0] === "schemas" && argumentsValue.args[1] === "dsl") {
|
|
1038
|
+
const tokens = Array.from({ length: argumentsValue.args.length - 2 }, (_, index) => argumentText(index + 2));
|
|
1039
|
+
const usage = "Usage: llm schemas dsl [OPTIONS] INPUT\n";
|
|
1040
|
+
if (tokens.includes("--help") || tokens.includes("-h")) {
|
|
1041
|
+
await emitText(usage + "\n Convert LLM's schema DSL to a JSON schema\n\n llm schema dsl 'name, age int, bio: their bio'\n\nOptions:\n --multi Wrap in an array\n -h, --help Show this message and exit.\n");
|
|
1042
|
+
return { exitCode: 0 };
|
|
1043
|
+
}
|
|
1044
|
+
let multi = false, optionsEnded = false;
|
|
1045
|
+
const inputs = [];
|
|
1046
|
+
let failure;
|
|
1047
|
+
for (const token of tokens) {
|
|
1048
|
+
await step();
|
|
1049
|
+
if (!optionsEnded && token === "--")
|
|
1050
|
+
optionsEnded = true;
|
|
1051
|
+
else if (!optionsEnded && token === "--multi")
|
|
1052
|
+
multi = true;
|
|
1053
|
+
else if (!optionsEnded && token.startsWith("-") && token !== "-") {
|
|
1054
|
+
failure = `No such option: ${token}`;
|
|
1055
|
+
break;
|
|
1056
|
+
} else {
|
|
1057
|
+
admitInput(new TextEncoder().encode(token).byteLength);
|
|
1058
|
+
inputs.push(token);
|
|
1059
|
+
}
|
|
1060
|
+
}
|
|
1061
|
+
failure ??= inputs.length === 0 ? "Missing argument 'INPUT'." : inputs.length > 1 ? `Got unexpected extra argument (${inputs[1]})` : void 0;
|
|
1062
|
+
if (failure) {
|
|
1063
|
+
await writeDiagnostic(context.stderr, usage + "Try 'llm schemas dsl -h' for help.\n\nError: " + failure + "\n", signal);
|
|
1064
|
+
return { exitCode: 2 };
|
|
1065
|
+
}
|
|
1066
|
+
await emitText(JSON.stringify(parseLlmSchemaDsl(inputs[0], multi), null, 2) + "\n");
|
|
1067
|
+
return { exitCode: 0 };
|
|
1068
|
+
}
|
|
1069
|
+
if (argumentsValue.args[0] === "templates") {
|
|
1070
|
+
try {
|
|
1071
|
+
await createLlmTemplateStore(context).command(Array.from({ length: argumentsValue.args.length - 1 }, (_, index) => argumentText(index + 1)), emitText);
|
|
1072
|
+
} catch (error) {
|
|
1073
|
+
throw new Error(`Error: ${error instanceof Error ? error.message : "Template failed"}`);
|
|
1074
|
+
}
|
|
1075
|
+
return { exitCode: 0 };
|
|
1076
|
+
}
|
|
1077
|
+
const configurationInvocation = argumentsValue.args[0] === "aliases" || argumentsValue.args[0] === "models" && ["default", "options"].includes(argumentsValue.args[1] ?? "") || argumentsValue.args[0] === "--version";
|
|
1078
|
+
if (configurationInvocation) {
|
|
1079
|
+
try {
|
|
1080
|
+
const tokens = Array.from({ length: argumentsValue.args.length }, (_, index) => argumentText(index));
|
|
1081
|
+
if (await configurationCommand(context, service, tokens, emitText, (text2) => writeDiagnostic(context.stderr, text2, signal)))
|
|
1082
|
+
return { exitCode: 0 };
|
|
1083
|
+
} catch (error) {
|
|
1084
|
+
throw new Error(`Error: ${error instanceof Error ? error.message : "Configuration failed"}`);
|
|
1085
|
+
}
|
|
1086
|
+
}
|
|
1087
|
+
if (argumentsValue.args[0] === "models") {
|
|
1088
|
+
await listLlmModels(context, service, Array.from({ length: argumentsValue.args.length - 1 }, (_, index) => argumentText(index + 1)), emitText, step);
|
|
1089
|
+
return { exitCode: 0 };
|
|
1090
|
+
}
|
|
1091
|
+
const promptOffset = argumentsValue.args[0] === "prompt" ? 1 : 0;
|
|
1092
|
+
const args = await parse(argumentsValue.args.length - promptOffset, (index) => argumentText(index + promptOffset), step);
|
|
1093
|
+
const configuration = createLlmConfiguration(context);
|
|
1094
|
+
const templateStore = createLlmTemplateStore(context);
|
|
1095
|
+
if (args.save && args.template)
|
|
1096
|
+
throw new Error("Error: --save cannot be used with --template");
|
|
1097
|
+
let stored;
|
|
1098
|
+
try {
|
|
1099
|
+
stored = args.template === void 0 ? void 0 : await templateStore.load(args.template);
|
|
1100
|
+
} catch (error) {
|
|
1101
|
+
throw new Error(`Error: ${error instanceof Error ? error.message : "Invalid template"}`);
|
|
1102
|
+
}
|
|
1103
|
+
if (stored) {
|
|
1104
|
+
try {
|
|
1105
|
+
validateLlmTemplateParameters(stored, args.params);
|
|
1106
|
+
} catch (error) {
|
|
1107
|
+
throw new Error(`Error: ${error instanceof Error ? error.message : "Invalid template"}`);
|
|
1108
|
+
}
|
|
1109
|
+
}
|
|
1110
|
+
const selected = args.model ?? stored?.model ?? (args.save ? void 0 : await configuration.defaultModel());
|
|
1111
|
+
const model = selected === void 0 ? void 0 : await configuration.resolveAlias(selected);
|
|
1112
|
+
const entry = args.save && selected === void 0 ? void 0 : service.resolve(model);
|
|
1113
|
+
const streamed = entry !== void 0 && service.streamSources !== void 0 && entry.provider.completeSources !== void 0 && entry.model.inputSources !== false;
|
|
1114
|
+
const stagePrompt = streamed && stored === void 0 && args.save === void 0;
|
|
1115
|
+
let promptSpool;
|
|
1116
|
+
let stdinBytes = 0;
|
|
1117
|
+
const fragments = [];
|
|
1118
|
+
const decoder = new TextDecoder("utf-8", { fatal: true });
|
|
1119
|
+
const templateUsesInput = stored !== void 0 && llmTemplateUsesInput(stored);
|
|
1120
|
+
if (stored === void 0 || templateUsesInput) {
|
|
1121
|
+
const input = await operation.acquire(() => context.stdinInput ? { next: () => context.stdinInput.read(Math.min(65536, inputLimit - inputBytes + 1), signal) } : context.stdin[Symbol.asyncIterator](), async (iterator2) => {
|
|
1122
|
+
await iterator2.return?.();
|
|
1123
|
+
});
|
|
1124
|
+
while (true) {
|
|
1125
|
+
await step();
|
|
1126
|
+
const result = await interrupted(() => input.next(), signal);
|
|
1127
|
+
signal.throwIfAborted();
|
|
1128
|
+
if (result.done)
|
|
1129
|
+
break;
|
|
1130
|
+
const chunk = result.value;
|
|
1131
|
+
if (!(chunk instanceof Uint8Array))
|
|
1132
|
+
throw new TypeError("Byte sources must yield Uint8Array chunks");
|
|
1133
|
+
admitInput(chunk.byteLength);
|
|
1134
|
+
stdinBytes += chunk.byteLength;
|
|
1135
|
+
if (stagePrompt) {
|
|
1136
|
+
for (let offset = 0; offset < chunk.byteLength; offset += 16384) {
|
|
1137
|
+
await step();
|
|
1138
|
+
decoder.decode(chunk.subarray(offset, Math.min(offset + 16384, chunk.byteLength)), { stream: true });
|
|
1139
|
+
}
|
|
1140
|
+
if (chunk.byteLength) {
|
|
1141
|
+
promptSpool ??= await operation.acquire(() => createLlmSpool(context.fs, context.cwd, signal, "input"), (spool) => spool.close());
|
|
1142
|
+
await promptSpool.write(chunk);
|
|
1143
|
+
}
|
|
1144
|
+
} else
|
|
1145
|
+
fragments.push(decoder.decode(chunk, { stream: true }));
|
|
1146
|
+
}
|
|
1147
|
+
}
|
|
1148
|
+
const decoderTail = decoder.decode();
|
|
1149
|
+
if (!stagePrompt)
|
|
1150
|
+
fragments.push(decoderTail);
|
|
1151
|
+
if (promptSpool && args.prompt) {
|
|
1152
|
+
if (stdinBytes)
|
|
1153
|
+
await promptSpool.write(new TextEncoder().encode(" "));
|
|
1154
|
+
for (let start = 0; start < args.prompt.length; ) {
|
|
1155
|
+
await step();
|
|
1156
|
+
let end = Math.min(args.prompt.length, start + 8192);
|
|
1157
|
+
const last = args.prompt.charCodeAt(end - 1);
|
|
1158
|
+
if (end < args.prompt.length && last >= 55296 && last <= 56319)
|
|
1159
|
+
end--;
|
|
1160
|
+
await promptSpool.write(new TextEncoder().encode(args.prompt.slice(start, end)));
|
|
1161
|
+
start = end;
|
|
1162
|
+
}
|
|
1163
|
+
}
|
|
1164
|
+
const content = fragments.join("");
|
|
1165
|
+
let prompt = content && args.prompt ? `${content} ${args.prompt}` : content || args.prompt;
|
|
1166
|
+
if (args.save) {
|
|
1167
|
+
const attachments2 = args.attachments.filter((item) => item.mimeType === void 0).map((item) => item.path);
|
|
1168
|
+
const attachmentTypes = args.attachments.filter((item) => item.mimeType !== void 0).map((item) => ({ type: item.mimeType, value: item.path }));
|
|
1169
|
+
const saved = {
|
|
1170
|
+
...args.model === void 0 ? {} : { model: entry.model.id },
|
|
1171
|
+
...prompt ? { prompt } : {},
|
|
1172
|
+
...args.system === void 0 ? {} : { system: args.system },
|
|
1173
|
+
...Object.keys(args.params).length ? { defaults: args.params } : {},
|
|
1174
|
+
...Object.keys(args.options).length ? { options: args.options } : {},
|
|
1175
|
+
...attachments2.length ? { attachments: attachments2 } : {},
|
|
1176
|
+
...attachmentTypes.length ? { attachment_types: attachmentTypes } : {}
|
|
1177
|
+
};
|
|
1178
|
+
await templateStore.save(args.save, saved);
|
|
1179
|
+
return { exitCode: 0 };
|
|
1180
|
+
}
|
|
1181
|
+
if (stored) {
|
|
1182
|
+
try {
|
|
1183
|
+
const evaluated = evaluateLlmTemplate(stored, templateUsesInput ? prompt : "", args.params);
|
|
1184
|
+
if (evaluated.prompt)
|
|
1185
|
+
prompt = !templateUsesInput && args.prompt ? `${evaluated.prompt}
|
|
1186
|
+
${args.prompt}` : evaluated.prompt;
|
|
1187
|
+
if (args.system === void 0 && evaluated.system !== void 0)
|
|
1188
|
+
args.system = evaluated.system;
|
|
1189
|
+
} catch (error) {
|
|
1190
|
+
throw new Error(`Error: ${error instanceof Error ? error.message : "Invalid template"}`);
|
|
1191
|
+
}
|
|
1192
|
+
}
|
|
1193
|
+
if (!entry)
|
|
1194
|
+
throw new Error("No model selected; use --model or configure defaultModel");
|
|
1195
|
+
args.options = { ...await configuration.modelOptions(entry.model.id), ...stored?.options, ...args.options };
|
|
1196
|
+
args.attachments = [
|
|
1197
|
+
...(stored?.attachments ?? []).map((path) => ({ path })),
|
|
1198
|
+
...args.attachments.filter((item) => item.mimeType === void 0),
|
|
1199
|
+
...(stored?.attachment_types ?? []).map((item) => ({ path: item.value, mimeType: item.type })),
|
|
1200
|
+
...args.attachments.filter((item) => item.mimeType !== void 0)
|
|
1201
|
+
];
|
|
1202
|
+
const attachments = [];
|
|
1203
|
+
const sourceAttachments = [];
|
|
1204
|
+
const textSource = (value) => ({
|
|
1205
|
+
async dispose() {
|
|
1206
|
+
},
|
|
1207
|
+
bytes: { async *[Symbol.asyncIterator]() {
|
|
1208
|
+
for (let offset = 0; offset < value.length; ) {
|
|
1209
|
+
await step();
|
|
1210
|
+
let end = Math.min(value.length, offset + 16384);
|
|
1211
|
+
const last = value.charCodeAt(end - 1);
|
|
1212
|
+
if (end < value.length && last >= 55296 && last <= 56319)
|
|
1213
|
+
end--;
|
|
1214
|
+
yield new TextEncoder().encode(value.slice(offset, end));
|
|
1215
|
+
offset = end;
|
|
1216
|
+
}
|
|
1217
|
+
} }
|
|
1218
|
+
});
|
|
1219
|
+
for (const attachment of args.attachments) {
|
|
1220
|
+
await step();
|
|
1221
|
+
if (attachment.path.includes("://"))
|
|
1222
|
+
throw new Error("URL attachments are not supported");
|
|
1223
|
+
const path = pathOf2(context, attachment.path);
|
|
1224
|
+
const stat = await interrupted(() => context.fs.stat(path, { signal }), signal);
|
|
1225
|
+
checkInput(stat.size);
|
|
1226
|
+
if (streamed) {
|
|
1227
|
+
const source = await operation.acquire(() => fileSource({ fs: context.fs, path, signal, maxBytes: inputLimit - inputBytes, expectedStat: stat }), (source2) => source2.dispose());
|
|
1228
|
+
const input = source.bytes[Symbol.asyncIterator]();
|
|
1229
|
+
const first = await interrupted(() => input.next(), signal);
|
|
1230
|
+
const mimeType2 = attachment.mimeType ?? sniffMimeType(path, first.done ? new Uint8Array() : first.value);
|
|
1231
|
+
if (!acceptsMimeType(entry.model.attachmentTypes ?? [], mimeType2))
|
|
1232
|
+
throw new Error(`Model ${entry.model.id} does not accept ${mimeType2}`);
|
|
1233
|
+
admitInput(stat.size);
|
|
1234
|
+
let closed2 = false, consumed = false;
|
|
1235
|
+
sourceAttachments.push({ mimeType: mimeType2, source: {
|
|
1236
|
+
async dispose() {
|
|
1237
|
+
closed2 = true;
|
|
1238
|
+
await source.dispose();
|
|
1239
|
+
},
|
|
1240
|
+
bytes: { async *[Symbol.asyncIterator]() {
|
|
1241
|
+
if (closed2 || consumed)
|
|
1242
|
+
throw new FsError6("EBADF", { message: "LLM attachment source is closed" });
|
|
1243
|
+
consumed = true;
|
|
1244
|
+
signal.throwIfAborted();
|
|
1245
|
+
if (!first.done)
|
|
1246
|
+
yield first.value;
|
|
1247
|
+
while (true) {
|
|
1248
|
+
if (closed2)
|
|
1249
|
+
throw new FsError6("EBADF", { message: "LLM attachment source is closed" });
|
|
1250
|
+
const next = await interrupted(() => input.next(), signal);
|
|
1251
|
+
if (closed2)
|
|
1252
|
+
throw new FsError6("EBADF", { message: "LLM attachment source is closed" });
|
|
1253
|
+
if (next.done)
|
|
1254
|
+
break;
|
|
1255
|
+
yield next.value;
|
|
1256
|
+
}
|
|
1257
|
+
} }
|
|
1258
|
+
} });
|
|
1259
|
+
continue;
|
|
1260
|
+
}
|
|
1261
|
+
const bytes = await interrupted(() => context.fs.readFile(path, {
|
|
1262
|
+
signal,
|
|
1263
|
+
...inputLimit === Infinity ? {} : { maxBytes: inputLimit - inputBytes }
|
|
1264
|
+
}), signal);
|
|
1265
|
+
signal.throwIfAborted();
|
|
1266
|
+
if (!(bytes instanceof Uint8Array))
|
|
1267
|
+
throw new TypeError("Attachment read must return Uint8Array");
|
|
1268
|
+
admitInput(bytes.byteLength);
|
|
1269
|
+
const mimeType = attachment.mimeType ?? sniffMimeType(path, bytes);
|
|
1270
|
+
if (!acceptsMimeType(entry.model.attachmentTypes ?? [], mimeType))
|
|
1271
|
+
throw new Error(`Model ${entry.model.id} does not accept ${mimeType}`);
|
|
1272
|
+
attachments.push({ mimeType, bytes: new Uint8Array(bytes) });
|
|
1273
|
+
}
|
|
1274
|
+
const request = {
|
|
1275
|
+
model: entry.model.id,
|
|
1276
|
+
prompt,
|
|
1277
|
+
...args.system === void 0 ? {} : { system: args.system },
|
|
1278
|
+
attachments,
|
|
1279
|
+
options: args.options,
|
|
1280
|
+
signal
|
|
1281
|
+
};
|
|
1282
|
+
signal.throwIfAborted();
|
|
1283
|
+
if (args.noStream)
|
|
1284
|
+
outputSpool = await operation.acquire(() => createLlmSpool(context.fs, context.cwd, signal), (spool) => spool.close());
|
|
1285
|
+
if (streamed) {
|
|
1286
|
+
const events = service.streamSources({
|
|
1287
|
+
model: request.model,
|
|
1288
|
+
options: request.options,
|
|
1289
|
+
signal,
|
|
1290
|
+
prompt: promptSpool ? { bytes: promptSpool.replay(), dispose: promptSpool.close } : textSource(prompt),
|
|
1291
|
+
...args.system === void 0 ? {} : { system: textSource(args.system) },
|
|
1292
|
+
attachments: sourceAttachments
|
|
1293
|
+
});
|
|
1294
|
+
iterator = (async function* () {
|
|
1295
|
+
for await (const event of events) {
|
|
1296
|
+
if (event.type === "text")
|
|
1297
|
+
yield event.text;
|
|
1298
|
+
else if (event.type === "bytes")
|
|
1299
|
+
yield event.data;
|
|
1300
|
+
}
|
|
1301
|
+
})()[Symbol.asyncIterator]();
|
|
1302
|
+
} else
|
|
1303
|
+
iterator = service.complete(request)[Symbol.asyncIterator]();
|
|
1304
|
+
const text = (entry.model.outputType ?? "text/plain").toLowerCase().startsWith("text/");
|
|
1305
|
+
let pendingSurrogate = "";
|
|
1306
|
+
while (true) {
|
|
1307
|
+
await step();
|
|
1308
|
+
const result = await interrupted(() => iterator.next(), signal);
|
|
1309
|
+
signal.throwIfAborted();
|
|
1310
|
+
if (result.done) {
|
|
1311
|
+
ended = true;
|
|
1312
|
+
break;
|
|
1313
|
+
}
|
|
1314
|
+
if (text ? typeof result.value !== "string" : !(result.value instanceof Uint8Array))
|
|
1315
|
+
throw new Error(`Provider ${entry.provider.name} returned a response chunk incompatible with ${entry.model.outputType ?? "text/plain"}`);
|
|
1316
|
+
if (typeof result.value === "string") {
|
|
1317
|
+
let chunk = pendingSurrogate + result.value;
|
|
1318
|
+
const last = chunk.charCodeAt(chunk.length - 1);
|
|
1319
|
+
pendingSurrogate = last >= 55296 && last <= 56319 ? chunk.slice(-1) : "";
|
|
1320
|
+
if (pendingSurrogate)
|
|
1321
|
+
chunk = chunk.slice(0, -1);
|
|
1322
|
+
if (chunk)
|
|
1323
|
+
await emitText(chunk);
|
|
1324
|
+
} else
|
|
1325
|
+
await write(result.value);
|
|
1326
|
+
}
|
|
1327
|
+
if (text) {
|
|
1328
|
+
if (pendingSurrogate)
|
|
1329
|
+
await emitText(pendingSurrogate);
|
|
1330
|
+
await write(Uint8Array.of(10));
|
|
1331
|
+
}
|
|
1332
|
+
if (outputSpool)
|
|
1333
|
+
for await (const chunk of outputSpool.replay()) {
|
|
1334
|
+
writing = true;
|
|
1335
|
+
await operation.output.write(chunk);
|
|
1336
|
+
writing = false;
|
|
1337
|
+
}
|
|
1338
|
+
return { exitCode: 0 };
|
|
1339
|
+
} catch (error) {
|
|
1340
|
+
context.signal.throwIfAborted();
|
|
1341
|
+
operation.signal.throwIfAborted();
|
|
1342
|
+
controller.abort(error);
|
|
1343
|
+
if (writing)
|
|
1344
|
+
throw error;
|
|
1345
|
+
await operation.close();
|
|
1346
|
+
await writeDiagnostic(context.stderr, `${error instanceof Error ? error.message.slice(0, 4096) : "llm provider failed"}
|
|
1347
|
+
`, context.signal);
|
|
1348
|
+
return { exitCode: error instanceof LlmModelsUsageError ? 2 : 1 };
|
|
1349
|
+
} finally {
|
|
1350
|
+
controller.abort(new Error("llm request closed"));
|
|
1351
|
+
await operation.close();
|
|
1352
|
+
}
|
|
1353
|
+
}
|
|
1354
|
+
function createLlmCommand(options = {}) {
|
|
1355
|
+
for (const [name, value] of Object.entries(options.limits ?? {})) {
|
|
1356
|
+
if (!Number.isSafeInteger(value) || value < 0)
|
|
1357
|
+
throw new TypeError(`Invalid llm limit: ${name}`);
|
|
1358
|
+
}
|
|
1359
|
+
const limits = options.limits === void 0 ? void 0 : Object.freeze({ ...options.limits });
|
|
1360
|
+
if (options.service && (options.providers !== void 0 || options.defaultModel !== void 0))
|
|
1361
|
+
throw new TypeError("Configure providers and defaultModel on the injected LLM service");
|
|
1362
|
+
const service = options.service ?? createLlmService({ ...options, providers: options.providers ?? [] });
|
|
1363
|
+
return { name: "llm", description: "Query injected language and media models", execute: (context) => execute(context, service, limits) };
|
|
1364
|
+
}
|
|
1365
|
+
function createLlmCommands(options = {}) {
|
|
1366
|
+
return [createLlmCommand(options)];
|
|
1367
|
+
}
|
|
1368
|
+
function llmCommands(options = {}) {
|
|
1369
|
+
const definitions = createLlmCommands(options);
|
|
1370
|
+
const replace = options.replace ?? false;
|
|
1371
|
+
return { name: "llm-commands", setup(host) {
|
|
1372
|
+
if (!replace && host.commands.has("llm"))
|
|
1373
|
+
throw new Error("Command already registered: llm");
|
|
1374
|
+
for (const definition of definitions)
|
|
1375
|
+
host.commands.register(definition, { replace });
|
|
1376
|
+
} };
|
|
1377
|
+
}
|
|
1378
|
+
|
|
1379
|
+
export {
|
|
1380
|
+
createLlmConfiguration,
|
|
1381
|
+
validateLlmTemplateParameters,
|
|
1382
|
+
evaluateLlmTemplate,
|
|
1383
|
+
createLlmTemplateStore,
|
|
1384
|
+
parseLlmSchemaDsl,
|
|
1385
|
+
createLlmCommand,
|
|
1386
|
+
createLlmCommands,
|
|
1387
|
+
llmCommands
|
|
1388
|
+
};
|