@poe-platform/safe-bash 0.1.817 → 0.1.819
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/image-ast/index.js +2 -2
- package/dist/mp4-ast/index.d.ts +2 -1
- package/dist/mp4-ast/mp4-metadata-source.d.ts +10 -0
- package/dist/mp4-ast/mp4-packets-source.d.ts +8 -1
- package/dist/mp4-ast/types.d.ts +21 -3
- package/dist/office-xml/retained-xml-document.d.ts +2 -2
- package/dist/pdf-ast/ast.d.ts +2 -0
- package/dist/pdf-ast/content/evaluator.d.ts +7 -0
- package/dist/pdf-ast/content/retained-evaluator.d.ts +2 -2
- package/dist/pdf-ast/content/retained-page.d.ts +2 -2
- package/dist/pdf-ast/cos/compact-number.d.ts +19 -0
- package/dist/pdf-ast/cos/mutable-object-store.d.ts +2 -1
- package/dist/pdf-ast/cos/retained-node-writer.d.ts +9 -0
- package/dist/pdf-ast/cos/text-store.d.ts +27 -0
- package/dist/pdf-ast/edit/retained-bookmarks.d.ts +2 -2
- package/dist/pdf-ast/edit/retained-info-updates.d.ts +3 -3
- package/dist/pdf-ast/edit/retained-merge-outlines.d.ts +43 -0
- package/dist/pdf-ast/edit/retained-page-copy.d.ts +2 -0
- package/dist/pdf-ast/extract/html-text-stream.d.ts +14 -0
- package/dist/pdf-ast/extract/logical-text-stream.d.ts +14 -0
- package/dist/pdf-ast/extract/raw-text-index.d.ts +18 -4
- package/dist/pdf-ast/extract/retained-color.d.ts +6 -6
- package/dist/pdf-ast/extract/retained-decoded-image.d.ts +2 -2
- package/dist/pdf-ast/extract/stored-text-glyphs.d.ts +8 -0
- package/dist/pdf-ast/fonts/retained.d.ts +2 -2
- package/dist/pdf-ast/image.d.ts +2 -0
- package/dist/pdf-ast/image.js +19 -0
- package/dist/pdf-ast/index.d.ts +6 -0
- package/dist/pdf-ast/index.js +270 -66852
- package/dist/pdf-ast/render/postscript.d.ts +6 -0
- package/dist/pdf-ast/render/raster.d.ts +21 -1
- package/dist/pdf-ast/retained-document.d.ts +23 -95
- package/dist/pdf-ast/retained-reader.d.ts +113 -0
- package/dist/safe-bash/ast-grep.js +1 -1
- package/dist/safe-bash/audio-ast.js +1 -1
- package/dist/safe-bash/byte-encoding.js +1 -1
- package/dist/safe-bash/chunks/{chunk-HD6DWOAC.js → chunk-67QE3JLU.js} +1 -1
- package/dist/safe-bash/chunks/{chunk-HPQE675Q.js → chunk-ESH5MDQR.js} +1 -1
- package/dist/safe-bash/chunks/chunk-HNT2MR4W.js +45 -0
- package/dist/safe-bash/chunks/{chunk-SXSEF5E2.js → chunk-IRJS54AA.js} +1 -1
- package/dist/safe-bash/chunks/{chunk-AXGI5JVL.js → chunk-NAETSXBW.js} +2 -2
- package/dist/safe-bash/chunks/{chunk-WW7QPLH2.js → chunk-PSD2RSOS.js} +2 -1
- package/dist/safe-bash/chunks/{chunk-FQRI5AS5.js → chunk-VF3Q2V3E.js} +1 -1
- package/dist/safe-bash/chunks/{pdfinfo-KQIQEDOF.js → pdfinfo-G7BGZXBN.js} +2 -12
- package/dist/safe-bash/command-chunks/biff-AYJZR2YV-YFF3BK43.js +5741 -0
- package/dist/safe-bash/command-chunks/{chunk-FEBTT5NH.js → chunk-22D6Q6SW.js} +5 -5
- package/dist/safe-bash/command-chunks/{chunk-ALD53QFL.js → chunk-2C4QMQQD.js} +42 -12
- package/dist/safe-bash/command-chunks/{chunk-ZHHALBM7.js → chunk-2E53ZL5D.js} +11 -9
- package/dist/safe-bash/command-chunks/{chunk-EJ4UP7DA.js → chunk-2ESK2YIE.js} +27 -5
- package/dist/safe-bash/command-chunks/{chunk-CKA7ZROU.js → chunk-2GU2UU2Z.js} +9 -9
- package/dist/safe-bash/command-chunks/{chunk-L2VLASZ4.js → chunk-2GUI3ZKE.js} +3 -3
- package/dist/safe-bash/command-chunks/chunk-2H6RJPCQ.js +721 -0
- package/dist/safe-bash/command-chunks/{chunk-DRHONH2C.js → chunk-2IGH6JIP.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-QDV2NIFR.js → chunk-2TMTGVJR.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-MQE77MEQ.js → chunk-2V6EUWE3.js} +3 -3
- package/dist/safe-bash/command-chunks/{chunk-BIJW6QWB.js → chunk-2VSNIHIW.js} +21 -21
- package/dist/safe-bash/command-chunks/{chunk-FSG6UC2N.js → chunk-2XR7B6DY.js} +420 -167
- package/dist/safe-bash/command-chunks/{chunk-EY3UE26F.js → chunk-2YC6MWQB.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-NLCUQD7Y.js → chunk-3DID6MQY.js} +21 -11
- package/dist/safe-bash/command-chunks/{chunk-5VO534FR.js → chunk-3K5FCRUG.js} +1 -0
- package/dist/safe-bash/command-chunks/{chunk-BSTABZIK.js → chunk-3LMUKOP2.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-XBWD6SI3.js → chunk-3MFYCMQU.js} +37 -37
- package/dist/safe-bash/command-chunks/chunk-3PO534WJ.js +37 -0
- package/dist/safe-bash/command-chunks/{chunk-UFLMOU3B.js → chunk-3RDEX4AF.js} +4 -4
- package/dist/safe-bash/command-chunks/{chunk-DOVWHVHI.js → chunk-3TXPZLFI.js} +6 -6
- package/dist/safe-bash/command-chunks/{chunk-TID5TSQW.js → chunk-42OQIFPW.js} +5 -5
- package/dist/safe-bash/command-chunks/{chunk-UJYXSLM6.js → chunk-45QE6QRR.js} +4 -4
- package/dist/safe-bash/command-chunks/{chunk-LMLBQSAM.js → chunk-4HJEZGYN.js} +8 -8
- package/dist/safe-bash/command-chunks/{chunk-5QXRIZSS.js → chunk-4Q3HP33O.js} +4 -4
- package/dist/safe-bash/command-chunks/{chunk-EBX5RKKT.js → chunk-4XYGJB24.js} +4 -4
- package/dist/safe-bash/command-chunks/{chunk-NDALIHKK.js → chunk-4ZQYBCB2.js} +22 -22
- package/dist/safe-bash/command-chunks/{chunk-OFONWWEZ.js → chunk-5IHJWBDR.js} +2 -2
- package/dist/safe-bash/command-chunks/{chunk-TG2RVQLP.js → chunk-5KWEZV5H.js} +2 -2
- package/dist/safe-bash/command-chunks/{chunk-UYZ6EFZE.js → chunk-5P5SF75H.js} +83 -34
- package/dist/safe-bash/command-chunks/{chunk-P462JTNT.js → chunk-5PJ6VT2O.js} +7 -7
- package/dist/safe-bash/command-chunks/{chunk-SICTBSLW.js → chunk-5QR4LTAK.js} +7 -7
- package/dist/safe-bash/command-chunks/{chunk-ARE267HR.js → chunk-5XIJYTQU.js} +7 -7
- package/dist/safe-bash/command-chunks/chunk-63WEASJ7.js +137 -0
- package/dist/safe-bash/command-chunks/{chunk-3K5CVXUV.js → chunk-64L57DEI.js} +19 -19
- package/dist/safe-bash/command-chunks/{chunk-2ALHVXEM.js → chunk-6EK76ERE.js} +2 -2
- package/dist/safe-bash/command-chunks/{chunk-4772DJKS.js → chunk-6GCK2KSL.js} +61 -26
- package/dist/safe-bash/command-chunks/{chunk-T5OQ53XS.js → chunk-6IID5HTY.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-ABL2DPJI.js → chunk-6PDXNY3T.js} +13 -13
- package/dist/safe-bash/command-chunks/{chunk-X42MJT2J.js → chunk-6RE4MZYM.js} +4 -4
- package/dist/safe-bash/command-chunks/{chunk-AF2IO57Q.js → chunk-6REH56FL.js} +14 -140
- package/dist/safe-bash/command-chunks/{chunk-XFIDOCYH.js → chunk-6ZHNKHQQ.js} +2 -2
- package/dist/safe-bash/command-chunks/{chunk-6JGICYHP.js → chunk-75OUKYCM.js} +2 -2
- package/dist/safe-bash/command-chunks/{chunk-POGVOCOB.js → chunk-772WNCU6.js} +10 -10
- package/dist/safe-bash/command-chunks/{chunk-3DWFXESW.js → chunk-7GJJDM2F.js} +2 -2
- package/dist/safe-bash/command-chunks/{chunk-XVEI4HZL.js → chunk-7JTJQKIV.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-WIW3KDBS.js → chunk-7NFICYRU.js} +2 -2
- package/dist/safe-bash/command-chunks/{chunk-3ZVK2OAY.js → chunk-A4GYNM2E.js} +6 -5
- package/dist/safe-bash/command-chunks/chunk-AC4FFCRL.js +3820 -0
- package/dist/safe-bash/command-chunks/{chunk-SQBWAFUI.js → chunk-ADN7BU5X.js} +58 -26
- package/dist/safe-bash/command-chunks/{chunk-FHQOFEQK.js → chunk-AEHEOKI2.js} +10 -10
- package/dist/safe-bash/command-chunks/{chunk-BZRWZ6GO.js → chunk-AH3ZEPAN.js} +12 -9
- package/dist/safe-bash/command-chunks/{chunk-3MUFXGA2.js → chunk-AR65HNNX.js} +3 -3
- package/dist/safe-bash/command-chunks/{chunk-VNNNVT4C.js → chunk-ARA57PMC.js} +5 -5
- package/dist/safe-bash/command-chunks/{chunk-3VGQTLO6.js → chunk-AXUHORS3.js} +4 -4
- package/dist/safe-bash/command-chunks/chunk-B6NAEWHC.js +53 -0
- package/dist/safe-bash/command-chunks/{chunk-2ZWRW6UQ.js → chunk-B74LVFAN.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-E4TF5W6O.js → chunk-BBOYR6LV.js} +5 -5
- package/dist/safe-bash/command-chunks/{chunk-ZM7HMBAJ.js → chunk-BDGNKRY4.js} +7 -7
- package/dist/safe-bash/command-chunks/{chunk-KDBU5Q2N.js → chunk-BFOVQUTF.js} +8 -8
- package/dist/safe-bash/command-chunks/{chunk-GNT3SCF3.js → chunk-BOMCPF7N.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-ZNCPIZCN.js → chunk-BSLXS4PE.js} +2 -2
- package/dist/safe-bash/command-chunks/{chunk-N6TG44VG.js → chunk-BTDSUATE.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-VZJRFHMZ.js → chunk-BXDNFBKZ.js} +26 -2
- package/dist/safe-bash/command-chunks/chunk-BZLLQWRK.js +296 -0
- package/dist/safe-bash/command-chunks/{chunk-YXR4JE4U.js → chunk-C3FERGHU.js} +4 -4
- package/dist/safe-bash/command-chunks/chunk-C5SLY3RB.js +279 -0
- package/dist/safe-bash/command-chunks/{chunk-5O45KGW5.js → chunk-C5VUJOUQ.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-T4SEQU66.js → chunk-CI6KHUFK.js} +5 -5
- package/dist/safe-bash/command-chunks/chunk-CJIFJ45R.js +203 -0
- package/dist/safe-bash/command-chunks/{chunk-OTEHQQU7.js → chunk-CKQ5SXOO.js} +8 -59
- package/dist/safe-bash/command-chunks/{chunk-LJ3UYESS.js → chunk-CP5EO5TT.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-TY7JXEWI.js → chunk-CPCXE2TM.js} +13 -13
- package/dist/safe-bash/command-chunks/{chunk-VVWHFNHD.js → chunk-CXOAMPOV.js} +420 -28
- package/dist/safe-bash/command-chunks/{chunk-57PK2QFX.js → chunk-D3WMD32B.js} +16 -16
- package/dist/safe-bash/command-chunks/{chunk-LECGQSQW.js → chunk-D54L2IOZ.js} +12 -12
- package/dist/safe-bash/command-chunks/{chunk-FGARVKAX.js → chunk-DBYY7IDI.js} +24 -20
- package/dist/safe-bash/command-chunks/{chunk-LNAZ3E4Q.js → chunk-DGFMOT4O.js} +4 -4
- package/dist/safe-bash/command-chunks/{chunk-N5J3IZZK.js → chunk-DQVOBGI2.js} +12414 -8140
- package/dist/safe-bash/command-chunks/{chunk-OHEZQ4QA.js → chunk-DTLIBRCQ.js} +11 -11
- package/dist/safe-bash/command-chunks/{chunk-FGHSE3RZ.js → chunk-DZ4ELL34.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-ICJH6A73.js → chunk-DZTT5SLG.js} +7 -7
- package/dist/safe-bash/command-chunks/{chunk-77NXQZGK.js → chunk-DZY7V74W.js} +3 -1
- package/dist/safe-bash/command-chunks/chunk-E47FFS5M.js +52 -0
- package/dist/safe-bash/command-chunks/{chunk-LNKZVU5V.js → chunk-E76WK7OQ.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-EWC56JNI.js → chunk-EBMKGNKF.js} +9 -9
- package/dist/safe-bash/command-chunks/{chunk-5GDF5FAS.js → chunk-EEJ3YXVO.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-GMBUOYTN.js → chunk-EG7VVDV3.js} +8 -8
- package/dist/safe-bash/command-chunks/{chunk-N32AP43V.js → chunk-EIZFAUUD.js} +9 -9
- package/dist/safe-bash/command-chunks/{chunk-FR63MJSO.js → chunk-ESIEU4E4.js} +9 -9
- package/dist/safe-bash/command-chunks/{chunk-QJZJWL2X.js → chunk-ET3CPTJT.js} +38 -25
- package/dist/safe-bash/command-chunks/{chunk-UT5X6QRU.js → chunk-ETS4BINB.js} +9 -9
- package/dist/safe-bash/command-chunks/{chunk-SBXS4S6Y.js → chunk-EU5SR3LS.js} +3 -3
- package/dist/safe-bash/command-chunks/{chunk-FTZFCMVI.js → chunk-FAVWWMFW.js} +12 -12
- package/dist/safe-bash/command-chunks/{chunk-YKODRSGT.js → chunk-FCGMSOF6.js} +8 -8
- package/dist/safe-bash/command-chunks/{chunk-S5ER73EA.js → chunk-FGK6HLSY.js} +8 -8
- package/dist/safe-bash/command-chunks/{chunk-WMV5224N.js → chunk-FILE5PBI.js} +3 -3
- package/dist/safe-bash/command-chunks/{chunk-7ADQE64C.js → chunk-FMGNXOMV.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-XPQUUFQD.js → chunk-FPOM47UA.js} +2 -2
- package/dist/safe-bash/command-chunks/{chunk-ZZERSKAR.js → chunk-FX54I4AC.js} +5 -5
- package/dist/safe-bash/command-chunks/{chunk-CORUUCS2.js → chunk-GAYTDZPP.js} +5 -5
- package/dist/safe-bash/command-chunks/chunk-GCSKS22X.js +15 -0
- package/dist/safe-bash/command-chunks/{chunk-2QZUAZTH.js → chunk-GIQUIF6E.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-UVZJAV2S.js → chunk-GNPPPYDF.js} +1 -78
- package/dist/safe-bash/command-chunks/{chunk-B6XTAKKQ.js → chunk-GNVAW6NL.js} +1 -1
- package/dist/safe-bash/command-chunks/chunk-GQV5RWMN.js +27 -0
- package/dist/safe-bash/command-chunks/{chunk-PWHIVWQT.js → chunk-GVDVRC7J.js} +15 -19
- package/dist/safe-bash/command-chunks/{chunk-N4HWOLGZ.js → chunk-GY2C555A.js} +2 -2
- package/dist/safe-bash/command-chunks/{chunk-KXM3HTAF.js → chunk-GYKQ3IOV.js} +27 -14
- package/dist/safe-bash/command-chunks/{chunk-VMZIAFVJ.js → chunk-HBR5PWX4.js} +8 -8
- package/dist/safe-bash/command-chunks/{chunk-YPG55QTP.js → chunk-HCJWEB6P.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-ZOEKSH3R.js → chunk-HCPEYQKT.js} +5 -4
- package/dist/safe-bash/command-chunks/{chunk-U42WHQRH.js → chunk-HCZITM4C.js} +8 -8
- package/dist/safe-bash/command-chunks/{chunk-4SISSPIH.js → chunk-HLRLMFMS.js} +1 -1
- package/dist/safe-bash/command-chunks/chunk-HNEWGADJ.js +43 -0
- package/dist/safe-bash/command-chunks/{chunk-DZOKH5BL.js → chunk-HQFX5XKV.js} +7 -7
- package/dist/safe-bash/command-chunks/{chunk-QNX5LZBK.js → chunk-HSB55ED5.js} +9 -9
- package/dist/safe-bash/command-chunks/{chunk-G3FK5VVG.js → chunk-HTBUIRTH.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-QCIAX6HZ.js → chunk-HUAQZFON.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-6M3JTPKE.js → chunk-HVLF3Y4B.js} +8 -8
- package/dist/safe-bash/command-chunks/{chunk-AYQPJQJR.js → chunk-I6CQDCIP.js} +8 -8
- package/dist/safe-bash/command-chunks/chunk-I7MEH76L.js +276 -0
- package/dist/safe-bash/command-chunks/{chunk-E3BL7W5C.js → chunk-IAHYG67O.js} +152 -80
- package/dist/safe-bash/command-chunks/{chunk-TXWDR2P4.js → chunk-IBT3OWXB.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-EAGIJ4VW.js → chunk-IC5XC4TO.js} +118 -118
- package/dist/safe-bash/command-chunks/{chunk-ERWIJYCS.js → chunk-IGZOQT2L.js} +10 -10
- package/dist/safe-bash/command-chunks/{chunk-CKIXC7AO.js → chunk-IPKYPADE.js} +3 -3
- package/dist/safe-bash/command-chunks/{chunk-FJLSYX5P.js → chunk-ITJDLFPW.js} +3 -3
- package/dist/safe-bash/command-chunks/{chunk-MUTARE5I.js → chunk-IYEAS7TU.js} +8 -8
- package/dist/safe-bash/command-chunks/{chunk-WDVPHDBH.js → chunk-J3ISXTYB.js} +5 -5
- package/dist/safe-bash/command-chunks/chunk-J3VS55K4.js +69097 -0
- package/dist/safe-bash/command-chunks/chunk-J4I7KCQQ.js +495 -0
- package/dist/safe-bash/command-chunks/{chunk-IWVANZWH.js → chunk-JLPBGKVC.js} +3 -3
- package/dist/safe-bash/command-chunks/{chunk-HQEYSSZV.js → chunk-JLS6XKAR.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-IJE65P52.js → chunk-JMUB5A26.js} +27 -8
- package/dist/safe-bash/command-chunks/{chunk-HOJ7WDTS.js → chunk-JQPDVCBU.js} +6 -6
- package/dist/safe-bash/command-chunks/{chunk-LQX7RAF7.js → chunk-JSW6YH6T.js} +7 -7
- package/dist/safe-bash/command-chunks/{chunk-DM5WURQL.js → chunk-JY2T3KV2.js} +2 -2
- package/dist/safe-bash/command-chunks/{chunk-IZ3SD5S2.js → chunk-K2NV6H7E.js} +4 -4
- package/dist/safe-bash/command-chunks/{chunk-YJ5IA5YQ.js → chunk-K576GZED.js} +3 -3
- package/dist/safe-bash/command-chunks/{chunk-VZTVR3JI.js → chunk-K6J3KFQ2.js} +17 -122
- package/dist/safe-bash/command-chunks/{chunk-RTHYAGKI.js → chunk-KD4JUF6R.js} +4 -4
- package/dist/safe-bash/command-chunks/{chunk-FUYZUETI.js → chunk-KQE2D7PX.js} +8 -8
- package/dist/safe-bash/command-chunks/{chunk-Q65GWGQR.js → chunk-KVTZJBLM.js} +5 -5
- package/dist/safe-bash/command-chunks/{chunk-ONQP4FNV.js → chunk-KZICRCQ7.js} +1 -1
- package/dist/safe-bash/command-chunks/chunk-L365UGC7.js +250 -0
- package/dist/safe-bash/command-chunks/{chunk-UKAGRRLZ.js → chunk-LBBJ5S3W.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-WHZ6XK7Y.js → chunk-LBILRPVR.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-ENMJHB2C.js → chunk-LDR3PPM3.js} +5 -5
- package/dist/safe-bash/command-chunks/chunk-LJLB7TBN.js +775 -0
- package/dist/safe-bash/command-chunks/{chunk-A6OTPNNI.js → chunk-LPKMNCC5.js} +3 -3
- package/dist/safe-bash/command-chunks/{chunk-JA36YOZI.js → chunk-LUJUYUOG.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-FB2WPI3M.js → chunk-LZHFVNEV.js} +17 -107
- package/dist/safe-bash/command-chunks/{chunk-4X2MPZXW.js → chunk-M42GCI5F.js} +2 -2
- package/dist/safe-bash/command-chunks/{chunk-URQSUMMJ.js → chunk-M7MQTU77.js} +6 -6
- package/dist/safe-bash/command-chunks/chunk-MCUDSE4H.js +77 -0
- package/dist/safe-bash/command-chunks/{chunk-V6JPIZUW.js → chunk-MD5ZSARP.js} +9 -9
- package/dist/safe-bash/command-chunks/chunk-MEST2HID.js +112 -0
- package/dist/safe-bash/command-chunks/{chunk-26JE5JEB.js → chunk-MLMFFBOU.js} +4 -4
- package/dist/safe-bash/command-chunks/{chunk-HOKPYTHQ.js → chunk-MPRUGL4W.js} +2 -2
- package/dist/safe-bash/command-chunks/{chunk-E22EAYJN.js → chunk-MQCLG2CT.js} +177 -34
- package/dist/safe-bash/command-chunks/{chunk-G3LUT475.js → chunk-N5Y7WWO6.js} +10 -10
- package/dist/safe-bash/command-chunks/{chunk-MZYQKH26.js → chunk-NA6YAGAH.js} +3 -3
- package/dist/safe-bash/command-chunks/{chunk-PPN53PX3.js → chunk-NDJPULBE.js} +4 -4
- package/dist/safe-bash/command-chunks/{chunk-2IMIKROX.js → chunk-NN6OWOJG.js} +6 -6
- package/dist/safe-bash/command-chunks/{chunk-SWIF6BBY.js → chunk-NNYOPI7K.js} +8 -8
- package/dist/safe-bash/command-chunks/{chunk-GAROGIVU.js → chunk-NP2QXF2X.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-SNA2LVBX.js → chunk-NPVOYY2A.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-T2FRXSQT.js → chunk-NR7POLKP.js} +2 -2
- package/dist/safe-bash/command-chunks/{chunk-A4P37F3P.js → chunk-NWA7ZJDV.js} +5 -5
- package/dist/safe-bash/command-chunks/{chunk-45DKGZYO.js → chunk-O3FTKLWR.js} +423 -213
- package/dist/safe-bash/command-chunks/{chunk-6KJDTKE4.js → chunk-O4H7HPMP.js} +35 -393
- package/dist/safe-bash/command-chunks/{chunk-J6FNSVHT.js → chunk-OLNV5MI6.js} +5 -5
- package/dist/safe-bash/command-chunks/{chunk-BBEAO5N7.js → chunk-OLXMWQJ5.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-MDFNUNK5.js → chunk-OMD45J52.js} +25 -21
- package/dist/safe-bash/command-chunks/{chunk-AXI7VMLG.js → chunk-OOYVZAWL.js} +3 -41
- package/dist/safe-bash/command-chunks/{chunk-2TWXRJPB.js → chunk-OPKLIF5P.js} +17 -17
- package/dist/safe-bash/command-chunks/{chunk-E3DF7RTE.js → chunk-OT75C5YS.js} +2 -2
- package/dist/safe-bash/command-chunks/{chunk-ROQ3VNVX.js → chunk-OVCSXD7N.js} +10 -10
- package/dist/safe-bash/command-chunks/chunk-P3LHQOX7.js +371 -0
- package/dist/safe-bash/command-chunks/{chunk-OFDJJRAD.js → chunk-P3TV5GIG.js} +11 -11
- package/dist/safe-bash/command-chunks/{chunk-LQDANF2B.js → chunk-P5UFNPRE.js} +10 -10
- package/dist/safe-bash/command-chunks/{chunk-5V7WIQ2D.js → chunk-PAEAEFK3.js} +122 -12
- package/dist/safe-bash/command-chunks/{chunk-OWCBX5M2.js → chunk-PAY4ULWY.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-TXU7MMHN.js → chunk-PH722HK2.js} +16 -16
- package/dist/safe-bash/command-chunks/{chunk-OU4VE5CR.js → chunk-PKH57OIC.js} +8 -6
- package/dist/safe-bash/command-chunks/{chunk-GTOMW4VV.js → chunk-PNOXBL2B.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-L4XSOULP.js → chunk-PPNPXNM6.js} +38 -2
- package/dist/safe-bash/command-chunks/{chunk-DXOXUKQB.js → chunk-PVKSBXHB.js} +11 -9
- package/dist/safe-bash/command-chunks/{chunk-EZDWPTYB.js → chunk-PYYAX5FB.js} +23 -23
- package/dist/safe-bash/command-chunks/{chunk-MOUCMZZP.js → chunk-PZVFNPRC.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-UPWLHHZ2.js → chunk-QCCRQU44.js} +18 -18
- package/dist/safe-bash/command-chunks/{chunk-IVKAFEPO.js → chunk-QEVSG6HQ.js} +9 -9
- package/dist/safe-bash/command-chunks/{chunk-6YF2QADH.js → chunk-QGSY4ZAU.js} +8 -8
- package/dist/safe-bash/command-chunks/{chunk-LZY46GYY.js → chunk-QMWBKR4C.js} +5 -5
- package/dist/safe-bash/command-chunks/{chunk-4YFTJS5U.js → chunk-QMXOKYMJ.js} +2 -2
- package/dist/safe-bash/command-chunks/{chunk-CHZE6FNT.js → chunk-QPHI7Y7Z.js} +4 -4
- package/dist/safe-bash/command-chunks/{chunk-N3ZH4YYH.js → chunk-QQ7ORF2D.js} +5 -5
- package/dist/safe-bash/command-chunks/{chunk-4ABR3KGK.js → chunk-QWQHLMDX.js} +7 -7
- package/dist/safe-bash/command-chunks/chunk-QX3WKBLI.js +58 -0
- package/dist/safe-bash/command-chunks/{chunk-V6OWCRHN.js → chunk-QZPSGPN5.js} +1 -1
- package/dist/safe-bash/command-chunks/chunk-R36PDP3L.js +106 -0
- package/dist/safe-bash/command-chunks/{chunk-N35IJXBK.js → chunk-R43WEA4C.js} +14 -14
- package/dist/safe-bash/command-chunks/{chunk-5YL453ZF.js → chunk-R6VXFTYL.js} +47 -47
- package/dist/safe-bash/command-chunks/{chunk-OVUY46QF.js → chunk-RC4TNFNF.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-PU5DMQGG.js → chunk-RESJSUHH.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-OCOJMKDP.js → chunk-RHXV2KG5.js} +522 -8
- package/dist/safe-bash/command-chunks/{chunk-7B2MHKIW.js → chunk-RKON2TGI.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-OIHQXURE.js → chunk-ROE6KD4C.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-ITXSHOLP.js → chunk-RQTFK7AV.js} +2 -2
- package/dist/safe-bash/command-chunks/{chunk-BKK4MS3V.js → chunk-RR6XG2I6.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-CFMJXJS5.js → chunk-RTUDDAAY.js} +9 -4
- package/dist/safe-bash/command-chunks/{chunk-FAU2KL6I.js → chunk-S5MBHFLB.js} +2 -2
- package/dist/safe-bash/command-chunks/{chunk-R7LF4XQV.js → chunk-S6223MIG.js} +2 -2
- package/dist/safe-bash/command-chunks/{chunk-6W4RMBFH.js → chunk-SKDJCMGI.js} +12 -10
- package/dist/safe-bash/command-chunks/{chunk-NCNHJRIY.js → chunk-SKF6PGA5.js} +12 -12
- package/dist/safe-bash/command-chunks/{chunk-3PM46VWH.js → chunk-SLD5A7IL.js} +11 -11
- package/dist/safe-bash/command-chunks/{chunk-KYIGYYEY.js → chunk-SMCRKN3O.js} +5 -5
- package/dist/safe-bash/command-chunks/{chunk-H56BSMFQ.js → chunk-T2LZWXWF.js} +8 -8
- package/dist/safe-bash/command-chunks/{chunk-KDDXLHN7.js → chunk-TMJG745A.js} +6 -6
- package/dist/safe-bash/command-chunks/{chunk-QMBMZSJF.js → chunk-TP5MZHCB.js} +6 -6
- package/dist/safe-bash/command-chunks/{chunk-ET6LMDEX.js → chunk-TPSRY72Q.js} +9 -9
- package/dist/safe-bash/command-chunks/{chunk-ZAYTFXUX.js → chunk-TTPT3OME.js} +7 -7
- package/dist/safe-bash/command-chunks/{chunk-GR4ONCQ5.js → chunk-U6VSRO6E.js} +9 -9
- package/dist/safe-bash/command-chunks/{chunk-5VF2EA7Z.js → chunk-U7J3R7HX.js} +6 -1
- package/dist/safe-bash/command-chunks/{chunk-A5SPMSKD.js → chunk-UDRJKA3P.js} +11 -11
- package/dist/safe-bash/command-chunks/{chunk-3B444A5G.js → chunk-UI5AS3FS.js} +10 -2
- package/dist/safe-bash/command-chunks/{chunk-RVWIEXR7.js → chunk-UMOQHHSV.js} +9 -9
- package/dist/safe-bash/command-chunks/{chunk-WH624PKJ.js → chunk-UNI6QG45.js} +5 -5
- package/dist/safe-bash/command-chunks/{chunk-BOVDUJ3A.js → chunk-UTSN7AKE.js} +9 -9
- package/dist/safe-bash/command-chunks/{chunk-F5QYUK2E.js → chunk-UWIDPTOB.js} +2 -2
- package/dist/safe-bash/command-chunks/{chunk-345YBIHP.js → chunk-V2J6AC6S.js} +19 -19
- package/dist/safe-bash/command-chunks/{chunk-ZZ27QNBY.js → chunk-V2PJO6JL.js} +29 -60
- package/dist/safe-bash/command-chunks/{chunk-QNETPOMH.js → chunk-VAMBWXDV.js} +72 -21
- package/dist/safe-bash/command-chunks/{chunk-KM2SMMXZ.js → chunk-VJQ5OWS5.js} +80 -2
- package/dist/safe-bash/command-chunks/{chunk-OCV5ZU35.js → chunk-VSTAHYCV.js} +3 -3
- package/dist/safe-bash/command-chunks/{chunk-MI2WY75O.js → chunk-VWBNUCUP.js} +28 -11
- package/dist/safe-bash/command-chunks/{chunk-SL4LD25A.js → chunk-W4BC2YGQ.js} +15 -15
- package/dist/safe-bash/command-chunks/{chunk-Y3ZRIZL7.js → chunk-W5LH7D23.js} +26 -13
- package/dist/safe-bash/command-chunks/{chunk-62RG3GHF.js → chunk-W6L4Z2VX.js} +10 -10
- package/dist/safe-bash/command-chunks/{chunk-RRAQII52.js → chunk-WEXEZRMH.js} +7 -7
- package/dist/safe-bash/command-chunks/chunk-WIUEM7HP.js +58 -0
- package/dist/safe-bash/command-chunks/{chunk-AQ3XOOPQ.js → chunk-WKS2PAZL.js} +2 -2
- package/dist/safe-bash/command-chunks/chunk-WOECEZAC.js +921 -0
- package/dist/safe-bash/command-chunks/{chunk-A2L3U7DW.js → chunk-WOO3YO2X.js} +7 -7
- package/dist/safe-bash/command-chunks/{chunk-7YDJ7LDO.js → chunk-WOT2YXBT.js} +8 -223
- package/dist/safe-bash/command-chunks/{chunk-LT2YCGC5.js → chunk-WV3C6BRD.js} +14 -14
- package/dist/safe-bash/command-chunks/{chunk-PRO7JOIH.js → chunk-X3EDCCXU.js} +10 -10
- package/dist/safe-bash/command-chunks/{chunk-WMBELKPP.js → chunk-XE75H5ZZ.js} +15 -15
- package/dist/safe-bash/command-chunks/{chunk-SHLT5R64.js → chunk-XMNPE6RN.js} +11 -11
- package/dist/safe-bash/command-chunks/{chunk-ISFGPCED.js → chunk-XNVL6AOV.js} +16 -16
- package/dist/safe-bash/command-chunks/{chunk-OBIXFO25.js → chunk-XPUYA7YU.js} +10 -10
- package/dist/safe-bash/command-chunks/{chunk-5KZMR6AJ.js → chunk-XXUMECE4.js} +22 -20
- package/dist/safe-bash/command-chunks/{chunk-OAM2SUUI.js → chunk-YB5TNDY6.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-KLAC2MIZ.js → chunk-YJMS5Q4Y.js} +12 -12
- package/dist/safe-bash/command-chunks/{chunk-FLSXHLJG.js → chunk-YJTP4ROI.js} +15 -15
- package/dist/safe-bash/command-chunks/{chunk-7ITPO2V6.js → chunk-YNFQ5AXM.js} +80 -45
- package/dist/safe-bash/command-chunks/{chunk-7PYDVQPB.js → chunk-YWP62BAZ.js} +2 -2
- package/dist/safe-bash/command-chunks/chunk-YXIJOYT6.js +416 -0
- package/dist/safe-bash/command-chunks/{chunk-NQL3WNFI.js → chunk-YYRVGXJH.js} +44 -5
- package/dist/safe-bash/command-chunks/{chunk-35DU6I2M.js → chunk-Z7UPCDTU.js} +5 -5
- package/dist/safe-bash/command-chunks/{chunk-O2XP6HQN.js → chunk-ZBGP6XEG.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-VWRHPDCD.js → chunk-ZIDESNHW.js} +3 -3
- package/dist/safe-bash/command-chunks/{chunk-VVV45NLY.js → chunk-ZJUU5IAS.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-3ZWFE4CK.js → chunk-ZLMCWAAU.js} +9 -9
- package/dist/safe-bash/command-chunks/{chunk-7OCTMVYJ.js → chunk-ZNABMTV3.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-QOKFSYD5.js → chunk-ZODGWV3Y.js} +11 -11
- package/dist/safe-bash/command-chunks/{chunk-DIRK47GT.js → chunk-ZPBL7TYJ.js} +3 -3
- package/dist/safe-bash/command-chunks/{chunk-5MNQTHED.js → chunk-ZQ4NQ24M.js} +10 -10
- package/dist/safe-bash/command-chunks/{chunk-4IDV763L.js → chunk-ZS4J5B6Y.js} +2 -2
- package/dist/safe-bash/command-chunks/chunk-ZTW2E5OT.js +1016 -0
- package/dist/safe-bash/command-chunks/{chunk-NKK76B4V.js → chunk-ZUOID3FA.js} +14 -14
- package/dist/safe-bash/command-chunks/chunk-ZWGERYLT.js +192 -0
- package/dist/safe-bash/command-chunks/{chunk-F2NF6FHV.js → chunk-ZXIOTUXC.js} +2 -2
- package/dist/safe-bash/command-chunks/{chunk-LFSWLJPR.js → chunk-ZZ6EIACJ.js} +250 -41
- package/dist/safe-bash/command-chunks/{chunk-XMRQ6UP2.js → chunk-ZZO3GYEZ.js} +1 -11
- package/dist/safe-bash/command-chunks/{command-engine-2QXVRRH3.js → command-engine-B6X6WAMX.js} +381 -114
- package/dist/safe-bash/command-chunks/{engine-T4GP6QOK-ECFKMR5V.js → engine-UPLVIV72-IGXUDNO5.js} +1 -1
- package/dist/safe-bash/command-chunks/model-store-RGLCVIML.js +54 -0
- package/dist/safe-bash/command-chunks/paradox-BHPRIGXX-RQN37FHB.js +370 -0
- package/dist/safe-bash/command-chunks/prompt-tool-debug-ERJKK3XZ.js +171 -0
- package/dist/safe-bash/commands/alias/index.js +1 -1
- package/dist/safe-bash/commands/apply-patch/index.js +1 -1
- package/dist/safe-bash/commands/archive/create.js +1 -1
- package/dist/safe-bash/commands/archive/extract.js +1 -1
- package/dist/safe-bash/commands/archive/format.js +1 -1
- package/dist/safe-bash/commands/archive/index.js +1 -1
- package/dist/safe-bash/commands/archive/internal.js +1 -1
- package/dist/safe-bash/commands/archive/listing.js +1 -1
- package/dist/safe-bash/commands/archive/modes.js +1 -1
- package/dist/safe-bash/commands/archive/options.js +1 -1
- package/dist/safe-bash/commands/archive/stream.js +1 -1
- package/dist/safe-bash/commands/archive/transform.js +1 -1
- package/dist/safe-bash/commands/archive/unzip/safety.js +1 -1
- package/dist/safe-bash/commands/archive/unzip.js +1 -1
- package/dist/safe-bash/commands/archive/zip/aes.js +1 -1
- package/dist/safe-bash/commands/archive/zip/comments.js +1 -1
- package/dist/safe-bash/commands/archive/zip/crc.js +1 -1
- package/dist/safe-bash/commands/archive/zip/crypto.js +1 -1
- package/dist/safe-bash/commands/archive/zip/dates.js +1 -1
- package/dist/safe-bash/commands/archive/zip/environment.js +1 -1
- package/dist/safe-bash/commands/archive/zip/grow.js +1 -1
- package/dist/safe-bash/commands/archive/zip/help.js +1 -1
- package/dist/safe-bash/commands/archive/zip/line-endings.js +1 -1
- package/dist/safe-bash/commands/archive/zip/log.js +1 -1
- package/dist/safe-bash/commands/archive/zip/lzma.js +1 -1
- package/dist/safe-bash/commands/archive/zip/move.js +1 -1
- package/dist/safe-bash/commands/archive/zip/names.js +1 -1
- package/dist/safe-bash/commands/archive/zip/options.js +1 -1
- package/dist/safe-bash/commands/archive/zip/repair.js +1 -1
- package/dist/safe-bash/commands/archive/zip/safety.js +1 -1
- package/dist/safe-bash/commands/archive/zip/sfx.js +1 -1
- package/dist/safe-bash/commands/archive/zip/test-command.js +1 -1
- package/dist/safe-bash/commands/archive/zip/volumes.js +1 -1
- package/dist/safe-bash/commands/archive/zip/zip64.js +1 -1
- package/dist/safe-bash/commands/archive/zip-format.js +1 -1
- package/dist/safe-bash/commands/archive/zip.js +1 -1
- package/dist/safe-bash/commands/ast-grep/index.js +1 -1
- package/dist/safe-bash/commands/audio/index.browser.js +2 -8
- package/dist/safe-bash/commands/audio/index.js +1 -1
- package/dist/safe-bash/commands/awk/index.js +1 -1
- package/dist/safe-bash/commands/base32/index.js +1 -1
- package/dist/safe-bash/commands/base64/index.js +1 -1
- package/dist/safe-bash/commands/bc/index.browser.js +1 -1
- package/dist/safe-bash/commands/bc/index.js +1 -1
- package/dist/safe-bash/commands/bytes/checksums/sm3.js +1 -1
- package/dist/safe-bash/commands/bytes/compression/bounded-codec.js +1 -1
- package/dist/safe-bash/commands/bytes/compression/codec-loader.js +1 -1
- package/dist/safe-bash/commands/bytes/compression/codec.js +1 -1
- package/dist/safe-bash/commands/bytes/compression/errors.js +1 -1
- package/dist/safe-bash/commands/bytes/compression/file-operation.js +1 -1
- package/dist/safe-bash/commands/bytes/compression/files.js +1 -1
- package/dist/safe-bash/commands/bytes/compression/gunzip.js +1 -1
- package/dist/safe-bash/commands/bytes/compression/stream.js +1 -1
- package/dist/safe-bash/commands/bytes/compression/xz-list.js +1 -1
- package/dist/safe-bash/commands/bytes/compression/zstd-decode.js +1 -1
- package/dist/safe-bash/commands/bytes/encoding/base.js +1 -1
- package/dist/safe-bash/commands/bytes/encoding/shared.js +1 -1
- package/dist/safe-bash/commands/bytes/input-budget.js +1 -1
- package/dist/safe-bash/commands/bzip2/index.js +1 -1
- package/dist/safe-bash/commands/cal/index.js +1 -1
- package/dist/safe-bash/commands/caller/index.js +1 -1
- package/dist/safe-bash/commands/canonicalize-existing-parent.js +1 -1
- package/dist/safe-bash/commands/chmod/index.js +1 -1
- package/dist/safe-bash/commands/column/index.js +1 -1
- package/dist/safe-bash/commands/comm/index.js +1 -1
- package/dist/safe-bash/commands/copy-backup.js +1 -1
- package/dist/safe-bash/commands/copy-preserve.js +1 -1
- package/dist/safe-bash/commands/copy-source.js +1 -1
- package/dist/safe-bash/commands/cp/index.js +1 -1
- package/dist/safe-bash/commands/csplit/index.js +1 -1
- package/dist/safe-bash/commands/csvcut/index.js +1 -1
- package/dist/safe-bash/commands/csvgrep/index.js +1 -1
- package/dist/safe-bash/commands/csvkit/index.js +1 -1
- package/dist/safe-bash/commands/curl/index.js +1 -1
- package/dist/safe-bash/commands/date/index.js +1 -1
- package/dist/safe-bash/commands/df/index.js +1 -1
- package/dist/safe-bash/commands/diff/index.js +1 -1
- package/dist/safe-bash/commands/diff-patch/diff-format.js +1 -1
- package/dist/safe-bash/commands/diff-patch/diff-options.js +1 -1
- package/dist/safe-bash/commands/diff-patch/diff-output.js +1 -1
- package/dist/safe-bash/commands/diff-patch/diff.js +1 -1
- package/dist/safe-bash/commands/diff-patch/index.js +2 -2
- package/dist/safe-bash/commands/diff-patch/patch-envelope.js +1 -1
- package/dist/safe-bash/commands/diff-patch/patch-formats.js +1 -1
- package/dist/safe-bash/commands/diff-patch/patch-gnu-paths.js +1 -1
- package/dist/safe-bash/commands/diff-patch/patch-gnu-reject.js +1 -1
- package/dist/safe-bash/commands/diff-patch/patch-path.js +1 -1
- package/dist/safe-bash/commands/diff-patch/patch-publication.js +1 -1
- package/dist/safe-bash/commands/diff-patch/patch.js +1 -1
- package/dist/safe-bash/commands/diff-patch/shared.js +1 -1
- package/dist/safe-bash/commands/diff-patch/unified.js +1 -1
- package/dist/safe-bash/commands/diff3/index.js +1 -1
- package/dist/safe-bash/commands/diffpdf/index.js +1 -1
- package/dist/safe-bash/commands/directory-admission.js +1 -1
- package/dist/safe-bash/commands/docx/index.js +1 -1
- package/dist/safe-bash/commands/docx/io.js +1 -1
- package/dist/safe-bash/commands/dos2unix/index.js +1 -1
- package/dist/safe-bash/commands/dot/index.js +1 -1
- package/dist/safe-bash/commands/du/index.js +1 -1
- package/dist/safe-bash/commands/egrep/index.js +1 -1
- package/dist/safe-bash/commands/env/index.js +1 -1
- package/dist/safe-bash/commands/env-split.js +1 -1
- package/dist/safe-bash/commands/exiftool/index.js +1 -1
- package/dist/safe-bash/commands/expand/index.js +1 -1
- package/dist/safe-bash/commands/expr/index.js +1 -1
- package/dist/safe-bash/commands/factor/index.js +1 -1
- package/dist/safe-bash/commands/fd/index.js +1 -1
- package/dist/safe-bash/commands/ffmpeg/index.js +1 -1
- package/dist/safe-bash/commands/ffprobe/index.js +1 -1
- package/dist/safe-bash/commands/fgrep/index.js +1 -1
- package/dist/safe-bash/commands/file/index.js +1 -1
- package/dist/safe-bash/commands/filesystem-requirements.js +1 -1
- package/dist/safe-bash/commands/find/index.js +1 -1
- package/dist/safe-bash/commands/find-format.js +1 -1
- package/dist/safe-bash/commands/find.js +1 -1
- package/dist/safe-bash/commands/fmt/index.js +1 -1
- package/dist/safe-bash/commands/fold/index.js +1 -1
- package/dist/safe-bash/commands/getconf/index.js +1 -1
- package/dist/safe-bash/commands/getopt/index.js +1 -1
- package/dist/safe-bash/commands/gnu-information.js +1 -1
- package/dist/safe-bash/commands/gpg/index.js +1 -1
- package/dist/safe-bash/commands/graphviz/index.js +3 -3
- package/dist/safe-bash/commands/grep/index.js +1 -1
- package/dist/safe-bash/commands/grep-aliases/aliases.js +1 -1
- package/dist/safe-bash/commands/grep.js +1 -1
- package/dist/safe-bash/commands/gzip/index.js +1 -1
- package/dist/safe-bash/commands/hexdump/index.js +1 -1
- package/dist/safe-bash/commands/hostname/index.js +1 -1
- package/dist/safe-bash/commands/html-to-markdown/index.js +1 -1
- package/dist/safe-bash/commands/htmlq/index.js +1 -1
- package/dist/safe-bash/commands/iconv/index.js +1 -1
- package/dist/safe-bash/commands/id/index.js +1 -1
- package/dist/safe-bash/commands/imagemagick/index.js +1 -1
- package/dist/safe-bash/commands/internal.js +1 -1
- package/dist/safe-bash/commands/join/index.js +1 -1
- package/dist/safe-bash/commands/jq/index.js +1 -1
- package/dist/safe-bash/commands/less/index.js +1 -1
- package/dist/safe-bash/commands/line-endings/index.js +1 -1
- package/dist/safe-bash/commands/llm/collections.js +1 -1
- package/dist/safe-bash/commands/llm/command.js +1 -1
- package/dist/safe-bash/commands/llm/elevenlabs-stream.js +1 -1
- package/dist/safe-bash/commands/llm/elevenlabs.js +1 -1
- package/dist/safe-bash/commands/llm/index.browser.js +21 -1
- package/dist/safe-bash/commands/llm/index.js +1 -1
- package/dist/safe-bash/commands/llm/mime.js +1 -1
- package/dist/safe-bash/commands/llm/openai-http.js +1 -1
- package/dist/safe-bash/commands/llm/openai-sse.js +1 -1
- package/dist/safe-bash/commands/llm/openai.js +1 -1
- package/dist/safe-bash/commands/llm/providers/elevenlabs.js +1 -1
- package/dist/safe-bash/commands/llm/providers/index.js +1 -1
- package/dist/safe-bash/commands/llm/providers/openai.js +1 -1
- package/dist/safe-bash/commands/llm/providers/shared.js +1 -1
- package/dist/safe-bash/commands/llm/service.js +1 -1
- package/dist/safe-bash/commands/locale/index.js +1 -1
- package/dist/safe-bash/commands/md5sum/index.js +1 -1
- package/dist/safe-bash/commands/mdq/index.js +1 -1
- package/dist/safe-bash/commands/media/index.js +1 -1
- package/dist/safe-bash/commands/media/plugin.js +1 -1
- package/dist/safe-bash/commands/media/remote.js +1 -1
- package/dist/safe-bash/commands/media/settings.js +1 -1
- package/dist/safe-bash/commands/metadata/chmod.js +1 -1
- package/dist/safe-bash/commands/metadata/internal.js +1 -1
- package/dist/safe-bash/commands/metadata/mktemp.js +1 -1
- package/dist/safe-bash/commands/metadata/stat.js +1 -1
- package/dist/safe-bash/commands/mktemp/index.js +1 -1
- package/dist/safe-bash/commands/mmdc/index.js +1 -1
- package/dist/safe-bash/commands/more/index.js +1 -1
- package/dist/safe-bash/commands/neato/index.js +1 -1
- package/dist/safe-bash/commands/network/aggregate.js +1 -1
- package/dist/safe-bash/commands/network/args.js +1 -1
- package/dist/safe-bash/commands/network/authorizer.js +1 -1
- package/dist/safe-bash/commands/network/body.js +1 -1
- package/dist/safe-bash/commands/network/curl.js +1 -1
- package/dist/safe-bash/commands/network/deadline.js +1 -1
- package/dist/safe-bash/commands/network/decode.js +1 -1
- package/dist/safe-bash/commands/network/fetch-transport.js +1 -1
- package/dist/safe-bash/commands/network/form-content-type.js +1 -1
- package/dist/safe-bash/commands/network/form-headers.js +1 -1
- package/dist/safe-bash/commands/network/glob.js +1 -1
- package/dist/safe-bash/commands/network/input.js +1 -1
- package/dist/safe-bash/commands/network/output.js +1 -1
- package/dist/safe-bash/commands/network/platform-portable.js +1 -1
- package/dist/safe-bash/commands/network/platform.js +1 -1
- package/dist/safe-bash/commands/network/private-address.js +1 -1
- package/dist/safe-bash/commands/network/shared.js +1 -1
- package/dist/safe-bash/commands/network/types.js +1 -1
- package/dist/safe-bash/commands/network/url.js +1 -1
- package/dist/safe-bash/commands/network/wget.js +1 -1
- package/dist/safe-bash/commands/nl/index.js +1 -1
- package/dist/safe-bash/commands/node/browser.js +1 -1
- package/dist/safe-bash/commands/node/buffer.js +1 -1
- package/dist/safe-bash/commands/node/default-runtime.js +1 -1
- package/dist/safe-bash/commands/node/filesystem.js +1 -1
- package/dist/safe-bash/commands/node/path.js +1 -1
- package/dist/safe-bash/commands/node/safejs.js +1 -1
- package/dist/safe-bash/commands/node/source-maps.js +1 -1
- package/dist/safe-bash/commands/node/timers.js +1 -1
- package/dist/safe-bash/commands/node/types.js +1 -1
- package/dist/safe-bash/commands/node/worker-types.js +1 -1
- package/dist/safe-bash/commands/nproc/index.js +1 -1
- package/dist/safe-bash/commands/numfmt/index.js +1 -1
- package/dist/safe-bash/commands/od/index.js +1 -1
- package/dist/safe-bash/commands/op/index.js +23 -1
- package/dist/safe-bash/commands/openssl/index.js +1 -1
- package/dist/safe-bash/commands/pandoc/index.browser.js +1 -1
- package/dist/safe-bash/commands/pandoc/index.js +1 -1
- package/dist/safe-bash/commands/paste/index.js +1 -1
- package/dist/safe-bash/commands/patch/index.js +1 -1
- package/dist/safe-bash/commands/pathchk/index.js +1 -1
- package/dist/safe-bash/commands/pdfimages/index.js +1 -1
- package/dist/safe-bash/commands/pdfinfo/index.js +1 -1
- package/dist/safe-bash/commands/pdfseparate/index.js +1 -1
- package/dist/safe-bash/commands/pdftk/index.js +1 -1
- package/dist/safe-bash/commands/pdftoppm/index.js +1 -1
- package/dist/safe-bash/commands/pdftotext/index.js +1 -1
- package/dist/safe-bash/commands/pdfunite/index.js +1 -1
- package/dist/safe-bash/commands/playwright/index.js +1 -1
- package/dist/safe-bash/commands/portable-random.js +1 -1
- package/dist/safe-bash/commands/portable-requirements.js +1 -1
- package/dist/safe-bash/commands/pptx/index.js +1 -1
- package/dist/safe-bash/commands/pr/index.js +1 -1
- package/dist/safe-bash/commands/printenv/index.js +1 -1
- package/dist/safe-bash/commands/python/executor-pool.js +1 -1
- package/dist/safe-bash/commands/python/executor.browser.js +2 -1
- package/dist/safe-bash/commands/python/executor.js +1 -1
- package/dist/safe-bash/commands/python/host-capabilities.js +1 -1
- package/dist/safe-bash/commands/python/index.browser.js +3 -1
- package/dist/safe-bash/commands/python/index.js +1 -1
- package/dist/safe-bash/commands/python/jspi-assets.js +1 -1
- package/dist/safe-bash/commands/python/jspi-trampoline.js +1 -1
- package/dist/safe-bash/commands/python/jspi.js +1 -1
- package/dist/safe-bash/commands/python/llm-capability.js +1 -1
- package/dist/safe-bash/commands/python/llm-dependencies.js +1 -1
- package/dist/safe-bash/commands/python/llm-module.js +1 -1
- package/dist/safe-bash/commands/python/llm-provider.js +1 -1
- package/dist/safe-bash/commands/python/llm-reference-module.js +1 -1
- package/dist/safe-bash/commands/python/provisioning.js +1 -1
- package/dist/safe-bash/commands/python/shell-capability.js +1 -1
- package/dist/safe-bash/commands/python/shell-module.js +1 -1
- package/dist/safe-bash/commands/python/worker.js +1 -1
- package/dist/safe-bash/commands/qpdf/index.js +1 -1
- package/dist/safe-bash/commands/qrencode/index.js +1 -1
- package/dist/safe-bash/commands/readlink/index.js +1 -1
- package/dist/safe-bash/commands/readlink-missing.js +1 -1
- package/dist/safe-bash/commands/realpath/index.js +1 -1
- package/dist/safe-bash/commands/record-buffer.js +1 -1
- package/dist/safe-bash/commands/regex-execution/ascii.js +1 -1
- package/dist/safe-bash/commands/regex-execution/bounded-glob.js +1 -1
- package/dist/safe-bash/commands/regex-execution/bounded-provider.js +1 -1
- package/dist/safe-bash/commands/regex-execution/ere/errors.js +1 -1
- package/dist/safe-bash/commands/regex-execution/ere/limits.js +1 -1
- package/dist/safe-bash/commands/regex-execution/ere/matcher.js +1 -1
- package/dist/safe-bash/commands/regex-execution/ere/syntax.js +1 -1
- package/dist/safe-bash/commands/regex-execution/portable.js +1 -1
- package/dist/safe-bash/commands/regex-execution/protocol.js +1 -1
- package/dist/safe-bash/commands/regex-execution/utf8.js +1 -1
- package/dist/safe-bash/commands/rev/index.js +1 -1
- package/dist/safe-bash/commands/rg/index.js +1 -1
- package/dist/safe-bash/commands/rgrep/index.js +1 -1
- package/dist/safe-bash/commands/rsvg-convert/index.js +1 -1
- package/dist/safe-bash/commands/safejs/io.js +1 -1
- package/dist/safe-bash/commands/safejs/options.js +1 -1
- package/dist/safe-bash/commands/safejs/render.js +1 -1
- package/dist/safe-bash/commands/safejs/runtime.js +1 -1
- package/dist/safe-bash/commands/safejs/types.js +1 -1
- package/dist/safe-bash/commands/search/ergonomic-regex.js +1 -1
- package/dist/safe-bash/commands/search/file-types.js +1 -1
- package/dist/safe-bash/commands/search/glob.js +1 -1
- package/dist/safe-bash/commands/search/grep-files.js +1 -1
- package/dist/safe-bash/commands/search/grep.js +1 -1
- package/dist/safe-bash/commands/search/matcher.js +1 -1
- package/dist/safe-bash/commands/search/options.js +1 -1
- package/dist/safe-bash/commands/search/output.js +1 -1
- package/dist/safe-bash/commands/search/requirements.js +1 -1
- package/dist/safe-bash/commands/search/rg-command.js +1 -1
- package/dist/safe-bash/commands/search/shared.js +1 -1
- package/dist/safe-bash/commands/search/walk.js +1 -1
- package/dist/safe-bash/commands/sed/index.js +1 -1
- package/dist/safe-bash/commands/seq/index.js +1 -1
- package/dist/safe-bash/commands/sha1sum/index.js +1 -1
- package/dist/safe-bash/commands/sha256sum/index.js +1 -1
- package/dist/safe-bash/commands/sha512sum/index.js +1 -1
- package/dist/safe-bash/commands/sips/index.js +1 -1
- package/dist/safe-bash/commands/sleep/index.js +1 -1
- package/dist/safe-bash/commands/soffice/index.js +1 -1
- package/dist/safe-bash/commands/sort/index.js +1 -1
- package/dist/safe-bash/commands/sort-admission.js +1 -1
- package/dist/safe-bash/commands/sox/index.js +1 -1
- package/dist/safe-bash/commands/soxi/index.js +1 -1
- package/dist/safe-bash/commands/split/index.js +1 -1
- package/dist/safe-bash/commands/sponge/index.js +1 -1
- package/dist/safe-bash/commands/sqlite3/index.js +1 -1
- package/dist/safe-bash/commands/ssh/index.js +1 -1
- package/dist/safe-bash/commands/stat/index.js +1 -1
- package/dist/safe-bash/commands/stream-format/shared.js +1 -1
- package/dist/safe-bash/commands/stream-inspection/numeric-options.js +1 -1
- package/dist/safe-bash/commands/stream-inspection/shared.js +1 -1
- package/dist/safe-bash/commands/stream-inspection/strings-object.js +1 -1
- package/dist/safe-bash/commands/strings/index.js +1 -1
- package/dist/safe-bash/commands/structured/bytes.js +1 -1
- package/dist/safe-bash/commands/structured/capture.js +1 -1
- package/dist/safe-bash/commands/structured/dates.js +1 -1
- package/dist/safe-bash/commands/structured/delpaths.js +1 -1
- package/dist/safe-bash/commands/structured/formats.js +1 -1
- package/dist/safe-bash/commands/structured/indices.js +1 -1
- package/dist/safe-bash/commands/structured/input.js +1 -1
- package/dist/safe-bash/commands/structured/interpreter.js +1 -1
- package/dist/safe-bash/commands/structured/jq.js +1 -1
- package/dist/safe-bash/commands/structured/limits.js +1 -1
- package/dist/safe-bash/commands/structured/numbers.js +1 -1
- package/dist/safe-bash/commands/structured/parser.js +1 -1
- package/dist/safe-bash/commands/structured/query-core.js +1 -1
- package/dist/safe-bash/commands/structured/recurse.js +1 -1
- package/dist/safe-bash/commands/structured/regex.js +1 -1
- package/dist/safe-bash/commands/structured/split.js +1 -1
- package/dist/safe-bash/commands/structured/splits.js +1 -1
- package/dist/safe-bash/commands/structured/values.js +1 -1
- package/dist/safe-bash/commands/svgo/index.js +1 -1
- package/dist/safe-bash/commands/table-text/internal.js +1 -1
- package/dist/safe-bash/commands/tac/index.js +1 -1
- package/dist/safe-bash/commands/tar/index.js +1 -1
- package/dist/safe-bash/commands/text-programs/awk-inspection.js +1 -1
- package/dist/safe-bash/commands/text-programs/awk-pipes.js +1 -1
- package/dist/safe-bash/commands/text-programs/awk-pretty.js +1 -1
- package/dist/safe-bash/commands/text-programs/awk-quote.js +1 -1
- package/dist/safe-bash/commands/text-programs/awk-reader.js +1 -1
- package/dist/safe-bash/commands/text-programs/awk-retention.js +1 -1
- package/dist/safe-bash/commands/text-programs/awk-runtime.js +1 -1
- package/dist/safe-bash/commands/text-programs/awk-syntax.js +1 -1
- package/dist/safe-bash/commands/text-programs/awk-values.js +1 -1
- package/dist/safe-bash/commands/text-programs/awk.js +1 -1
- package/dist/safe-bash/commands/text-programs/inplace.js +1 -1
- package/dist/safe-bash/commands/text-programs/regex.js +1 -1
- package/dist/safe-bash/commands/text-programs/replacement-buffer.js +1 -1
- package/dist/safe-bash/commands/text-programs/sed.js +1 -1
- package/dist/safe-bash/commands/text-programs/shared.js +1 -1
- package/dist/safe-bash/commands/time-env/calendar.js +1 -1
- package/dist/safe-bash/commands/time-env/format.js +1 -1
- package/dist/safe-bash/commands/time-env/shared.js +1 -1
- package/dist/safe-bash/commands/timeout/index.js +1 -1
- package/dist/safe-bash/commands/touch/index.js +1 -1
- package/dist/safe-bash/commands/touch-target.js +1 -1
- package/dist/safe-bash/commands/touch-times.js +1 -1
- package/dist/safe-bash/commands/tree/index.js +1 -1
- package/dist/safe-bash/commands/tsort/index.js +1 -1
- package/dist/safe-bash/commands/unalias/index.js +1 -1
- package/dist/safe-bash/commands/uname/index.js +1 -1
- package/dist/safe-bash/commands/unexpand/index.js +1 -1
- package/dist/safe-bash/commands/unix2dos/index.js +1 -1
- package/dist/safe-bash/commands/unrtf/index.js +1 -1
- package/dist/safe-bash/commands/unzip/index.js +1 -1
- package/dist/safe-bash/commands/wdiff/index.js +1 -1
- package/dist/safe-bash/commands/wget/index.js +1 -1
- package/dist/safe-bash/commands/which/index.js +1 -1
- package/dist/safe-bash/commands/whoami/index.js +1 -1
- package/dist/safe-bash/commands/wkhtmltopdf/index.js +1 -1
- package/dist/safe-bash/commands/xan/index.js +1 -1
- package/dist/safe-bash/commands/xml/index.js +1 -1
- package/dist/safe-bash/commands/xmllint/index.js +1 -1
- package/dist/safe-bash/commands/xq/index.js +1 -1
- package/dist/safe-bash/commands/xxd/index.js +1 -1
- package/dist/safe-bash/commands/xz/index.js +1 -1
- package/dist/safe-bash/commands/yq/index.js +1 -1
- package/dist/safe-bash/commands/zip/index.js +1 -1
- package/dist/safe-bash/commands/zstd/index.js +1 -1
- package/dist/safe-bash/core.browser.js +2 -2
- package/dist/safe-bash/full-core.browser.js +29 -7
- package/dist/safe-bash/integrations/safejs/filesystem.js +1 -1
- package/dist/safe-bash/integrations/safejs/shell.js +1 -1
- package/dist/safe-bash/integrations/safejs/values.js +1 -1
- package/dist/safe-bash/playwright/abilities.js +1 -1
- package/dist/safe-bash/playwright/ability-execution.js +1 -1
- package/dist/safe-bash/playwright/adapter.js +1 -1
- package/dist/safe-bash/playwright/builtins.js +1 -1
- package/dist/safe-bash/playwright/canonical-locator-parser.js +1 -1
- package/dist/safe-bash/playwright/capability-events.js +1 -1
- package/dist/safe-bash/playwright/capability-result.js +1 -1
- package/dist/safe-bash/playwright/catalog.js +1 -1
- package/dist/safe-bash/playwright/checkpoint.js +1 -1
- package/dist/safe-bash/playwright/command-budget.js +1 -1
- package/dist/safe-bash/playwright/command-reference.js +1 -1
- package/dist/safe-bash/playwright/config-ini.js +1 -1
- package/dist/safe-bash/playwright/config-json.js +1 -1
- package/dist/safe-bash/playwright/controller.js +1 -1
- package/dist/safe-bash/playwright/devices.js +1 -1
- package/dist/safe-bash/playwright/download-capabilities.js +1 -1
- package/dist/safe-bash/playwright/drop-capability.js +1 -1
- package/dist/safe-bash/playwright/find.js +1 -1
- package/dist/safe-bash/playwright/frame-snapshot.js +1 -1
- package/dist/safe-bash/playwright/generated-locator.js +1 -1
- package/dist/safe-bash/playwright/help-reference.js +1 -1
- package/dist/safe-bash/playwright/help.js +1 -1
- package/dist/safe-bash/playwright/highlight.js +1 -1
- package/dist/safe-bash/playwright/index.js +1 -1
- package/dist/safe-bash/playwright/invocation.js +1 -1
- package/dist/safe-bash/playwright/locator-selector.js +1 -1
- package/dist/safe-bash/playwright/modal-capabilities.js +1 -1
- package/dist/safe-bash/playwright/native-evaluation.js +1 -1
- package/dist/safe-bash/playwright/native-json-snapshot.js +1 -1
- package/dist/safe-bash/playwright/native-snapshot.js +1 -1
- package/dist/safe-bash/playwright/native-storage-realm.js +1 -1
- package/dist/safe-bash/playwright/native-storage-replacement.js +1 -1
- package/dist/safe-bash/playwright/native-storage-sources.generated.js +1 -1
- package/dist/safe-bash/playwright/native-storage-targets.js +1 -1
- package/dist/safe-bash/playwright/network-policy.js +1 -1
- package/dist/safe-bash/playwright/open-options.js +1 -1
- package/dist/safe-bash/playwright/private-target-transport.js +1 -1
- package/dist/safe-bash/playwright/profile.js +1 -1
- package/dist/safe-bash/playwright/recording-capabilities.js +1 -1
- package/dist/safe-bash/playwright/recovery.js +1 -1
- package/dist/safe-bash/playwright/resource-limit.js +1 -1
- package/dist/safe-bash/playwright/response.js +1 -1
- package/dist/safe-bash/playwright/route-capabilities.js +1 -1
- package/dist/safe-bash/playwright/route-policy.js +1 -1
- package/dist/safe-bash/playwright/screenshot.js +1 -1
- package/dist/safe-bash/playwright/session-configuration.js +1 -1
- package/dist/safe-bash/playwright/session-runtime.js +1 -1
- package/dist/safe-bash/playwright/session-selection.js +1 -1
- package/dist/safe-bash/playwright/snapshot-reference-error.js +1 -1
- package/dist/safe-bash/playwright/snapshot.js +1 -1
- package/dist/safe-bash/playwright/standard-capabilities.js +1 -1
- package/dist/safe-bash/playwright/storage-capabilities.js +1 -1
- package/dist/safe-bash/playwright/storage-state.js +1 -1
- package/dist/safe-bash/playwright/target-screenshot.js +1 -1
- package/dist/safe-bash/playwright/targets.js +1 -1
- package/dist/safe-bash/playwright/tracing-capabilities.js +1 -1
- package/dist/safe-bash/playwright/webmcp-capabilities.js +1 -1
- package/dist/safe-bash/playwright/webmcp-params.js +1 -1
- package/dist/safe-bash/playwright/workspace-assets.js +1 -1
- package/dist/safe-bash/playwright/workspace.js +1 -1
- package/dist/safe-bash/plugins/index.browser.js +4 -4
- package/dist/safe-bash/registry-entry.browser.js +2 -2
- package/dist/safe-bash/search.browser.js +1 -1
- package/dist/safe-bash/shell/parser.js +2 -1
- package/dist/safe-bash/shell/pattern.js +1 -1
- package/dist/safe-bash/shell/string-operations.js +1 -1
- package/dist/safe-bash/shell-entry.browser.js +2 -2
- package/dist/safe-bash/ts-ast.js +1 -1
- package/dist/safe-bash-checksum-engine/index.js +1 -1
- package/dist/safe-bash-command-audio/index.js +2 -2
- package/dist/safe-bash-command-awk/awk-inspection.js +2 -2
- package/dist/safe-bash-command-awk/awk-runtime.js +2 -2
- package/dist/safe-bash-command-awk/awk-syntax.js +1 -1
- package/dist/safe-bash-command-awk/awk.js +6 -6
- package/dist/safe-bash-command-awk/index.js +6 -6
- package/dist/safe-bash-command-bc/index.js +13 -14
- package/dist/safe-bash-command-cal/index.js +25 -31
- package/dist/safe-bash-command-cp/index.js +3 -3
- package/dist/safe-bash-command-csvgrep/command.d.ts +1 -0
- package/dist/safe-bash-command-csvgrep/index.js +7 -0
- package/dist/safe-bash-command-diff/diff.js +2 -2
- package/dist/safe-bash-command-diff/index.js +2 -2
- package/dist/safe-bash-command-docx/sdk.js +1 -1
- package/dist/safe-bash-command-expr/bre-engine.js +1 -1
- package/dist/safe-bash-command-factor/command.js +2 -2
- package/dist/safe-bash-command-factor/index.js +2 -2
- package/dist/safe-bash-command-fd/index.js +4 -3
- package/dist/safe-bash-command-ffmpeg/index.js +13 -2
- package/dist/safe-bash-command-ffprobe/index.js +2 -2
- package/dist/safe-bash-command-ffprobe/media.js +2 -2
- package/dist/safe-bash-command-getconf/index.js +11 -4
- package/dist/safe-bash-command-git/git_rust.wasm +0 -0
- package/dist/safe-bash-command-git/index.js +96 -14
- package/dist/safe-bash-command-html-to-markdown/index.js +1 -1
- package/dist/safe-bash-command-html-to-markdown/stored-text.d.ts +2 -0
- package/dist/safe-bash-command-html-to-markdown/stored-text.js +1 -1
- package/dist/safe-bash-command-imagemagick/index.js +18 -4
- package/dist/safe-bash-command-jq/index.js +1 -1
- package/dist/safe-bash-command-jq/jq.js +1 -1
- package/dist/safe-bash-command-llm/collections.js +48 -192
- package/dist/safe-bash-command-llm/command.js +14 -6
- package/dist/safe-bash-command-llm/elevenlabs.js +2 -2
- package/dist/safe-bash-command-llm/fragment-loaders.d.ts +29 -0
- package/dist/safe-bash-command-llm/fragments.d.ts +24 -0
- package/dist/safe-bash-command-llm/import-json-document.d.ts +5 -2
- package/dist/safe-bash-command-llm/index.d.ts +7 -0
- package/dist/safe-bash-command-llm/index.js +47 -17
- package/dist/safe-bash-command-llm/input-budget.d.ts +2 -0
- package/dist/safe-bash-command-llm/openai-sse.d.ts +1 -1
- package/dist/safe-bash-command-llm/openai-sse.js +4 -1
- package/dist/safe-bash-command-llm/openai.js +11 -7
- package/dist/safe-bash-command-llm/providers/elevenlabs.js +2 -2
- package/dist/safe-bash-command-llm/providers/index.js +16 -10
- package/dist/safe-bash-command-llm/providers/openai.js +11 -7
- package/dist/safe-bash-command-llm/providers/shared.d.ts +2 -0
- package/dist/safe-bash-command-llm/providers/shared.js +1 -1
- package/dist/safe-bash-command-llm/retained-spool.d.ts +4 -0
- package/dist/safe-bash-command-llm/service.d.ts +3 -1
- package/dist/safe-bash-command-llm/service.js +5 -2
- package/dist/safe-bash-command-llm/tool-chain.d.ts +22 -0
- package/dist/safe-bash-command-llm/tool-execution.d.ts +55 -0
- package/dist/safe-bash-command-llm/tool-registry.d.ts +43 -0
- package/dist/safe-bash-command-llm/types.d.ts +39 -11
- package/dist/safe-bash-command-llm/url-fragment-source.d.ts +6 -0
- package/dist/safe-bash-command-llm/url-source.d.ts +3 -1
- package/dist/safe-bash-command-mcp/index.browser.d.ts +1 -0
- package/dist/safe-bash-command-mcp/index.browser.js +4 -4
- package/dist/safe-bash-command-mcp/index.d.ts +1 -0
- package/dist/safe-bash-command-mcp/index.js +28 -7
- package/dist/safe-bash-command-mdq/index.js +10 -3
- package/dist/safe-bash-command-node/commands/node/browser.js +6 -6
- package/dist/safe-bash-command-node/commands/node/default-runtime.js +6 -6
- package/dist/safe-bash-command-node/commands/node/filesystem.js +2 -2
- package/dist/safe-bash-command-node/commands/node/quickjs.js +1 -1
- package/dist/safe-bash-command-node/commands/node/safejs.js +6 -6
- package/dist/safe-bash-command-node/commands/node/timers.js +2 -2
- package/dist/safe-bash-command-pandoc/command.js +9 -9
- package/dist/safe-bash-command-pandoc/index.js +57 -57
- package/dist/safe-bash-command-pandoc/lua-filters.js +1 -1
- package/dist/safe-bash-command-patch/index.js +6 -6
- package/dist/safe-bash-command-patch/patch-formats.js +2 -2
- package/dist/safe-bash-command-patch/patch-publication.js +1 -1
- package/dist/safe-bash-command-patch/patch.js +5 -5
- package/dist/safe-bash-command-patch/unified.js +1 -1
- package/dist/safe-bash-command-pdfinfo/index.js +2 -2
- package/dist/safe-bash-command-pdftk/index.js +550 -137
- package/dist/safe-bash-command-pdftoppm/index.js +89 -124
- package/dist/safe-bash-command-pdftotext/index.d.ts +1 -1
- package/dist/safe-bash-command-pdftotext/index.js +554 -381
- package/dist/safe-bash-command-playwright-cli/index.js +26 -25
- package/dist/safe-bash-command-playwright-cli/playwright/abilities.js +7 -7
- package/dist/safe-bash-command-playwright-cli/playwright/adapter.js +3 -3
- package/dist/safe-bash-command-playwright-cli/playwright/controller.js +16 -15
- package/dist/safe-bash-command-playwright-cli/playwright/index.js +26 -25
- package/dist/safe-bash-command-playwright-cli/playwright/native-storage-replacement.js +2 -2
- package/dist/safe-bash-command-playwright-cli/playwright/open-options.js +2 -2
- package/dist/safe-bash-command-playwright-cli/playwright/profile.d.ts +1 -1
- package/dist/safe-bash-command-playwright-cli/playwright/profile.js +6 -5
- package/dist/safe-bash-command-playwright-cli/playwright/standard-capabilities.js +5 -5
- package/dist/safe-bash-command-playwright-cli/playwright/storage-capabilities.js +3 -3
- package/dist/safe-bash-command-pptx/engine.js +2 -2
- package/dist/safe-bash-command-python/executor.d.ts +1 -0
- package/dist/safe-bash-command-python/executor.js +24 -22
- package/dist/safe-bash-command-python/index.js +24 -22
- package/dist/safe-bash-command-python/jspi.js +2 -2
- package/dist/safe-bash-command-python/llm-capability.js +1 -1
- package/dist/safe-bash-command-python/llm-functions-loader.d.ts +5 -0
- package/dist/safe-bash-command-python/llm-packages.js +51 -2
- package/dist/safe-bash-command-python/llm-provider.js +1 -1
- package/dist/safe-bash-command-rg/glob.d.ts +6 -0
- package/dist/safe-bash-command-rg/glob.js +2 -2
- package/dist/safe-bash-command-rg/index.js +8 -8
- package/dist/safe-bash-command-rg/matcher.d.ts +2 -0
- package/dist/safe-bash-command-rg/matcher.js +2 -2
- package/dist/safe-bash-command-rg/options.d.ts +2 -0
- package/dist/safe-bash-command-rg/options.js +1 -1
- package/dist/safe-bash-command-rg/output.js +3 -3
- package/dist/safe-bash-command-rg/replacement.js +2 -2
- package/dist/safe-bash-command-rg/rg-command.js +8 -8
- package/dist/safe-bash-command-rg/shared.d.ts +0 -2
- package/dist/safe-bash-command-rg/shared.js +2 -4
- package/dist/safe-bash-command-rg/walk.js +4 -4
- package/dist/safe-bash-command-safejs/index.js +5 -5
- package/dist/safe-bash-command-safejs/runtime.js +3 -3
- package/dist/safe-bash-command-soffice/index.js +2 -2
- package/dist/safe-bash-command-sqlite3/engine.d.ts +15 -0
- package/dist/safe-bash-command-sqlite3/index.js +310 -15
- package/dist/safe-bash-command-ssconvert/index.js +13 -13
- package/dist/safe-bash-command-tar/create.js +2 -2
- package/dist/safe-bash-command-tar/extract.js +2 -2
- package/dist/safe-bash-command-tar/index.js +6 -6
- package/dist/safe-bash-command-tar/modes.js +4 -4
- package/dist/safe-bash-command-unzip/index.js +5 -5
- package/dist/safe-bash-command-unzip/unzip.js +2 -2
- package/dist/safe-bash-command-yq/parser.js +1 -1
- package/dist/safe-bash-command-yq/query.js +1 -1
- package/dist/safe-bash-contracts/escaping.js +2 -2
- package/dist/safe-bash-contracts/index.js +15 -15
- package/dist/safe-bash-csv-engine/index.js +5 -3
- package/dist/safe-bash-csv-engine/python-codepages.js +2 -1
- package/dist/safe-bash-csv-engine/python-file-codepages.d.ts +1 -0
- package/dist/safe-bash-csv-engine/python-file-codepages.js +8 -0
- package/dist/safe-bash-csv-engine/python-utf16.js +3 -2
- package/dist/safe-bash-csv-engine/text-decoder.js +5 -3
- package/dist/safe-bash-docx-engine/ancillary-resources.js +10 -10
- package/dist/safe-bash-docx-engine/batch-operations.js +68 -68
- package/dist/safe-bash-docx-engine/batch-result-schema.js +80 -80
- package/dist/safe-bash-docx-engine/batch.js +79 -79
- package/dist/safe-bash-docx-engine/bookmarks.js +18 -18
- package/dist/safe-bash-docx-engine/charts.js +11 -11
- package/dist/safe-bash-docx-engine/command-option-rules.js +5 -5
- package/dist/safe-bash-docx-engine/command-properties.js +3 -3
- package/dist/safe-bash-docx-engine/comments.js +27 -27
- package/dist/safe-bash-docx-engine/control-bindings.js +22 -22
- package/dist/safe-bash-docx-engine/control-repeat.js +21 -21
- package/dist/safe-bash-docx-engine/controls.js +19 -19
- package/dist/safe-bash-docx-engine/create.js +10 -10
- package/dist/safe-bash-docx-engine/diagrams.js +11 -11
- package/dist/safe-bash-docx-engine/diff.js +13 -13
- package/dist/safe-bash-docx-engine/document-properties.js +17 -17
- package/dist/safe-bash-docx-engine/equations.js +18 -18
- package/dist/safe-bash-docx-engine/extract.js +14 -14
- package/dist/safe-bash-docx-engine/fields.js +23 -23
- package/dist/safe-bash-docx-engine/font-inventory.js +18 -18
- package/dist/safe-bash-docx-engine/font-resources.js +5 -5
- package/dist/safe-bash-docx-engine/image-batch-operations.js +13 -13
- package/dist/safe-bash-docx-engine/image-insertion.js +22 -22
- package/dist/safe-bash-docx-engine/image-layout.js +20 -20
- package/dist/safe-bash-docx-engine/image-replacement.js +23 -23
- package/dist/safe-bash-docx-engine/images.js +20 -20
- package/dist/safe-bash-docx-engine/index.js +138 -138
- package/dist/safe-bash-docx-engine/inspection.js +21 -21
- package/dist/safe-bash-docx-engine/invocation.js +8 -8
- package/dist/safe-bash-docx-engine/io.js +8 -8
- package/dist/safe-bash-docx-engine/links.js +21 -21
- package/dist/safe-bash-docx-engine/lists.js +20 -20
- package/dist/safe-bash-docx-engine/locations.js +15 -15
- package/dist/safe-bash-docx-engine/notes.js +22 -22
- package/dist/safe-bash-docx-engine/objects.js +20 -20
- package/dist/safe-bash-docx-engine/operation-json-schema.js +3 -3
- package/dist/safe-bash-docx-engine/operation-schema.js +2 -2
- package/dist/safe-bash-docx-engine/pack.js +14 -14
- package/dist/safe-bash-docx-engine/package-view-batch-operations.js +21 -21
- package/dist/safe-bash-docx-engine/pandoc-adapter.js +29 -29
- package/dist/safe-bash-docx-engine/paragraph-edit.js +26 -26
- package/dist/safe-bash-docx-engine/part-provider.js +3 -3
- package/dist/safe-bash-docx-engine/property-values.js +3 -3
- package/dist/safe-bash-docx-engine/publication.js +8 -8
- package/dist/safe-bash-docx-engine/removal.js +21 -21
- package/dist/safe-bash-docx-engine/revision-decisions.js +23 -23
- package/dist/safe-bash-docx-engine/revision-edit.js +20 -20
- package/dist/safe-bash-docx-engine/revisions.js +18 -18
- package/dist/safe-bash-docx-engine/run-format.js +20 -20
- package/dist/safe-bash-docx-engine/sanitize.js +35 -35
- package/dist/safe-bash-docx-engine/sections.js +19 -19
- package/dist/safe-bash-docx-engine/settings.js +12 -12
- package/dist/safe-bash-docx-engine/shape-edit.js +22 -22
- package/dist/safe-bash-docx-engine/signatures.js +16 -16
- package/dist/safe-bash-docx-engine/stories.js +22 -22
- package/dist/safe-bash-docx-engine/structure-model-batch-operations.js +38 -38
- package/dist/safe-bash-docx-engine/style-model-batch-operations.js +26 -26
- package/dist/safe-bash-docx-engine/style-model-result-schema.js +44 -44
- package/dist/safe-bash-docx-engine/styles.js +18 -18
- package/dist/safe-bash-docx-engine/table-edit.js +28 -28
- package/dist/safe-bash-docx-engine/table-read.js +16 -16
- package/dist/safe-bash-docx-engine/template.js +22 -22
- package/dist/safe-bash-docx-engine/text-replace.js +20 -20
- package/dist/safe-bash-docx-engine/text-resource-read.js +16 -16
- package/dist/safe-bash-docx-engine/text.js +16 -16
- package/dist/safe-bash-docx-engine/validation.js +6 -6
- package/dist/safe-bash-docx-engine/xml-parts.js +23 -23
- package/dist/safe-bash-io-engine/commands/text-programs/shared.js +4 -4
- package/dist/safe-bash-line-ending-engine/command.js +4 -4
- package/dist/safe-bash-line-ending-engine/index.js +4 -4
- package/dist/safe-bash-markdown-engine/commonmark-blocks.js +1 -1
- package/dist/safe-bash-markdown-engine/index.js +3 -3
- package/dist/safe-bash-network-engine/transfer.js +12 -12
- package/dist/safe-bash-pptx-engine/bytes.js +1 -1
- package/dist/safe-bash-pptx-engine/index.js +1 -1
- package/dist/safe-bash-presentation-engine/accessibility.js +33 -31
- package/dist/safe-bash-presentation-engine/animation-editing.js +17 -16
- package/dist/safe-bash-presentation-engine/animations.js +17 -16
- package/dist/safe-bash-presentation-engine/backgrounds.js +18 -17
- package/dist/safe-bash-presentation-engine/bytes.js +4 -4
- package/dist/safe-bash-presentation-engine/chart-editing.js +36 -34
- package/dist/safe-bash-presentation-engine/chart-object-operations.js +26 -25
- package/dist/safe-bash-presentation-engine/charts.js +33 -31
- package/dist/safe-bash-presentation-engine/command-placeholder.js +63 -60
- package/dist/safe-bash-presentation-engine/comments.js +18 -17
- package/dist/safe-bash-presentation-engine/connector-operations.js +34 -32
- package/dist/safe-bash-presentation-engine/connectors.js +31 -29
- package/dist/safe-bash-presentation-engine/content-types.js +5 -5
- package/dist/safe-bash-presentation-engine/creation.js +7 -7
- package/dist/safe-bash-presentation-engine/diff.js +40 -37
- package/dist/safe-bash-presentation-engine/drawing-format.js +21 -20
- package/dist/safe-bash-presentation-engine/drawing-operations.js +33 -31
- package/dist/safe-bash-presentation-engine/drawing-schema.js +22 -21
- package/dist/safe-bash-presentation-engine/equations.js +18 -17
- package/dist/safe-bash-presentation-engine/errors.js +3 -3
- package/dist/safe-bash-presentation-engine/fields.js +18 -17
- package/dist/safe-bash-presentation-engine/font-metrics.js +4 -4
- package/dist/safe-bash-presentation-engine/image-extraction.js +23 -21
- package/dist/safe-bash-presentation-engine/image-formatting.js +35 -33
- package/dist/safe-bash-presentation-engine/image-insertion.js +20 -19
- package/dist/safe-bash-presentation-engine/image-metadata.d.ts +7 -1
- package/dist/safe-bash-presentation-engine/image-metadata.js +5 -3
- package/dist/safe-bash-presentation-engine/image-replacement.js +24 -22
- package/dist/safe-bash-presentation-engine/image-value.js +6 -6
- package/dist/safe-bash-presentation-engine/images.d.ts +1 -0
- package/dist/safe-bash-presentation-engine/images.js +24 -20
- package/dist/safe-bash-presentation-engine/index.js +151 -146
- package/dist/safe-bash-presentation-engine/layouts.js +17 -16
- package/dist/safe-bash-presentation-engine/length.js +4 -4
- package/dist/safe-bash-presentation-engine/links.js +17 -16
- package/dist/safe-bash-presentation-engine/masters.js +16 -15
- package/dist/safe-bash-presentation-engine/media-editing.js +30 -25
- package/dist/safe-bash-presentation-engine/media-extraction.d.ts +4 -0
- package/dist/safe-bash-presentation-engine/media-extraction.js +33 -19
- package/dist/safe-bash-presentation-engine/media.d.ts +2 -0
- package/dist/safe-bash-presentation-engine/media.js +32 -18
- package/dist/safe-bash-presentation-engine/memberships.d.ts +1 -0
- package/dist/safe-bash-presentation-engine/memberships.js +25 -17
- package/dist/safe-bash-presentation-engine/notes.js +20 -18
- package/dist/safe-bash-presentation-engine/ole-enum.js +5 -5
- package/dist/safe-bash-presentation-engine/ole-insertion.js +22 -21
- package/dist/safe-bash-presentation-engine/opaque-objects.d.ts +4 -0
- package/dist/safe-bash-presentation-engine/opaque-objects.js +30 -12
- package/dist/safe-bash-presentation-engine/package-reader.js +6 -6
- package/dist/safe-bash-presentation-engine/package-tools.js +24 -20
- package/dist/safe-bash-presentation-engine/package-uri.js +4 -4
- package/dist/safe-bash-presentation-engine/package-writer.js +5 -5
- package/dist/safe-bash-presentation-engine/presentation-model.js +62 -59
- package/dist/safe-bash-presentation-engine/presentation-settings.d.ts +1 -0
- package/dist/safe-bash-presentation-engine/presentation-settings.js +25 -16
- package/dist/safe-bash-presentation-engine/properties.js +21 -18
- package/dist/safe-bash-presentation-engine/relationships.js +5 -5
- package/dist/safe-bash-presentation-engine/resource-limits.js +2 -2
- package/dist/safe-bash-presentation-engine/retained-extraction-output.d.ts +8 -4
- package/dist/safe-bash-presentation-engine/retained-fonts.d.ts +26 -0
- package/dist/safe-bash-presentation-engine/retained-image-metadata.d.ts +13 -0
- package/dist/safe-bash-presentation-engine/retained-inspection.js +16 -14
- package/dist/safe-bash-presentation-engine/retained-media-extraction.d.ts +21 -0
- package/dist/safe-bash-presentation-engine/retained-media.d.ts +54 -0
- package/dist/safe-bash-presentation-engine/retained-memberships.d.ts +25 -0
- package/dist/safe-bash-presentation-engine/retained-object-extraction.d.ts +22 -0
- package/dist/safe-bash-presentation-engine/retained-objects.d.ts +25 -0
- package/dist/safe-bash-presentation-engine/retained-package.js +6 -6
- package/dist/safe-bash-presentation-engine/retained-presentation-settings.d.ts +25 -0
- package/dist/safe-bash-presentation-engine/retained-shape-geometry.d.ts +20 -0
- package/dist/safe-bash-presentation-engine/retained-text.d.ts +24 -4
- package/dist/safe-bash-presentation-engine/retained-text.js +35 -31
- package/dist/safe-bash-presentation-engine/retained-transitions.d.ts +18 -0
- package/dist/safe-bash-presentation-engine/sanitize.js +22 -19
- package/dist/safe-bash-presentation-engine/selectors.js +11 -11
- package/dist/safe-bash-presentation-engine/shape-groups.js +33 -31
- package/dist/safe-bash-presentation-engine/shape-operations.js +32 -30
- package/dist/safe-bash-presentation-engine/shape-path-operations.js +34 -32
- package/dist/safe-bash-presentation-engine/shape-paths.js +17 -16
- package/dist/safe-bash-presentation-engine/shape-presets.js +4 -4
- package/dist/safe-bash-presentation-engine/shape-selection.js +33 -31
- package/dist/safe-bash-presentation-engine/shape-transforms.d.ts +6 -0
- package/dist/safe-bash-presentation-engine/shape-transforms.js +26 -20
- package/dist/safe-bash-presentation-engine/shapes.js +28 -27
- package/dist/safe-bash-presentation-engine/slide-copy.js +21 -17
- package/dist/safe-bash-presentation-engine/slide-import.js +19 -18
- package/dist/safe-bash-presentation-engine/slide-merge-split.js +21 -20
- package/dist/safe-bash-presentation-engine/slide-model.js +46 -44
- package/dist/safe-bash-presentation-engine/slide-removal.js +19 -18
- package/dist/safe-bash-presentation-engine/slide-transfer-budget.js +10 -10
- package/dist/safe-bash-presentation-engine/slides.js +21 -19
- package/dist/safe-bash-presentation-engine/table-operations.js +35 -33
- package/dist/safe-bash-presentation-engine/table-spans.js +34 -32
- package/dist/safe-bash-presentation-engine/tables.js +33 -31
- package/dist/safe-bash-presentation-engine/tags.js +20 -18
- package/dist/safe-bash-presentation-engine/template-bindings.js +36 -34
- package/dist/safe-bash-presentation-engine/template-repeat.js +46 -41
- package/dist/safe-bash-presentation-engine/text-fitting.js +28 -27
- package/dist/safe-bash-presentation-engine/text-frames.js +28 -27
- package/dist/safe-bash-presentation-engine/text-paragraphs.js +28 -27
- package/dist/safe-bash-presentation-engine/text-reading.js +12 -12
- package/dist/safe-bash-presentation-engine/text-replacement.js +18 -17
- package/dist/safe-bash-presentation-engine/text-runs.js +21 -20
- package/dist/safe-bash-presentation-engine/themes.js +17 -16
- package/dist/safe-bash-presentation-engine/transitions.d.ts +1 -0
- package/dist/safe-bash-presentation-engine/transitions.js +24 -16
- package/dist/safe-bash-presentation-engine/validation.js +11 -10
- package/dist/safe-bash-presentation-engine/xml-parts.js +21 -19
- package/dist/safe-bash-presentation-engine/xml-view.js +4 -4
- package/dist/safe-bash-presentation-engine/xml.js +4 -4
- package/dist/safe-bash-query-engine/capture.js +5 -5
- package/dist/safe-bash-query-engine/dates.js +2 -2
- package/dist/safe-bash-query-engine/delpaths.js +5 -5
- package/dist/safe-bash-query-engine/formats.js +3 -3
- package/dist/safe-bash-query-engine/index.js +15 -15
- package/dist/safe-bash-query-engine/indices.js +5 -5
- package/dist/safe-bash-query-engine/input.js +2 -2
- package/dist/safe-bash-query-engine/interpreter.d.ts +2 -1
- package/dist/safe-bash-query-engine/interpreter.js +13 -13
- package/dist/safe-bash-query-engine/limits.d.ts +1 -0
- package/dist/safe-bash-query-engine/limits.js +1 -1
- package/dist/safe-bash-query-engine/parser.js +2 -2
- package/dist/safe-bash-query-engine/query-core.js +15 -15
- package/dist/safe-bash-query-engine/recurse.js +2 -2
- package/dist/safe-bash-query-engine/regex.js +6 -6
- package/dist/safe-bash-query-engine/split.js +2 -2
- package/dist/safe-bash-query-engine/splits.js +7 -7
- package/dist/safe-bash-query-engine/values.js +4 -4
- package/dist/safe-bash-regex-engine/ere/matcher.d.ts +1 -1
- package/dist/safe-bash-regex-engine/ere/matcher.js +18 -10
- package/dist/safe-bash-regex-engine/ere/syntax.d.ts +1 -1
- package/dist/safe-bash-regex-engine/ere/syntax.js +1 -1
- package/dist/safe-bash-regex-engine/ere/types.d.ts +1 -0
- package/dist/safe-bash-regex-engine/execution/bounded-provider.js +5 -6
- package/dist/safe-bash-search-engine/ergonomic-regex.d.ts +1 -0
- package/dist/safe-bash-search-engine/ergonomic-regex.js +2 -2
- package/dist/safe-bash-sqlite-engine/sqlite-read-session.d.ts +17 -0
- package/dist/safe-bash-sqlite-engine/storage.d.ts +1 -0
- package/dist/safe-bash-sqlite-engine/storage.js +159 -89
- package/dist/safe-bash-xml-engine/document.js +3 -3
- package/dist/safe-bash-xml-engine/evaluate.js +1 -1
- package/dist/safe-bash-xml-engine/index.js +4 -4
- package/dist/safe-bash-xml-engine/json.js +14 -7
- package/dist/safe-bash-xml-engine/query.js +2 -2
- package/dist/safe-bash-xml-engine/recovery.d.ts +13 -3
- package/dist/safe-bash-xml-engine/stored-document.d.ts +18 -3
- package/dist/safe-bash-xml-engine/stored-document.js +1 -1
- package/dist/safe-bash-xml-engine/stored-evaluate.js +5 -5
- package/dist/safe-bash-xml-engine/stored-map.d.ts +35 -0
- package/dist/safe-bash-zip-engine/index.js +3 -3
- package/dist/safe-bash-zip-engine/zip/repair.js +3 -3
- package/dist/safe-bash-zip-engine/zip/sfx.js +3 -3
- package/dist/safe-bash-zip-engine/zip-format.js +3 -3
- package/dist/safe-playwright-cloudflare/browser-provider.generated.js +11819 -11773
- package/dist/safe-playwright-cloudflare/browser-run-code-guest.generated.js +1 -1
- package/dist/spreadsheet-engine/formatting/cell-text.js +1 -1
- package/dist/spreadsheet-engine/{rendering/print → formatting}/general-number.js +3 -3
- package/dist/spreadsheet-engine/formulas/functions/python-printf.js +16 -10
- package/dist/spreadsheet-engine/solver/program.js +3 -2
- package/dist/spreadsheet-engine/solver/run.js +8 -2
- package/dist/spreadsheet-engine/solver/sensitivity.d.ts +4 -2
- package/dist/spreadsheet-engine/solver/sensitivity.js +80 -42
- package/dist/spreadsheet-format-xls/biff-properties-merge.d.ts +2 -1
- package/dist/spreadsheet-format-xls/biff-properties-merge.js +35 -29
- package/dist/spreadsheet-format-xls/biff-properties-write.js +16 -7
- package/dist/spreadsheet-format-xls/biff-property-names.d.ts +3 -0
- package/dist/spreadsheet-format-xls/biff-property-names.js +44 -1
- package/dist/spreadsheet-format-xls/biff-property-observations.d.ts +33 -0
- package/dist/spreadsheet-format-xls/biff-property-observations.js +160 -0
- package/package.json +8 -5
- package/third-party/pdf-ast/THIRD_PARTY_NOTICES.md +15 -0
- package/third-party/pdf-ast/licenses/PYTHON-PSF.txt +254 -0
- package/third-party/pdf-ast/licenses/V8-BSD.txt +61 -0
- package/dist/safe-bash/chunks/chunk-FL6XE3W4.js +0 -35
- package/dist/safe-bash/command-chunks/biff-KLS4T7FP-UO3CXFFF.js +0 -5581
- package/dist/safe-bash/command-chunks/chunk-6EZWG56T.js +0 -455
- package/dist/safe-bash/command-chunks/chunk-6RLWPB44.js +0 -107
- package/dist/safe-bash/command-chunks/chunk-CGJ7GMHO.js +0 -297
- package/dist/safe-bash/command-chunks/chunk-E64ZI2YB.js +0 -550
- package/dist/safe-bash/command-chunks/chunk-IOXMGD2H.js +0 -260
- package/dist/safe-bash/command-chunks/chunk-KSM5CCHT.js +0 -1850
- package/dist/safe-bash/command-chunks/chunk-P4OWVKMD.js +0 -228
- package/dist/safe-bash/command-chunks/chunk-UPXFSGQG.js +0 -134
- package/dist/safe-bash/command-chunks/chunk-WKUV62RJ.js +0 -92
- package/dist/safe-bash/command-chunks/chunk-WOL3LBXE.js +0 -144
- package/dist/safe-bash/command-chunks/chunk-Z3PGWMSQ.js +0 -63
- package/dist/safe-bash/command-chunks/model-store-I7YAWL5V.js +0 -54
- package/dist/safe-bash/command-chunks/paradox-4FCZE53D-LQPGVMEL.js +0 -365
- package/dist/safe-bash-xml-engine/stored-namespaces.d.ts +0 -21
- package/dist/safe-bash/command-chunks/{chunk-WKU65Z3Q.js → chunk-3NJETNC2.js} +3 -3
- package/dist/safe-bash/command-chunks/{chunk-SRXARACJ.js → chunk-3TP4SSPS.js} +3 -3
- package/dist/safe-bash/command-chunks/{chunk-AV6N7DDA.js → chunk-DDYPQAXN.js} +3 -3
- package/dist/safe-bash/command-chunks/{chunk-FEKECRJP.js → chunk-EBTKM7KX.js} +3 -3
- package/dist/safe-bash/command-chunks/{chunk-M3OXQXCU.js → chunk-NBRXQUK7.js} +3 -3
- package/dist/safe-bash/command-chunks/{chunk-WVD5WZXD.js → chunk-QWHBQBPB.js} +5 -5
- package/dist/safe-bash/command-chunks/{chunk-5MFRN3CB.js → chunk-R64BI5MT.js} +4 -4
- package/dist/safe-bash/command-chunks/{chunk-2ANW3FXH.js → chunk-U33GIOUY.js} +3 -3
- package/dist/safe-bash/command-chunks/{chunk-OEKLEUUW.js → chunk-YZE7BKHC.js} +3 -3
- package/dist/safe-bash/command-chunks/{chunk-WXW665TV.js → chunk-ZSHXZ3XG.js} +6 -6
- package/dist/safe-bash/command-chunks/{chunk-RXXNLH7A.js → chunk-ZSQCROFE.js} +3 -3
- package/dist/safe-bash/command-chunks/{dif-BXKPQOCO-4KB3RC6G.js → dif-BXKPQOCO-FVJYYGYB.js} +4 -4
- package/dist/safe-bash/command-chunks/{pln-DFS7VLVS-OVOBS4QX.js → pln-DFS7VLVS-JATX6FS7.js} +3 -3
- package/dist/safe-bash/command-chunks/{psion-YBI6JEQI-GY4S6ZLC.js → psion-YBI6JEQI-6OMC2PGC.js} +3 -3
- package/dist/safe-bash/command-chunks/{sylk-25D7TL2Y-RU6ANKGT.js → sylk-25D7TL2Y-NJKBZZTF.js} +4 -4
- /package/dist/spreadsheet-engine/{rendering/print → formatting}/general-number.d.ts +0 -0
|
@@ -0,0 +1,3820 @@
|
|
|
1
|
+
import {
|
|
2
|
+
pythonRepr
|
|
3
|
+
} from "./chunk-MCUDSE4H.js";
|
|
4
|
+
import {
|
|
5
|
+
createLlmConfiguration,
|
|
6
|
+
embeddingCommand,
|
|
7
|
+
publishConfiguration
|
|
8
|
+
} from "./chunk-WOT2YXBT.js";
|
|
9
|
+
import {
|
|
10
|
+
createLlmSpool,
|
|
11
|
+
fileSource,
|
|
12
|
+
isPythonWhitespace,
|
|
13
|
+
stripPythonWhitespace
|
|
14
|
+
} from "./chunk-BZLLQWRK.js";
|
|
15
|
+
import {
|
|
16
|
+
createLlmService,
|
|
17
|
+
validateModelOptions
|
|
18
|
+
} from "./chunk-YNFQ5AXM.js";
|
|
19
|
+
import {
|
|
20
|
+
validateJsonData
|
|
21
|
+
} from "./chunk-3PO534WJ.js";
|
|
22
|
+
import {
|
|
23
|
+
attachmentBytesId,
|
|
24
|
+
getLlmAttachmentUrlId
|
|
25
|
+
} from "./chunk-B74LVFAN.js";
|
|
26
|
+
import {
|
|
27
|
+
tokenInteger
|
|
28
|
+
} from "./chunk-GDH7OVYK.js";
|
|
29
|
+
import {
|
|
30
|
+
resolveUrlAttachment,
|
|
31
|
+
validateAttachmentUrl
|
|
32
|
+
} from "./chunk-B6NAEWHC.js";
|
|
33
|
+
import {
|
|
34
|
+
referenceJson
|
|
35
|
+
} from "./chunk-E47FFS5M.js";
|
|
36
|
+
import {
|
|
37
|
+
sourceBytes,
|
|
38
|
+
waitForSource
|
|
39
|
+
} from "./chunk-QX3WKBLI.js";
|
|
40
|
+
import {
|
|
41
|
+
jsonValue
|
|
42
|
+
} from "./chunk-GNPPPYDF.js";
|
|
43
|
+
import {
|
|
44
|
+
acceptsMimeType,
|
|
45
|
+
sniffMimeType
|
|
46
|
+
} from "./chunk-VMA3NJXU.js";
|
|
47
|
+
|
|
48
|
+
// packages/safe-bash-command-llm/src/plugins-command.ts
|
|
49
|
+
var usage = "Usage: llm plugins [OPTIONS]\n";
|
|
50
|
+
var help = usage + "\n List installed plugins\n\nOptions:\n --all Include built-in default plugins\n --hook TEXT Filter for plugins that implement this hook\n -h, --help Show this message and exit.\n";
|
|
51
|
+
async function pluginsCommand(args, output, diagnostic, step, signal, load) {
|
|
52
|
+
const error = async (message, withUsage = false) => {
|
|
53
|
+
await diagnostic((withUsage ? usage + "Try 'llm plugins -h' for help.\n\n" : "") + "Error: " + message + "\n");
|
|
54
|
+
return 2;
|
|
55
|
+
};
|
|
56
|
+
const hooks = [], extra = [];
|
|
57
|
+
let all = false, showHelp = false, ended = false;
|
|
58
|
+
for (let index = 0; index < args.length; index++) {
|
|
59
|
+
await step();
|
|
60
|
+
const token = args[index];
|
|
61
|
+
if (ended || !token.startsWith("-") || token === "-") {
|
|
62
|
+
extra.push(token);
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
if (token === "--") {
|
|
66
|
+
ended = true;
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
const equals = token.indexOf("="), flag = equals < 0 ? token : token.slice(0, equals);
|
|
70
|
+
if (flag === "--all" || flag === "--help") {
|
|
71
|
+
if (equals >= 0) return error(`Option '${flag}' does not take a value.`);
|
|
72
|
+
if (flag === "--all") all = true;
|
|
73
|
+
else showHelp = true;
|
|
74
|
+
} else if (flag === "--hook") {
|
|
75
|
+
if (equals < 0 && args[++index] === void 0) return error("Option '--hook' requires an argument.");
|
|
76
|
+
hooks.push(equals < 0 ? args[index] : token.slice(equals + 1));
|
|
77
|
+
} else if (!token.startsWith("--")) {
|
|
78
|
+
for (const letter of token.slice(1)) {
|
|
79
|
+
if (letter !== "h") return error(`No such option: -${letter}`, true);
|
|
80
|
+
showHelp = true;
|
|
81
|
+
}
|
|
82
|
+
} else return error(`No such option: ${flag}`, true);
|
|
83
|
+
}
|
|
84
|
+
if (showHelp) {
|
|
85
|
+
await output(help);
|
|
86
|
+
return 0;
|
|
87
|
+
}
|
|
88
|
+
if (extra.length) return error(`Got unexpected extra argument${extra.length === 1 ? "" : "s"} (${extra.join(" ")})`, true);
|
|
89
|
+
if (!load) {
|
|
90
|
+
await diagnostic("Error: Python plugin discovery is not configured\n");
|
|
91
|
+
return 1;
|
|
92
|
+
}
|
|
93
|
+
const plugins = await load({ all, hooks });
|
|
94
|
+
for await (const bytes of referenceJson(plugins, signal, true)) {
|
|
95
|
+
await step();
|
|
96
|
+
await output(new TextDecoder().decode(bytes));
|
|
97
|
+
}
|
|
98
|
+
await output("\n");
|
|
99
|
+
return 0;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// packages/safe-bash-command-llm/src/chat-help.ts
|
|
103
|
+
var chatHelp = "Usage: llm chat [OPTIONS]\n\n Hold an ongoing chat with a model.\n\nOptions:\n -s, --system TEXT System prompt to use\n -m, --model TEXT Model to use\n -f, --fragment TEXT Fragment (alias, URL, hash or file path) to\n add to the prompt\n --sf, --system-fragment TEXT Fragment to add to system prompt\n -t, --template TEXT Template to use\n -p, --param <TEXT TEXT>... Parameters for template\n -o, --option <TEXT TEXT>... key/value options for the model\n --no-stream Do not stream output\n --key TEXT API key to use\n -T, --tool TEXT Name of a tool to make available to the model\n --functions TEXT Python code block or file path defining\n functions to register as tools\n --td, --tools-debug Show full details of tool executions\n --ta, --tools-approve Manually approve every tool execution\n --cl, --chain-limit INTEGER How many chained tool responses to allow,\n default 5, set 0 for unlimited\n -h, --help Show this message and exit.\n";
|
|
104
|
+
|
|
105
|
+
// packages/safe-bash-command-llm/src/chat-editor.ts
|
|
106
|
+
import { FsError } from "../../safe-bash-contracts/index.js";
|
|
107
|
+
var serial = 0;
|
|
108
|
+
async function editChatPrompt(options) {
|
|
109
|
+
const { context, operation } = options, { fs, signal } = context;
|
|
110
|
+
if (!context.invoke) throw new Error("Chat editor is not configured");
|
|
111
|
+
if (!fs.createStagedFile || !fs.removeFileConditional) throw new FsError("ENOTSUP", { message: "Chat editing requires caller staging and conditional cleanup" });
|
|
112
|
+
const parent = await fs.stat(context.cwd, { signal });
|
|
113
|
+
let staging;
|
|
114
|
+
for (let attempt = 0; attempt < 16; attempt++) {
|
|
115
|
+
try {
|
|
116
|
+
staging = await operation.acquire(() => fs.createStagedFile(
|
|
117
|
+
`${context.cwd === "/" ? "" : context.cwd}/.llm-edit-${++serial}`,
|
|
118
|
+
"prompt.txt",
|
|
119
|
+
{ type: "file", data: new Uint8Array(0) },
|
|
120
|
+
{ parent, mode: 384, retainCleanup: true, signal }
|
|
121
|
+
), async (value) => {
|
|
122
|
+
try {
|
|
123
|
+
await value.cleanup?.remove();
|
|
124
|
+
} finally {
|
|
125
|
+
await value.cleanup?.close();
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
break;
|
|
129
|
+
} catch (error) {
|
|
130
|
+
signal.throwIfAborted();
|
|
131
|
+
if (!(error instanceof FsError) || error.code !== "EEXIST") throw error;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
if (!staging?.writer || !staging.cleanup) throw new FsError("ENOTSUP", { message: "Chat editor staging needs retained handles" });
|
|
135
|
+
const owned = staging;
|
|
136
|
+
const initial = await owned.writer.finish({ signal });
|
|
137
|
+
const path = owned.file.path;
|
|
138
|
+
let expected = initial, failed = false;
|
|
139
|
+
const cleanup = async () => {
|
|
140
|
+
try {
|
|
141
|
+
expected = await fs.lstat(path);
|
|
142
|
+
} catch (error) {
|
|
143
|
+
if (error instanceof FsError && error.code === "ENOENT") return;
|
|
144
|
+
throw error;
|
|
145
|
+
}
|
|
146
|
+
await fs.removeFileConditional(path, { parent: owned.directory.stat, expected });
|
|
147
|
+
};
|
|
148
|
+
try {
|
|
149
|
+
const editor = context.env.VISUAL || context.env.EDITOR || "vi";
|
|
150
|
+
const result = await context.invoke("sh", ["-c", editor + ' "$1"', "llm-chat-editor", path], {
|
|
151
|
+
signal,
|
|
152
|
+
cwd: context.cwd,
|
|
153
|
+
env: context.env,
|
|
154
|
+
replaceEnv: true,
|
|
155
|
+
stdin: context.stdin,
|
|
156
|
+
stdout: context.stdout,
|
|
157
|
+
stderr: context.stderr,
|
|
158
|
+
externalInvocation: true
|
|
159
|
+
});
|
|
160
|
+
signal.throwIfAborted();
|
|
161
|
+
if (result.exitCode !== 0) throw new Error("Editing failed!");
|
|
162
|
+
expected = await fs.lstat(path, { signal });
|
|
163
|
+
if (expected.type !== "file") throw new FsError("EINVAL", { path });
|
|
164
|
+
if (expected.mtimeMs === initial.mtimeMs) return void 0;
|
|
165
|
+
const source = await operation.acquire(() => fileSource({ fs, path, signal, expectedStat: expected }), (value) => value.dispose());
|
|
166
|
+
const raw = await operation.acquire(() => createLlmSpool(fs, context.cwd, signal, "input"), (value) => value.close());
|
|
167
|
+
const decoder = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }), encoder = new TextEncoder();
|
|
168
|
+
let offset = 0, start = -1, end = 0;
|
|
169
|
+
const inspect = (text) => {
|
|
170
|
+
for (const char of text) {
|
|
171
|
+
const size = encoder.encode(char).length;
|
|
172
|
+
if (!isPythonWhitespace(char)) {
|
|
173
|
+
if (start < 0) start = offset;
|
|
174
|
+
end = offset + size;
|
|
175
|
+
}
|
|
176
|
+
offset += size;
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
try {
|
|
180
|
+
for await (const bytes of source.bytes) {
|
|
181
|
+
options.admit(bytes.length, false);
|
|
182
|
+
await raw.write(bytes);
|
|
183
|
+
inspect(decoder.decode(bytes, { stream: true }));
|
|
184
|
+
}
|
|
185
|
+
inspect(decoder.decode());
|
|
186
|
+
} finally {
|
|
187
|
+
await source.dispose();
|
|
188
|
+
}
|
|
189
|
+
const trimmed = await operation.acquire(() => createLlmSpool(fs, context.cwd, signal, "input"), (value) => value.close());
|
|
190
|
+
try {
|
|
191
|
+
if (start >= 0) for await (const bytes of raw.replay(async () => ({ start, end }))) await trimmed.write(bytes);
|
|
192
|
+
} finally {
|
|
193
|
+
await raw.close();
|
|
194
|
+
}
|
|
195
|
+
return trimmed;
|
|
196
|
+
} catch (error) {
|
|
197
|
+
failed = true;
|
|
198
|
+
throw error;
|
|
199
|
+
} finally {
|
|
200
|
+
await cleanup().catch((error) => {
|
|
201
|
+
if (!failed) throw error;
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// packages/safe-bash-command-llm/src/chat-input.ts
|
|
207
|
+
import { yieldTurn } from "../../safe-bash-contracts/yield.js";
|
|
208
|
+
function createChatInput(options) {
|
|
209
|
+
const { context, operation } = options, { signal } = context;
|
|
210
|
+
let iterator, pending = new Uint8Array(0), position = 0, ended = false;
|
|
211
|
+
let multi, multiSize = 0, endToken = "!end", iterations = 0;
|
|
212
|
+
const create = () => operation.acquire(() => createLlmSpool(context.fs, context.cwd, signal, "input"), (spool) => spool.close());
|
|
213
|
+
const chunk = async () => {
|
|
214
|
+
while (position === pending.length) {
|
|
215
|
+
if (ended) return { done: true, value: void 0 };
|
|
216
|
+
iterator ??= await operation.acquire(() => context.stdinInput ? { next: () => context.stdinInput.readAvailable ? context.stdinInput.readAvailable(4096, signal, 10) : context.stdinInput.read(1, signal) } : context.stdin[Symbol.asyncIterator](), async (input) => {
|
|
217
|
+
await input.return?.();
|
|
218
|
+
});
|
|
219
|
+
const next = await waitForSource(() => iterator.next(), signal);
|
|
220
|
+
if (next.done) {
|
|
221
|
+
ended = true;
|
|
222
|
+
continue;
|
|
223
|
+
}
|
|
224
|
+
if (!(next.value instanceof Uint8Array)) throw new TypeError("Byte sources must yield Uint8Array chunks");
|
|
225
|
+
options.admit(next.value.length, false);
|
|
226
|
+
pending = next.value;
|
|
227
|
+
position = 0;
|
|
228
|
+
await yieldTurn(signal);
|
|
229
|
+
}
|
|
230
|
+
const start = position;
|
|
231
|
+
while (position < pending.length && position - start < 4096) {
|
|
232
|
+
const byte = pending[position++];
|
|
233
|
+
if (byte === 10) break;
|
|
234
|
+
}
|
|
235
|
+
return { done: false, value: pending.subarray(start, position) };
|
|
236
|
+
};
|
|
237
|
+
const inspect = async (spool) => {
|
|
238
|
+
let probe = "", whitespace2 = "", overflow = false;
|
|
239
|
+
const decoder = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true });
|
|
240
|
+
const accept = (text) => {
|
|
241
|
+
for (const char of text) {
|
|
242
|
+
if (isPythonWhitespace(char)) {
|
|
243
|
+
if (probe && whitespace2.length <= 4096) whitespace2 += char;
|
|
244
|
+
} else {
|
|
245
|
+
if (probe.length + whitespace2.length + char.length > 4096) overflow = true;
|
|
246
|
+
if (!overflow) probe += whitespace2 + char;
|
|
247
|
+
whitespace2 = "";
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
};
|
|
251
|
+
for await (const bytes of spool.replay()) {
|
|
252
|
+
accept(decoder.decode(bytes, { stream: true }));
|
|
253
|
+
await yieldTurn(signal);
|
|
254
|
+
}
|
|
255
|
+
accept(decoder.decode());
|
|
256
|
+
return { probe, exact: !overflow };
|
|
257
|
+
};
|
|
258
|
+
const line = async () => {
|
|
259
|
+
const spool = await create();
|
|
260
|
+
let size = 0, seen = false;
|
|
261
|
+
while (true) {
|
|
262
|
+
const next = await chunk();
|
|
263
|
+
if (next.done) return seen ? { spool, size } : (await spool.close(), void 0);
|
|
264
|
+
let bytes = next.value;
|
|
265
|
+
if (!bytes.length) continue;
|
|
266
|
+
seen = true;
|
|
267
|
+
const last = bytes[bytes.length - 1];
|
|
268
|
+
const newline = last === 10;
|
|
269
|
+
if (newline) bytes = bytes.subarray(0, -1);
|
|
270
|
+
await spool.write(bytes);
|
|
271
|
+
size += bytes.length;
|
|
272
|
+
if (newline) return { spool, size };
|
|
273
|
+
}
|
|
274
|
+
};
|
|
275
|
+
const control = async (spool) => {
|
|
276
|
+
let value = "";
|
|
277
|
+
const decoder = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true });
|
|
278
|
+
for await (const bytes of spool.replay()) {
|
|
279
|
+
options.admit(bytes.length, true);
|
|
280
|
+
value += decoder.decode(bytes, { stream: true });
|
|
281
|
+
}
|
|
282
|
+
return value + decoder.decode();
|
|
283
|
+
};
|
|
284
|
+
const words = (value) => {
|
|
285
|
+
const result = [];
|
|
286
|
+
let word = "";
|
|
287
|
+
for (const char of value) {
|
|
288
|
+
if (isPythonWhitespace(char)) {
|
|
289
|
+
if (word) result.push(word);
|
|
290
|
+
word = "";
|
|
291
|
+
} else word += char;
|
|
292
|
+
}
|
|
293
|
+
if (word) result.push(word);
|
|
294
|
+
return result;
|
|
295
|
+
};
|
|
296
|
+
return {
|
|
297
|
+
approvalInput: () => ({ next: chunk }),
|
|
298
|
+
async next() {
|
|
299
|
+
while (true) {
|
|
300
|
+
await options.write(multi ? " " : "> ");
|
|
301
|
+
const value = await line();
|
|
302
|
+
if (!value) throw new Error("Aborted!");
|
|
303
|
+
if (!value.size) {
|
|
304
|
+
await value.spool.close();
|
|
305
|
+
continue;
|
|
306
|
+
}
|
|
307
|
+
let includeInitialFragments = iterations++ === 0;
|
|
308
|
+
let inspected = await inspect(value.spool);
|
|
309
|
+
if (inspected.probe.startsWith("!multi")) {
|
|
310
|
+
const bits = words(stripPythonWhitespace(await control(value.spool)));
|
|
311
|
+
if (bits.length > 1) endToken = "!end " + bits.slice(1).join(" ");
|
|
312
|
+
multi ??= await create();
|
|
313
|
+
await value.spool.close();
|
|
314
|
+
continue;
|
|
315
|
+
}
|
|
316
|
+
if (inspected.exact && inspected.probe === "!edit") {
|
|
317
|
+
await value.spool.close();
|
|
318
|
+
const edited = await editChatPrompt({ ...options, context: { ...context, stdin: { async *[Symbol.asyncIterator]() {
|
|
319
|
+
while (true) {
|
|
320
|
+
const next = await chunk();
|
|
321
|
+
if (next.done) return;
|
|
322
|
+
yield next.value;
|
|
323
|
+
}
|
|
324
|
+
} } } });
|
|
325
|
+
if (!edited) {
|
|
326
|
+
await options.diagnostic("Editor closed without saving.\n");
|
|
327
|
+
continue;
|
|
328
|
+
}
|
|
329
|
+
value.spool = edited;
|
|
330
|
+
value.size = 0;
|
|
331
|
+
for await (const bytes of edited.replay()) value.size += bytes.length;
|
|
332
|
+
inspected = await inspect(edited);
|
|
333
|
+
}
|
|
334
|
+
const fragments = [];
|
|
335
|
+
if (inspected.probe.startsWith("!fragment ")) {
|
|
336
|
+
includeInitialFragments = false;
|
|
337
|
+
const text = await control(value.spool);
|
|
338
|
+
const lines = [];
|
|
339
|
+
let start = 0;
|
|
340
|
+
for (let index = 0; index < text.length; index++) {
|
|
341
|
+
if (!["\n", "\r", "\v", "\f", "", "", "", "\x85", "\u2028", "\u2029"].includes(text[index])) continue;
|
|
342
|
+
lines.push(text.slice(start, index));
|
|
343
|
+
if (text[index] === "\r" && text[index + 1] === "\n") index++;
|
|
344
|
+
start = index + 1;
|
|
345
|
+
}
|
|
346
|
+
if (start < text.length) lines.push(text.slice(start));
|
|
347
|
+
const promptLines = [];
|
|
348
|
+
for (const line2 of lines) {
|
|
349
|
+
if (line2.startsWith("!fragment ")) fragments.push(...words(stripPythonWhitespace(line2).slice(10)));
|
|
350
|
+
else promptLines.push(line2);
|
|
351
|
+
}
|
|
352
|
+
await value.spool.close();
|
|
353
|
+
value.spool = await create();
|
|
354
|
+
const bytes = new TextEncoder().encode(promptLines.join("\n"));
|
|
355
|
+
await value.spool.write(bytes);
|
|
356
|
+
value.size = bytes.length;
|
|
357
|
+
}
|
|
358
|
+
if (fragments.length) await options.resolveFragments(fragments);
|
|
359
|
+
if (multi) {
|
|
360
|
+
if (stripPythonWhitespace(inspected.exact ? inspected.probe : inspected.probe.startsWith("!end") ? await control(value.spool) : "") === endToken) {
|
|
361
|
+
await value.spool.close();
|
|
362
|
+
value.spool = multi;
|
|
363
|
+
multi = void 0;
|
|
364
|
+
multiSize = 0;
|
|
365
|
+
} else {
|
|
366
|
+
if (value.size) {
|
|
367
|
+
if (multiSize) {
|
|
368
|
+
await multi.write(Uint8Array.of(10));
|
|
369
|
+
multiSize++;
|
|
370
|
+
options.admit(1, false);
|
|
371
|
+
}
|
|
372
|
+
for await (const bytes of value.spool.replay()) await multi.write(bytes);
|
|
373
|
+
multiSize += value.size;
|
|
374
|
+
}
|
|
375
|
+
await value.spool.close();
|
|
376
|
+
continue;
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
const final = await inspect(value.spool);
|
|
380
|
+
return { spool: value.spool, includeInitialFragments, exit: final.exact && (final.probe === "exit" || final.probe === "quit") };
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
};
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
// packages/safe-bash-command-llm/src/prompt-tool-chain.ts
|
|
387
|
+
import { yieldTurn as yieldTurn4 } from "../../safe-bash-contracts/yield.js";
|
|
388
|
+
|
|
389
|
+
// packages/safe-bash-command-llm/src/tool-chain.ts
|
|
390
|
+
import { shellValueByteLength } from "../../safe-bash-contracts/index.js";
|
|
391
|
+
import { inheritYieldCheckpoint as inheritYieldCheckpoint2, yieldTurn as yieldTurn3 } from "../../safe-bash-contracts/yield.js";
|
|
392
|
+
|
|
393
|
+
// packages/safe-bash-command-llm/src/tool-execution.ts
|
|
394
|
+
import { inheritYieldCheckpoint, yieldTurn as yieldTurn2 } from "../../safe-bash-contracts/yield.js";
|
|
395
|
+
var LlmCancelToolCall = class extends Error {
|
|
396
|
+
};
|
|
397
|
+
async function* outputBytes(output, signal) {
|
|
398
|
+
if (typeof output !== "string") {
|
|
399
|
+
yield* referenceJson(output, signal);
|
|
400
|
+
return;
|
|
401
|
+
}
|
|
402
|
+
const encoder = new TextEncoder();
|
|
403
|
+
for (let offset = 0; offset < output.length; ) {
|
|
404
|
+
signal.throwIfAborted();
|
|
405
|
+
let end = Math.min(output.length, offset + 4096);
|
|
406
|
+
const last = output.charCodeAt(end - 1);
|
|
407
|
+
if (end < output.length && last >= 55296 && last <= 56319) end--;
|
|
408
|
+
yield encoder.encode(output.slice(offset, end));
|
|
409
|
+
offset = end;
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
async function executeLlmToolCalls(options, visit) {
|
|
413
|
+
const limit = options.maxOutputBytes ?? Infinity;
|
|
414
|
+
if (limit !== Infinity && (!Number.isSafeInteger(limit) || limit < 0))
|
|
415
|
+
throw new RangeError("Invalid tool output byte limit");
|
|
416
|
+
const controller = new AbortController();
|
|
417
|
+
const signal = options.async ? AbortSignal.any([options.context.signal, controller.signal]) : options.context.signal;
|
|
418
|
+
inheritYieldCheckpoint(options.context.signal, signal);
|
|
419
|
+
const tools = new Map(options.tools.map((tool) => [tool.name, tool]));
|
|
420
|
+
let size = 0;
|
|
421
|
+
const context = {
|
|
422
|
+
...options.context,
|
|
423
|
+
signal,
|
|
424
|
+
get maxBytes() {
|
|
425
|
+
return limit - size;
|
|
426
|
+
}
|
|
427
|
+
};
|
|
428
|
+
const execute2 = async (call, index) => {
|
|
429
|
+
const tool = tools.get(call.name);
|
|
430
|
+
let closed = false, failed2 = false, cleanup;
|
|
431
|
+
const resources = /* @__PURE__ */ new Map();
|
|
432
|
+
const own = (source) => {
|
|
433
|
+
const existing = resources.get(source);
|
|
434
|
+
if (existing) return existing.lease;
|
|
435
|
+
let disposal, read = false;
|
|
436
|
+
const dispose = () => disposal ??= Promise.resolve().then(() => source.dispose());
|
|
437
|
+
const lease = {
|
|
438
|
+
dispose,
|
|
439
|
+
bytes: {
|
|
440
|
+
async *[Symbol.asyncIterator]() {
|
|
441
|
+
if (closed || disposal || read)
|
|
442
|
+
throw new Error("Tool result lease is closed or already consumed");
|
|
443
|
+
read = true;
|
|
444
|
+
let steps = 0;
|
|
445
|
+
for await (const bytes of sourceBytes(source.bytes, signal)) {
|
|
446
|
+
if (++steps % 256 === 0) await yieldTurn2(signal);
|
|
447
|
+
if (closed || disposal) throw new Error("Tool result lease is closed");
|
|
448
|
+
if (bytes.length > limit - size)
|
|
449
|
+
throw new RangeError("Tool output byte limit exceeded");
|
|
450
|
+
size += bytes.length;
|
|
451
|
+
for (let offset = 0; offset < bytes.length; offset += 16384) {
|
|
452
|
+
if (++steps % 256 === 0) await yieldTurn2(signal);
|
|
453
|
+
signal.throwIfAborted();
|
|
454
|
+
if (closed || disposal) throw new Error("Tool result lease is closed");
|
|
455
|
+
yield Uint8Array.from(bytes.subarray(offset, offset + 16384));
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
};
|
|
461
|
+
resources.set(source, { lease, dispose });
|
|
462
|
+
if (closed) void dispose().catch(() => void 0);
|
|
463
|
+
return lease;
|
|
464
|
+
};
|
|
465
|
+
const close = () => {
|
|
466
|
+
closed = true;
|
|
467
|
+
return cleanup ??= Promise.allSettled(
|
|
468
|
+
Array.from(resources.values(), (resource) => resource.dispose())
|
|
469
|
+
).then((results) => {
|
|
470
|
+
const rejected = results.find((result) => result.status === "rejected");
|
|
471
|
+
if (rejected?.status === "rejected") throw rejected.reason;
|
|
472
|
+
});
|
|
473
|
+
};
|
|
474
|
+
const abort = () => {
|
|
475
|
+
void close().catch(() => void 0);
|
|
476
|
+
};
|
|
477
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
478
|
+
try {
|
|
479
|
+
signal.throwIfAborted();
|
|
480
|
+
let exception, output, executed = false;
|
|
481
|
+
try {
|
|
482
|
+
await waitForSource(
|
|
483
|
+
() => Promise.resolve(options.beforeCall?.(tool, call, context)),
|
|
484
|
+
signal
|
|
485
|
+
);
|
|
486
|
+
} catch (error) {
|
|
487
|
+
signal.throwIfAborted();
|
|
488
|
+
if (!(error instanceof LlmCancelToolCall)) throw error;
|
|
489
|
+
exception = error;
|
|
490
|
+
output = { output: "Cancelled: " + error.message };
|
|
491
|
+
}
|
|
492
|
+
if (!output && !tool) {
|
|
493
|
+
const error = new Error(`tool "${call.name}" does not exist`);
|
|
494
|
+
exception = error;
|
|
495
|
+
output = { output: "Error: " + error.message };
|
|
496
|
+
}
|
|
497
|
+
if (!output) {
|
|
498
|
+
if (!tool.implementation)
|
|
499
|
+
throw new Error(`No implementation available for tool: ${call.name}`);
|
|
500
|
+
executed = true;
|
|
501
|
+
try {
|
|
502
|
+
if (!call.arguments || typeof call.arguments !== "object" || Array.isArray(call.arguments))
|
|
503
|
+
throw new TypeError("Tool arguments must be a JSON object");
|
|
504
|
+
validateJsonData(call.arguments, "Tool arguments must be finite JSON data");
|
|
505
|
+
const pending2 = Promise.resolve().then(() => {
|
|
506
|
+
signal.throwIfAborted();
|
|
507
|
+
return tool.implementation(
|
|
508
|
+
call.arguments,
|
|
509
|
+
context
|
|
510
|
+
);
|
|
511
|
+
}).then((value) => {
|
|
512
|
+
if (value?.source) own(value.source);
|
|
513
|
+
if (Array.isArray(value?.attachments)) {
|
|
514
|
+
for (const attachment of value.attachments)
|
|
515
|
+
if (attachment?.source) own(attachment.source);
|
|
516
|
+
}
|
|
517
|
+
return value;
|
|
518
|
+
});
|
|
519
|
+
output = await waitForSource(() => pending2, signal);
|
|
520
|
+
if (!output || typeof output !== "object" || "source" in output === "output" in output)
|
|
521
|
+
throw new TypeError("Invalid tool output");
|
|
522
|
+
if ("output" in output)
|
|
523
|
+
validateJsonData(output.output, "Tool output must be finite JSON data");
|
|
524
|
+
if ("source" in output && (!output.source || typeof output.source.dispose !== "function" || typeof output.source.bytes?.[Symbol.asyncIterator] !== "function"))
|
|
525
|
+
throw new TypeError("Invalid tool output source");
|
|
526
|
+
} catch (error) {
|
|
527
|
+
signal.throwIfAborted();
|
|
528
|
+
exception = error;
|
|
529
|
+
output = { output: "Error: " + (error instanceof Error ? error.message : String(error)) };
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
const attachments = [];
|
|
533
|
+
if (output.attachments !== void 0 && !Array.isArray(output.attachments))
|
|
534
|
+
throw new TypeError("Invalid tool attachments");
|
|
535
|
+
for (const attachment of output.attachments ?? []) {
|
|
536
|
+
if (!attachment || typeof attachment.mimeType !== "string" || !attachment.mimeType || attachment.id !== void 0 && typeof attachment.id !== "string")
|
|
537
|
+
throw new TypeError("Invalid tool attachment");
|
|
538
|
+
if (attachment.url !== void 0) {
|
|
539
|
+
if (attachment.source !== void 0) throw new TypeError("Invalid tool attachment");
|
|
540
|
+
validateAttachmentUrl(attachment.url);
|
|
541
|
+
attachments.push(attachment);
|
|
542
|
+
} else {
|
|
543
|
+
if (!attachment.source || typeof attachment.source.dispose !== "function" || typeof attachment.source.bytes?.[Symbol.asyncIterator] !== "function")
|
|
544
|
+
throw new TypeError("Invalid tool attachment source");
|
|
545
|
+
attachments.push({ ...attachment, source: own(attachment.source) });
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
const source = output.source ?? {
|
|
549
|
+
bytes: outputBytes(output.output, signal),
|
|
550
|
+
async dispose() {
|
|
551
|
+
}
|
|
552
|
+
};
|
|
553
|
+
await waitForSource(
|
|
554
|
+
() => Promise.resolve(
|
|
555
|
+
visit({
|
|
556
|
+
call,
|
|
557
|
+
output: own(source),
|
|
558
|
+
attachments,
|
|
559
|
+
executed,
|
|
560
|
+
...exception === void 0 ? {} : { exception }
|
|
561
|
+
}, index)
|
|
562
|
+
),
|
|
563
|
+
signal
|
|
564
|
+
);
|
|
565
|
+
} catch (error) {
|
|
566
|
+
failed2 = true;
|
|
567
|
+
throw signal.aborted ? signal.reason : error;
|
|
568
|
+
} finally {
|
|
569
|
+
signal.removeEventListener("abort", abort);
|
|
570
|
+
await close().catch((error) => {
|
|
571
|
+
if (!failed2 && !signal.aborted) throw error;
|
|
572
|
+
});
|
|
573
|
+
}
|
|
574
|
+
};
|
|
575
|
+
const pending = [];
|
|
576
|
+
let failure, failed = false;
|
|
577
|
+
const fail = (error) => {
|
|
578
|
+
if (!failed) {
|
|
579
|
+
failed = true;
|
|
580
|
+
failure = error;
|
|
581
|
+
controller.abort(error);
|
|
582
|
+
}
|
|
583
|
+
};
|
|
584
|
+
try {
|
|
585
|
+
const preparations = new Set([...tools.values()].map((tool) => tool.prepare).filter((prepare) => prepare !== void 0));
|
|
586
|
+
for (const prepare of preparations) {
|
|
587
|
+
await waitForSource(async () => prepare(context, { async: options.async ?? false }), signal);
|
|
588
|
+
}
|
|
589
|
+
for (let index = 0; index < options.calls.length; index++) {
|
|
590
|
+
await yieldTurn2(signal);
|
|
591
|
+
const call = options.calls[index];
|
|
592
|
+
const tool = tools.get(call.name);
|
|
593
|
+
if (options.async && !tool?.implementation) continue;
|
|
594
|
+
if (options.async && tool?.async) {
|
|
595
|
+
pending.push(execute2(call, index).catch(fail));
|
|
596
|
+
} else await execute2(call, index);
|
|
597
|
+
}
|
|
598
|
+
} catch (error) {
|
|
599
|
+
fail(error);
|
|
600
|
+
}
|
|
601
|
+
await Promise.all(pending);
|
|
602
|
+
if (failed) throw failure;
|
|
603
|
+
signal.throwIfAborted();
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
// packages/safe-bash-command-llm/src/tool-chain.ts
|
|
607
|
+
async function* streamLlmToolChain(options) {
|
|
608
|
+
const chainLimit = options.chainLimit === void 0 ? 10 : options.chainLimit;
|
|
609
|
+
if (chainLimit !== null && typeof chainLimit !== "bigint" && !Number.isSafeInteger(chainLimit)) throw new RangeError("Invalid chain limit");
|
|
610
|
+
const outputLimit = options.maxOutputBytes ?? Infinity;
|
|
611
|
+
const toolLimit = options.maxToolOutputBytes ?? Infinity;
|
|
612
|
+
for (const limit of [outputLimit, toolLimit])
|
|
613
|
+
if (limit !== Infinity && (!Number.isSafeInteger(limit) || limit < 0)) throw new RangeError("Invalid chain byte limit");
|
|
614
|
+
const controller = new AbortController();
|
|
615
|
+
const signal = AbortSignal.any([options.context.signal, controller.signal]);
|
|
616
|
+
inheritYieldCheckpoint2(options.context.signal, signal);
|
|
617
|
+
let outputBytes2 = 0, toolBytes = 0;
|
|
618
|
+
const admit = (size) => {
|
|
619
|
+
if (size > outputLimit - outputBytes2) throw new RangeError("LLM chain output byte limit exceeded");
|
|
620
|
+
outputBytes2 += size;
|
|
621
|
+
};
|
|
622
|
+
const counted = (source) => ({
|
|
623
|
+
dispose: () => source.dispose(),
|
|
624
|
+
bytes: { async *[Symbol.asyncIterator]() {
|
|
625
|
+
for await (const bytes of source.bytes) {
|
|
626
|
+
toolBytes += bytes.length;
|
|
627
|
+
yield bytes;
|
|
628
|
+
}
|
|
629
|
+
} }
|
|
630
|
+
});
|
|
631
|
+
try {
|
|
632
|
+
for (let index = 0; ; index++) {
|
|
633
|
+
await yieldTurn3(signal);
|
|
634
|
+
const iterator = options.openResponse(index, signal)[Symbol.asyncIterator]();
|
|
635
|
+
let ended = false;
|
|
636
|
+
let events = 0;
|
|
637
|
+
let response;
|
|
638
|
+
try {
|
|
639
|
+
while (true) {
|
|
640
|
+
if (++events % 256 === 0) await yieldTurn3(signal);
|
|
641
|
+
const next = await waitForSource(() => iterator.next(), signal);
|
|
642
|
+
if (next.done) {
|
|
643
|
+
ended = true;
|
|
644
|
+
break;
|
|
645
|
+
}
|
|
646
|
+
const event = next.value;
|
|
647
|
+
if (response) throw new Error("LLM response event must be final");
|
|
648
|
+
if (event.type === "response") {
|
|
649
|
+
response = event;
|
|
650
|
+
if (event.response.toolCalls) for await (const bytes of jsonValue(event.response.toolCalls, signal)) admit(bytes.length);
|
|
651
|
+
yield event;
|
|
652
|
+
} else if (event.type === "text") {
|
|
653
|
+
for (let offset = 0; offset < event.text.length; ) {
|
|
654
|
+
await yieldTurn3(signal);
|
|
655
|
+
let end = Math.min(event.text.length, offset + 4096);
|
|
656
|
+
const last = event.text.charCodeAt(end - 1);
|
|
657
|
+
if (end < event.text.length && last >= 55296 && last <= 56319) end--;
|
|
658
|
+
const text = event.text.slice(offset, end);
|
|
659
|
+
admit(shellValueByteLength(text));
|
|
660
|
+
yield { type: "text", text };
|
|
661
|
+
offset = end;
|
|
662
|
+
}
|
|
663
|
+
} else if (event.type === "bytes") {
|
|
664
|
+
for (let offset = 0; offset < event.data.length; offset += 16384) {
|
|
665
|
+
await yieldTurn3(signal);
|
|
666
|
+
const bytes = event.data.subarray(offset, offset + 16384);
|
|
667
|
+
admit(bytes.length);
|
|
668
|
+
yield { type: "bytes", data: Uint8Array.from(bytes) };
|
|
669
|
+
}
|
|
670
|
+
} else throw new TypeError("Invalid LLM stream event");
|
|
671
|
+
}
|
|
672
|
+
} finally {
|
|
673
|
+
if (!ended) {
|
|
674
|
+
controller.abort(new Error("LLM chain response closed"));
|
|
675
|
+
void Promise.resolve().then(() => iterator.return?.()).catch(() => void 0);
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
signal.throwIfAborted();
|
|
679
|
+
if (!response) throw new Error("LLM stream ended without response metadata");
|
|
680
|
+
if (chainLimit && index + 1 >= chainLimit) throw new Error(`Chain limit of ${chainLimit} exceeded.`);
|
|
681
|
+
const calls = response.response.toolCalls ?? [];
|
|
682
|
+
let visited = false;
|
|
683
|
+
await executeLlmToolCalls({
|
|
684
|
+
...options.async === void 0 ? {} : { async: options.async },
|
|
685
|
+
tools: options.tools,
|
|
686
|
+
calls,
|
|
687
|
+
context: { ...options.context, signal },
|
|
688
|
+
maxOutputBytes: toolLimit - toolBytes,
|
|
689
|
+
...options.beforeCall ? { beforeCall: options.beforeCall } : {}
|
|
690
|
+
}, (result, callIndex) => {
|
|
691
|
+
visited = true;
|
|
692
|
+
return options.visit({
|
|
693
|
+
...result,
|
|
694
|
+
output: counted(result.output),
|
|
695
|
+
attachments: result.attachments.map((attachment) => attachment.source ? { ...attachment, source: counted(attachment.source) } : attachment)
|
|
696
|
+
}, callIndex);
|
|
697
|
+
});
|
|
698
|
+
if (!visited) return;
|
|
699
|
+
}
|
|
700
|
+
} finally {
|
|
701
|
+
controller.abort(new Error("LLM chain closed"));
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
// packages/safe-bash-command-llm/src/prompt-tool-chain.ts
|
|
706
|
+
async function* promptToolChain(options) {
|
|
707
|
+
const { context, operation, request, service, tools, streamed, textSource } = options;
|
|
708
|
+
const signal = request.signal;
|
|
709
|
+
const create = () => operation.acquire(() => createLlmSpool(context.fs, context.cwd, signal, "input"), (spool) => spool.close());
|
|
710
|
+
const retain = async (source, admit, text) => {
|
|
711
|
+
const spool = await create();
|
|
712
|
+
let size = 0;
|
|
713
|
+
const decoder = text ? new TextDecoder("utf-8", { fatal: true }) : void 0;
|
|
714
|
+
try {
|
|
715
|
+
for await (const bytes of sourceBytes(source.bytes, signal)) {
|
|
716
|
+
if (admit) options.admitInput(bytes.length, !streamed);
|
|
717
|
+
decoder?.decode(bytes, { stream: true });
|
|
718
|
+
await spool.write(bytes);
|
|
719
|
+
size += bytes.length;
|
|
720
|
+
}
|
|
721
|
+
decoder?.decode();
|
|
722
|
+
return { spool, size };
|
|
723
|
+
} finally {
|
|
724
|
+
await source.dispose();
|
|
725
|
+
}
|
|
726
|
+
};
|
|
727
|
+
const retainAttachments = async (attachments, admit) => {
|
|
728
|
+
const result = [];
|
|
729
|
+
for (const attachment of attachments) {
|
|
730
|
+
const identity = { mimeType: attachment.mimeType, ...attachment.id === void 0 ? {} : { id: attachment.id } };
|
|
731
|
+
if (admit) {
|
|
732
|
+
for await (const bytes of jsonValue({ ...identity, ...attachment.url === void 0 ? {} : { url: attachment.url } }, signal)) options.admitInput(bytes.length, true);
|
|
733
|
+
}
|
|
734
|
+
result.push(attachment.source ? { ...identity, content: await retain(attachment.source, admit, false) } : { ...identity, url: attachment.url });
|
|
735
|
+
}
|
|
736
|
+
return result;
|
|
737
|
+
};
|
|
738
|
+
const lease = (content, activeSignal) => operation.acquire(() => content.spool.lease(activeSignal), (source) => source.dispose());
|
|
739
|
+
const sourceAttachments = (attachments, activeSignal) => Promise.all(attachments.map(async (attachment) => attachment.content ? { mimeType: attachment.mimeType, ...attachment.id === void 0 ? {} : { id: attachment.id }, source: await lease(attachment.content, activeSignal) } : { mimeType: attachment.mimeType, ...attachment.id === void 0 ? {} : { id: attachment.id }, url: attachment.url }));
|
|
740
|
+
const sameContent = async (left, right) => {
|
|
741
|
+
if (left.size !== right.size) return false;
|
|
742
|
+
const first = await lease(left, signal), second = await lease(right, signal);
|
|
743
|
+
const iterator = sourceBytes(second.bytes, signal)[Symbol.asyncIterator]();
|
|
744
|
+
let pending = new Uint8Array(0), offset = 0;
|
|
745
|
+
try {
|
|
746
|
+
for await (const bytes of sourceBytes(first.bytes, signal)) {
|
|
747
|
+
await yieldTurn4(signal);
|
|
748
|
+
for (const byte of bytes) {
|
|
749
|
+
while (offset === pending.length) {
|
|
750
|
+
const next = await iterator.next();
|
|
751
|
+
if (next.done) return false;
|
|
752
|
+
pending = next.value;
|
|
753
|
+
offset = 0;
|
|
754
|
+
}
|
|
755
|
+
if (byte !== pending[offset++]) return false;
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
return true;
|
|
759
|
+
} finally {
|
|
760
|
+
try {
|
|
761
|
+
await iterator.return?.();
|
|
762
|
+
} finally {
|
|
763
|
+
await Promise.all([first.dispose(), second.dispose()]);
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
};
|
|
767
|
+
const materialize = async (content) => {
|
|
768
|
+
let value = "";
|
|
769
|
+
const decoder = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true });
|
|
770
|
+
const source = await lease(content, signal);
|
|
771
|
+
try {
|
|
772
|
+
for await (const bytes of source.bytes) value += decoder.decode(bytes, { stream: true });
|
|
773
|
+
} finally {
|
|
774
|
+
await source.dispose();
|
|
775
|
+
}
|
|
776
|
+
return value + decoder.decode();
|
|
777
|
+
};
|
|
778
|
+
const bufferedAttachments = async (attachments) => Promise.all(attachments.map(async (attachment) => {
|
|
779
|
+
const identity = { mimeType: attachment.mimeType, ...attachment.id === void 0 ? {} : { id: attachment.id } };
|
|
780
|
+
if (!attachment.content) return { ...identity, url: attachment.url };
|
|
781
|
+
const bytes = new Uint8Array(attachment.content.size);
|
|
782
|
+
let offset = 0;
|
|
783
|
+
for await (const chunk of attachment.content.spool.replay()) {
|
|
784
|
+
bytes.set(chunk, offset);
|
|
785
|
+
offset += chunk.length;
|
|
786
|
+
}
|
|
787
|
+
return { ...identity, bytes };
|
|
788
|
+
}));
|
|
789
|
+
const declarations = tools.map(({ name, description, inputSchema }) => ({ name, ...description === void 0 ? {} : { description }, inputSchema }));
|
|
790
|
+
for await (const bytes of jsonValue(declarations, signal)) options.admitInput(bytes.length, true);
|
|
791
|
+
const prompt = await retain(request.prompt, false, true);
|
|
792
|
+
const system = request.system === void 0 ? void 0 : await retain(request.system, false, true);
|
|
793
|
+
const initialAttachments = await retainAttachments(request.attachments, false);
|
|
794
|
+
const empty = await retain(textSource(""), false, true);
|
|
795
|
+
const messages = options.chatMessages ?? [];
|
|
796
|
+
let currentPrompt = prompt, currentAttachments = initialAttachments, currentSystem = system;
|
|
797
|
+
if (options.chatMessages) {
|
|
798
|
+
if (!system?.size) currentSystem = void 0;
|
|
799
|
+
else if (messages.length) {
|
|
800
|
+
let previous;
|
|
801
|
+
for (let index = messages.length - 1; index >= 0; index--) {
|
|
802
|
+
if (messages[index].role === "system") {
|
|
803
|
+
previous = messages[index];
|
|
804
|
+
break;
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
if (!previous || !await sameContent(previous.content, system)) messages.push({ role: "system", content: system });
|
|
808
|
+
currentSystem = void 0;
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
let responseContent, responseCalls = [], prepared = false;
|
|
812
|
+
let nextAttachments = [];
|
|
813
|
+
const pendingResults = /* @__PURE__ */ new Map();
|
|
814
|
+
let approvals = Promise.resolve(), diagnostics = Promise.resolve();
|
|
815
|
+
yield* streamLlmToolChain({
|
|
816
|
+
context: { ...context, signal },
|
|
817
|
+
tools,
|
|
818
|
+
chainLimit: options.chainLimit,
|
|
819
|
+
...request.async ? { async: true } : {},
|
|
820
|
+
maxOutputBytes: options.maxOutputBytes,
|
|
821
|
+
maxToolOutputBytes: options.remainingInput(),
|
|
822
|
+
openResponse(index, activeSignal) {
|
|
823
|
+
return (async function* () {
|
|
824
|
+
if (index) {
|
|
825
|
+
for (let callIndex = 0; callIndex < responseCalls.length; callIndex++) {
|
|
826
|
+
const result = pendingResults.get(callIndex);
|
|
827
|
+
if (result) {
|
|
828
|
+
messages.push(result.message);
|
|
829
|
+
nextAttachments.push(...result.attachments);
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
pendingResults.clear();
|
|
833
|
+
currentPrompt = empty;
|
|
834
|
+
currentSystem = void 0;
|
|
835
|
+
currentAttachments = nextAttachments;
|
|
836
|
+
nextAttachments = [];
|
|
837
|
+
}
|
|
838
|
+
prepared = false;
|
|
839
|
+
const base = {
|
|
840
|
+
...request.async ? { async: true } : {},
|
|
841
|
+
maxOutputBytes: options.maxOutputBytes,
|
|
842
|
+
...request.model === void 0 ? {} : { model: request.model },
|
|
843
|
+
options: request.options,
|
|
844
|
+
signal: activeSignal,
|
|
845
|
+
stream: request.stream,
|
|
846
|
+
...request.key === void 0 ? {} : { key: request.key },
|
|
847
|
+
tools: declarations,
|
|
848
|
+
...!index && request.schema !== void 0 ? { schema: request.schema } : {}
|
|
849
|
+
};
|
|
850
|
+
const events = streamed ? service.streamSources({
|
|
851
|
+
...base,
|
|
852
|
+
prompt: await lease(currentPrompt, activeSignal),
|
|
853
|
+
...currentSystem ? { system: await lease(currentSystem, activeSignal) } : {},
|
|
854
|
+
attachments: await sourceAttachments(currentAttachments, activeSignal),
|
|
855
|
+
messages: await Promise.all(messages.map(async (message) => ({ ...message, content: await lease(message.content, activeSignal) })))
|
|
856
|
+
}) : service.stream({
|
|
857
|
+
...base,
|
|
858
|
+
prompt: await materialize(currentPrompt),
|
|
859
|
+
...currentSystem ? { system: await materialize(currentSystem) } : {},
|
|
860
|
+
attachments: await bufferedAttachments(currentAttachments),
|
|
861
|
+
messages: await Promise.all(messages.map(async (message) => ({ ...message, content: await materialize(message.content) })))
|
|
862
|
+
});
|
|
863
|
+
responseContent = { spool: await create(), size: 0 };
|
|
864
|
+
let surrogate = "";
|
|
865
|
+
const append = async (text) => {
|
|
866
|
+
for await (const bytes of textSource(text).bytes) {
|
|
867
|
+
await responseContent.spool.write(bytes);
|
|
868
|
+
responseContent.size += bytes.length;
|
|
869
|
+
}
|
|
870
|
+
};
|
|
871
|
+
for await (const event of events) {
|
|
872
|
+
if (event.type === "text") {
|
|
873
|
+
let text = surrogate + event.text;
|
|
874
|
+
const last = text.charCodeAt(text.length - 1);
|
|
875
|
+
surrogate = last >= 55296 && last <= 56319 ? text.slice(-1) : "";
|
|
876
|
+
if (surrogate) text = text.slice(0, -1);
|
|
877
|
+
await append(text);
|
|
878
|
+
} else if (event.type === "bytes") {
|
|
879
|
+
await responseContent.spool.write(event.data);
|
|
880
|
+
responseContent.size += event.data.length;
|
|
881
|
+
} else {
|
|
882
|
+
if (surrogate) await append(surrogate);
|
|
883
|
+
responseCalls = event.response.toolCalls ?? [];
|
|
884
|
+
}
|
|
885
|
+
yield event;
|
|
886
|
+
}
|
|
887
|
+
})();
|
|
888
|
+
},
|
|
889
|
+
beforeCall(tool, call, context2) {
|
|
890
|
+
const approval = approvals.then(async () => {
|
|
891
|
+
context2.signal.throwIfAborted();
|
|
892
|
+
if (!prepared) {
|
|
893
|
+
prepared = true;
|
|
894
|
+
options.admitInput(responseContent.size, !streamed);
|
|
895
|
+
for await (const bytes of jsonValue(responseCalls, signal)) options.admitInput(bytes.length, true);
|
|
896
|
+
if (currentSystem?.size) messages.push({ role: "system", content: currentSystem });
|
|
897
|
+
if (currentPrompt.size) messages.push({ role: "user", content: currentPrompt });
|
|
898
|
+
if (responseContent.size) messages.push({ role: "assistant", content: responseContent });
|
|
899
|
+
messages.push({ role: "assistant", content: empty, toolCalls: responseCalls });
|
|
900
|
+
}
|
|
901
|
+
await options.beforeCall?.(tool, call, context2);
|
|
902
|
+
});
|
|
903
|
+
approvals = approval.then(() => {
|
|
904
|
+
}, () => {
|
|
905
|
+
});
|
|
906
|
+
return approval;
|
|
907
|
+
},
|
|
908
|
+
async visit(result, callIndex) {
|
|
909
|
+
const content = await retain(result.output, true, true);
|
|
910
|
+
const attachments = await retainAttachments(result.attachments, true);
|
|
911
|
+
pendingResults.set(callIndex, { message: { role: "tool", ...result.call.id === void 0 ? {} : { toolCallId: result.call.id }, content }, attachments });
|
|
912
|
+
if (options.debugWrite) {
|
|
913
|
+
const write = options.debugWrite;
|
|
914
|
+
diagnostics = diagnostics.then(async () => {
|
|
915
|
+
signal.throwIfAborted();
|
|
916
|
+
const { debugToolResult } = await import("./prompt-tool-debug-ERJKK3XZ.js");
|
|
917
|
+
await debugToolResult({ context: { ...context, signal }, result, output: content.spool, attachments, write });
|
|
918
|
+
});
|
|
919
|
+
await diagnostics;
|
|
920
|
+
}
|
|
921
|
+
}
|
|
922
|
+
});
|
|
923
|
+
if (options.chatMessages && responseContent && !prepared) {
|
|
924
|
+
options.admitInput(responseContent.size, !streamed);
|
|
925
|
+
if (currentSystem?.size) messages.push({ role: "system", content: currentSystem });
|
|
926
|
+
if (currentPrompt.size) messages.push({ role: "user", content: currentPrompt });
|
|
927
|
+
if (responseContent.size) messages.push({ role: "assistant", content: responseContent });
|
|
928
|
+
}
|
|
929
|
+
}
|
|
930
|
+
|
|
931
|
+
// packages/safe-bash-command-llm/src/prompt-tool-approval.ts
|
|
932
|
+
import { pipeBytes } from "../../safe-bash-contracts/index.js";
|
|
933
|
+
import { writeDiagnostic } from "../../safe-bash-contracts/escaping.js";
|
|
934
|
+
import { yieldTurn as yieldTurn5 } from "../../safe-bash-contracts/yield.js";
|
|
935
|
+
function createToolApproval(options) {
|
|
936
|
+
const { context, write, admitInput } = options, { signal } = context;
|
|
937
|
+
const encoder = new TextEncoder();
|
|
938
|
+
let iterator, pending = new Uint8Array(0), position = 0, ended = false, skipLineFeed = false;
|
|
939
|
+
const answer = async () => {
|
|
940
|
+
const decoder = new TextDecoder("utf-8", { fatal: true });
|
|
941
|
+
let value = "", seen = false, trailing = false, invalid = false, steps = 0;
|
|
942
|
+
const accept = (text) => {
|
|
943
|
+
for (const char of text) {
|
|
944
|
+
if (isPythonWhitespace(char)) {
|
|
945
|
+
if (value) trailing = true;
|
|
946
|
+
} else if (trailing || value.length >= 3) invalid = true;
|
|
947
|
+
else value += char.toLowerCase();
|
|
948
|
+
}
|
|
949
|
+
};
|
|
950
|
+
while (true) {
|
|
951
|
+
if (++steps % 256 === 0) await yieldTurn5(signal);
|
|
952
|
+
signal.throwIfAborted();
|
|
953
|
+
if (position === pending.length) {
|
|
954
|
+
if (ended) {
|
|
955
|
+
accept(decoder.decode());
|
|
956
|
+
return seen ? invalid ? "invalid" : value : void 0;
|
|
957
|
+
}
|
|
958
|
+
iterator ??= await options.openInput();
|
|
959
|
+
const next = await waitForSource(() => iterator.next(), signal);
|
|
960
|
+
if (next.done) {
|
|
961
|
+
ended = true;
|
|
962
|
+
continue;
|
|
963
|
+
}
|
|
964
|
+
if (!(next.value instanceof Uint8Array)) throw new TypeError("Byte sources must yield Uint8Array chunks");
|
|
965
|
+
admitInput(next.value.length);
|
|
966
|
+
pending = next.value;
|
|
967
|
+
position = 0;
|
|
968
|
+
continue;
|
|
969
|
+
}
|
|
970
|
+
if (skipLineFeed) {
|
|
971
|
+
skipLineFeed = false;
|
|
972
|
+
if (pending[position] === 10) {
|
|
973
|
+
position++;
|
|
974
|
+
continue;
|
|
975
|
+
}
|
|
976
|
+
}
|
|
977
|
+
seen = true;
|
|
978
|
+
const end = Math.min(pending.length, position + 4096);
|
|
979
|
+
let newline = position;
|
|
980
|
+
while (newline < end && pending[newline] !== 10 && pending[newline] !== 13) newline++;
|
|
981
|
+
accept(decoder.decode(pending.subarray(position, newline), { stream: true }));
|
|
982
|
+
position = newline;
|
|
983
|
+
if (newline < end) {
|
|
984
|
+
skipLineFeed = pending[position] === 13;
|
|
985
|
+
position++;
|
|
986
|
+
accept(decoder.decode());
|
|
987
|
+
return invalid ? "invalid" : value;
|
|
988
|
+
}
|
|
989
|
+
}
|
|
990
|
+
};
|
|
991
|
+
return async (_tool, call) => {
|
|
992
|
+
await writeDiagnostic(context.stderr, `Tool call: ${call.name}(`, signal);
|
|
993
|
+
await pipeBytes(pythonRepr(call.arguments, signal), context.stderr, signal);
|
|
994
|
+
await writeDiagnostic(context.stderr, ")\n", signal);
|
|
995
|
+
while (true) {
|
|
996
|
+
await write(encoder.encode("Approve tool call? [y/N]: "));
|
|
997
|
+
const value = await answer();
|
|
998
|
+
if (value === void 0) throw new Error("");
|
|
999
|
+
if (value === "y" || value === "yes") return;
|
|
1000
|
+
if (value === "" || value === "n" || value === "no") throw new LlmCancelToolCall("User cancelled tool call");
|
|
1001
|
+
await write(encoder.encode("Error: invalid input\n"));
|
|
1002
|
+
}
|
|
1003
|
+
};
|
|
1004
|
+
}
|
|
1005
|
+
|
|
1006
|
+
// packages/safe-bash-command-llm/src/tool-registry.ts
|
|
1007
|
+
function createLlmToolRegistry(tools) {
|
|
1008
|
+
const registry = /* @__PURE__ */ new Map();
|
|
1009
|
+
for (const tool of tools) {
|
|
1010
|
+
if (!tool || typeof tool.name !== "string" || !tool.name || !tool.inputSchema || Array.isArray(tool.inputSchema) || typeof tool.inputSchema !== "object")
|
|
1011
|
+
throw new TypeError("Invalid LLM tool definition");
|
|
1012
|
+
for (const value of [tool.description, tool.plugin, tool.signature, tool.registryKey])
|
|
1013
|
+
if (value !== void 0 && typeof value !== "string")
|
|
1014
|
+
throw new TypeError("Invalid LLM tool metadata");
|
|
1015
|
+
if (tool.implementation !== void 0 && typeof tool.implementation !== "function")
|
|
1016
|
+
throw new TypeError("Invalid LLM tool implementation");
|
|
1017
|
+
if (tool.selectionIndex !== void 0 && (!Number.isSafeInteger(tool.selectionIndex) || tool.selectionIndex < 0))
|
|
1018
|
+
throw new TypeError("Invalid LLM tool selection index");
|
|
1019
|
+
if (tool.prepare !== void 0 && typeof tool.prepare !== "function")
|
|
1020
|
+
throw new TypeError("Invalid LLM tool preparation");
|
|
1021
|
+
if (tool.async !== void 0 && typeof tool.async !== "boolean")
|
|
1022
|
+
throw new TypeError("Invalid LLM tool async declaration");
|
|
1023
|
+
validateJsonData(tool.inputSchema, "Tool schema must be finite JSON data");
|
|
1024
|
+
let name = tool.name, suffix = 0;
|
|
1025
|
+
while (registry.has(name)) name = `${tool.name}_${++suffix}`;
|
|
1026
|
+
registry.set(name, tool);
|
|
1027
|
+
}
|
|
1028
|
+
return registry;
|
|
1029
|
+
}
|
|
1030
|
+
function selectLlmTools(registry, names) {
|
|
1031
|
+
const missing = names.filter((name) => !registry.has(name));
|
|
1032
|
+
if (missing.length)
|
|
1033
|
+
throw new Error(
|
|
1034
|
+
`Tool(s) ${missing.join(", ")} not found. Available tools: ${[...registry.keys()].join(", ")}`
|
|
1035
|
+
);
|
|
1036
|
+
return names.map((name) => registry.get(name));
|
|
1037
|
+
}
|
|
1038
|
+
|
|
1039
|
+
// packages/safe-bash-command-llm/src/fragment-loader-command.ts
|
|
1040
|
+
async function fragmentLoaderCommand(tokens, loaders, output, diagnostic) {
|
|
1041
|
+
const usage3 = "Usage: llm fragments loaders [OPTIONS]\n";
|
|
1042
|
+
let failure, help2 = false, ended = false;
|
|
1043
|
+
const operands = [];
|
|
1044
|
+
for (const token of tokens) {
|
|
1045
|
+
if (!ended && token === "--") ended = true;
|
|
1046
|
+
else if (!ended && (token === "--help" || token === "-h")) help2 = true;
|
|
1047
|
+
else if (!ended && token.startsWith("-") && token !== "-") {
|
|
1048
|
+
failure = `No such option: ${token.split("=")[0]}`;
|
|
1049
|
+
break;
|
|
1050
|
+
} else operands.push(token);
|
|
1051
|
+
}
|
|
1052
|
+
if (help2 && !failure) {
|
|
1053
|
+
await output(usage3 + "\n Show fragment loaders registered by plugins\n\nOptions:\n -h, --help Show this message and exit.\n");
|
|
1054
|
+
return 0;
|
|
1055
|
+
}
|
|
1056
|
+
failure ??= operands.length ? `Got unexpected extra argument (${operands[0]})` : void 0;
|
|
1057
|
+
if (failure) {
|
|
1058
|
+
await diagnostic(usage3 + "Try 'llm fragments loaders --help' for help.\n\nError: " + failure + "\n");
|
|
1059
|
+
return 2;
|
|
1060
|
+
}
|
|
1061
|
+
let found = false;
|
|
1062
|
+
for (const [prefix, loader] of loaders) {
|
|
1063
|
+
if (found) await output("\n");
|
|
1064
|
+
found = true;
|
|
1065
|
+
await output(`${prefix}:
|
|
1066
|
+
`);
|
|
1067
|
+
const lines = (loader.description || "Undocumented").split("\n");
|
|
1068
|
+
let common;
|
|
1069
|
+
for (const line of lines) {
|
|
1070
|
+
if (!line.trim()) continue;
|
|
1071
|
+
let width = 0;
|
|
1072
|
+
while (line[width] === " " || line[width] === " ") width++;
|
|
1073
|
+
const indent = line.slice(0, width);
|
|
1074
|
+
if (common === void 0) common = indent;
|
|
1075
|
+
else {
|
|
1076
|
+
let i = 0;
|
|
1077
|
+
while (i < common.length && common[i] === indent[i]) i++;
|
|
1078
|
+
common = common.slice(0, i);
|
|
1079
|
+
}
|
|
1080
|
+
}
|
|
1081
|
+
const description = lines.map((line) => line.trim() ? line.slice(common?.length ?? 0) : "").join("\n").trim();
|
|
1082
|
+
for (const line of description.split("\n")) await output((line.trim() ? ` ${line}` : line) + "\n");
|
|
1083
|
+
}
|
|
1084
|
+
if (!found) await output("No fragment loaders found\n");
|
|
1085
|
+
return 0;
|
|
1086
|
+
}
|
|
1087
|
+
|
|
1088
|
+
// packages/safe-bash-command-llm/src/tools-command.ts
|
|
1089
|
+
var usage2 = "Usage: llm tools list [OPTIONS] [TOOL_DEFS]...\n";
|
|
1090
|
+
var groupHelp = "Usage: llm tools [OPTIONS] COMMAND [ARGS]...\n\n Manage tools that can be made available to LLMs\n\nOptions:\n -h, --help Show this message and exit.\n\nCommands:\n list* List available tools that have been provided by plugins\n";
|
|
1091
|
+
var listHelp = usage2 + "\n List available tools that have been provided by plugins\n\nOptions:\n --json Output as JSON\n --functions TEXT Python code block or file path defining functions to\n register as tools\n -h, --help Show this message and exit.\n";
|
|
1092
|
+
function compareNames(left, right) {
|
|
1093
|
+
let a = 0, b = 0;
|
|
1094
|
+
while (a < left.length && b < right.length) {
|
|
1095
|
+
const x = left.codePointAt(a), y = right.codePointAt(b);
|
|
1096
|
+
if (x !== y) return x - y;
|
|
1097
|
+
a += x > 65535 ? 2 : 1;
|
|
1098
|
+
b += y > 65535 ? 2 : 1;
|
|
1099
|
+
}
|
|
1100
|
+
return left.length - a - (right.length - b);
|
|
1101
|
+
}
|
|
1102
|
+
async function toolsCommand(tokens, registry, output, diagnostic, step, signal, load) {
|
|
1103
|
+
let groupEager = false, separator = -1;
|
|
1104
|
+
const error = async (message, withUsage = false) => {
|
|
1105
|
+
await diagnostic(
|
|
1106
|
+
(withUsage ? usage2 + "Try 'llm tools list --help' for help.\n\n" : "") + "Error: " + message + "\n"
|
|
1107
|
+
);
|
|
1108
|
+
return 2;
|
|
1109
|
+
};
|
|
1110
|
+
for (let index = 0; index < tokens.length; index++) {
|
|
1111
|
+
await step();
|
|
1112
|
+
const token = tokens[index];
|
|
1113
|
+
if (token === "--") {
|
|
1114
|
+
separator = index;
|
|
1115
|
+
break;
|
|
1116
|
+
}
|
|
1117
|
+
if (!token.startsWith("-") || token === "-") break;
|
|
1118
|
+
if (token.startsWith("--help=")) return error("Option '--help' does not take a value.");
|
|
1119
|
+
if (token === "--help" || !token.startsWith("--") && token.slice(1).includes("h"))
|
|
1120
|
+
groupEager = true;
|
|
1121
|
+
}
|
|
1122
|
+
if (groupEager) {
|
|
1123
|
+
await output(groupHelp);
|
|
1124
|
+
return 0;
|
|
1125
|
+
}
|
|
1126
|
+
const groupArgs = tokens.filter((_, index) => index !== separator);
|
|
1127
|
+
const args = groupArgs[0] === "list" ? groupArgs.slice(1) : groupArgs;
|
|
1128
|
+
const names = [];
|
|
1129
|
+
let json = false, help2 = false, ended = false;
|
|
1130
|
+
const functions = [];
|
|
1131
|
+
for (let index = 0; index < args.length; index++) {
|
|
1132
|
+
await step();
|
|
1133
|
+
const token = args[index];
|
|
1134
|
+
if (ended || !token.startsWith("-") || token === "-") {
|
|
1135
|
+
names.push(token);
|
|
1136
|
+
continue;
|
|
1137
|
+
}
|
|
1138
|
+
if (token === "--") {
|
|
1139
|
+
ended = true;
|
|
1140
|
+
continue;
|
|
1141
|
+
}
|
|
1142
|
+
const equals = token.indexOf("="), flag = equals < 0 ? token : token.slice(0, equals);
|
|
1143
|
+
if (["--json", "--help"].includes(flag) && equals >= 0)
|
|
1144
|
+
return error(`Option '${flag}' does not take a value.`);
|
|
1145
|
+
if (token === "--json") {
|
|
1146
|
+
json = true;
|
|
1147
|
+
continue;
|
|
1148
|
+
}
|
|
1149
|
+
if (token === "--help" || token === "-h") {
|
|
1150
|
+
help2 = true;
|
|
1151
|
+
continue;
|
|
1152
|
+
}
|
|
1153
|
+
if (flag === "--functions") {
|
|
1154
|
+
if (equals < 0 && args[++index] === void 0)
|
|
1155
|
+
return error("Option '--functions' requires an argument.");
|
|
1156
|
+
functions.push(equals < 0 ? args[index] : token.slice(equals + 1));
|
|
1157
|
+
continue;
|
|
1158
|
+
}
|
|
1159
|
+
return error(`No such option '${flag}'.`, true);
|
|
1160
|
+
}
|
|
1161
|
+
if (help2) {
|
|
1162
|
+
await output(listHelp);
|
|
1163
|
+
return 0;
|
|
1164
|
+
}
|
|
1165
|
+
if (functions.length && !load) {
|
|
1166
|
+
await diagnostic("Error: Python tool loading is not configured\n");
|
|
1167
|
+
return 1;
|
|
1168
|
+
}
|
|
1169
|
+
let selected;
|
|
1170
|
+
let toolboxes = [];
|
|
1171
|
+
try {
|
|
1172
|
+
const dynamicNames = names.filter((name) => !registry.has(name));
|
|
1173
|
+
const loaded = load && (!names.length || functions.length || dynamicNames.length) ? await load(functions, dynamicNames, !names.length || dynamicNames.length > 0) : { tools: [] };
|
|
1174
|
+
toolboxes = [...loaded.toolboxes ?? []].sort((left, right) => compareNames(left.name, right.name));
|
|
1175
|
+
selected = new Map(names.length ? [...loaded.tools, ...selectLlmTools(registry, load ? names.filter((name) => registry.has(name)) : names)].map((tool) => [tool.name, tool]) : [...registry, ...loaded.tools.map((tool) => [tool.registryKey ?? tool.name, tool])]);
|
|
1176
|
+
} catch (failure) {
|
|
1177
|
+
await diagnostic("Error: " + (failure instanceof Error ? failure.message : String(failure)) + "\n");
|
|
1178
|
+
return 1;
|
|
1179
|
+
}
|
|
1180
|
+
const entries = [...selected].sort(([left], [right]) => compareNames(left, right));
|
|
1181
|
+
if (json) {
|
|
1182
|
+
const tools = entries.map(([name, tool]) => ({
|
|
1183
|
+
name,
|
|
1184
|
+
description: tool.description ?? null,
|
|
1185
|
+
arguments: tool.inputSchema,
|
|
1186
|
+
plugin: tool.plugin ?? null
|
|
1187
|
+
}));
|
|
1188
|
+
for await (const bytes of referenceJson({ tools, toolboxes: toolboxes.map((box) => ({ name: box.name, tools: box.tools.map((tool) => ({
|
|
1189
|
+
name: tool.name,
|
|
1190
|
+
description: tool.description ?? null,
|
|
1191
|
+
arguments: tool.inputSchema
|
|
1192
|
+
})) })) }, signal, true)) {
|
|
1193
|
+
await step();
|
|
1194
|
+
await output(new TextDecoder().decode(bytes));
|
|
1195
|
+
}
|
|
1196
|
+
await output("\n");
|
|
1197
|
+
return 0;
|
|
1198
|
+
}
|
|
1199
|
+
const describe = async (tool, indent) => {
|
|
1200
|
+
await step();
|
|
1201
|
+
await output(indent + tool.name + (tool.signature ?? "()") + (tool.plugin ? ` (plugin: ${tool.plugin})` : "") + "\n\n");
|
|
1202
|
+
if (tool.description) {
|
|
1203
|
+
const description = tool.description.trim();
|
|
1204
|
+
let start = 0;
|
|
1205
|
+
while (start <= description.length) {
|
|
1206
|
+
await step();
|
|
1207
|
+
const newline = description.indexOf("\n", start), end = newline < 0 ? description.length : newline;
|
|
1208
|
+
const line = description.slice(start, end);
|
|
1209
|
+
await output((line.trim() ? indent + " " : "") + line + "\n");
|
|
1210
|
+
if (newline < 0) break;
|
|
1211
|
+
start = end + 1;
|
|
1212
|
+
}
|
|
1213
|
+
await output("\n");
|
|
1214
|
+
}
|
|
1215
|
+
};
|
|
1216
|
+
for (const [, tool] of entries) await describe(tool, "");
|
|
1217
|
+
for (const box of toolboxes) {
|
|
1218
|
+
await step();
|
|
1219
|
+
await output(box.name + ":\n\n");
|
|
1220
|
+
for (const tool of box.tools) await describe(tool, " ");
|
|
1221
|
+
}
|
|
1222
|
+
return 0;
|
|
1223
|
+
}
|
|
1224
|
+
|
|
1225
|
+
// packages/safe-bash-command-llm/src/fragment-loaders.ts
|
|
1226
|
+
import { yieldTurn as yieldTurn6 } from "../../safe-bash-contracts/yield.js";
|
|
1227
|
+
function getLlmFragmentPrefix(reference) {
|
|
1228
|
+
const colon = reference.indexOf(":");
|
|
1229
|
+
if (colon <= 0) return void 0;
|
|
1230
|
+
for (let i = 0; i < colon; i++) {
|
|
1231
|
+
const code = reference.charCodeAt(i);
|
|
1232
|
+
if (!(code >= 48 && code <= 57 || code >= 65 && code <= 90 || code >= 97 && code <= 122 || code === 45 || code === 95)) return void 0;
|
|
1233
|
+
}
|
|
1234
|
+
return reference.slice(0, colon);
|
|
1235
|
+
}
|
|
1236
|
+
function createLlmFragmentLoaders(entries) {
|
|
1237
|
+
const loaders = /* @__PURE__ */ new Map();
|
|
1238
|
+
for (const [prefix, loader] of entries) {
|
|
1239
|
+
let name = prefix, suffix = 0;
|
|
1240
|
+
while (loaders.has(name)) name = `${prefix}_${++suffix}`;
|
|
1241
|
+
loaders.set(name, loader);
|
|
1242
|
+
}
|
|
1243
|
+
return loaders;
|
|
1244
|
+
}
|
|
1245
|
+
async function* loadLlmPluginFragments(reference, loaders, context, allowAttachments = true) {
|
|
1246
|
+
const prefix = getLlmFragmentPrefix(reference), loader = prefix === void 0 ? void 0 : loaders.get(prefix);
|
|
1247
|
+
if (!loader) throw new Error(`Unknown fragment prefix: ${prefix ?? reference}`);
|
|
1248
|
+
const { signal } = context;
|
|
1249
|
+
let iterator, ended = false;
|
|
1250
|
+
try {
|
|
1251
|
+
signal.throwIfAborted();
|
|
1252
|
+
iterator = loader(reference.slice(prefix.length + 1), context)[Symbol.asyncIterator]();
|
|
1253
|
+
while (true) {
|
|
1254
|
+
await yieldTurn6(signal);
|
|
1255
|
+
const pending = Promise.resolve().then(() => {
|
|
1256
|
+
signal.throwIfAborted();
|
|
1257
|
+
return iterator.next();
|
|
1258
|
+
});
|
|
1259
|
+
void pending.then((result2) => {
|
|
1260
|
+
if (signal.aborted && !result2.done) void result2.value.source.dispose().catch(() => void 0);
|
|
1261
|
+
}, () => void 0);
|
|
1262
|
+
const result = await waitForSource(() => pending, signal);
|
|
1263
|
+
if (result.done) {
|
|
1264
|
+
ended = true;
|
|
1265
|
+
break;
|
|
1266
|
+
}
|
|
1267
|
+
const value = result.value;
|
|
1268
|
+
let closing;
|
|
1269
|
+
const dispose = () => closing ??= Promise.resolve().then(() => value.source.dispose());
|
|
1270
|
+
try {
|
|
1271
|
+
if (value.type !== "text" && value.type !== "attachment") throw new TypeError("Invalid fragment loader result");
|
|
1272
|
+
if (value.type === "attachment" && !allowAttachments) throw new Error(`Fragment loader ${prefix} returned a disallowed attachment`);
|
|
1273
|
+
const source = { bytes: value.source.bytes, dispose, normalizeNewlines: false };
|
|
1274
|
+
yield { ...value, source };
|
|
1275
|
+
} finally {
|
|
1276
|
+
await dispose();
|
|
1277
|
+
}
|
|
1278
|
+
}
|
|
1279
|
+
} catch (error) {
|
|
1280
|
+
signal.throwIfAborted();
|
|
1281
|
+
throw new Error(`Could not load fragment ${reference}: ${error instanceof Error ? error.message : String(error)}`);
|
|
1282
|
+
} finally {
|
|
1283
|
+
if (iterator && !ended) {
|
|
1284
|
+
const retired = Promise.resolve().then(() => iterator.return?.());
|
|
1285
|
+
if (signal.aborted) void retired.catch(() => void 0);
|
|
1286
|
+
else await waitForSource(() => retired, signal);
|
|
1287
|
+
}
|
|
1288
|
+
}
|
|
1289
|
+
}
|
|
1290
|
+
|
|
1291
|
+
// packages/safe-bash-command-llm/src/url-fragment-source.ts
|
|
1292
|
+
import { pythonFileCodepages } from "../../safe-bash-csv-engine/python-file-codepages.js";
|
|
1293
|
+
import { pythonSingleByteCodepages } from "../../safe-bash-csv-engine/python-codepages.js";
|
|
1294
|
+
import { normalizeEncoding, pythonCodecAliases } from "../../safe-bash-csv-engine/python-codec-aliases.js";
|
|
1295
|
+
|
|
1296
|
+
// packages/safe-bash-command-llm/src/url-source.ts
|
|
1297
|
+
import { FsError as FsError2 } from "../../safe-bash-contracts/index.js";
|
|
1298
|
+
import { inheritYieldCheckpoint as inheritYieldCheckpoint3, yieldTurn as yieldTurn7 } from "../../safe-bash-contracts/yield.js";
|
|
1299
|
+
function createLlmUrlSource(options) {
|
|
1300
|
+
validateAttachmentUrl(options.url);
|
|
1301
|
+
const limit = options.maxBytes ?? Infinity;
|
|
1302
|
+
const maxRedirects = options.maxRedirects ?? 0;
|
|
1303
|
+
if (!Number.isSafeInteger(maxRedirects) || maxRedirects < 0) throw new RangeError("Invalid URL redirect limit");
|
|
1304
|
+
if (limit !== Infinity && (!Number.isSafeInteger(limit) || limit < 0)) throw new RangeError("Invalid URL input byte limit");
|
|
1305
|
+
if (typeof options.fetch !== "function") throw new TypeError("Attachment URL loading is not configured");
|
|
1306
|
+
options.signal.throwIfAborted();
|
|
1307
|
+
const controller = new AbortController();
|
|
1308
|
+
const signal = AbortSignal.any([options.signal, controller.signal]);
|
|
1309
|
+
inheritYieldCheckpoint3(options.signal, signal);
|
|
1310
|
+
let response;
|
|
1311
|
+
let reader;
|
|
1312
|
+
let closed = false, consumed = false;
|
|
1313
|
+
let cancellation;
|
|
1314
|
+
const cancel = () => {
|
|
1315
|
+
if (!response) return Promise.resolve();
|
|
1316
|
+
return cancellation ??= Promise.resolve().then(() => reader ? reader.cancel() : response.body?.cancel());
|
|
1317
|
+
};
|
|
1318
|
+
const abort = () => {
|
|
1319
|
+
void cancel().catch(() => void 0);
|
|
1320
|
+
};
|
|
1321
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
1322
|
+
const dispose = async () => {
|
|
1323
|
+
closed = true;
|
|
1324
|
+
controller.abort(new FsError2("EBADF", { message: "LLM URL input is closed" }));
|
|
1325
|
+
signal.removeEventListener("abort", abort);
|
|
1326
|
+
const cleanup = cancel();
|
|
1327
|
+
if (options.signal.aborted) void cleanup.catch(() => void 0);
|
|
1328
|
+
else await cleanup;
|
|
1329
|
+
};
|
|
1330
|
+
return { dispose, bytes: { async *[Symbol.asyncIterator]() {
|
|
1331
|
+
if (closed || consumed) throw new FsError2("EBADF", { message: "LLM URL input is closed or consumed" });
|
|
1332
|
+
consumed = true;
|
|
1333
|
+
let failed = false, size = 0, windows = 0;
|
|
1334
|
+
try {
|
|
1335
|
+
signal.throwIfAborted();
|
|
1336
|
+
let url = options.url;
|
|
1337
|
+
for (let redirects = 0; ; redirects++) {
|
|
1338
|
+
await waitForSource(() => options.fetch(url, { method: "GET", redirect: "manual", signal }).then((value) => {
|
|
1339
|
+
response = value;
|
|
1340
|
+
if (closed || signal.aborted) void cancel().catch(() => void 0);
|
|
1341
|
+
return value;
|
|
1342
|
+
}), signal);
|
|
1343
|
+
signal.throwIfAborted();
|
|
1344
|
+
const location = response.headers.get("location");
|
|
1345
|
+
if (![301, 302, 303, 307, 308].includes(response.status) || !location || maxRedirects === 0) break;
|
|
1346
|
+
if (redirects >= maxRedirects) throw new Error("Exceeded maximum allowed redirects.");
|
|
1347
|
+
const next = new URL(location, url).href;
|
|
1348
|
+
validateAttachmentUrl(next);
|
|
1349
|
+
await waitForSource(cancel, signal);
|
|
1350
|
+
response = void 0;
|
|
1351
|
+
cancellation = void 0;
|
|
1352
|
+
url = next;
|
|
1353
|
+
}
|
|
1354
|
+
if (!response.ok) throw new Error(`Attachment URL returned HTTP ${response.status}`);
|
|
1355
|
+
if (!response.body) return;
|
|
1356
|
+
reader = response.body.getReader();
|
|
1357
|
+
while (true) {
|
|
1358
|
+
const next = await waitForSource(() => reader.read(), signal);
|
|
1359
|
+
if (next.done) return;
|
|
1360
|
+
if (!(next.value instanceof Uint8Array)) throw new TypeError("Attachment URL must return byte chunks");
|
|
1361
|
+
if (next.value.length > limit - size) throw new FsError2("EFBIG", { message: "Attachment URL input byte limit exceeded" });
|
|
1362
|
+
options.admitBytes?.(next.value.length);
|
|
1363
|
+
size += next.value.length;
|
|
1364
|
+
if (!next.value.length && ++windows % 64 === 0) await yieldTurn7(signal);
|
|
1365
|
+
for (let offset = 0; offset < next.value.length; offset += 16384) {
|
|
1366
|
+
if (++windows % 64 === 0) await yieldTurn7(signal);
|
|
1367
|
+
signal.throwIfAborted();
|
|
1368
|
+
yield next.value.slice(offset, offset + 16384);
|
|
1369
|
+
}
|
|
1370
|
+
}
|
|
1371
|
+
} catch (error) {
|
|
1372
|
+
failed = true;
|
|
1373
|
+
throw signal.aborted ? signal.reason : error;
|
|
1374
|
+
} finally {
|
|
1375
|
+
await dispose().catch((error) => {
|
|
1376
|
+
if (!failed) throw error;
|
|
1377
|
+
});
|
|
1378
|
+
reader?.releaseLock();
|
|
1379
|
+
}
|
|
1380
|
+
} } };
|
|
1381
|
+
}
|
|
1382
|
+
|
|
1383
|
+
// packages/safe-bash-command-llm/src/url-fragment-source.ts
|
|
1384
|
+
function charset(header) {
|
|
1385
|
+
const parameters = [];
|
|
1386
|
+
let part = "", quoted = false, escaped = false;
|
|
1387
|
+
for (const character of header ?? "") {
|
|
1388
|
+
if (escaped) {
|
|
1389
|
+
part += character;
|
|
1390
|
+
escaped = false;
|
|
1391
|
+
continue;
|
|
1392
|
+
}
|
|
1393
|
+
if (quoted && character === "\\") {
|
|
1394
|
+
escaped = true;
|
|
1395
|
+
continue;
|
|
1396
|
+
}
|
|
1397
|
+
if (character === '"') {
|
|
1398
|
+
quoted = !quoted;
|
|
1399
|
+
continue;
|
|
1400
|
+
}
|
|
1401
|
+
if (character === ";" && !quoted) {
|
|
1402
|
+
parameters.push(part);
|
|
1403
|
+
part = "";
|
|
1404
|
+
} else part += character;
|
|
1405
|
+
}
|
|
1406
|
+
parameters.push(part);
|
|
1407
|
+
for (const parameter of parameters.slice(1)) {
|
|
1408
|
+
const equals = parameter.indexOf("=");
|
|
1409
|
+
if (equals >= 0 && parameter.slice(0, equals).trim().toLowerCase() === "charset")
|
|
1410
|
+
return parameter.slice(equals + 1).trim();
|
|
1411
|
+
}
|
|
1412
|
+
return "utf-8";
|
|
1413
|
+
}
|
|
1414
|
+
function responseDecoder(header) {
|
|
1415
|
+
const name = charset(header), encoding = pythonCodecAliases[normalizeEncoding(name)] ?? "utf-8";
|
|
1416
|
+
const table = pythonSingleByteCodepages[encoding] ?? pythonFileCodepages[encoding];
|
|
1417
|
+
if (table)
|
|
1418
|
+
return {
|
|
1419
|
+
decode(bytes) {
|
|
1420
|
+
let result = "";
|
|
1421
|
+
for (const byte of bytes ?? []) {
|
|
1422
|
+
const code = table[byte];
|
|
1423
|
+
result += String.fromCodePoint(code < 0 ? 65533 : code);
|
|
1424
|
+
}
|
|
1425
|
+
return result;
|
|
1426
|
+
}
|
|
1427
|
+
};
|
|
1428
|
+
if (encoding !== "utf-8" && encoding !== "utf-8-sig")
|
|
1429
|
+
throw new Error(`Unsupported URL fragment charset: ${name}`);
|
|
1430
|
+
const decoder = new TextDecoder("utf-8", { ignoreBOM: true });
|
|
1431
|
+
if (encoding === "utf-8") return decoder;
|
|
1432
|
+
const signature = Uint8Array.of(239, 187, 191);
|
|
1433
|
+
let offset = 0, decided = false;
|
|
1434
|
+
return {
|
|
1435
|
+
decode(bytes = new Uint8Array(), options) {
|
|
1436
|
+
let index = 0, prefix = "";
|
|
1437
|
+
while (!decided && index < bytes.length) {
|
|
1438
|
+
if (bytes[index] !== signature[offset]) {
|
|
1439
|
+
decided = true;
|
|
1440
|
+
prefix = decoder.decode(signature.subarray(0, offset), { stream: true });
|
|
1441
|
+
break;
|
|
1442
|
+
}
|
|
1443
|
+
index++;
|
|
1444
|
+
offset++;
|
|
1445
|
+
if (offset === 3) decided = true;
|
|
1446
|
+
}
|
|
1447
|
+
return decided ? prefix + decoder.decode(bytes.subarray(index), options) : "";
|
|
1448
|
+
}
|
|
1449
|
+
};
|
|
1450
|
+
}
|
|
1451
|
+
function createLlmUrlFragmentSource(options) {
|
|
1452
|
+
let decoder, contentType = null;
|
|
1453
|
+
const raw = createLlmUrlSource({
|
|
1454
|
+
...options,
|
|
1455
|
+
maxRedirects: 3,
|
|
1456
|
+
fetch: async (input, init) => {
|
|
1457
|
+
const response = await options.fetch(input, init);
|
|
1458
|
+
contentType = response.headers.get("content-type");
|
|
1459
|
+
return response;
|
|
1460
|
+
}
|
|
1461
|
+
});
|
|
1462
|
+
return {
|
|
1463
|
+
normalizeNewlines: false,
|
|
1464
|
+
dispose: raw.dispose,
|
|
1465
|
+
bytes: {
|
|
1466
|
+
async *[Symbol.asyncIterator]() {
|
|
1467
|
+
const encoder = new TextEncoder();
|
|
1468
|
+
try {
|
|
1469
|
+
for await (const bytes of raw.bytes) {
|
|
1470
|
+
if (!bytes.length) continue;
|
|
1471
|
+
decoder ??= responseDecoder(contentType);
|
|
1472
|
+
const text = decoder.decode(bytes, { stream: true });
|
|
1473
|
+
if (text) yield encoder.encode(text);
|
|
1474
|
+
}
|
|
1475
|
+
options.signal.throwIfAborted();
|
|
1476
|
+
const tail = decoder?.decode();
|
|
1477
|
+
if (tail) yield encoder.encode(tail);
|
|
1478
|
+
} finally {
|
|
1479
|
+
await raw.dispose();
|
|
1480
|
+
}
|
|
1481
|
+
}
|
|
1482
|
+
}
|
|
1483
|
+
};
|
|
1484
|
+
}
|
|
1485
|
+
|
|
1486
|
+
// packages/safe-bash-command-llm/src/fragments.ts
|
|
1487
|
+
import { yieldTurn as yieldTurn8 } from "../../safe-bash-contracts/yield.js";
|
|
1488
|
+
function whitespace(code) {
|
|
1489
|
+
return code >= 9 && code <= 13 || code >= 28 && code <= 32 || code === 133 || code === 160 || code === 5760 || code >= 8192 && code <= 8202 || code === 8232 || code === 8233 || code === 8239 || code === 8287 || code === 12288;
|
|
1490
|
+
}
|
|
1491
|
+
async function createLlmFragmentSource(options) {
|
|
1492
|
+
const { fs, directory, signal } = options;
|
|
1493
|
+
let output;
|
|
1494
|
+
try {
|
|
1495
|
+
output = await createLlmSpool(fs, directory, signal, "input");
|
|
1496
|
+
} catch (error) {
|
|
1497
|
+
await options.tail?.dispose();
|
|
1498
|
+
throw error;
|
|
1499
|
+
}
|
|
1500
|
+
let count = 0, tailDisposed = false;
|
|
1501
|
+
const append = async (source, tail = false) => {
|
|
1502
|
+
let part;
|
|
1503
|
+
try {
|
|
1504
|
+
part = await createLlmSpool(fs, directory, signal, "input");
|
|
1505
|
+
const decoder = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true });
|
|
1506
|
+
let size = 0, start, end = 0, previousCR = false;
|
|
1507
|
+
const normalize = (text) => {
|
|
1508
|
+
if (!(source.normalizeNewlines ?? options.normalizeNewlines) || tail) return text;
|
|
1509
|
+
let result = "";
|
|
1510
|
+
for (const character of text) {
|
|
1511
|
+
if (character !== "\n" || !previousCR) result += character === "\r" ? "\n" : character;
|
|
1512
|
+
previousCR = character === "\r";
|
|
1513
|
+
}
|
|
1514
|
+
return result;
|
|
1515
|
+
};
|
|
1516
|
+
const scan = (text) => {
|
|
1517
|
+
for (const character of text) {
|
|
1518
|
+
const code = character.codePointAt(0);
|
|
1519
|
+
const length = code < 128 ? 1 : code < 2048 ? 2 : code < 65536 ? 3 : 4;
|
|
1520
|
+
if (!whitespace(code)) {
|
|
1521
|
+
start ??= size;
|
|
1522
|
+
end = size + length;
|
|
1523
|
+
}
|
|
1524
|
+
size += length;
|
|
1525
|
+
}
|
|
1526
|
+
};
|
|
1527
|
+
for await (const chunk of sourceBytes(source.bytes, signal)) {
|
|
1528
|
+
if (!tail) options.admitBytes?.(chunk.byteLength, source);
|
|
1529
|
+
if (!chunk.byteLength) await yieldTurn8(signal);
|
|
1530
|
+
for (let offset = 0; offset < chunk.byteLength; offset += 16384) {
|
|
1531
|
+
await yieldTurn8(signal);
|
|
1532
|
+
const window = chunk.subarray(offset, offset + 16384);
|
|
1533
|
+
const text = normalize(decoder.decode(window, { stream: true }));
|
|
1534
|
+
scan(text);
|
|
1535
|
+
await part.write(new TextEncoder().encode(text));
|
|
1536
|
+
}
|
|
1537
|
+
}
|
|
1538
|
+
const last = normalize(decoder.decode());
|
|
1539
|
+
scan(last);
|
|
1540
|
+
if (last) await part.write(new TextEncoder().encode(last));
|
|
1541
|
+
if (options.system ? start === void 0 : tail && size === 0) return;
|
|
1542
|
+
if (count++) {
|
|
1543
|
+
const separator = options.system ? Uint8Array.of(10, 10) : Uint8Array.of(10);
|
|
1544
|
+
options.admitSeparator?.(separator.byteLength);
|
|
1545
|
+
await output.write(separator);
|
|
1546
|
+
}
|
|
1547
|
+
for await (const chunk of part.replay(
|
|
1548
|
+
options.system ? async () => ({ start, end }) : void 0
|
|
1549
|
+
))
|
|
1550
|
+
await output.write(chunk);
|
|
1551
|
+
} finally {
|
|
1552
|
+
try {
|
|
1553
|
+
await part?.close();
|
|
1554
|
+
} finally {
|
|
1555
|
+
if (tail) tailDisposed = true;
|
|
1556
|
+
await source.dispose();
|
|
1557
|
+
}
|
|
1558
|
+
}
|
|
1559
|
+
};
|
|
1560
|
+
let iterator, ended = false;
|
|
1561
|
+
try {
|
|
1562
|
+
iterator = options.fragments[Symbol.asyncIterator]();
|
|
1563
|
+
while (true) {
|
|
1564
|
+
await yieldTurn8(signal);
|
|
1565
|
+
const pending = Promise.resolve().then(() => {
|
|
1566
|
+
signal.throwIfAborted();
|
|
1567
|
+
return iterator.next();
|
|
1568
|
+
});
|
|
1569
|
+
void pending.then(
|
|
1570
|
+
(result2) => {
|
|
1571
|
+
if (signal.aborted && !result2.done) void result2.value.dispose().catch(() => void 0);
|
|
1572
|
+
},
|
|
1573
|
+
() => void 0
|
|
1574
|
+
);
|
|
1575
|
+
const result = await waitForSource(() => pending, signal);
|
|
1576
|
+
if (result.done) {
|
|
1577
|
+
ended = true;
|
|
1578
|
+
break;
|
|
1579
|
+
}
|
|
1580
|
+
await append(result.value);
|
|
1581
|
+
}
|
|
1582
|
+
if (options.tail) await append(options.tail, true);
|
|
1583
|
+
return { bytes: output.replay(), dispose: output.close };
|
|
1584
|
+
} catch (error) {
|
|
1585
|
+
await output.close();
|
|
1586
|
+
throw error;
|
|
1587
|
+
} finally {
|
|
1588
|
+
try {
|
|
1589
|
+
if (!tailDisposed) await options.tail?.dispose();
|
|
1590
|
+
} finally {
|
|
1591
|
+
if (iterator && !ended) {
|
|
1592
|
+
const retired = Promise.resolve().then(() => iterator.return?.());
|
|
1593
|
+
if (signal.aborted) void retired.catch(() => void 0);
|
|
1594
|
+
else await retired;
|
|
1595
|
+
}
|
|
1596
|
+
}
|
|
1597
|
+
}
|
|
1598
|
+
}
|
|
1599
|
+
|
|
1600
|
+
// packages/safe-bash-command-llm/src/embed-models-command.ts
|
|
1601
|
+
var groupHelp2 = "Usage: llm embed-models [OPTIONS] COMMAND [ARGS]...\n\n Manage available embedding models\n\nOptions:\n -h, --help Show this message and exit.\n\nCommands:\n list* List available embedding models\n default Show or set the default embedding model\n";
|
|
1602
|
+
async function embeddingModelsCommand(context, service, tokens, emit, diagnostic, step, maxConfigurationBytes = Infinity) {
|
|
1603
|
+
if (tokens[0] === "--" && ["list", "default"].includes(tokens[1] ?? "")) tokens = tokens.slice(1);
|
|
1604
|
+
const defaults = tokens[0] === "default", explicit = tokens[0] === "list" || defaults;
|
|
1605
|
+
const command = defaults ? "default" : "list";
|
|
1606
|
+
const usage3 = `Usage: llm embed-models ${command} [OPTIONS]${defaults ? " [MODEL]" : ""}
|
|
1607
|
+
`;
|
|
1608
|
+
const fail = async (message, withUsage = true) => {
|
|
1609
|
+
await diagnostic((withUsage ? usage3 + `Try 'llm embed-models ${command} -h' for help.
|
|
1610
|
+
|
|
1611
|
+
` : "") + `Error: ${message}
|
|
1612
|
+
`);
|
|
1613
|
+
return 2;
|
|
1614
|
+
};
|
|
1615
|
+
const terminator = tokens.indexOf("--");
|
|
1616
|
+
const groupFlags = terminator < 0 ? tokens : tokens.slice(0, terminator);
|
|
1617
|
+
if (!explicit && groupFlags.some((token) => token === "--help" || token.startsWith("-") && !token.startsWith("--") && token.slice(1).includes("h"))) {
|
|
1618
|
+
await emit(groupHelp2);
|
|
1619
|
+
return 0;
|
|
1620
|
+
}
|
|
1621
|
+
const args = explicit ? tokens.slice(1) : tokens.filter((_, index) => index !== terminator);
|
|
1622
|
+
const queries = [], operands = [];
|
|
1623
|
+
let ended = false, help2 = false, remove = false;
|
|
1624
|
+
for (let index = 0; index < args.length; index++) {
|
|
1625
|
+
await step();
|
|
1626
|
+
const token = args[index];
|
|
1627
|
+
if (!ended && token === "--") {
|
|
1628
|
+
ended = true;
|
|
1629
|
+
continue;
|
|
1630
|
+
}
|
|
1631
|
+
if (ended || !token.startsWith("-") || token === "-") {
|
|
1632
|
+
operands.push(token);
|
|
1633
|
+
continue;
|
|
1634
|
+
}
|
|
1635
|
+
if (token === "--help" || token === "-h") {
|
|
1636
|
+
help2 = true;
|
|
1637
|
+
continue;
|
|
1638
|
+
}
|
|
1639
|
+
if (defaults && token === "--remove-default") {
|
|
1640
|
+
remove = true;
|
|
1641
|
+
continue;
|
|
1642
|
+
}
|
|
1643
|
+
if (!token.startsWith("--")) {
|
|
1644
|
+
for (let cursor = 1; cursor < token.length; cursor++) {
|
|
1645
|
+
const flag2 = "-" + token[cursor];
|
|
1646
|
+
if (flag2 === "-h") {
|
|
1647
|
+
help2 = true;
|
|
1648
|
+
continue;
|
|
1649
|
+
}
|
|
1650
|
+
if (defaults || flag2 !== "-q") return fail(`No such option: ${flag2}`);
|
|
1651
|
+
const value2 = token.slice(cursor + 1) || args[++index];
|
|
1652
|
+
if (value2 === void 0) return fail(`Option '${flag2}' requires an argument.`, false);
|
|
1653
|
+
queries.push(value2.toLowerCase());
|
|
1654
|
+
break;
|
|
1655
|
+
}
|
|
1656
|
+
continue;
|
|
1657
|
+
}
|
|
1658
|
+
const equals = token.indexOf("=");
|
|
1659
|
+
const flag = token.slice(0, equals < 0 ? void 0 : equals);
|
|
1660
|
+
if (equals >= 0 && (flag === "--help" || defaults && flag === "--remove-default")) return fail(`Option '${flag}' does not take a value.`, false);
|
|
1661
|
+
if (defaults || flag !== "--query") return fail(`No such option: ${flag}`);
|
|
1662
|
+
const attached = equals < 0 ? void 0 : token.slice(equals + 1);
|
|
1663
|
+
const value = attached ?? args[++index];
|
|
1664
|
+
if (value === void 0) return fail(`Option '${flag}' requires an argument.`, false);
|
|
1665
|
+
queries.push(value.toLowerCase());
|
|
1666
|
+
}
|
|
1667
|
+
if (help2) {
|
|
1668
|
+
await emit(usage3 + (defaults ? "\n Show or set the default embedding model\n\nOptions:\n --remove-default Reset to specifying no default model\n -h, --help Show this message and exit.\n" : "\n List available embedding models\n\nOptions:\n -q, --query TEXT Search for embedding models matching these strings\n -h, --help Show this message and exit.\n"));
|
|
1669
|
+
return 0;
|
|
1670
|
+
}
|
|
1671
|
+
const extra = operands.slice(defaults ? 1 : 0);
|
|
1672
|
+
if (extra.length) return fail(`Got unexpected extra argument${extra.length === 1 ? "" : "s"} (${extra.join(" ")})`);
|
|
1673
|
+
const configuration = createLlmConfiguration(context, maxConfigurationBytes);
|
|
1674
|
+
if (defaults) {
|
|
1675
|
+
const selected = operands[0];
|
|
1676
|
+
if (!selected && !remove) {
|
|
1677
|
+
const model = await configuration.defaultModel("default_embedding_model.txt");
|
|
1678
|
+
if (model === void 0) await diagnostic("<No default embedding model set>\n");
|
|
1679
|
+
else await emit(model + "\n");
|
|
1680
|
+
} else if (remove) await configuration.setDefaultModel(null, "default_embedding_model.txt");
|
|
1681
|
+
else {
|
|
1682
|
+
const resolved = await configuration.resolveAlias(selected);
|
|
1683
|
+
let entry;
|
|
1684
|
+
try {
|
|
1685
|
+
entry = service.resolve(resolved);
|
|
1686
|
+
} catch {
|
|
1687
|
+
}
|
|
1688
|
+
if (!entry?.model.capabilities?.includes("embed") || !entry.provider.embed && !entry.provider.embedSources) {
|
|
1689
|
+
await diagnostic(`Error: Unknown embedding model: ${selected}
|
|
1690
|
+
`);
|
|
1691
|
+
return 1;
|
|
1692
|
+
}
|
|
1693
|
+
await configuration.setDefaultModel(entry.model.id, "default_embedding_model.txt");
|
|
1694
|
+
}
|
|
1695
|
+
return 0;
|
|
1696
|
+
}
|
|
1697
|
+
const configured = await configuration.aliases();
|
|
1698
|
+
let emitted = false;
|
|
1699
|
+
for (const entry of service.models) {
|
|
1700
|
+
await step();
|
|
1701
|
+
if (!entry.model.capabilities?.includes("embed") || !entry.provider.embed && !entry.provider.embedSources) continue;
|
|
1702
|
+
const aliases = [...entry.model.aliases ?? []];
|
|
1703
|
+
for (const [alias, target] of Object.entries(configured)) {
|
|
1704
|
+
await step();
|
|
1705
|
+
if (target === entry.model.id) aliases.push(alias);
|
|
1706
|
+
}
|
|
1707
|
+
const description = `${entry.provider.name}: ${entry.model.id}`;
|
|
1708
|
+
const terms = [description, ...aliases].map((value) => value.toLowerCase());
|
|
1709
|
+
if (!queries.every((query) => terms.some((term) => term.includes(query)))) continue;
|
|
1710
|
+
await emit(description + (aliases.length ? ` (aliases: ${aliases.join(", ")})` : "") + "\n");
|
|
1711
|
+
emitted = true;
|
|
1712
|
+
}
|
|
1713
|
+
if (!emitted) await emit("\n");
|
|
1714
|
+
return 0;
|
|
1715
|
+
}
|
|
1716
|
+
|
|
1717
|
+
// packages/safe-bash-command-llm/src/usage.ts
|
|
1718
|
+
async function* serializeLlmTokenUsage(usage3, signal) {
|
|
1719
|
+
signal.throwIfAborted();
|
|
1720
|
+
const encoder = new TextEncoder();
|
|
1721
|
+
let separator = "";
|
|
1722
|
+
for (const name of ["input", "output"]) {
|
|
1723
|
+
const value = usage3?.[name];
|
|
1724
|
+
if (value === void 0 || value === null) continue;
|
|
1725
|
+
if (typeof value !== "number" || !Number.isFinite(value)) throw new TypeError(`Invalid LLM ${name} token count`);
|
|
1726
|
+
yield encoder.encode(`${separator}${value.toLocaleString("en-US", { maximumFractionDigits: 20 })} ${name}`);
|
|
1727
|
+
separator = ", ";
|
|
1728
|
+
}
|
|
1729
|
+
const details = usage3?.details;
|
|
1730
|
+
if (!details || typeof details !== "object") return;
|
|
1731
|
+
let nonempty = false;
|
|
1732
|
+
for (const key in details) if (Object.hasOwn(details, key)) {
|
|
1733
|
+
nonempty = true;
|
|
1734
|
+
break;
|
|
1735
|
+
}
|
|
1736
|
+
if (!nonempty) return;
|
|
1737
|
+
yield encoder.encode(separator);
|
|
1738
|
+
yield* referenceJson(details, signal);
|
|
1739
|
+
}
|
|
1740
|
+
|
|
1741
|
+
// packages/safe-bash-command-llm/src/input-budget.ts
|
|
1742
|
+
import { FsError as FsError3, shellValueByteLength as shellValueByteLength2 } from "../../safe-bash-contracts/index.js";
|
|
1743
|
+
function createLlmInputBudget(limits = {}, parent) {
|
|
1744
|
+
for (const [name, value] of Object.entries({ maxInputBytes: limits.maxInputBytes, maxBufferedInputBytes: limits.maxBufferedInputBytes })) {
|
|
1745
|
+
if (value !== void 0 && value !== Infinity && (!Number.isSafeInteger(value) || value < 0)) throw new RangeError(`Invalid LLM input limit: ${name}`);
|
|
1746
|
+
}
|
|
1747
|
+
const totalLimit = Math.min(limits.maxInputBytes ?? Infinity, parent?.maxBytes ?? Infinity);
|
|
1748
|
+
const bufferedLimit = limits.maxBufferedInputBytes ?? Infinity;
|
|
1749
|
+
let total = 0, buffered = 0;
|
|
1750
|
+
const check = (size, materialized = false) => {
|
|
1751
|
+
if (!Number.isSafeInteger(size) || size < 0) throw new RangeError("Invalid LLM input size");
|
|
1752
|
+
if (materialized && size > bufferedLimit - buffered) throw new FsError3("EFBIG", { message: "llm buffered input byte limit exceeded" });
|
|
1753
|
+
if (size > totalLimit - total) throw new FsError3("EFBIG", { message: "llm input byte limit exceeded" });
|
|
1754
|
+
parent?.check(total + size);
|
|
1755
|
+
};
|
|
1756
|
+
return {
|
|
1757
|
+
check,
|
|
1758
|
+
get totalBytes() {
|
|
1759
|
+
return total;
|
|
1760
|
+
},
|
|
1761
|
+
remaining(materialized = false) {
|
|
1762
|
+
return Math.min(totalLimit - total, materialized ? bufferedLimit - buffered : Infinity);
|
|
1763
|
+
},
|
|
1764
|
+
admit(size, materialized = false) {
|
|
1765
|
+
check(size, materialized);
|
|
1766
|
+
total += size;
|
|
1767
|
+
if (materialized) buffered += size;
|
|
1768
|
+
},
|
|
1769
|
+
/** Charge materialization of bytes already admitted as streamed input. */
|
|
1770
|
+
materialize(size) {
|
|
1771
|
+
if (!Number.isSafeInteger(size) || size < 0) throw new RangeError("Invalid LLM input size");
|
|
1772
|
+
if (size > bufferedLimit - buffered) throw new FsError3("EFBIG", { message: "llm buffered input byte limit exceeded" });
|
|
1773
|
+
buffered += size;
|
|
1774
|
+
},
|
|
1775
|
+
admitText(text) {
|
|
1776
|
+
const size = shellValueByteLength2(text);
|
|
1777
|
+
check(size, true);
|
|
1778
|
+
total += size;
|
|
1779
|
+
buffered += size;
|
|
1780
|
+
}
|
|
1781
|
+
};
|
|
1782
|
+
}
|
|
1783
|
+
|
|
1784
|
+
// packages/safe-bash-command-llm/src/command.ts
|
|
1785
|
+
import { pipeBytes as pipeBytes2, createOutputOperation, getCommandArguments, shellValueByteLength as shellValueByteLength3, FsError as FsError6 } from "../../safe-bash-contracts/index.js";
|
|
1786
|
+
import { inheritYieldCheckpoint as inheritYieldCheckpoint4, yieldTurn as yieldTurn11 } from "../../safe-bash-contracts/yield.js";
|
|
1787
|
+
import { writeDiagnostic as writeDiagnostic2 } from "../../safe-bash-contracts/escaping.js";
|
|
1788
|
+
import { pathOf as pathOf3 } from "../../safe-bash-contracts/path.js";
|
|
1789
|
+
|
|
1790
|
+
// packages/safe-bash-command-llm/src/templates.ts
|
|
1791
|
+
import { FsError as FsError4 } from "../../safe-bash-contracts/index.js";
|
|
1792
|
+
import { pathOf } from "../../safe-bash-contracts/path.js";
|
|
1793
|
+
function unicodeOrder(left, right) {
|
|
1794
|
+
let a = 0, b = 0;
|
|
1795
|
+
while (a < left.length && b < right.length) {
|
|
1796
|
+
const x = left.codePointAt(a), y = right.codePointAt(b);
|
|
1797
|
+
if (x !== y) return x - y;
|
|
1798
|
+
a += x > 65535 ? 2 : 1;
|
|
1799
|
+
b += y > 65535 ? 2 : 1;
|
|
1800
|
+
}
|
|
1801
|
+
return (a < left.length ? 1 : 0) - (b < right.length ? 1 : 0);
|
|
1802
|
+
}
|
|
1803
|
+
var templateFields = ["name", "prompt", "system", "model", "defaults", "options", "attachments", "attachment_types", "extract", "extract_last", "schema_object", "fragments", "system_fragments", "tools", "functions"];
|
|
1804
|
+
function template(value, name) {
|
|
1805
|
+
if (typeof value === "string") return { name, prompt: value };
|
|
1806
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error(`Invalid template: ${name}`);
|
|
1807
|
+
const fields = { ...value, name };
|
|
1808
|
+
for (const [key, item] of Object.entries(fields)) {
|
|
1809
|
+
if (!templateFields.includes(key)) throw new Error(`Unsupported template field: ${key}`);
|
|
1810
|
+
if (item === null) {
|
|
1811
|
+
delete fields[key];
|
|
1812
|
+
continue;
|
|
1813
|
+
}
|
|
1814
|
+
if (["attachments", "fragments", "system_fragments", "tools"].includes(key)) {
|
|
1815
|
+
if (!Array.isArray(item) || item.some((value2) => typeof value2 !== "string")) throw new Error(`Invalid template: ${name}`);
|
|
1816
|
+
} else if (key === "attachment_types") {
|
|
1817
|
+
if (!Array.isArray(item) || item.some((value2) => !value2 || typeof value2 !== "object" || Array.isArray(value2) || typeof value2.type !== "string" || typeof value2.value !== "string")) throw new Error(`Invalid template: ${name}`);
|
|
1818
|
+
fields[key] = item.map(({ type, value: value2 }) => ({ type, value: value2 }));
|
|
1819
|
+
} else if (["defaults", "options"].includes(key)) {
|
|
1820
|
+
if (!item || typeof item !== "object" || Array.isArray(item)) throw new Error(`Invalid template: ${name}`);
|
|
1821
|
+
} else if (key === "schema_object") {
|
|
1822
|
+
if (typeof item !== "object" || Array.isArray(item)) throw new Error(`Invalid template: ${name}`);
|
|
1823
|
+
} else if (["extract", "extract_last"].includes(key)) {
|
|
1824
|
+
if (typeof item !== "boolean") throw new Error(`Invalid template: ${name}`);
|
|
1825
|
+
} else if (typeof item !== "string") throw new Error(`Invalid template: ${name}`);
|
|
1826
|
+
}
|
|
1827
|
+
return { ...fields, name };
|
|
1828
|
+
}
|
|
1829
|
+
function interpolate(text, params, validateOnly = false, admitText) {
|
|
1830
|
+
if (!text) return text;
|
|
1831
|
+
let result = "";
|
|
1832
|
+
const append = (value) => {
|
|
1833
|
+
if (!validateOnly) {
|
|
1834
|
+
admitText?.(value);
|
|
1835
|
+
result += value;
|
|
1836
|
+
}
|
|
1837
|
+
};
|
|
1838
|
+
const missing = [];
|
|
1839
|
+
for (let index = 0; index < text.length; index++) {
|
|
1840
|
+
if (text[index] !== "$") {
|
|
1841
|
+
const point = text.codePointAt(index);
|
|
1842
|
+
const literal = String.fromCodePoint(point);
|
|
1843
|
+
append(literal);
|
|
1844
|
+
if (point > 65535) index++;
|
|
1845
|
+
continue;
|
|
1846
|
+
}
|
|
1847
|
+
if (text[index + 1] === "$") {
|
|
1848
|
+
append("$");
|
|
1849
|
+
index++;
|
|
1850
|
+
continue;
|
|
1851
|
+
}
|
|
1852
|
+
const start = index, braced = text[index + 1] === "{";
|
|
1853
|
+
if (braced) index++;
|
|
1854
|
+
let name = "";
|
|
1855
|
+
while (index + 1 < text.length && "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_".includes(text[index + 1])) name += text[++index];
|
|
1856
|
+
if (!name || "0123456789".includes(name[0]) || braced && text[index + 1] !== "}") throw new Error(`Invalid placeholder in template at position ${start}`);
|
|
1857
|
+
if (braced) index++;
|
|
1858
|
+
if (!Object.hasOwn(params, name)) {
|
|
1859
|
+
if (!missing.includes(name)) missing.push(name);
|
|
1860
|
+
} else if (!validateOnly) append(String(params[name]));
|
|
1861
|
+
}
|
|
1862
|
+
if (missing.length) throw new Error(`Missing variables: ${missing.join(", ")}`);
|
|
1863
|
+
return result;
|
|
1864
|
+
}
|
|
1865
|
+
function validateLlmTemplateParameters(value, params) {
|
|
1866
|
+
const variables = { ...value.defaults, ...params, input: "" };
|
|
1867
|
+
for (const text of [value.prompt, value.system]) interpolate(text, variables, true);
|
|
1868
|
+
}
|
|
1869
|
+
function llmTemplateUsesInput(value) {
|
|
1870
|
+
for (const text of [value.prompt, value.system]) {
|
|
1871
|
+
if (!text) continue;
|
|
1872
|
+
for (let index = 0; index < text.length; index++) {
|
|
1873
|
+
if (text[index] !== "$") continue;
|
|
1874
|
+
if (text[index + 1] === "$") {
|
|
1875
|
+
index++;
|
|
1876
|
+
continue;
|
|
1877
|
+
}
|
|
1878
|
+
let name = "";
|
|
1879
|
+
while (index + 1 < text.length && "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_".includes(text[index + 1])) name += text[++index];
|
|
1880
|
+
if (name === "input") return true;
|
|
1881
|
+
}
|
|
1882
|
+
}
|
|
1883
|
+
return false;
|
|
1884
|
+
}
|
|
1885
|
+
function evaluateLlmTemplate(value, input, params, admitText) {
|
|
1886
|
+
const variables = { ...value.defaults, ...params, input };
|
|
1887
|
+
if (!value.prompt) admitText?.(input);
|
|
1888
|
+
return { prompt: value.prompt ? interpolate(value.prompt, variables, false, admitText) : input, ...value.system === void 0 ? {} : { system: interpolate(value.system, variables, false, admitText) } };
|
|
1889
|
+
}
|
|
1890
|
+
function abortLoader(start, signal, late) {
|
|
1891
|
+
signal.throwIfAborted();
|
|
1892
|
+
return new Promise((resolve, reject) => {
|
|
1893
|
+
const abort = () => {
|
|
1894
|
+
signal.removeEventListener("abort", abort);
|
|
1895
|
+
reject(signal.reason);
|
|
1896
|
+
};
|
|
1897
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
1898
|
+
Promise.resolve().then(() => {
|
|
1899
|
+
signal.throwIfAborted();
|
|
1900
|
+
return start();
|
|
1901
|
+
}).then((value) => {
|
|
1902
|
+
signal.removeEventListener("abort", abort);
|
|
1903
|
+
if (signal.aborted) {
|
|
1904
|
+
if (late) void Promise.resolve().then(() => late(value)).catch(() => void 0);
|
|
1905
|
+
reject(signal.reason);
|
|
1906
|
+
} else resolve(value);
|
|
1907
|
+
}, (error) => {
|
|
1908
|
+
signal.removeEventListener("abort", abort);
|
|
1909
|
+
reject(signal.aborted ? signal.reason : error);
|
|
1910
|
+
});
|
|
1911
|
+
if (signal.aborted) abort();
|
|
1912
|
+
});
|
|
1913
|
+
}
|
|
1914
|
+
function createLlmTemplateStore(context, loaders) {
|
|
1915
|
+
const directory = `${createLlmConfiguration(context).directory}/templates`;
|
|
1916
|
+
const filename = (name) => {
|
|
1917
|
+
if (!name || name.includes("/") || name.includes("\\") || name === "." || name === "..") throw new Error(`Invalid template name: ${name}`);
|
|
1918
|
+
return `${directory}/${name}.yaml`;
|
|
1919
|
+
};
|
|
1920
|
+
const load = async (name) => {
|
|
1921
|
+
try {
|
|
1922
|
+
context.signal.throwIfAborted();
|
|
1923
|
+
if (name.startsWith("https://") || name.startsWith("http://")) {
|
|
1924
|
+
const fetch = context.fetch ?? context.capabilities?.fetch;
|
|
1925
|
+
if (!fetch) throw new Error("Template URL loading is not configured");
|
|
1926
|
+
if (!loaders || loaders.maxRemoteBytes !== Infinity && (!Number.isSafeInteger(loaders.maxRemoteBytes) || loaders.maxRemoteBytes < 1)) throw new Error("Template URL byte limit is not configured");
|
|
1927
|
+
const materializedLimit = loaders.maxBytes ?? Infinity;
|
|
1928
|
+
let response, failed = false;
|
|
1929
|
+
let reader;
|
|
1930
|
+
const abort = () => {
|
|
1931
|
+
void reader?.cancel().catch(() => {
|
|
1932
|
+
});
|
|
1933
|
+
};
|
|
1934
|
+
try {
|
|
1935
|
+
response = await abortLoader(() => fetch(name, { signal: context.signal }), context.signal, async (response2) => {
|
|
1936
|
+
await response2.body?.cancel();
|
|
1937
|
+
});
|
|
1938
|
+
if (!response.ok) {
|
|
1939
|
+
const kind = response.status < 500 ? "Client" : "Server";
|
|
1940
|
+
throw new Error(`${kind} error '${response.status} ${response.statusText}' for url '${name}'
|
|
1941
|
+
For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/${response.status}`);
|
|
1942
|
+
}
|
|
1943
|
+
reader = response.body?.getReader();
|
|
1944
|
+
context.signal.addEventListener("abort", abort, { once: true });
|
|
1945
|
+
context.signal.throwIfAborted();
|
|
1946
|
+
const decoder = new TextDecoder("utf-8", { fatal: true });
|
|
1947
|
+
const chunks = [];
|
|
1948
|
+
let total = 0;
|
|
1949
|
+
while (reader) {
|
|
1950
|
+
context.signal.throwIfAborted();
|
|
1951
|
+
const next = await abortLoader(() => reader.read(), context.signal);
|
|
1952
|
+
context.signal.throwIfAborted();
|
|
1953
|
+
if (next.done) break;
|
|
1954
|
+
total += next.value.byteLength;
|
|
1955
|
+
if (total > loaders.maxRemoteBytes) throw new RangeError("Template URL exceeds byte limit");
|
|
1956
|
+
if (total > materializedLimit) throw new FsError4("EFBIG", { message: "llm buffered input byte limit exceeded" });
|
|
1957
|
+
loaders.admitBytes?.(next.value.byteLength);
|
|
1958
|
+
chunks.push(decoder.decode(next.value, { stream: true }));
|
|
1959
|
+
}
|
|
1960
|
+
chunks.push(decoder.decode());
|
|
1961
|
+
const { parse: parse3 } = await import("../bundled-yaml/index.js");
|
|
1962
|
+
const value = template(parse3(chunks.join("")), name);
|
|
1963
|
+
Object.defineProperty(value, "functionsTrusted", { value: false });
|
|
1964
|
+
return value;
|
|
1965
|
+
} catch (error) {
|
|
1966
|
+
failed = true;
|
|
1967
|
+
context.signal.throwIfAborted();
|
|
1968
|
+
throw new Error(`Could not load template ${name}: ${error instanceof Error ? error.message : String(error)}`);
|
|
1969
|
+
} finally {
|
|
1970
|
+
context.signal.removeEventListener("abort", abort);
|
|
1971
|
+
if (reader) {
|
|
1972
|
+
const cancelled = reader.cancel();
|
|
1973
|
+
if (context.signal.aborted) {
|
|
1974
|
+
void cancelled.catch(() => void 0);
|
|
1975
|
+
reader.releaseLock();
|
|
1976
|
+
} else try {
|
|
1977
|
+
await cancelled.catch((error) => {
|
|
1978
|
+
if (!failed) throw error;
|
|
1979
|
+
});
|
|
1980
|
+
} finally {
|
|
1981
|
+
reader.releaseLock();
|
|
1982
|
+
}
|
|
1983
|
+
} else if (response?.body) {
|
|
1984
|
+
const cancelled = response.body.cancel();
|
|
1985
|
+
if (context.signal.aborted) void cancelled.catch(() => void 0);
|
|
1986
|
+
else await cancelled.catch((error) => {
|
|
1987
|
+
if (!failed) throw error;
|
|
1988
|
+
});
|
|
1989
|
+
}
|
|
1990
|
+
}
|
|
1991
|
+
}
|
|
1992
|
+
const { parse: parse2 } = await import("../bundled-yaml/index.js");
|
|
1993
|
+
let path = pathOf(context, name);
|
|
1994
|
+
try {
|
|
1995
|
+
await context.fs.stat(path, { signal: context.signal });
|
|
1996
|
+
} catch (error) {
|
|
1997
|
+
if (!(error instanceof FsError4) || error.code !== "ENOENT") throw error;
|
|
1998
|
+
const colon = name.indexOf(":");
|
|
1999
|
+
if (colon > 0) {
|
|
2000
|
+
const prefix = name.slice(0, colon);
|
|
2001
|
+
let valid = true;
|
|
2002
|
+
for (const letter of prefix) if (!"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-".includes(letter)) {
|
|
2003
|
+
valid = false;
|
|
2004
|
+
break;
|
|
2005
|
+
}
|
|
2006
|
+
if (valid) {
|
|
2007
|
+
const loader = loaders?.loaders?.get(prefix);
|
|
2008
|
+
if (!loader) throw new Error(`Unknown template prefix: ${prefix}`);
|
|
2009
|
+
try {
|
|
2010
|
+
const loaded = await abortLoader(() => loader(name.slice(colon + 1), context.signal), context.signal);
|
|
2011
|
+
context.signal.throwIfAborted();
|
|
2012
|
+
const materializedLimit = loaders?.maxBytes ?? Infinity;
|
|
2013
|
+
let loadedBytes = 0;
|
|
2014
|
+
if (loaders?.admitBytes || materializedLimit !== Infinity) for await (const bytes2 of jsonValue(loaded, context.signal)) {
|
|
2015
|
+
loadedBytes += bytes2.byteLength;
|
|
2016
|
+
if (loadedBytes > materializedLimit) throw new FsError4("EFBIG", { message: "llm buffered input byte limit exceeded" });
|
|
2017
|
+
loaders?.admitBytes?.(bytes2.byteLength);
|
|
2018
|
+
}
|
|
2019
|
+
const value = template(loaded, loaded.name);
|
|
2020
|
+
Object.defineProperty(value, "functionsTrusted", { value: false });
|
|
2021
|
+
return value;
|
|
2022
|
+
} catch (error2) {
|
|
2023
|
+
context.signal.throwIfAborted();
|
|
2024
|
+
throw new Error(`Could not load template ${name}: ${error2 instanceof Error ? error2.message : String(error2)}`);
|
|
2025
|
+
}
|
|
2026
|
+
}
|
|
2027
|
+
}
|
|
2028
|
+
path = filename(name);
|
|
2029
|
+
}
|
|
2030
|
+
const size = (await context.fs.stat(path, { signal: context.signal })).size;
|
|
2031
|
+
if (size > (loaders?.maxBytes ?? Infinity)) throw new FsError4("EFBIG", { message: "llm buffered input byte limit exceeded" });
|
|
2032
|
+
const bytes = await context.fs.readFile(path, { signal: context.signal, ...loaders?.maxBytes === void 0 || loaders.maxBytes === Infinity ? {} : { maxBytes: loaders.maxBytes } });
|
|
2033
|
+
loaders?.admitBytes?.(bytes.byteLength);
|
|
2034
|
+
return template(parse2(new TextDecoder("utf-8", { fatal: true }).decode(bytes)), name);
|
|
2035
|
+
} catch (error) {
|
|
2036
|
+
if (error instanceof FsError4 && error.code === "ENOENT") throw new Error(`Invalid template: ${name}`);
|
|
2037
|
+
throw error;
|
|
2038
|
+
}
|
|
2039
|
+
};
|
|
2040
|
+
const publish = async (name, bytes) => {
|
|
2041
|
+
const path = filename(name);
|
|
2042
|
+
await context.fs.mkdir(directory, { recursive: true, signal: context.signal });
|
|
2043
|
+
const parent = await context.fs.stat(directory, { signal: context.signal });
|
|
2044
|
+
let expected;
|
|
2045
|
+
try {
|
|
2046
|
+
expected = await context.fs.lstat(path, { signal: context.signal });
|
|
2047
|
+
} catch (error) {
|
|
2048
|
+
if (!(error instanceof FsError4) || error.code !== "ENOENT") throw error;
|
|
2049
|
+
expected = null;
|
|
2050
|
+
}
|
|
2051
|
+
await publishConfiguration(context.fs, directory, path, bytes, parent, expected, context.signal);
|
|
2052
|
+
};
|
|
2053
|
+
return {
|
|
2054
|
+
directory,
|
|
2055
|
+
load,
|
|
2056
|
+
async save(name, value) {
|
|
2057
|
+
const { stringify } = await import("../bundled-yaml/index.js");
|
|
2058
|
+
await publish(name, new TextEncoder().encode(stringify(value, { indent: 4, lineWidth: 0 })));
|
|
2059
|
+
},
|
|
2060
|
+
async command(args, output, diagnostic) {
|
|
2061
|
+
const actions = ["list", "edit", "loaders", "path", "show"];
|
|
2062
|
+
const grouped = args.length === 1 && ["--help", "-h"].includes(args[0]);
|
|
2063
|
+
const routed = args[0] === "--" ? args.slice(1) : args;
|
|
2064
|
+
const explicit = actions.includes(routed[0] ?? "");
|
|
2065
|
+
const command = explicit ? routed[0] : "list";
|
|
2066
|
+
const tokens = explicit ? routed.slice(1) : routed;
|
|
2067
|
+
const descriptions = {
|
|
2068
|
+
list: "List available prompt templates",
|
|
2069
|
+
edit: "Edit the specified prompt template using the default $EDITOR",
|
|
2070
|
+
loaders: "Show template loaders registered by plugins",
|
|
2071
|
+
path: "Output the path to the templates directory",
|
|
2072
|
+
show: "Show the specified prompt template"
|
|
2073
|
+
};
|
|
2074
|
+
const usage3 = `Usage: llm templates ${command} [OPTIONS]${["show", "edit"].includes(command) ? " NAME" : ""}
|
|
2075
|
+
`;
|
|
2076
|
+
if (grouped) {
|
|
2077
|
+
await output("Usage: llm templates [OPTIONS] COMMAND [ARGS]...\n\n Manage stored prompt templates\n\nOptions:\n -h, --help Show this message and exit.\n\nCommands:\n list* List available prompt templates\n edit Edit the specified prompt template using the default $EDITOR\n loaders Show template loaders registered by plugins\n path Output the path to the templates directory\n show Show the specified prompt template\n");
|
|
2078
|
+
return 0;
|
|
2079
|
+
}
|
|
2080
|
+
let optionsEnded = false;
|
|
2081
|
+
const operands = [];
|
|
2082
|
+
let failure;
|
|
2083
|
+
let help2 = false, showUsage = true;
|
|
2084
|
+
for (const token of tokens) {
|
|
2085
|
+
context.signal.throwIfAborted();
|
|
2086
|
+
if (!optionsEnded && token === "--") optionsEnded = true;
|
|
2087
|
+
else if (!optionsEnded && token === "--help") help2 = true;
|
|
2088
|
+
else if (!optionsEnded && token.startsWith("--help=")) {
|
|
2089
|
+
failure = "Option '--help' does not take a value.";
|
|
2090
|
+
showUsage = false;
|
|
2091
|
+
break;
|
|
2092
|
+
} else if (!optionsEnded && token.startsWith("-") && !token.startsWith("--") && token !== "-") {
|
|
2093
|
+
for (const letter of token.slice(1)) {
|
|
2094
|
+
if (letter === "h") help2 = true;
|
|
2095
|
+
else {
|
|
2096
|
+
failure = `No such option: -${letter}`;
|
|
2097
|
+
break;
|
|
2098
|
+
}
|
|
2099
|
+
}
|
|
2100
|
+
if (failure) break;
|
|
2101
|
+
} else if (!optionsEnded && token.startsWith("-") && token !== "-") {
|
|
2102
|
+
failure = `No such option: ${token.split("=")[0]}`;
|
|
2103
|
+
break;
|
|
2104
|
+
} else operands.push(token);
|
|
2105
|
+
}
|
|
2106
|
+
if (help2 && !failure) {
|
|
2107
|
+
await output(usage3 + `
|
|
2108
|
+
${descriptions[command]}
|
|
2109
|
+
|
|
2110
|
+
Options:
|
|
2111
|
+
-h, --help Show this message and exit.
|
|
2112
|
+
`);
|
|
2113
|
+
return 0;
|
|
2114
|
+
}
|
|
2115
|
+
const needsName = ["show", "edit"].includes(command);
|
|
2116
|
+
failure ??= needsName && !operands.length ? "Missing argument 'NAME'." : operands.length > (needsName ? 1 : 0) ? `Got unexpected extra argument (${operands[needsName ? 1 : 0]})` : void 0;
|
|
2117
|
+
if (failure) {
|
|
2118
|
+
await diagnostic((showUsage ? usage3 + `Try 'llm templates ${command} -h' for help.
|
|
2119
|
+
|
|
2120
|
+
` : "") + `Error: ${failure}
|
|
2121
|
+
`);
|
|
2122
|
+
return 2;
|
|
2123
|
+
}
|
|
2124
|
+
const name = operands[0];
|
|
2125
|
+
if (command === "loaders") {
|
|
2126
|
+
if (!loaders?.loaders?.size) await output("No template loaders found\n");
|
|
2127
|
+
else for (const [prefix, loader] of loaders.loaders) {
|
|
2128
|
+
context.signal.throwIfAborted();
|
|
2129
|
+
const lines = (loader.description || "Undocumented").split("\n");
|
|
2130
|
+
let margin;
|
|
2131
|
+
for (const line of lines) {
|
|
2132
|
+
if (!line.trim()) continue;
|
|
2133
|
+
let length = 0;
|
|
2134
|
+
while (length < line.length && (line[length] === " " || line[length] === " ")) length++;
|
|
2135
|
+
const leading = line.slice(0, length);
|
|
2136
|
+
if (margin === void 0) margin = leading;
|
|
2137
|
+
else {
|
|
2138
|
+
let common = 0;
|
|
2139
|
+
while (common < margin.length && common < leading.length && margin[common] === leading[common]) common++;
|
|
2140
|
+
margin = margin.slice(0, common);
|
|
2141
|
+
}
|
|
2142
|
+
}
|
|
2143
|
+
const docs = lines.map((line) => line.trim() ? line.slice(margin?.length ?? 0) : "").join("\n").trim();
|
|
2144
|
+
await output(prefix + ":\n" + docs.split("\n").map((line) => line.trim() ? " " + line : line).join("\n") + "\n");
|
|
2145
|
+
}
|
|
2146
|
+
return 0;
|
|
2147
|
+
}
|
|
2148
|
+
if (command === "path") {
|
|
2149
|
+
await output(directory + "\n");
|
|
2150
|
+
return 0;
|
|
2151
|
+
}
|
|
2152
|
+
if (command === "show" && name) {
|
|
2153
|
+
let value;
|
|
2154
|
+
try {
|
|
2155
|
+
value = await load(name);
|
|
2156
|
+
} catch {
|
|
2157
|
+
throw new Error(`Template '${name}' not found or invalid`);
|
|
2158
|
+
}
|
|
2159
|
+
const { templateYaml } = await import("./template-yaml-2YVS7IVT.js");
|
|
2160
|
+
await output(templateYaml(value));
|
|
2161
|
+
return 0;
|
|
2162
|
+
}
|
|
2163
|
+
if (command === "edit") {
|
|
2164
|
+
if (!context.invoke) throw new Error("Template editor is not configured");
|
|
2165
|
+
const path = filename(name);
|
|
2166
|
+
try {
|
|
2167
|
+
await context.fs.lstat(path, { signal: context.signal });
|
|
2168
|
+
} catch (error) {
|
|
2169
|
+
if (!(error instanceof FsError4) || error.code !== "ENOENT") throw error;
|
|
2170
|
+
await publish(name, new TextEncoder().encode("prompt: "));
|
|
2171
|
+
}
|
|
2172
|
+
const editor = context.env.VISUAL || context.env.EDITOR || "vi";
|
|
2173
|
+
const result = await context.invoke("sh", ["-c", editor + ' "$1"', "llm-template-editor", path], {
|
|
2174
|
+
signal: context.signal,
|
|
2175
|
+
cwd: context.cwd,
|
|
2176
|
+
env: context.env,
|
|
2177
|
+
replaceEnv: true,
|
|
2178
|
+
...context.stdin ? { stdin: context.stdin } : {},
|
|
2179
|
+
...context.stdout ? { stdout: context.stdout } : {},
|
|
2180
|
+
...context.stderr ? { stderr: context.stderr } : {},
|
|
2181
|
+
externalInvocation: true
|
|
2182
|
+
});
|
|
2183
|
+
context.signal.throwIfAborted();
|
|
2184
|
+
if (result.exitCode !== 0) throw new Error("Editing failed!");
|
|
2185
|
+
await load(name);
|
|
2186
|
+
return 0;
|
|
2187
|
+
}
|
|
2188
|
+
let files;
|
|
2189
|
+
try {
|
|
2190
|
+
files = await context.fs.readdir(directory, { signal: context.signal });
|
|
2191
|
+
} catch (error) {
|
|
2192
|
+
if (error instanceof FsError4 && error.code === "ENOENT") return 0;
|
|
2193
|
+
throw error;
|
|
2194
|
+
}
|
|
2195
|
+
const values = [];
|
|
2196
|
+
for (const file of files) {
|
|
2197
|
+
if (file.type !== "file" || !file.name.endsWith(".yaml")) continue;
|
|
2198
|
+
try {
|
|
2199
|
+
values.push(await load(file.name.slice(0, -5)));
|
|
2200
|
+
} catch {
|
|
2201
|
+
context.signal.throwIfAborted();
|
|
2202
|
+
}
|
|
2203
|
+
}
|
|
2204
|
+
const width = Math.max(0, ...values.map((value) => [...value.name].length));
|
|
2205
|
+
for (const value of values.sort((a, b) => unicodeOrder(a.name, b.name))) {
|
|
2206
|
+
const description = (value.system ? `system: ${value.system}${value.prompt ? ` prompt: ${value.prompt}` : ""}` : value.prompt ?? "").split("\n").join(" ");
|
|
2207
|
+
let suppliedColumns = NaN;
|
|
2208
|
+
const columnText = (context.env.COLUMNS ?? "").trim();
|
|
2209
|
+
const digits = columnText.startsWith("+") || columnText.startsWith("-") ? columnText.slice(1) : columnText;
|
|
2210
|
+
let valid = digits.length > 0;
|
|
2211
|
+
for (const digit of digits) if (!"0123456789".includes(digit)) {
|
|
2212
|
+
valid = false;
|
|
2213
|
+
break;
|
|
2214
|
+
}
|
|
2215
|
+
if (valid) suppliedColumns = Number(columnText);
|
|
2216
|
+
const columns = Number.isSafeInteger(suppliedColumns) && suppliedColumns > 0 ? suppliedColumns : 80;
|
|
2217
|
+
const text = `${value.name}${" ".repeat(width - [...value.name].length)} : ${description}`;
|
|
2218
|
+
const points = [...text];
|
|
2219
|
+
const truncated = points.length > columns ? points.slice(0, Math.max(0, columns - 3)).join("") + "..." : text;
|
|
2220
|
+
await output(truncated + "\n");
|
|
2221
|
+
}
|
|
2222
|
+
return 0;
|
|
2223
|
+
}
|
|
2224
|
+
};
|
|
2225
|
+
}
|
|
2226
|
+
|
|
2227
|
+
// packages/safe-bash-command-llm/src/extract-range.ts
|
|
2228
|
+
import { yieldTurn as yieldTurn9 } from "../../safe-bash-contracts/yield.js";
|
|
2229
|
+
|
|
2230
|
+
// packages/safe-bash-command-llm/src/word-ranges.ts
|
|
2231
|
+
var wordRanges = [[48, 57], [65, 90], [95, 95], [97, 122], [170, 170], [178, 179], [181, 181], [185, 186], [188, 190], [192, 214], [216, 246], [248, 705], [710, 721], [736, 740], [748, 748], [750, 750], [880, 884], [886, 887], [890, 893], [895, 895], [902, 902], [904, 906], [908, 908], [910, 929], [931, 1013], [1015, 1153], [1162, 1327], [1329, 1366], [1369, 1369], [1376, 1416], [1488, 1514], [1519, 1522], [1568, 1610], [1632, 1641], [1646, 1647], [1649, 1747], [1749, 1749], [1765, 1766], [1774, 1788], [1791, 1791], [1808, 1808], [1810, 1839], [1869, 1957], [1969, 1969], [1984, 2026], [2036, 2037], [2042, 2042], [2048, 2069], [2074, 2074], [2084, 2084], [2088, 2088], [2112, 2136], [2144, 2154], [2208, 2228], [2230, 2247], [2308, 2361], [2365, 2365], [2384, 2384], [2392, 2401], [2406, 2415], [2417, 2432], [2437, 2444], [2447, 2448], [2451, 2472], [2474, 2480], [2482, 2482], [2486, 2489], [2493, 2493], [2510, 2510], [2524, 2525], [2527, 2529], [2534, 2545], [2548, 2553], [2556, 2556], [2565, 2570], [2575, 2576], [2579, 2600], [2602, 2608], [2610, 2611], [2613, 2614], [2616, 2617], [2649, 2652], [2654, 2654], [2662, 2671], [2674, 2676], [2693, 2701], [2703, 2705], [2707, 2728], [2730, 2736], [2738, 2739], [2741, 2745], [2749, 2749], [2768, 2768], [2784, 2785], [2790, 2799], [2809, 2809], [2821, 2828], [2831, 2832], [2835, 2856], [2858, 2864], [2866, 2867], [2869, 2873], [2877, 2877], [2908, 2909], [2911, 2913], [2918, 2927], [2929, 2935], [2947, 2947], [2949, 2954], [2958, 2960], [2962, 2965], [2969, 2970], [2972, 2972], [2974, 2975], [2979, 2980], [2984, 2986], [2990, 3001], [3024, 3024], [3046, 3058], [3077, 3084], [3086, 3088], [3090, 3112], [3114, 3129], [3133, 3133], [3160, 3162], [3168, 3169], [3174, 3183], [3192, 3198], [3200, 3200], [3205, 3212], [3214, 3216], [3218, 3240], [3242, 3251], [3253, 3257], [3261, 3261], [3294, 3294], [3296, 3297], [3302, 3311], [3313, 3314], [3332, 3340], [3342, 3344], [3346, 3386], [3389, 3389], [3406, 3406], [3412, 3414], [3416, 3425], [3430, 3448], [3450, 3455], [3461, 3478], [3482, 3505], [3507, 3515], [3517, 3517], [3520, 3526], [3558, 3567], [3585, 3632], [3634, 3635], [3648, 3654], [3664, 3673], [3713, 3714], [3716, 3716], [3718, 3722], [3724, 3747], [3749, 3749], [3751, 3760], [3762, 3763], [3773, 3773], [3776, 3780], [3782, 3782], [3792, 3801], [3804, 3807], [3840, 3840], [3872, 3891], [3904, 3911], [3913, 3948], [3976, 3980], [4096, 4138], [4159, 4169], [4176, 4181], [4186, 4189], [4193, 4193], [4197, 4198], [4206, 4208], [4213, 4225], [4238, 4238], [4240, 4249], [4256, 4293], [4295, 4295], [4301, 4301], [4304, 4346], [4348, 4680], [4682, 4685], [4688, 4694], [4696, 4696], [4698, 4701], [4704, 4744], [4746, 4749], [4752, 4784], [4786, 4789], [4792, 4798], [4800, 4800], [4802, 4805], [4808, 4822], [4824, 4880], [4882, 4885], [4888, 4954], [4969, 4988], [4992, 5007], [5024, 5109], [5112, 5117], [5121, 5740], [5743, 5759], [5761, 5786], [5792, 5866], [5870, 5880], [5888, 5900], [5902, 5905], [5920, 5937], [5952, 5969], [5984, 5996], [5998, 6e3], [6016, 6067], [6103, 6103], [6108, 6108], [6112, 6121], [6128, 6137], [6160, 6169], [6176, 6264], [6272, 6276], [6279, 6312], [6314, 6314], [6320, 6389], [6400, 6430], [6470, 6509], [6512, 6516], [6528, 6571], [6576, 6601], [6608, 6618], [6656, 6678], [6688, 6740], [6784, 6793], [6800, 6809], [6823, 6823], [6917, 6963], [6981, 6987], [6992, 7001], [7043, 7072], [7086, 7141], [7168, 7203], [7232, 7241], [7245, 7293], [7296, 7304], [7312, 7354], [7357, 7359], [7401, 7404], [7406, 7411], [7413, 7414], [7418, 7418], [7424, 7615], [7680, 7957], [7960, 7965], [7968, 8005], [8008, 8013], [8016, 8023], [8025, 8025], [8027, 8027], [8029, 8029], [8031, 8061], [8064, 8116], [8118, 8124], [8126, 8126], [8130, 8132], [8134, 8140], [8144, 8147], [8150, 8155], [8160, 8172], [8178, 8180], [8182, 8188], [8304, 8305], [8308, 8313], [8319, 8329], [8336, 8348], [8450, 8450], [8455, 8455], [8458, 8467], [8469, 8469], [8473, 8477], [8484, 8484], [8486, 8486], [8488, 8488], [8490, 8493], [8495, 8505], [8508, 8511], [8517, 8521], [8526, 8526], [8528, 8585], [9312, 9371], [9450, 9471], [10102, 10131], [11264, 11310], [11312, 11358], [11360, 11492], [11499, 11502], [11506, 11507], [11517, 11517], [11520, 11557], [11559, 11559], [11565, 11565], [11568, 11623], [11631, 11631], [11648, 11670], [11680, 11686], [11688, 11694], [11696, 11702], [11704, 11710], [11712, 11718], [11720, 11726], [11728, 11734], [11736, 11742], [11823, 11823], [12293, 12295], [12321, 12329], [12337, 12341], [12344, 12348], [12353, 12438], [12445, 12447], [12449, 12538], [12540, 12543], [12549, 12591], [12593, 12686], [12690, 12693], [12704, 12735], [12784, 12799], [12832, 12841], [12872, 12879], [12881, 12895], [12928, 12937], [12977, 12991], [13312, 19903], [19968, 40956], [40960, 42124], [42192, 42237], [42240, 42508], [42512, 42539], [42560, 42606], [42623, 42653], [42656, 42735], [42775, 42783], [42786, 42888], [42891, 42943], [42946, 42954], [42997, 43009], [43011, 43013], [43015, 43018], [43020, 43042], [43056, 43061], [43072, 43123], [43138, 43187], [43216, 43225], [43250, 43255], [43259, 43259], [43261, 43262], [43264, 43301], [43312, 43334], [43360, 43388], [43396, 43442], [43471, 43481], [43488, 43492], [43494, 43518], [43520, 43560], [43584, 43586], [43588, 43595], [43600, 43609], [43616, 43638], [43642, 43642], [43646, 43695], [43697, 43697], [43701, 43702], [43705, 43709], [43712, 43712], [43714, 43714], [43739, 43741], [43744, 43754], [43762, 43764], [43777, 43782], [43785, 43790], [43793, 43798], [43808, 43814], [43816, 43822], [43824, 43866], [43868, 43881], [43888, 44002], [44016, 44025], [44032, 55203], [55216, 55238], [55243, 55291], [63744, 64109], [64112, 64217], [64256, 64262], [64275, 64279], [64285, 64285], [64287, 64296], [64298, 64310], [64312, 64316], [64318, 64318], [64320, 64321], [64323, 64324], [64326, 64433], [64467, 64829], [64848, 64911], [64914, 64967], [65008, 65019], [65136, 65140], [65142, 65276], [65296, 65305], [65313, 65338], [65345, 65370], [65382, 65470], [65474, 65479], [65482, 65487], [65490, 65495], [65498, 65500], [65536, 65547], [65549, 65574], [65576, 65594], [65596, 65597], [65599, 65613], [65616, 65629], [65664, 65786], [65799, 65843], [65856, 65912], [65930, 65931], [66176, 66204], [66208, 66256], [66273, 66299], [66304, 66339], [66349, 66378], [66384, 66421], [66432, 66461], [66464, 66499], [66504, 66511], [66513, 66517], [66560, 66717], [66720, 66729], [66736, 66771], [66776, 66811], [66816, 66855], [66864, 66915], [67072, 67382], [67392, 67413], [67424, 67431], [67584, 67589], [67592, 67592], [67594, 67637], [67639, 67640], [67644, 67644], [67647, 67669], [67672, 67702], [67705, 67742], [67751, 67759], [67808, 67826], [67828, 67829], [67835, 67867], [67872, 67897], [67968, 68023], [68028, 68047], [68050, 68096], [68112, 68115], [68117, 68119], [68121, 68149], [68160, 68168], [68192, 68222], [68224, 68255], [68288, 68295], [68297, 68324], [68331, 68335], [68352, 68405], [68416, 68437], [68440, 68466], [68472, 68497], [68521, 68527], [68608, 68680], [68736, 68786], [68800, 68850], [68858, 68899], [68912, 68921], [69216, 69246], [69248, 69289], [69296, 69297], [69376, 69415], [69424, 69445], [69457, 69460], [69552, 69579], [69600, 69622], [69635, 69687], [69714, 69743], [69763, 69807], [69840, 69864], [69872, 69881], [69891, 69926], [69942, 69951], [69956, 69956], [69959, 69959], [69968, 70002], [70006, 70006], [70019, 70066], [70081, 70084], [70096, 70106], [70108, 70108], [70113, 70132], [70144, 70161], [70163, 70187], [70272, 70278], [70280, 70280], [70282, 70285], [70287, 70301], [70303, 70312], [70320, 70366], [70384, 70393], [70405, 70412], [70415, 70416], [70419, 70440], [70442, 70448], [70450, 70451], [70453, 70457], [70461, 70461], [70480, 70480], [70493, 70497], [70656, 70708], [70727, 70730], [70736, 70745], [70751, 70753], [70784, 70831], [70852, 70853], [70855, 70855], [70864, 70873], [71040, 71086], [71128, 71131], [71168, 71215], [71236, 71236], [71248, 71257], [71296, 71338], [71352, 71352], [71360, 71369], [71424, 71450], [71472, 71483], [71680, 71723], [71840, 71922], [71935, 71942], [71945, 71945], [71948, 71955], [71957, 71958], [71960, 71983], [71999, 71999], [72001, 72001], [72016, 72025], [72096, 72103], [72106, 72144], [72161, 72161], [72163, 72163], [72192, 72192], [72203, 72242], [72250, 72250], [72272, 72272], [72284, 72329], [72349, 72349], [72384, 72440], [72704, 72712], [72714, 72750], [72768, 72768], [72784, 72812], [72818, 72847], [72960, 72966], [72968, 72969], [72971, 73008], [73030, 73030], [73040, 73049], [73056, 73061], [73063, 73064], [73066, 73097], [73112, 73112], [73120, 73129], [73440, 73458], [73648, 73648], [73664, 73684], [73728, 74649], [74752, 74862], [74880, 75075], [77824, 78894], [82944, 83526], [92160, 92728], [92736, 92766], [92768, 92777], [92880, 92909], [92928, 92975], [92992, 92995], [93008, 93017], [93019, 93025], [93027, 93047], [93053, 93071], [93760, 93846], [93952, 94026], [94032, 94032], [94099, 94111], [94176, 94177], [94179, 94179], [94208, 100343], [100352, 101589], [101632, 101640], [110592, 110878], [110928, 110930], [110948, 110951], [110960, 111355], [113664, 113770], [113776, 113788], [113792, 113800], [113808, 113817], [119520, 119539], [119648, 119672], [119808, 119892], [119894, 119964], [119966, 119967], [119970, 119970], [119973, 119974], [119977, 119980], [119982, 119993], [119995, 119995], [119997, 120003], [120005, 120069], [120071, 120074], [120077, 120084], [120086, 120092], [120094, 120121], [120123, 120126], [120128, 120132], [120134, 120134], [120138, 120144], [120146, 120485], [120488, 120512], [120514, 120538], [120540, 120570], [120572, 120596], [120598, 120628], [120630, 120654], [120656, 120686], [120688, 120712], [120714, 120744], [120746, 120770], [120772, 120779], [120782, 120831], [123136, 123180], [123191, 123197], [123200, 123209], [123214, 123214], [123584, 123627], [123632, 123641], [124928, 125124], [125127, 125135], [125184, 125251], [125259, 125259], [125264, 125273], [126065, 126123], [126125, 126127], [126129, 126132], [126209, 126253], [126255, 126269], [126464, 126467], [126469, 126495], [126497, 126498], [126500, 126500], [126503, 126503], [126505, 126514], [126516, 126519], [126521, 126521], [126523, 126523], [126530, 126530], [126535, 126535], [126537, 126537], [126539, 126539], [126541, 126543], [126545, 126546], [126548, 126548], [126551, 126551], [126553, 126553], [126555, 126555], [126557, 126557], [126559, 126559], [126561, 126562], [126564, 126564], [126567, 126570], [126572, 126578], [126580, 126583], [126585, 126588], [126590, 126590], [126592, 126601], [126603, 126619], [126625, 126627], [126629, 126633], [126635, 126651], [127232, 127244], [130032, 130041], [131072, 173789], [173824, 177972], [177984, 178205], [178208, 183969], [183984, 191456], [194560, 195101], [196608, 201546]];
|
|
2232
|
+
|
|
2233
|
+
// packages/safe-bash-command-llm/src/extract-range.ts
|
|
2234
|
+
function isWord(value) {
|
|
2235
|
+
let low = 0, high = wordRanges.length - 1;
|
|
2236
|
+
while (low <= high) {
|
|
2237
|
+
const mid = low + high >>> 1;
|
|
2238
|
+
const [start, end] = wordRanges[mid];
|
|
2239
|
+
if (value < start) high = mid - 1;
|
|
2240
|
+
else if (value > end) low = mid + 1;
|
|
2241
|
+
else return true;
|
|
2242
|
+
}
|
|
2243
|
+
return false;
|
|
2244
|
+
}
|
|
2245
|
+
async function findExtractedRange(reader, last, signal) {
|
|
2246
|
+
let cache = new Uint8Array(0);
|
|
2247
|
+
let cacheStart = -1, work = 0;
|
|
2248
|
+
async function byte(position2) {
|
|
2249
|
+
signal.throwIfAborted();
|
|
2250
|
+
if (++work % 4096 === 0) await yieldTurn9(signal);
|
|
2251
|
+
if (position2 < 0 || position2 >= reader.size) throw new Error("Invalid extraction position");
|
|
2252
|
+
if (position2 < cacheStart || position2 >= cacheStart + cache.length) {
|
|
2253
|
+
cache = await reader.read(position2, Math.min(16384, reader.size - position2));
|
|
2254
|
+
cacheStart = position2;
|
|
2255
|
+
signal.throwIfAborted();
|
|
2256
|
+
if (!cache.length || cache.length > Math.min(16384, reader.size - position2)) throw new Error("Invalid extraction read");
|
|
2257
|
+
}
|
|
2258
|
+
return cache[position2 - cacheStart];
|
|
2259
|
+
}
|
|
2260
|
+
async function line(start) {
|
|
2261
|
+
let position2 = start, ticks = 0;
|
|
2262
|
+
while (position2 < reader.size && await byte(position2) === 96) {
|
|
2263
|
+
ticks++;
|
|
2264
|
+
position2++;
|
|
2265
|
+
}
|
|
2266
|
+
let opening = ticks >= 3, closing = ticks >= 3;
|
|
2267
|
+
while (position2 < reader.size) {
|
|
2268
|
+
const value = await byte(position2);
|
|
2269
|
+
if (value === 10) return { start, next: position2 + 1, ticks, opening, closing };
|
|
2270
|
+
closing = closing && value === 32;
|
|
2271
|
+
let point = value, width = 1;
|
|
2272
|
+
if (value >= 194 && value <= 244) {
|
|
2273
|
+
width = value < 224 ? 2 : value < 240 ? 3 : 4;
|
|
2274
|
+
point = value & (width === 2 ? 31 : width === 3 ? 15 : 7);
|
|
2275
|
+
for (let i = 1; i < width; i++) {
|
|
2276
|
+
if (position2 + i >= reader.size) {
|
|
2277
|
+
opening = false;
|
|
2278
|
+
width = 1;
|
|
2279
|
+
break;
|
|
2280
|
+
}
|
|
2281
|
+
const continuation = await byte(position2 + i);
|
|
2282
|
+
if (continuation < 128 || continuation > 191) {
|
|
2283
|
+
opening = false;
|
|
2284
|
+
width = 1;
|
|
2285
|
+
break;
|
|
2286
|
+
}
|
|
2287
|
+
point = point << 6 | continuation & 63;
|
|
2288
|
+
}
|
|
2289
|
+
} else if (value >= 128) opening = false;
|
|
2290
|
+
opening = opening && isWord(point);
|
|
2291
|
+
position2 += width;
|
|
2292
|
+
}
|
|
2293
|
+
return { start, next: reader.size, ticks, opening: false, closing };
|
|
2294
|
+
}
|
|
2295
|
+
const failedLengths = new Uint8Array(16384);
|
|
2296
|
+
let position = 0, selected;
|
|
2297
|
+
while (position < reader.size) {
|
|
2298
|
+
const candidate = await line(position);
|
|
2299
|
+
position = candidate.next;
|
|
2300
|
+
if (!candidate.opening) continue;
|
|
2301
|
+
if (candidate.ticks < failedLengths.length * 8 && failedLengths[candidate.ticks >>> 3] & 1 << (candidate.ticks & 7)) continue;
|
|
2302
|
+
let matched = false;
|
|
2303
|
+
let search = candidate.next;
|
|
2304
|
+
while (search < reader.size) {
|
|
2305
|
+
const ending = await line(search);
|
|
2306
|
+
search = ending.next;
|
|
2307
|
+
if (ending.closing && ending.ticks === candidate.ticks) {
|
|
2308
|
+
matched = true;
|
|
2309
|
+
selected = { start: candidate.next, end: ending.start };
|
|
2310
|
+
if (!last) return selected;
|
|
2311
|
+
position = ending.next;
|
|
2312
|
+
break;
|
|
2313
|
+
}
|
|
2314
|
+
}
|
|
2315
|
+
if (!matched && candidate.ticks < failedLengths.length * 8) failedLengths[candidate.ticks >>> 3] |= 1 << (candidate.ticks & 7);
|
|
2316
|
+
}
|
|
2317
|
+
return selected;
|
|
2318
|
+
}
|
|
2319
|
+
|
|
2320
|
+
// packages/safe-bash-command-llm/src/schemas.ts
|
|
2321
|
+
function parseLlmSchemaDsl(input, multi = false) {
|
|
2322
|
+
const properties = /* @__PURE__ */ Object.create(null);
|
|
2323
|
+
const required = [];
|
|
2324
|
+
const types = { int: "integer", float: "number", bool: "boolean", str: "string" };
|
|
2325
|
+
for (const field of input.split(input.includes("\n") ? "\n" : ",").map((value) => value.trim()).filter(Boolean)) {
|
|
2326
|
+
const colon = field.indexOf(":");
|
|
2327
|
+
const info = (colon < 0 ? field : field.slice(0, colon)).trim();
|
|
2328
|
+
const description = colon < 0 ? "" : field.slice(colon + 1).trim();
|
|
2329
|
+
const parts = [];
|
|
2330
|
+
let word = "";
|
|
2331
|
+
for (const character of info) {
|
|
2332
|
+
if (character.trim() === "") {
|
|
2333
|
+
if (word) parts.push(word);
|
|
2334
|
+
word = "";
|
|
2335
|
+
} else word += character;
|
|
2336
|
+
}
|
|
2337
|
+
if (word) parts.push(word);
|
|
2338
|
+
const name = parts[0];
|
|
2339
|
+
if (!name) throw new Error("Schema field requires a name");
|
|
2340
|
+
const indicator = parts[1] ?? "str";
|
|
2341
|
+
const type = Object.hasOwn(types, indicator) ? types[indicator] : "string";
|
|
2342
|
+
properties[name] = { type, ...description ? { description } : {} };
|
|
2343
|
+
required.push(name);
|
|
2344
|
+
}
|
|
2345
|
+
const schema = { type: "object", properties, required };
|
|
2346
|
+
return multi ? { type: "object", properties: { items: { type: "array", items: schema } }, required: ["items"] } : schema;
|
|
2347
|
+
}
|
|
2348
|
+
|
|
2349
|
+
// packages/safe-bash-command-llm/src/schema-input.ts
|
|
2350
|
+
import { FsError as FsError5 } from "../../safe-bash-contracts/index.js";
|
|
2351
|
+
import { pathOf as pathOf2 } from "../../safe-bash-contracts/path.js";
|
|
2352
|
+
async function resolveLlmSchemaInput(context, input, options) {
|
|
2353
|
+
context.signal.throwIfAborted();
|
|
2354
|
+
let schema;
|
|
2355
|
+
const trimmed = input.trim();
|
|
2356
|
+
if (trimmed.startsWith("t:")) {
|
|
2357
|
+
const name = trimmed.slice(2);
|
|
2358
|
+
const template2 = await options.loadTemplate(name);
|
|
2359
|
+
schema = template2.schema_object;
|
|
2360
|
+
if (!schema) throw new Error("Template '" + name + "' has no schema");
|
|
2361
|
+
} else {
|
|
2362
|
+
if (trimmed.startsWith("{")) {
|
|
2363
|
+
try {
|
|
2364
|
+
schema = JSON.parse(input);
|
|
2365
|
+
} catch {
|
|
2366
|
+
}
|
|
2367
|
+
}
|
|
2368
|
+
if (schema === void 0 && (trimmed.includes(" ") || input.includes(","))) schema = parseLlmSchemaDsl(input);
|
|
2369
|
+
if (schema === void 0) {
|
|
2370
|
+
const path = pathOf2(context, input);
|
|
2371
|
+
let stat;
|
|
2372
|
+
try {
|
|
2373
|
+
stat = await context.fs.stat(path, { signal: context.signal });
|
|
2374
|
+
} catch (error) {
|
|
2375
|
+
if (!(error instanceof FsError5) || error.code !== "ENOENT") throw error;
|
|
2376
|
+
}
|
|
2377
|
+
if (stat) {
|
|
2378
|
+
const source = await fileSource({ fs: context.fs, path, signal: context.signal, maxBytes: options.maxBytes ?? Infinity, expectedStat: stat });
|
|
2379
|
+
let text = "";
|
|
2380
|
+
const decoder = new TextDecoder("utf-8", { fatal: true });
|
|
2381
|
+
try {
|
|
2382
|
+
for await (const bytes of source.bytes) {
|
|
2383
|
+
options.admitBytes?.(bytes.byteLength);
|
|
2384
|
+
text += decoder.decode(bytes, { stream: true });
|
|
2385
|
+
}
|
|
2386
|
+
text += decoder.decode();
|
|
2387
|
+
} finally {
|
|
2388
|
+
await source.dispose();
|
|
2389
|
+
}
|
|
2390
|
+
try {
|
|
2391
|
+
schema = JSON.parse(text);
|
|
2392
|
+
} catch {
|
|
2393
|
+
throw new Error("Schema file contained invalid JSON");
|
|
2394
|
+
}
|
|
2395
|
+
}
|
|
2396
|
+
}
|
|
2397
|
+
}
|
|
2398
|
+
context.signal.throwIfAborted();
|
|
2399
|
+
if (!schema || typeof schema !== "object" || Array.isArray(schema)) throw new Error("Invalid schema");
|
|
2400
|
+
return options.multi ? { type: "object", properties: { items: { type: "array", items: schema } }, required: ["items"] } : schema;
|
|
2401
|
+
}
|
|
2402
|
+
|
|
2403
|
+
// packages/safe-bash-command-llm/src/configuration-command.ts
|
|
2404
|
+
async function configurationCommand(context, service, args, output, diagnostic, admitInput, maxConfigurationBytes = Infinity) {
|
|
2405
|
+
if (args.length === 1 && args[0] === "--version") {
|
|
2406
|
+
await output("llm, version 0.27.1\n");
|
|
2407
|
+
return true;
|
|
2408
|
+
}
|
|
2409
|
+
const keysCmd = args[0] === "keys";
|
|
2410
|
+
const aliases = args[0] === "aliases";
|
|
2411
|
+
const defaults = args[0] === "models" && args[1] === "default";
|
|
2412
|
+
const options = args[0] === "models" && args[1] === "options";
|
|
2413
|
+
if (!keysCmd && !aliases && !defaults && !options) return false;
|
|
2414
|
+
const configuration = createLlmConfiguration(context, maxConfigurationBytes);
|
|
2415
|
+
if (keysCmd) {
|
|
2416
|
+
const tokens2 = args.slice(1), sub = tokens2[0];
|
|
2417
|
+
if (sub === "path" && tokens2.length === 1) {
|
|
2418
|
+
await output(`${configuration.directory}/keys.json
|
|
2419
|
+
`);
|
|
2420
|
+
return true;
|
|
2421
|
+
}
|
|
2422
|
+
if (sub === void 0 || sub === "list" && tokens2.length === 1) {
|
|
2423
|
+
const path = `${configuration.directory}/keys.json`;
|
|
2424
|
+
let exists = true;
|
|
2425
|
+
try {
|
|
2426
|
+
await context.fs.lstat(path, { signal: context.signal });
|
|
2427
|
+
} catch {
|
|
2428
|
+
exists = false;
|
|
2429
|
+
}
|
|
2430
|
+
if (!exists) {
|
|
2431
|
+
await output("No keys found\n");
|
|
2432
|
+
return true;
|
|
2433
|
+
}
|
|
2434
|
+
const stored = await configuration.keys();
|
|
2435
|
+
for (const key of Object.keys(stored).sort()) {
|
|
2436
|
+
await output(`${key}
|
|
2437
|
+
`);
|
|
2438
|
+
}
|
|
2439
|
+
return true;
|
|
2440
|
+
}
|
|
2441
|
+
if (sub === "get" && tokens2.length === 2) {
|
|
2442
|
+
await output(`${await configuration.getKey(tokens2[1])}
|
|
2443
|
+
`);
|
|
2444
|
+
return true;
|
|
2445
|
+
}
|
|
2446
|
+
if (sub === "set") {
|
|
2447
|
+
let name;
|
|
2448
|
+
let value;
|
|
2449
|
+
for (let i = 1; i < tokens2.length; i++) {
|
|
2450
|
+
const token = tokens2[i];
|
|
2451
|
+
if (token === "--value") {
|
|
2452
|
+
if (++i >= tokens2.length) throw new Error("Option '--value' requires an argument");
|
|
2453
|
+
value = tokens2[i];
|
|
2454
|
+
} else if (token.startsWith("--value=")) {
|
|
2455
|
+
value = token.slice(8);
|
|
2456
|
+
} else if (token.startsWith("-")) {
|
|
2457
|
+
throw new Error(`No such option: ${token}`);
|
|
2458
|
+
} else if (name === void 0) {
|
|
2459
|
+
name = token;
|
|
2460
|
+
} else {
|
|
2461
|
+
throw new Error("Unexpected extra arguments");
|
|
2462
|
+
}
|
|
2463
|
+
}
|
|
2464
|
+
if (!name) throw new Error("Missing argument 'NAME'");
|
|
2465
|
+
if (value === void 0) {
|
|
2466
|
+
let stdinText = "";
|
|
2467
|
+
const decoder = new TextDecoder();
|
|
2468
|
+
for await (const chunk of context.stdin) {
|
|
2469
|
+
context.signal.throwIfAborted();
|
|
2470
|
+
admitInput(chunk.byteLength, true);
|
|
2471
|
+
stdinText += decoder.decode(chunk, { stream: true });
|
|
2472
|
+
}
|
|
2473
|
+
stdinText += decoder.decode();
|
|
2474
|
+
value = stdinText.replace(/\r?\n$/, "");
|
|
2475
|
+
}
|
|
2476
|
+
await configuration.setKey(name, value);
|
|
2477
|
+
return true;
|
|
2478
|
+
}
|
|
2479
|
+
throw new Error("Invalid keys command");
|
|
2480
|
+
}
|
|
2481
|
+
const canonical = async (model) => {
|
|
2482
|
+
const resolved = await configuration.resolveAlias(model);
|
|
2483
|
+
try {
|
|
2484
|
+
return service.resolve(resolved).model.id;
|
|
2485
|
+
} catch {
|
|
2486
|
+
return resolved;
|
|
2487
|
+
}
|
|
2488
|
+
};
|
|
2489
|
+
const tokens = args.slice(aliases ? 1 : 2), command = tokens[0];
|
|
2490
|
+
if (defaults) {
|
|
2491
|
+
if (tokens.length > 1) throw new Error("Unexpected extra arguments");
|
|
2492
|
+
if (command === void 0) await output(`${await configuration.defaultModel() ?? service.resolve().model.id}
|
|
2493
|
+
`);
|
|
2494
|
+
else {
|
|
2495
|
+
const model = service.resolve(await canonical(command)).model.id;
|
|
2496
|
+
await configuration.setDefaultModel(model);
|
|
2497
|
+
}
|
|
2498
|
+
return true;
|
|
2499
|
+
}
|
|
2500
|
+
if (aliases) {
|
|
2501
|
+
if (command === "path" && tokens.length === 1) await output(`${configuration.directory}/aliases.json
|
|
2502
|
+
`);
|
|
2503
|
+
else if (command === "set") {
|
|
2504
|
+
const operands = [], queries = [];
|
|
2505
|
+
for (let index = 1; index < tokens.length; index++) {
|
|
2506
|
+
const token = tokens[index];
|
|
2507
|
+
if (token === "-q" || token === "--query") {
|
|
2508
|
+
const query = tokens[++index];
|
|
2509
|
+
if (query === void 0) throw new Error(`Option '${token}' requires an argument`);
|
|
2510
|
+
queries.push(query);
|
|
2511
|
+
} else if (token.startsWith("--query=")) queries.push(token.slice(8));
|
|
2512
|
+
else if (token.startsWith("-q") && token.length > 2) queries.push(token.slice(2));
|
|
2513
|
+
else if (token.startsWith("-")) throw new Error(`No such option: ${token}`);
|
|
2514
|
+
else operands.push(token);
|
|
2515
|
+
}
|
|
2516
|
+
if (!operands.length || operands.length > 2) throw new Error("Invalid aliases set arguments");
|
|
2517
|
+
let model = operands[1];
|
|
2518
|
+
const queried = model === void 0;
|
|
2519
|
+
if (model === void 0) {
|
|
2520
|
+
if (!queries.length) throw new Error("You must provide a model_id or at least one -q option");
|
|
2521
|
+
const persisted = await configuration.aliases();
|
|
2522
|
+
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()))));
|
|
2523
|
+
if (!found) throw new Error(`No model found matching query: ${queries.join(", ")}`);
|
|
2524
|
+
model = found.model.id;
|
|
2525
|
+
}
|
|
2526
|
+
await configuration.setAlias(operands[0], await canonical(model));
|
|
2527
|
+
if (queried) await diagnostic(`Alias '${operands[0]}' set to model '${model}'
|
|
2528
|
+
`);
|
|
2529
|
+
} else if (command === "remove" && tokens.length === 2) await configuration.removeAlias(tokens[1]);
|
|
2530
|
+
else if ((command === void 0 || command === "list" || command === "--json") && tokens.slice(command === void 0 ? 0 : 1).every((token) => token === "--json")) {
|
|
2531
|
+
const values = {};
|
|
2532
|
+
for (const { model } of service.models) for (const alias of model.aliases ?? []) if (alias !== model.id) Object.defineProperty(values, alias, { value: model.id, enumerable: true, configurable: true, writable: true });
|
|
2533
|
+
const entries = Object.entries({ ...values, ...await configuration.aliases() });
|
|
2534
|
+
if (tokens.includes("--json")) await output(JSON.stringify(Object.fromEntries(entries), null, 4) + "\n");
|
|
2535
|
+
else {
|
|
2536
|
+
const width = Math.max(0, ...entries.map(([alias]) => [...alias].length));
|
|
2537
|
+
for (const [alias, model] of entries) await output(`${alias}${" ".repeat(width - [...alias].length)} : ${model}
|
|
2538
|
+
`);
|
|
2539
|
+
}
|
|
2540
|
+
} else throw new Error("Invalid aliases command");
|
|
2541
|
+
return true;
|
|
2542
|
+
}
|
|
2543
|
+
if (command === "set" && tokens.length === 4) {
|
|
2544
|
+
const model = await canonical(tokens[1]);
|
|
2545
|
+
const entry = service.models.find((entry2) => entry2.model.id === model);
|
|
2546
|
+
if (entry) validateModelOptions(entry.model, { [tokens[2]]: tokens[3] });
|
|
2547
|
+
await configuration.setModelOption(model, tokens[2], tokens[3]);
|
|
2548
|
+
await diagnostic(`Set default option ${tokens[2]}=${tokens[3]} for model ${model}
|
|
2549
|
+
`);
|
|
2550
|
+
} else if (command === "show" && tokens.length === 2) {
|
|
2551
|
+
const model = await canonical(tokens[1]), values = await configuration.modelOptions(model);
|
|
2552
|
+
if (!Object.keys(values).length) await diagnostic(`No default options set for model '${model}'.
|
|
2553
|
+
`);
|
|
2554
|
+
else for (const [key, value] of Object.entries(values)) await output(`${key}: ${value}
|
|
2555
|
+
`);
|
|
2556
|
+
} else if (command === "clear" && (tokens.length === 2 || tokens.length === 3)) {
|
|
2557
|
+
const model = await canonical(tokens[1]);
|
|
2558
|
+
const keys = tokens[2] === void 0 ? Object.keys(await configuration.modelOptions(model)) : [tokens[2]];
|
|
2559
|
+
await configuration.clearModelOption(model, tokens[2]);
|
|
2560
|
+
if (keys.length === 1) await output(`Cleared option '${keys[0]}' for model ${model}
|
|
2561
|
+
`);
|
|
2562
|
+
else if (keys.length > 1) await output(`Cleared ${keys.join(", ")} options for model ${model}
|
|
2563
|
+
`);
|
|
2564
|
+
} else if (command === "list" && tokens.length === 1 || command === void 0) {
|
|
2565
|
+
await listOptions(configuration, output, diagnostic);
|
|
2566
|
+
} else throw new Error("Invalid models options command");
|
|
2567
|
+
return true;
|
|
2568
|
+
}
|
|
2569
|
+
async function listOptions(configuration, output, diagnostic) {
|
|
2570
|
+
const entries = Object.entries(await configuration.allModelOptions());
|
|
2571
|
+
if (!entries.length) await diagnostic("No default options set for any models.\n");
|
|
2572
|
+
for (const [model, values] of entries) {
|
|
2573
|
+
await output(`${model}:
|
|
2574
|
+
`);
|
|
2575
|
+
for (const [key, value] of Object.entries(values)) await output(` ${key}: ${value}
|
|
2576
|
+
`);
|
|
2577
|
+
}
|
|
2578
|
+
}
|
|
2579
|
+
|
|
2580
|
+
// packages/safe-bash-command-llm/src/model-selection.ts
|
|
2581
|
+
import { yieldTurn as yieldTurn10 } from "../../safe-bash-contracts/yield.js";
|
|
2582
|
+
function getLlmModelAliases({ provider, model }, configured) {
|
|
2583
|
+
const aliases = new Set(model.aliases);
|
|
2584
|
+
for (const [alias, target] of Object.entries(configured)) {
|
|
2585
|
+
if (target === model.id || target === `${provider.name}/${model.id}` || model.aliases?.includes(target)) aliases.add(alias);
|
|
2586
|
+
}
|
|
2587
|
+
return [...aliases];
|
|
2588
|
+
}
|
|
2589
|
+
async function selectLlmModelByQuery(models, queries, configuredAliases = {}, signal) {
|
|
2590
|
+
if (!queries.length) throw new TypeError("Model selection requires a query");
|
|
2591
|
+
let selected;
|
|
2592
|
+
const normalized = queries.map((query) => query.toLowerCase());
|
|
2593
|
+
for (let index = 0; index < models.length; index++) {
|
|
2594
|
+
signal?.throwIfAborted();
|
|
2595
|
+
if (signal && index && index % 256 === 0) await yieldTurn10(signal);
|
|
2596
|
+
const entry = models[index];
|
|
2597
|
+
const terms = [entry.model.displayName ?? `${entry.provider.name}: ${entry.model.id}`, ...getLlmModelAliases(entry, configuredAliases), ...entry.model.asyncModel ? [entry.model.id] : []].map((value) => value.toLowerCase());
|
|
2598
|
+
if (normalized.every((query) => terms.some((term) => term.includes(query))) && (!selected || [...entry.model.id].length < [...selected.model.id].length)) selected = entry;
|
|
2599
|
+
}
|
|
2600
|
+
signal?.throwIfAborted();
|
|
2601
|
+
if (!selected) throw new Error(`No model found matching queries ${queries.join(", ")}`);
|
|
2602
|
+
return selected;
|
|
2603
|
+
}
|
|
2604
|
+
|
|
2605
|
+
// packages/safe-bash-command-llm/src/models-list.ts
|
|
2606
|
+
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";
|
|
2607
|
+
var LlmModelsUsageError = class extends Error {
|
|
2608
|
+
constructor(message, usage3 = true) {
|
|
2609
|
+
super((usage3 ? "Usage: llm models list [OPTIONS]\nTry 'llm models list -h' for help.\n\n" : "") + `Error: ${message}`);
|
|
2610
|
+
}
|
|
2611
|
+
};
|
|
2612
|
+
function wrapDescription(description) {
|
|
2613
|
+
const lines = [];
|
|
2614
|
+
let line = "";
|
|
2615
|
+
for (const word of description.split(" ")) {
|
|
2616
|
+
if (!word) continue;
|
|
2617
|
+
if (line && line.length + word.length + 1 > 70) {
|
|
2618
|
+
lines.push(line);
|
|
2619
|
+
line = "";
|
|
2620
|
+
}
|
|
2621
|
+
line += (line ? " " : "") + word;
|
|
2622
|
+
}
|
|
2623
|
+
if (line) lines.push(line);
|
|
2624
|
+
return lines.join("\n ");
|
|
2625
|
+
}
|
|
2626
|
+
async function listLlmModels(context, service, tokens, emit, step, maxConfigurationBytes = Infinity) {
|
|
2627
|
+
const explicit = tokens[0] === "list";
|
|
2628
|
+
const terminator = tokens.indexOf("--");
|
|
2629
|
+
const groupFlags = terminator < 0 ? tokens : tokens.slice(0, terminator);
|
|
2630
|
+
if (!explicit && groupFlags.some((token) => token === "--help" || token.startsWith("-") && !token.startsWith("--") && token.slice(1).includes("h"))) {
|
|
2631
|
+
await emit(modelsGroupHelp);
|
|
2632
|
+
return;
|
|
2633
|
+
}
|
|
2634
|
+
const queries = [], selected = [];
|
|
2635
|
+
let schemas = false, tools = false, asyncModels = false, options = false, help2 = false, ended = false;
|
|
2636
|
+
const unexpected = [];
|
|
2637
|
+
const args = explicit ? tokens.slice(1) : tokens.filter((_, index) => index !== terminator);
|
|
2638
|
+
for (let index = 0; index < args.length; index++) {
|
|
2639
|
+
await step();
|
|
2640
|
+
const argument = args[index];
|
|
2641
|
+
if (ended) {
|
|
2642
|
+
unexpected.push(argument);
|
|
2643
|
+
continue;
|
|
2644
|
+
}
|
|
2645
|
+
if (argument === "--") {
|
|
2646
|
+
ended = true;
|
|
2647
|
+
continue;
|
|
2648
|
+
}
|
|
2649
|
+
if (argument === "--help" || argument === "-h") {
|
|
2650
|
+
help2 = true;
|
|
2651
|
+
continue;
|
|
2652
|
+
}
|
|
2653
|
+
if (argument === "--options") {
|
|
2654
|
+
options = true;
|
|
2655
|
+
continue;
|
|
2656
|
+
}
|
|
2657
|
+
if (argument === "--schemas") {
|
|
2658
|
+
schemas = true;
|
|
2659
|
+
continue;
|
|
2660
|
+
}
|
|
2661
|
+
if (argument === "--tools") {
|
|
2662
|
+
tools = true;
|
|
2663
|
+
continue;
|
|
2664
|
+
}
|
|
2665
|
+
if (argument === "--async") {
|
|
2666
|
+
asyncModels = true;
|
|
2667
|
+
continue;
|
|
2668
|
+
}
|
|
2669
|
+
if (!argument.startsWith("-") || argument === "-") {
|
|
2670
|
+
unexpected.push(argument);
|
|
2671
|
+
continue;
|
|
2672
|
+
}
|
|
2673
|
+
const equals = argument.indexOf("=");
|
|
2674
|
+
const long = argument.startsWith("--");
|
|
2675
|
+
const flag = long ? argument.slice(0, equals < 0 ? void 0 : equals) : argument.slice(0, 2);
|
|
2676
|
+
const attached = long ? equals < 0 ? void 0 : argument.slice(equals + 1) : argument.length > 2 ? argument.slice(2) : void 0;
|
|
2677
|
+
if (equals >= 0 && ["--schemas", "--tools", "--async", "--options", "--help", "-h"].includes(flag)) throw new LlmModelsUsageError(`Option '${flag}' does not take a value.`, false);
|
|
2678
|
+
if (!["-q", "--query", "-m", "--model"].includes(flag)) throw new LlmModelsUsageError(`No such option: ${flag}`);
|
|
2679
|
+
const value = attached ?? args[++index];
|
|
2680
|
+
if (value === void 0) throw new LlmModelsUsageError(`Option '${flag}' requires an argument.`, false);
|
|
2681
|
+
(flag === "-q" || flag === "--query" ? queries : selected).push(value);
|
|
2682
|
+
}
|
|
2683
|
+
if (help2) {
|
|
2684
|
+
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");
|
|
2685
|
+
return;
|
|
2686
|
+
}
|
|
2687
|
+
if (unexpected.length) throw new LlmModelsUsageError(`Got unexpected extra argument${unexpected.length === 1 ? "" : "s"} (${unexpected.join(" ")})`);
|
|
2688
|
+
const configuration = createLlmConfiguration(context, maxConfigurationBytes);
|
|
2689
|
+
const configuredAliases = await configuration.aliases();
|
|
2690
|
+
const shownDescriptions = /* @__PURE__ */ new Set();
|
|
2691
|
+
for (const { provider, model: syncModel } of service.models) {
|
|
2692
|
+
await step();
|
|
2693
|
+
const aliases = getLlmModelAliases({ provider, model: syncModel }, configuredAliases);
|
|
2694
|
+
const description = syncModel.displayName ?? `${provider.name}: ${syncModel.id}`;
|
|
2695
|
+
const terms = [description, ...aliases, ...syncModel.asyncModel ? [syncModel.id] : []].map((value) => value.toLowerCase());
|
|
2696
|
+
if (!queries.every((query) => terms.some((term) => term.includes(query.toLowerCase())))) continue;
|
|
2697
|
+
if (selected.length && !selected.some((value) => value === syncModel.id || aliases.includes(value))) continue;
|
|
2698
|
+
if (schemas && !syncModel.capabilities?.includes("schema") || tools && !syncModel.capabilities?.includes("tools") || asyncModels && !syncModel.asyncModel) continue;
|
|
2699
|
+
const model = asyncModels ? service.resolve(syncModel.id, { async: true }).model : syncModel;
|
|
2700
|
+
let output = (model.displayName ?? `${provider.name}: ${model.id}`) + (aliases.length ? ` (aliases: ${aliases.join(", ")})` : "");
|
|
2701
|
+
if (model.outputType) output += `
|
|
2702
|
+
Output type: ${model.outputType}`;
|
|
2703
|
+
if (options && Object.keys(model.options ?? {}).length) {
|
|
2704
|
+
output += "\n Options:";
|
|
2705
|
+
for (const [name, rule] of Object.entries(model.options)) {
|
|
2706
|
+
const type = { number: "float", integer: "int", boolean: "boolean", string: "str", object: "dict", array: "list" }[rule.type];
|
|
2707
|
+
output += `
|
|
2708
|
+
${name}: ${type}`;
|
|
2709
|
+
if (rule.description && !shownDescriptions.has(provider.name)) output += `
|
|
2710
|
+
${wrapDescription(rule.description)}`;
|
|
2711
|
+
}
|
|
2712
|
+
shownDescriptions.add(provider.name);
|
|
2713
|
+
}
|
|
2714
|
+
if (options && model.attachmentTypes?.length) output += `
|
|
2715
|
+
Attachment types:
|
|
2716
|
+
${[...model.attachmentTypes].sort().join(", ")}`;
|
|
2717
|
+
const features = [
|
|
2718
|
+
...model.canStream ? ["streaming"] : [],
|
|
2719
|
+
...model.capabilities?.includes("schema") ? ["schemas"] : [],
|
|
2720
|
+
...model.capabilities?.includes("tools") ? ["tools"] : [],
|
|
2721
|
+
...syncModel.asyncModel ? ["async"] : []
|
|
2722
|
+
];
|
|
2723
|
+
if (options && features.length) output += "\n Features:\n" + features.map((feature) => ` - ${feature}`).join("\n");
|
|
2724
|
+
await emit(output + "\n");
|
|
2725
|
+
}
|
|
2726
|
+
if (!queries.length && !selected.length && !schemas && !options) {
|
|
2727
|
+
const configured = await configuration.defaultModel();
|
|
2728
|
+
let model = configured;
|
|
2729
|
+
if (model === void 0) {
|
|
2730
|
+
try {
|
|
2731
|
+
model = service.resolve().model.id;
|
|
2732
|
+
} catch {
|
|
2733
|
+
}
|
|
2734
|
+
}
|
|
2735
|
+
if (model !== void 0) await emit(`Default: ${model}
|
|
2736
|
+
`);
|
|
2737
|
+
}
|
|
2738
|
+
}
|
|
2739
|
+
|
|
2740
|
+
// packages/safe-bash-command-llm/src/command.ts
|
|
2741
|
+
var llmReferenceVersion = "0.27.1";
|
|
2742
|
+
var LlmPromptUsageError = class extends Error {
|
|
2743
|
+
};
|
|
2744
|
+
async function parse(length, text, step, chat = false) {
|
|
2745
|
+
const parsed = { toolNames: [], functions: [], chainLimit: 5, prompt: "", queries: [], fragments: [], systemFragments: [], params: {}, options: /* @__PURE__ */ Object.create(null), attachments: [] };
|
|
2746
|
+
const operands = [];
|
|
2747
|
+
let ended = false;
|
|
2748
|
+
for (let index = 0; index < length; index++) {
|
|
2749
|
+
await step();
|
|
2750
|
+
const argument = text(index);
|
|
2751
|
+
if (ended || !argument.startsWith("-") || argument === "-") {
|
|
2752
|
+
operands.push(argument);
|
|
2753
|
+
continue;
|
|
2754
|
+
}
|
|
2755
|
+
if (argument === "--") {
|
|
2756
|
+
ended = true;
|
|
2757
|
+
continue;
|
|
2758
|
+
}
|
|
2759
|
+
const equals = argument.indexOf("="), long = argument.startsWith("--");
|
|
2760
|
+
for (let cursor = long ? 0 : 1; cursor < argument.length; cursor++) {
|
|
2761
|
+
await step();
|
|
2762
|
+
const flag = long ? argument.slice(0, equals < 0 ? void 0 : equals) : "-" + argument[cursor];
|
|
2763
|
+
if (chat) {
|
|
2764
|
+
if (flag === "-h" || flag === "--help") {
|
|
2765
|
+
if (long && equals >= 0) throw new LlmPromptUsageError(`Error: Option '${flag}' does not take a value.`);
|
|
2766
|
+
parsed.help = true;
|
|
2767
|
+
if (long) break;
|
|
2768
|
+
continue;
|
|
2769
|
+
}
|
|
2770
|
+
if (!["--td", "--tools-debug", "--ta", "--tools-approve", "--no-stream", "--functions", "-T", "--tool", "--cl", "--chain-limit", "-f", "--fragment", "--sf", "--system-fragment", "-m", "--model", "-s", "--system", "-o", "--option", "-t", "--template", "-p", "--param", "--key"].includes(flag))
|
|
2771
|
+
throw new LlmPromptUsageError(`Usage: llm chat [OPTIONS]
|
|
2772
|
+
Try 'llm chat -h' for help.
|
|
2773
|
+
|
|
2774
|
+
Error: No such option: ${flag}`);
|
|
2775
|
+
}
|
|
2776
|
+
const boolean = ["--async", "--td", "--tools-debug", "--ta", "--tools-approve", "--no-log", "-n", "-x", "--extract", "--xl", "--extract-last", "-u", "--usage", "--no-stream"].includes(flag);
|
|
2777
|
+
if (boolean) {
|
|
2778
|
+
if (long && equals >= 0) throw new LlmPromptUsageError(`Error: Option '${flag}' does not take a value.`);
|
|
2779
|
+
if (["-x", "--extract", "--xl", "--extract-last"].includes(flag)) {
|
|
2780
|
+
parsed.extract = flag === "--xl" || flag === "--extract-last" ? "last" : parsed.extract ?? "first";
|
|
2781
|
+
parsed.noStream = true;
|
|
2782
|
+
} else if (flag === "-u" || flag === "--usage") parsed.usage = true;
|
|
2783
|
+
else if (flag === "--no-stream") parsed.noStream = true;
|
|
2784
|
+
else if (flag === "--async") parsed.async = true;
|
|
2785
|
+
else if (flag === "--ta" || flag === "--tools-approve") parsed.toolsApprove = true;
|
|
2786
|
+
else if (flag === "--td" || flag === "--tools-debug") parsed.toolsDebug = true;
|
|
2787
|
+
if (long) break;
|
|
2788
|
+
continue;
|
|
2789
|
+
}
|
|
2790
|
+
if (!["--functions", "-T", "--tool", "--cl", "--chain-limit", "-f", "--fragment", "--sf", "--system-fragment", "-q", "--query", "-m", "--model", "-s", "--system", "-o", "--option", "-a", "--attachment", "--at", "--attachment-type", "-t", "--template", "--save", "-p", "--param", "--key", "--schema", "--schema-multi"].includes(flag)) throw new Error(`Unknown option: ${flag}`);
|
|
2791
|
+
const attached = long ? equals < 0 ? void 0 : argument.slice(equals + 1) : argument.slice(cursor + 1) || void 0;
|
|
2792
|
+
const arity = ["-o", "--option", "-p", "--param", "--at", "--attachment-type"].includes(flag) ? 2 : 1;
|
|
2793
|
+
if (length - index - 1 < arity - (attached === void 0 ? 0 : 1)) throw new LlmPromptUsageError(`Error: Option '${flag}' requires ${arity === 2 ? "2 arguments" : "an argument"}.`);
|
|
2794
|
+
const value = attached ?? text(++index);
|
|
2795
|
+
if (flag === "--functions") parsed.functions.push(value);
|
|
2796
|
+
else if (flag === "-T" || flag === "--tool") parsed.toolNames.push(value);
|
|
2797
|
+
else if (flag === "--cl" || flag === "--chain-limit") {
|
|
2798
|
+
const integer = tokenInteger(value);
|
|
2799
|
+
if (integer === void 0) throw new LlmPromptUsageError(`Usage: llm prompt [OPTIONS] [PROMPT]
|
|
2800
|
+
Try 'llm prompt --help' for help.
|
|
2801
|
+
|
|
2802
|
+
Error: Invalid value for '--cl' / '--chain-limit': '${value}' is not a valid integer.`);
|
|
2803
|
+
parsed.chainLimit = BigInt(integer);
|
|
2804
|
+
} else if (flag === "-f" || flag === "--fragment") parsed.fragments.push(value);
|
|
2805
|
+
else if (flag === "--sf" || flag === "--system-fragment") parsed.systemFragments.push(value);
|
|
2806
|
+
else if (flag === "-q" || flag === "--query") parsed.queries.push(value);
|
|
2807
|
+
else if (flag === "-t" || flag === "--template") parsed.template = value;
|
|
2808
|
+
else if (flag === "--schema") parsed.schema = value;
|
|
2809
|
+
else if (flag === "--schema-multi") parsed.schemaMulti = value;
|
|
2810
|
+
else if (flag === "--key") parsed.key = value;
|
|
2811
|
+
else if (flag === "--save") parsed.save = value;
|
|
2812
|
+
else if (flag === "-p" || flag === "--param") Object.defineProperty(parsed.params, value, { value: text(++index), enumerable: true, configurable: true, writable: true });
|
|
2813
|
+
else if (flag === "-m" || flag === "--model") parsed.model = value;
|
|
2814
|
+
else if (flag === "-s" || flag === "--system") parsed.system = value;
|
|
2815
|
+
else if (flag === "-o" || flag === "--option") parsed.options[value] = text(++index);
|
|
2816
|
+
else if (flag === "--at" || flag === "--attachment-type") parsed.attachments.push({ path: value, mimeType: text(++index) });
|
|
2817
|
+
else parsed.attachments.push({ path: value });
|
|
2818
|
+
break;
|
|
2819
|
+
}
|
|
2820
|
+
}
|
|
2821
|
+
if (parsed.help) return parsed;
|
|
2822
|
+
if (chat && operands.length) throw new LlmPromptUsageError(`Usage: llm chat [OPTIONS]
|
|
2823
|
+
Try 'llm chat -h' for help.
|
|
2824
|
+
|
|
2825
|
+
Error: Got unexpected extra argument${operands.length === 1 ? "" : "s"} (${operands.join(" ")})`);
|
|
2826
|
+
if (operands.length > 1) throw new LlmPromptUsageError(`Usage: llm prompt [OPTIONS] [PROMPT]
|
|
2827
|
+
Try 'llm prompt --help' for help.
|
|
2828
|
+
|
|
2829
|
+
Error: Got unexpected extra argument${operands.length === 2 ? "" : "s"} (${operands.slice(1).join(" ")})`);
|
|
2830
|
+
parsed.prompt = operands[0] ?? "";
|
|
2831
|
+
parsed.promptSupplied = operands.length > 0;
|
|
2832
|
+
return parsed;
|
|
2833
|
+
}
|
|
2834
|
+
async function interrupted(start, signal) {
|
|
2835
|
+
signal.throwIfAborted();
|
|
2836
|
+
return new Promise((resolve, reject) => {
|
|
2837
|
+
const aborted = () => reject(signal.reason);
|
|
2838
|
+
signal.addEventListener("abort", aborted, { once: true });
|
|
2839
|
+
Promise.resolve().then(() => {
|
|
2840
|
+
signal.throwIfAborted();
|
|
2841
|
+
return start();
|
|
2842
|
+
}).then(
|
|
2843
|
+
(value) => {
|
|
2844
|
+
signal.removeEventListener("abort", aborted);
|
|
2845
|
+
resolve(value);
|
|
2846
|
+
},
|
|
2847
|
+
(error) => {
|
|
2848
|
+
signal.removeEventListener("abort", aborted);
|
|
2849
|
+
reject(error);
|
|
2850
|
+
}
|
|
2851
|
+
);
|
|
2852
|
+
});
|
|
2853
|
+
}
|
|
2854
|
+
async function execute(context, service, limits, templateLoaderOptions, collections, fragmentLoaders, tools, loadTools) {
|
|
2855
|
+
context.signal.throwIfAborted();
|
|
2856
|
+
const controller = new AbortController();
|
|
2857
|
+
const operation = createOutputOperation(context, context.stdout);
|
|
2858
|
+
const signal = AbortSignal.any([operation.signal, controller.signal]);
|
|
2859
|
+
inheritYieldCheckpoint4(context.signal, signal);
|
|
2860
|
+
let iterator;
|
|
2861
|
+
let responseUsage;
|
|
2862
|
+
let closed = false;
|
|
2863
|
+
let ended = false;
|
|
2864
|
+
operation.registerCleanup(() => {
|
|
2865
|
+
if (closed) return;
|
|
2866
|
+
closed = true;
|
|
2867
|
+
controller.abort(new Error("llm request closed"));
|
|
2868
|
+
if (!ended && iterator) {
|
|
2869
|
+
const resource = iterator;
|
|
2870
|
+
void Promise.resolve().then(() => resource.return?.()).catch(() => {
|
|
2871
|
+
});
|
|
2872
|
+
}
|
|
2873
|
+
});
|
|
2874
|
+
let work = 0;
|
|
2875
|
+
const step = async () => {
|
|
2876
|
+
signal.throwIfAborted();
|
|
2877
|
+
if (closed) throw new Error("LLM invocation is closed");
|
|
2878
|
+
work++;
|
|
2879
|
+
if (work % 256 === 0) await yieldTurn11(signal);
|
|
2880
|
+
};
|
|
2881
|
+
let outputSpool;
|
|
2882
|
+
let usageSpool;
|
|
2883
|
+
let outputBytes2 = 0;
|
|
2884
|
+
let outputFailed = false;
|
|
2885
|
+
const writeOutput = async (sink, chunk) => {
|
|
2886
|
+
try {
|
|
2887
|
+
await sink.write(chunk);
|
|
2888
|
+
} catch (error) {
|
|
2889
|
+
outputFailed = true;
|
|
2890
|
+
throw error;
|
|
2891
|
+
}
|
|
2892
|
+
};
|
|
2893
|
+
const admitOutput = (size) => {
|
|
2894
|
+
if (size > (limits?.maxOutputBytes ?? Infinity) - outputBytes2) throw new FsError6("EFBIG", { message: "llm output byte limit exceeded" });
|
|
2895
|
+
outputBytes2 += size;
|
|
2896
|
+
};
|
|
2897
|
+
const write = async (chunk, immediate = false) => {
|
|
2898
|
+
admitOutput(chunk.byteLength);
|
|
2899
|
+
if (outputSpool && !immediate) {
|
|
2900
|
+
await outputSpool.write(chunk);
|
|
2901
|
+
return;
|
|
2902
|
+
}
|
|
2903
|
+
await writeOutput(operation.output, chunk);
|
|
2904
|
+
};
|
|
2905
|
+
const emitText = async (text) => {
|
|
2906
|
+
for (let offset = 0; offset < text.length; ) {
|
|
2907
|
+
await step();
|
|
2908
|
+
let end = Math.min(text.length, offset + 16384);
|
|
2909
|
+
const last = text.charCodeAt(end - 1);
|
|
2910
|
+
if (end < text.length && last >= 55296 && last <= 56319) end--;
|
|
2911
|
+
await write(new TextEncoder().encode(text.slice(offset, end)));
|
|
2912
|
+
offset = end;
|
|
2913
|
+
}
|
|
2914
|
+
};
|
|
2915
|
+
const input = createLlmInputBudget(limits);
|
|
2916
|
+
let shellInputBytes = 0;
|
|
2917
|
+
const admitInput = (size, materialized = false) => {
|
|
2918
|
+
context.inputBudget?.check(shellInputBytes + size);
|
|
2919
|
+
input.admit(size, materialized);
|
|
2920
|
+
shellInputBytes += size;
|
|
2921
|
+
};
|
|
2922
|
+
const admitBuffered = (size) => input.admit(size, true);
|
|
2923
|
+
const functionSessions = /* @__PURE__ */ new Set();
|
|
2924
|
+
const loadDefinitions = async (definitions, toolNames = [], discovery = false, pluginQuery) => {
|
|
2925
|
+
if (!loadTools) throw new Error("Python tool loading is not configured");
|
|
2926
|
+
const diagnostic = operation.child(context.stderr).output;
|
|
2927
|
+
const loaded = await operation.acquire(async () => {
|
|
2928
|
+
const value = await loadTools({
|
|
2929
|
+
definitions,
|
|
2930
|
+
toolNames,
|
|
2931
|
+
discovery,
|
|
2932
|
+
...pluginQuery ? { pluginQuery } : {},
|
|
2933
|
+
context: { ...context, signal, stdout: { write: (bytes) => write(bytes, true) }, stderr: { write: async (bytes) => {
|
|
2934
|
+
admitOutput(bytes.length);
|
|
2935
|
+
await writeOutput(diagnostic, bytes);
|
|
2936
|
+
} } },
|
|
2937
|
+
maxInputBytes: input.remaining(true),
|
|
2938
|
+
maxOutputBytes: limits?.maxOutputBytes ?? Infinity
|
|
2939
|
+
});
|
|
2940
|
+
let closing;
|
|
2941
|
+
return { tools: value.tools, ...value.plugins ? { plugins: value.plugins } : {}, ...value.toolboxes ? { toolboxes: value.toolboxes } : {}, close: () => closing ??= Promise.resolve().then(() => value.close()) };
|
|
2942
|
+
}, (value) => value.close());
|
|
2943
|
+
functionSessions.add(loaded);
|
|
2944
|
+
return loaded;
|
|
2945
|
+
};
|
|
2946
|
+
const invocationLoaders = { ...templateLoaderOptions, get maxBytes() {
|
|
2947
|
+
return input.remaining(true);
|
|
2948
|
+
}, admitBytes: admitBuffered };
|
|
2949
|
+
try {
|
|
2950
|
+
let argumentsValue = getCommandArguments(context);
|
|
2951
|
+
const argumentText = (index) => {
|
|
2952
|
+
const value = argumentsValue.values[index];
|
|
2953
|
+
if (value === void 0) throw new Error("Missing option argument");
|
|
2954
|
+
input.admit(shellValueByteLength3(value), true);
|
|
2955
|
+
const bytes = argumentsValue.bytes(index);
|
|
2956
|
+
if (!bytes) throw new Error("Missing option argument");
|
|
2957
|
+
return new TextDecoder("utf-8", { fatal: true }).decode(bytes);
|
|
2958
|
+
};
|
|
2959
|
+
let eager;
|
|
2960
|
+
let separator;
|
|
2961
|
+
for (let index = 0; index < argumentsValue.args.length; index++) {
|
|
2962
|
+
await step();
|
|
2963
|
+
const token = argumentsValue.args[index];
|
|
2964
|
+
if (token === "--") {
|
|
2965
|
+
separator = index;
|
|
2966
|
+
break;
|
|
2967
|
+
}
|
|
2968
|
+
if (!token.startsWith("-") || token === "-") break;
|
|
2969
|
+
if (token.startsWith("--")) {
|
|
2970
|
+
const equals = token.indexOf("=");
|
|
2971
|
+
const flag = equals < 0 ? token : token.slice(0, equals);
|
|
2972
|
+
if (flag !== "--version" && flag !== "--help") continue;
|
|
2973
|
+
argumentText(index);
|
|
2974
|
+
if (equals >= 0) {
|
|
2975
|
+
await writeDiagnostic2(context.stderr, `Error: Option '${flag}' does not take a value.
|
|
2976
|
+
`, signal);
|
|
2977
|
+
return { exitCode: 2 };
|
|
2978
|
+
}
|
|
2979
|
+
eager ??= flag === "--version" ? "version" : "help";
|
|
2980
|
+
} else {
|
|
2981
|
+
for (let cursor = 1; cursor < token.length; cursor++) {
|
|
2982
|
+
await step();
|
|
2983
|
+
if (token[cursor] !== "h") continue;
|
|
2984
|
+
argumentText(index);
|
|
2985
|
+
eager ??= "help";
|
|
2986
|
+
break;
|
|
2987
|
+
}
|
|
2988
|
+
}
|
|
2989
|
+
}
|
|
2990
|
+
if (eager === "version") {
|
|
2991
|
+
await emitText(`llm, version ${llmReferenceVersion}
|
|
2992
|
+
`);
|
|
2993
|
+
return { exitCode: 0 };
|
|
2994
|
+
}
|
|
2995
|
+
if (eager === "help") {
|
|
2996
|
+
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, -u/--usage; -- ends options\n");
|
|
2997
|
+
return { exitCode: 0 };
|
|
2998
|
+
}
|
|
2999
|
+
if (separator !== void 0) {
|
|
3000
|
+
argumentText(separator);
|
|
3001
|
+
argumentsValue = argumentsValue.select(Array.from({ length: argumentsValue.args.length - 1 }, (_, position) => position < separator ? position : position + 1));
|
|
3002
|
+
}
|
|
3003
|
+
if (argumentsValue.args.length === 2 && argumentsValue.args[0] === "models" && ["--help", "-h"].includes(argumentsValue.args[1])) {
|
|
3004
|
+
argumentText(0);
|
|
3005
|
+
argumentText(1);
|
|
3006
|
+
await emitText(modelsGroupHelp);
|
|
3007
|
+
return { exitCode: 0 };
|
|
3008
|
+
}
|
|
3009
|
+
if (argumentsValue.args[0] === "plugins") {
|
|
3010
|
+
argumentText(0);
|
|
3011
|
+
const tokens = Array.from({ length: argumentsValue.args.length - 1 }, (_, index) => argumentText(index + 1));
|
|
3012
|
+
return { exitCode: await pluginsCommand(
|
|
3013
|
+
tokens,
|
|
3014
|
+
emitText,
|
|
3015
|
+
(text) => writeDiagnostic2(context.stderr, text, signal),
|
|
3016
|
+
step,
|
|
3017
|
+
signal,
|
|
3018
|
+
loadTools ? async (query) => {
|
|
3019
|
+
const session = await loadDefinitions([], [], false, query);
|
|
3020
|
+
if (!session.plugins) throw new Error("Python runtime did not return plugin metadata");
|
|
3021
|
+
return session.plugins;
|
|
3022
|
+
} : void 0
|
|
3023
|
+
) };
|
|
3024
|
+
}
|
|
3025
|
+
if (argumentsValue.args[0] === "tools") {
|
|
3026
|
+
argumentText(0);
|
|
3027
|
+
const tokens = Array.from({ length: argumentsValue.args.length - 1 }, (_, index) => argumentText(index + 1));
|
|
3028
|
+
return { exitCode: await toolsCommand(tokens, tools, emitText, (text) => writeDiagnostic2(context.stderr, text, signal), step, signal, loadTools ? loadDefinitions : void 0) };
|
|
3029
|
+
}
|
|
3030
|
+
if (argumentsValue.args[0] === "fragments") {
|
|
3031
|
+
if (argumentsValue.args[1] !== "loaders") {
|
|
3032
|
+
await writeDiagnostic2(context.stderr, "Error: Fragment history is host-owned. Use a file, URL, or registered loader.\n", signal);
|
|
3033
|
+
return { exitCode: 2 };
|
|
3034
|
+
}
|
|
3035
|
+
const tokens = Array.from({ length: argumentsValue.args.length - 2 }, (_, index) => argumentText(index + 2));
|
|
3036
|
+
return { exitCode: await fragmentLoaderCommand(tokens, fragmentLoaders, emitText, (text) => writeDiagnostic2(context.stderr, text, signal)) };
|
|
3037
|
+
}
|
|
3038
|
+
if (argumentsValue.args[0] === "schemas" && argumentsValue.args[1] !== "dsl") {
|
|
3039
|
+
await writeDiagnostic2(context.stderr, "Error: Stored schema history is host-owned. Use an inline schema, file, template, or 'llm schemas dsl'.\n", signal);
|
|
3040
|
+
return { exitCode: 2 };
|
|
3041
|
+
}
|
|
3042
|
+
if (argumentsValue.args[0] === "schemas" && argumentsValue.args[1] === "dsl") {
|
|
3043
|
+
const tokens = Array.from({ length: argumentsValue.args.length - 2 }, (_, index) => argumentText(index + 2));
|
|
3044
|
+
const usage3 = "Usage: llm schemas dsl [OPTIONS] INPUT\n";
|
|
3045
|
+
if (tokens.includes("--help") || tokens.includes("-h")) {
|
|
3046
|
+
await emitText(usage3 + "\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");
|
|
3047
|
+
return { exitCode: 0 };
|
|
3048
|
+
}
|
|
3049
|
+
let multi = false, optionsEnded = false;
|
|
3050
|
+
const inputs = [];
|
|
3051
|
+
let failure;
|
|
3052
|
+
for (const token of tokens) {
|
|
3053
|
+
await step();
|
|
3054
|
+
if (!optionsEnded && token === "--") optionsEnded = true;
|
|
3055
|
+
else if (!optionsEnded && token === "--multi") multi = true;
|
|
3056
|
+
else if (!optionsEnded && token.startsWith("-") && token !== "-") {
|
|
3057
|
+
failure = `No such option: ${token}`;
|
|
3058
|
+
break;
|
|
3059
|
+
} else inputs.push(token);
|
|
3060
|
+
}
|
|
3061
|
+
failure ??= inputs.length === 0 ? "Missing argument 'INPUT'." : inputs.length > 1 ? `Got unexpected extra argument (${inputs[1]})` : void 0;
|
|
3062
|
+
if (failure) {
|
|
3063
|
+
await writeDiagnostic2(context.stderr, usage3 + "Try 'llm schemas dsl -h' for help.\n\nError: " + failure + "\n", signal);
|
|
3064
|
+
return { exitCode: 2 };
|
|
3065
|
+
}
|
|
3066
|
+
await emitText(JSON.stringify(parseLlmSchemaDsl(inputs[0], multi), null, 2) + "\n");
|
|
3067
|
+
return { exitCode: 0 };
|
|
3068
|
+
}
|
|
3069
|
+
if (argumentsValue.args[0] === "collections" || argumentsValue.args[0] === "similar" || argumentsValue.args[0] === "embed-multi" || collections && argumentsValue.args[0] === "embed") {
|
|
3070
|
+
const tokens = Array.from({ length: argumentsValue.args.length - 1 }, (_, index) => argumentText(index + 1));
|
|
3071
|
+
if (!collections) {
|
|
3072
|
+
await writeDiagnostic2(context.stderr, "Error: Collection storage is not configured\n", signal);
|
|
3073
|
+
return { exitCode: 1 };
|
|
3074
|
+
}
|
|
3075
|
+
return { exitCode: await collections.execute({ context: { ...context, signal }, service, command: argumentsValue.args[0], tokens, write, diagnostic: (text) => writeDiagnostic2(context.stderr, text, signal), step, admit: admitInput, maxConfigurationBytes: limits?.maxConfigurationBytes ?? Infinity, maxInputBytes: limits?.maxInputBytes ?? Infinity }) };
|
|
3076
|
+
}
|
|
3077
|
+
if (argumentsValue.args[0] === "embed") {
|
|
3078
|
+
const tokens = Array.from({ length: argumentsValue.args.length - 1 }, (_, index) => argumentText(index + 1));
|
|
3079
|
+
return { exitCode: await embeddingCommand({ ...context, signal }, service, tokens, write, (text) => writeDiagnostic2(context.stderr, text, signal), step, admitInput, limits?.maxConfigurationBytes) };
|
|
3080
|
+
}
|
|
3081
|
+
if (argumentsValue.args[0] === "embed-models") {
|
|
3082
|
+
const tokens = Array.from({ length: argumentsValue.args.length - 1 }, (_, index) => argumentText(index + 1));
|
|
3083
|
+
return { exitCode: await embeddingModelsCommand({ ...context, signal }, service, tokens, emitText, (text) => writeDiagnostic2(context.stderr, text, signal), step, limits?.maxConfigurationBytes) };
|
|
3084
|
+
}
|
|
3085
|
+
if (argumentsValue.args[0] === "templates") {
|
|
3086
|
+
let exitCode = 0;
|
|
3087
|
+
try {
|
|
3088
|
+
exitCode = await createLlmTemplateStore(context, invocationLoaders).command(Array.from({ length: argumentsValue.args.length - 1 }, (_, index) => argumentText(index + 1)), emitText, (text) => writeDiagnostic2(context.stderr, text, signal));
|
|
3089
|
+
} catch (error) {
|
|
3090
|
+
throw new Error(`Error: ${error instanceof Error ? error.message : "Template failed"}`);
|
|
3091
|
+
}
|
|
3092
|
+
return { exitCode };
|
|
3093
|
+
}
|
|
3094
|
+
const configurationInvocation = argumentsValue.args[0] === "keys" || argumentsValue.args[0] === "aliases" || argumentsValue.args[0] === "models" && ["default", "options"].includes(argumentsValue.args[1] ?? "") || argumentsValue.args[0] === "--version";
|
|
3095
|
+
if (configurationInvocation) {
|
|
3096
|
+
try {
|
|
3097
|
+
const tokens = Array.from({ length: argumentsValue.args.length }, (_, index) => argumentText(index));
|
|
3098
|
+
if (await configurationCommand(context, service, tokens, emitText, (text) => writeDiagnostic2(context.stderr, text, signal), admitInput, limits?.maxConfigurationBytes)) return { exitCode: 0 };
|
|
3099
|
+
} catch (error) {
|
|
3100
|
+
throw new Error(`Error: ${error instanceof Error ? error.message : "Configuration failed"}`);
|
|
3101
|
+
}
|
|
3102
|
+
}
|
|
3103
|
+
if (argumentsValue.args[0] === "models") {
|
|
3104
|
+
await listLlmModels(context, service, Array.from({ length: argumentsValue.args.length - 1 }, (_, index) => argumentText(index + 1)), emitText, step, limits?.maxConfigurationBytes);
|
|
3105
|
+
return { exitCode: 0 };
|
|
3106
|
+
}
|
|
3107
|
+
const isChat = argumentsValue.args[0] === "chat";
|
|
3108
|
+
const promptOffset = argumentsValue.args[0] === "prompt" || isChat ? 1 : 0;
|
|
3109
|
+
let args = await parse(argumentsValue.args.length - promptOffset, (index) => argumentText(index + promptOffset), step, isChat);
|
|
3110
|
+
if (args.help) {
|
|
3111
|
+
await emitText(chatHelp);
|
|
3112
|
+
return { exitCode: 0 };
|
|
3113
|
+
}
|
|
3114
|
+
if (!args.toolsDebug && context.env.LLM_TOOLS_DEBUG) {
|
|
3115
|
+
const raw = context.env.LLM_TOOLS_DEBUG, value = stripPythonWhitespace(raw).toLowerCase();
|
|
3116
|
+
if (["1", "true", "t", "yes", "y", "on"].includes(value)) args.toolsDebug = true;
|
|
3117
|
+
else if (!["", "0", "false", "f", "no", "n", "off"].includes(value)) throw new LlmPromptUsageError(`Usage: llm prompt [OPTIONS] [PROMPT]
|
|
3118
|
+
Try 'llm prompt --help' for help.
|
|
3119
|
+
|
|
3120
|
+
Error: Invalid value for '--td' / '--tools-debug': '${raw}' is not a valid boolean. Recognized values: , 0, 1, f, false, n, no, off, on, t, true, y, yes`);
|
|
3121
|
+
}
|
|
3122
|
+
const configuration = createLlmConfiguration(context, limits?.maxConfigurationBytes, invocationLoaders);
|
|
3123
|
+
if (args.model === void 0 && args.queries.length) {
|
|
3124
|
+
try {
|
|
3125
|
+
args.model = (await selectLlmModelByQuery(service.models, args.queries, await configuration.aliases(), signal)).model.id;
|
|
3126
|
+
} catch (error) {
|
|
3127
|
+
throw new Error(`Error: ${error instanceof Error ? error.message : "Model selection failed"}`);
|
|
3128
|
+
}
|
|
3129
|
+
}
|
|
3130
|
+
const templateStore = createLlmTemplateStore(context, invocationLoaders);
|
|
3131
|
+
const schemaInput = args.schemaMulti ?? args.schema;
|
|
3132
|
+
let schema = schemaInput ? await resolveLlmSchemaInput({ ...context, signal }, schemaInput, {
|
|
3133
|
+
multi: Boolean(args.schemaMulti),
|
|
3134
|
+
maxBytes: input.remaining(true),
|
|
3135
|
+
admitBytes: admitBuffered,
|
|
3136
|
+
loadTemplate: (name) => templateStore.load(name)
|
|
3137
|
+
}) : void 0;
|
|
3138
|
+
if (args.save && args.template) throw new Error("Error: --save cannot be used with --template");
|
|
3139
|
+
let stored;
|
|
3140
|
+
try {
|
|
3141
|
+
stored = args.template === void 0 ? void 0 : await templateStore.load(args.template);
|
|
3142
|
+
} catch (error) {
|
|
3143
|
+
throw new Error(`Error: ${error instanceof Error ? error.message : "Invalid template"}`);
|
|
3144
|
+
}
|
|
3145
|
+
if (stored) {
|
|
3146
|
+
if (!isChat && stored.schema_object) schema = stored.schema_object;
|
|
3147
|
+
try {
|
|
3148
|
+
validateLlmTemplateParameters(stored, args.params);
|
|
3149
|
+
} catch (error) {
|
|
3150
|
+
throw new Error(`Error: ${error instanceof Error ? error.message : "Invalid template"}`);
|
|
3151
|
+
}
|
|
3152
|
+
}
|
|
3153
|
+
const selected = args.model ?? stored?.model ?? (args.save ? void 0 : await configuration.defaultModel());
|
|
3154
|
+
const model = selected === void 0 ? void 0 : await configuration.resolveAlias(selected);
|
|
3155
|
+
let entry;
|
|
3156
|
+
try {
|
|
3157
|
+
entry = args.save && selected === void 0 ? void 0 : service.resolve(model, args.async && !args.save ? { async: true } : void 0);
|
|
3158
|
+
} catch (error) {
|
|
3159
|
+
if (!args.async || args.save) throw error;
|
|
3160
|
+
let detail = "";
|
|
3161
|
+
for await (const bytes of pythonRepr(error instanceof Error ? error.message : String(error), signal)) {
|
|
3162
|
+
detail += new TextDecoder().decode(bytes);
|
|
3163
|
+
if (detail.length >= 4096) break;
|
|
3164
|
+
}
|
|
3165
|
+
throw new Error("Error: " + detail);
|
|
3166
|
+
}
|
|
3167
|
+
if (!args.save && entry?.model.canStream === false) args.noStream = true;
|
|
3168
|
+
const streamed = entry !== void 0 && service.streamSources !== void 0 && entry.provider.completeSources !== void 0 && entry.model.inputSources !== false;
|
|
3169
|
+
const stagePrompt = streamed && stored === void 0 && args.save === void 0;
|
|
3170
|
+
if (isChat && args.promptSupplied) throw new LlmPromptUsageError(`Usage: llm chat [OPTIONS]
|
|
3171
|
+
Try 'llm chat -h' for help.
|
|
3172
|
+
|
|
3173
|
+
Error: Got unexpected extra argument (${args.prompt})`);
|
|
3174
|
+
const loadSelectedTools = async () => {
|
|
3175
|
+
let selectedTools2;
|
|
3176
|
+
try {
|
|
3177
|
+
const definitions = [...stored?.functions && Object.getOwnPropertyDescriptor(stored, "functionsTrusted")?.value !== false ? [stored.functions] : [], ...args.functions];
|
|
3178
|
+
const names = [...stored?.tools ?? [], ...args.toolNames];
|
|
3179
|
+
const dynamicNames = names.filter((name) => !tools.has(name));
|
|
3180
|
+
const loaded = definitions.length || loadTools && dynamicNames.length ? await loadDefinitions(definitions, dynamicNames) : { tools: [] };
|
|
3181
|
+
if (!loadTools) selectedTools2 = [...loaded.tools, ...selectLlmTools(tools, names)];
|
|
3182
|
+
else {
|
|
3183
|
+
selectedTools2 = loaded.tools.filter((tool) => tool.selectionIndex === void 0);
|
|
3184
|
+
const groups = /* @__PURE__ */ new Map();
|
|
3185
|
+
for (const tool of loaded.tools) if (tool.selectionIndex !== void 0) {
|
|
3186
|
+
const group = groups.get(tool.selectionIndex) ?? [];
|
|
3187
|
+
group.push(tool);
|
|
3188
|
+
groups.set(tool.selectionIndex, group);
|
|
3189
|
+
}
|
|
3190
|
+
let dynamicIndex = 0;
|
|
3191
|
+
for (const name of names) {
|
|
3192
|
+
if (tools.has(name)) selectedTools2.push(tools.get(name));
|
|
3193
|
+
else {
|
|
3194
|
+
selectedTools2.push(...groups.get(dynamicIndex) ?? []);
|
|
3195
|
+
dynamicIndex++;
|
|
3196
|
+
}
|
|
3197
|
+
}
|
|
3198
|
+
}
|
|
3199
|
+
} catch (error) {
|
|
3200
|
+
throw new Error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
3201
|
+
}
|
|
3202
|
+
return selectedTools2;
|
|
3203
|
+
};
|
|
3204
|
+
let selectedTools = isChat ? await loadSelectedTools() : void 0;
|
|
3205
|
+
const pendingChatFragments = [];
|
|
3206
|
+
const chat = isChat ? createChatInput({ resolveFragments: async (paths) => {
|
|
3207
|
+
pendingChatFragments.push(...await prepareFragments(paths, false));
|
|
3208
|
+
}, context: { ...context, signal, stdout: { write: (bytes) => write(bytes, true) } }, operation, write: emitText, diagnostic: (text) => writeDiagnostic2(context.stderr, text, signal), admit: (size, materialized) => materialized ? input.materialize(size) : admitInput(size, false) }) : void 0;
|
|
3209
|
+
const textSource = (value) => ({
|
|
3210
|
+
async dispose() {
|
|
3211
|
+
},
|
|
3212
|
+
bytes: { async *[Symbol.asyncIterator]() {
|
|
3213
|
+
for (let offset = 0; offset < value.length; ) {
|
|
3214
|
+
await step();
|
|
3215
|
+
let end = Math.min(value.length, offset + 16384);
|
|
3216
|
+
const last = value.charCodeAt(end - 1);
|
|
3217
|
+
if (end < value.length && last >= 55296 && last <= 56319) end--;
|
|
3218
|
+
yield new TextEncoder().encode(value.slice(offset, end));
|
|
3219
|
+
offset = end;
|
|
3220
|
+
}
|
|
3221
|
+
} }
|
|
3222
|
+
});
|
|
3223
|
+
const admittedFragments = /* @__PURE__ */ new WeakSet(), bufferedFragments = /* @__PURE__ */ new WeakSet();
|
|
3224
|
+
const remoteFragments = /* @__PURE__ */ new WeakSet();
|
|
3225
|
+
const pluginAttachments = [], pluginSourceAttachments = [];
|
|
3226
|
+
const loadFragments = async function* (paths, system) {
|
|
3227
|
+
for (const reference of paths) {
|
|
3228
|
+
await step();
|
|
3229
|
+
if (reference === "-") {
|
|
3230
|
+
if (!chat) {
|
|
3231
|
+
yield textSource("");
|
|
3232
|
+
continue;
|
|
3233
|
+
}
|
|
3234
|
+
const source2 = { bytes: { async *[Symbol.asyncIterator]() {
|
|
3235
|
+
const input2 = chat.approvalInput();
|
|
3236
|
+
while (true) {
|
|
3237
|
+
const next = await input2.next();
|
|
3238
|
+
if (next.done) return;
|
|
3239
|
+
yield next.value;
|
|
3240
|
+
}
|
|
3241
|
+
} }, async dispose() {
|
|
3242
|
+
} };
|
|
3243
|
+
admittedFragments.add(source2);
|
|
3244
|
+
yield source2;
|
|
3245
|
+
continue;
|
|
3246
|
+
}
|
|
3247
|
+
if (reference.startsWith("http://") || reference.startsWith("https://")) {
|
|
3248
|
+
const fetch = context.capabilities?.fetch;
|
|
3249
|
+
if (!fetch) throw new Error("Fragment URL loading is not configured");
|
|
3250
|
+
const source2 = await operation.acquire(() => createLlmUrlFragmentSource({
|
|
3251
|
+
url: reference,
|
|
3252
|
+
fetch,
|
|
3253
|
+
signal,
|
|
3254
|
+
maxBytes: input.remaining(!streamed),
|
|
3255
|
+
admitBytes: (size) => {
|
|
3256
|
+
context.inputBudget?.check(shellInputBytes + size);
|
|
3257
|
+
shellInputBytes += size;
|
|
3258
|
+
}
|
|
3259
|
+
}), (value) => value.dispose());
|
|
3260
|
+
remoteFragments.add(source2);
|
|
3261
|
+
yield source2;
|
|
3262
|
+
continue;
|
|
3263
|
+
}
|
|
3264
|
+
if (getLlmFragmentPrefix(reference) !== void 0) {
|
|
3265
|
+
try {
|
|
3266
|
+
for await (const loaded of loadLlmPluginFragments(reference, fragmentLoaders, { fs: context.fs, cwd: context.cwd, signal, capabilities: context.capabilities, get maxBytes() {
|
|
3267
|
+
return input.remaining(!streamed);
|
|
3268
|
+
} }, !system)) {
|
|
3269
|
+
const source2 = await operation.acquire(() => loaded.source, (value) => value.dispose());
|
|
3270
|
+
if (loaded.type === "text") {
|
|
3271
|
+
yield source2;
|
|
3272
|
+
continue;
|
|
3273
|
+
}
|
|
3274
|
+
input.admitText(loaded.mimeType);
|
|
3275
|
+
if (loaded.id !== void 0) input.admitText(loaded.id);
|
|
3276
|
+
if (!acceptsMimeType(entry.model.attachmentTypes ?? [], loaded.mimeType)) throw new Error(`Model ${entry.model.id} does not accept ${loaded.mimeType}`);
|
|
3277
|
+
const identity = loaded.id === void 0 ? {} : { id: loaded.id };
|
|
3278
|
+
if (streamed) {
|
|
3279
|
+
const spool = await operation.acquire(() => createLlmSpool(context.fs, context.cwd, signal, "input"), (value) => value.close());
|
|
3280
|
+
for await (const bytes of sourceBytes(source2.bytes, signal)) {
|
|
3281
|
+
admitInput(bytes.byteLength, false);
|
|
3282
|
+
await spool.write(bytes);
|
|
3283
|
+
}
|
|
3284
|
+
pluginSourceAttachments.push({ mimeType: loaded.mimeType, source: { bytes: spool.replay(), dispose: spool.close }, ...identity });
|
|
3285
|
+
} else {
|
|
3286
|
+
const chunks = [];
|
|
3287
|
+
let size = 0;
|
|
3288
|
+
for await (const bytes2 of sourceBytes(source2.bytes, signal)) {
|
|
3289
|
+
admitInput(bytes2.byteLength, true);
|
|
3290
|
+
chunks.push(bytes2.slice());
|
|
3291
|
+
size += bytes2.byteLength;
|
|
3292
|
+
}
|
|
3293
|
+
const bytes = new Uint8Array(size);
|
|
3294
|
+
let offset = 0;
|
|
3295
|
+
for (const chunk of chunks) {
|
|
3296
|
+
bytes.set(chunk, offset);
|
|
3297
|
+
offset += chunk.length;
|
|
3298
|
+
}
|
|
3299
|
+
pluginAttachments.push({ mimeType: loaded.mimeType, bytes, ...identity });
|
|
3300
|
+
}
|
|
3301
|
+
}
|
|
3302
|
+
} catch (error) {
|
|
3303
|
+
signal.throwIfAborted();
|
|
3304
|
+
throw new Error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
3305
|
+
}
|
|
3306
|
+
continue;
|
|
3307
|
+
}
|
|
3308
|
+
const path = pathOf3(context, reference);
|
|
3309
|
+
let source;
|
|
3310
|
+
try {
|
|
3311
|
+
source = await operation.acquire(() => fileSource({ fs: context.fs, path, signal, maxBytes: input.remaining(!streamed) }), (value) => value.dispose());
|
|
3312
|
+
} catch (error) {
|
|
3313
|
+
if (error instanceof FsError6 && error.code === "ENOENT") throw new Error(`Error: Fragment '${reference}' not found`);
|
|
3314
|
+
throw error;
|
|
3315
|
+
}
|
|
3316
|
+
yield source;
|
|
3317
|
+
}
|
|
3318
|
+
};
|
|
3319
|
+
const admitFragment = (size, source) => {
|
|
3320
|
+
if (admittedFragments.has(source)) {
|
|
3321
|
+
if (!streamed && !bufferedFragments.has(source)) input.materialize(size);
|
|
3322
|
+
} else if (remoteFragments.has(source)) input.admit(size, !streamed);
|
|
3323
|
+
else admitInput(size, !streamed);
|
|
3324
|
+
};
|
|
3325
|
+
const prepareFragments = async (paths, system) => {
|
|
3326
|
+
if (!paths.length) return [];
|
|
3327
|
+
let hasText = false;
|
|
3328
|
+
const source = await operation.acquire(() => createLlmFragmentSource({
|
|
3329
|
+
fs: context.fs,
|
|
3330
|
+
directory: context.cwd,
|
|
3331
|
+
signal,
|
|
3332
|
+
system,
|
|
3333
|
+
normalizeNewlines: true,
|
|
3334
|
+
fragments: { async *[Symbol.asyncIterator]() {
|
|
3335
|
+
for await (const source2 of loadFragments(paths, system)) {
|
|
3336
|
+
hasText = true;
|
|
3337
|
+
yield source2;
|
|
3338
|
+
}
|
|
3339
|
+
} },
|
|
3340
|
+
admitBytes: admitFragment,
|
|
3341
|
+
admitSeparator: (size) => input.admit(size, !streamed)
|
|
3342
|
+
}), (value) => value.dispose());
|
|
3343
|
+
if (!hasText) {
|
|
3344
|
+
await source.dispose();
|
|
3345
|
+
return [];
|
|
3346
|
+
}
|
|
3347
|
+
const retained = { ...source, normalizeNewlines: false };
|
|
3348
|
+
admittedFragments.add(retained);
|
|
3349
|
+
bufferedFragments.add(retained);
|
|
3350
|
+
return [retained];
|
|
3351
|
+
};
|
|
3352
|
+
const compose = async (paths, tail, system, prepared = []) => operation.acquire(
|
|
3353
|
+
() => createLlmFragmentSource({ fs: context.fs, directory: context.cwd, signal, fragments: { async *[Symbol.asyncIterator]() {
|
|
3354
|
+
yield* prepared;
|
|
3355
|
+
yield* loadFragments(paths, system);
|
|
3356
|
+
} }, tail, system, normalizeNewlines: true, admitBytes: admitFragment, admitSeparator: (size) => input.admit(size, !streamed) }),
|
|
3357
|
+
(value) => value.dispose()
|
|
3358
|
+
);
|
|
3359
|
+
const chatMessages = [];
|
|
3360
|
+
const initialArgs = args;
|
|
3361
|
+
let chatTurn = 0;
|
|
3362
|
+
let initialPromptFragments = [], initialSystemFragments = [];
|
|
3363
|
+
const initialAttachments = [], initialSourceAttachments = [];
|
|
3364
|
+
if (chat) {
|
|
3365
|
+
validateModelOptions(entry.model, { ...await configuration.modelOptions(entry.model.id), ...args.options });
|
|
3366
|
+
initialPromptFragments = await prepareFragments(args.fragments, false);
|
|
3367
|
+
initialSystemFragments = await prepareFragments(args.systemFragments, true);
|
|
3368
|
+
initialAttachments.push(...pluginAttachments);
|
|
3369
|
+
initialSourceAttachments.push(...pluginSourceAttachments);
|
|
3370
|
+
await emitText(`Chatting with ${entry.model.id}
|
|
3371
|
+
Type 'exit' or 'quit' to exit
|
|
3372
|
+
Type '!multi' to enter multiple lines, then '!end' to finish
|
|
3373
|
+
Type '!edit' to open your default editor and modify the prompt
|
|
3374
|
+
Type '!fragment <my_fragment> [<another_fragment> ...]' to insert one or more fragments
|
|
3375
|
+
`);
|
|
3376
|
+
}
|
|
3377
|
+
while (true) {
|
|
3378
|
+
if (chat) {
|
|
3379
|
+
pluginAttachments.length = 0;
|
|
3380
|
+
pluginSourceAttachments.length = 0;
|
|
3381
|
+
}
|
|
3382
|
+
const chatPrompt = await chat?.next();
|
|
3383
|
+
const preparedPrompt = [...chatPrompt?.includeInitialFragments ? initialPromptFragments : [], ...pendingChatFragments.splice(0)];
|
|
3384
|
+
const preparedSystem = chatTurn ? [] : initialSystemFragments;
|
|
3385
|
+
if (chat) {
|
|
3386
|
+
if (chatPrompt.includeInitialFragments) {
|
|
3387
|
+
pluginAttachments.push(...initialAttachments);
|
|
3388
|
+
pluginSourceAttachments.push(...initialSourceAttachments);
|
|
3389
|
+
}
|
|
3390
|
+
args = {
|
|
3391
|
+
...initialArgs,
|
|
3392
|
+
options: { ...initialArgs.options },
|
|
3393
|
+
attachments: [...initialArgs.attachments],
|
|
3394
|
+
fragments: [],
|
|
3395
|
+
systemFragments: []
|
|
3396
|
+
};
|
|
3397
|
+
if (chatTurn) delete args.system;
|
|
3398
|
+
if (stored) {
|
|
3399
|
+
const decoder2 = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true });
|
|
3400
|
+
args.prompt = "";
|
|
3401
|
+
for await (const bytes of chatPrompt.spool.replay()) {
|
|
3402
|
+
input.materialize(bytes.length);
|
|
3403
|
+
args.prompt += decoder2.decode(bytes, { stream: true });
|
|
3404
|
+
}
|
|
3405
|
+
args.prompt += decoder2.decode();
|
|
3406
|
+
args.promptSupplied = true;
|
|
3407
|
+
}
|
|
3408
|
+
}
|
|
3409
|
+
let stdinIterator;
|
|
3410
|
+
const openStdin = async (approval = false) => approval && chat ? chat.approvalInput() : stdinIterator ??= await operation.acquire(() => chatPrompt ? chatPrompt.spool.replay()[Symbol.asyncIterator]() : context.stdinInput ? { next: () => approval && context.stdinInput.readAvailable ? context.stdinInput.readAvailable(4096, signal, 10) : context.stdinInput.read(approval ? 1 : Math.min(65536, input.remaining(!stagePrompt) + 1), signal) } : context.stdin[Symbol.asyncIterator](), async (resource) => {
|
|
3411
|
+
await resource.return?.();
|
|
3412
|
+
});
|
|
3413
|
+
let promptSpool;
|
|
3414
|
+
let stdinBytes = 0;
|
|
3415
|
+
const fragments = [];
|
|
3416
|
+
const decoder = new TextDecoder("utf-8", { fatal: true });
|
|
3417
|
+
const templateUsesInput = stored !== void 0 && llmTemplateUsesInput(stored);
|
|
3418
|
+
const readTerminalPrompt = !args.promptSupplied && !args.save && !args.attachments.length && !schema && !args.fragments.length;
|
|
3419
|
+
if (!(chat && stored) && (stored === void 0 || templateUsesInput) && (chat || !context.shellPredicates?.terminal(0) || readTerminalPrompt)) {
|
|
3420
|
+
const stdin = await openStdin();
|
|
3421
|
+
while (true) {
|
|
3422
|
+
await step();
|
|
3423
|
+
const result = await interrupted(() => stdin.next(), signal);
|
|
3424
|
+
signal.throwIfAborted();
|
|
3425
|
+
if (result.done) break;
|
|
3426
|
+
const chunk = result.value;
|
|
3427
|
+
if (!(chunk instanceof Uint8Array)) throw new TypeError("Byte sources must yield Uint8Array chunks");
|
|
3428
|
+
if (!chat) admitInput(chunk.byteLength, !stagePrompt);
|
|
3429
|
+
else if (!stagePrompt) input.materialize(chunk.byteLength);
|
|
3430
|
+
stdinBytes += chunk.byteLength;
|
|
3431
|
+
if (stagePrompt) {
|
|
3432
|
+
for (let offset = 0; offset < chunk.byteLength; offset += 16384) {
|
|
3433
|
+
await step();
|
|
3434
|
+
decoder.decode(chunk.subarray(offset, Math.min(offset + 16384, chunk.byteLength)), { stream: true });
|
|
3435
|
+
}
|
|
3436
|
+
if (chunk.byteLength) {
|
|
3437
|
+
promptSpool ??= await operation.acquire(() => createLlmSpool(context.fs, context.cwd, signal, "input"), (spool) => spool.close());
|
|
3438
|
+
await promptSpool.write(chunk);
|
|
3439
|
+
}
|
|
3440
|
+
} else fragments.push(decoder.decode(chunk, { stream: true }));
|
|
3441
|
+
}
|
|
3442
|
+
}
|
|
3443
|
+
const decoderTail = decoder.decode();
|
|
3444
|
+
if (!stagePrompt) fragments.push(decoderTail);
|
|
3445
|
+
if (stdinBytes && args.prompt) input.admit(1, !stagePrompt);
|
|
3446
|
+
if (promptSpool && args.prompt) {
|
|
3447
|
+
if (stdinBytes) await promptSpool.write(new TextEncoder().encode(" "));
|
|
3448
|
+
for (let start = 0; start < args.prompt.length; ) {
|
|
3449
|
+
await step();
|
|
3450
|
+
let end = Math.min(args.prompt.length, start + 8192);
|
|
3451
|
+
const last = args.prompt.charCodeAt(end - 1);
|
|
3452
|
+
if (end < args.prompt.length && last >= 55296 && last <= 56319) end--;
|
|
3453
|
+
await promptSpool.write(new TextEncoder().encode(args.prompt.slice(start, end)));
|
|
3454
|
+
start = end;
|
|
3455
|
+
}
|
|
3456
|
+
}
|
|
3457
|
+
const content = fragments.join("");
|
|
3458
|
+
let prompt = content && args.prompt ? `${content} ${args.prompt}` : content || args.prompt;
|
|
3459
|
+
if (args.save) {
|
|
3460
|
+
const attachments2 = args.attachments.filter((item) => item.mimeType === void 0).map((item) => item.path);
|
|
3461
|
+
const attachmentTypes = args.attachments.filter((item) => item.mimeType !== void 0).map((item) => ({ type: item.mimeType, value: item.path }));
|
|
3462
|
+
const saved = {
|
|
3463
|
+
...schema === void 0 ? {} : { schema_object: schema },
|
|
3464
|
+
...args.model === void 0 ? {} : { model: entry.model.id },
|
|
3465
|
+
...prompt ? { prompt } : {},
|
|
3466
|
+
...args.system === void 0 ? {} : { system: args.system },
|
|
3467
|
+
...args.extract === "last" ? { extract_last: true } : args.extract === "first" ? { extract: true } : {},
|
|
3468
|
+
...Object.keys(args.params).length ? { defaults: args.params } : {},
|
|
3469
|
+
...Object.keys(args.options).length ? { options: args.options } : {},
|
|
3470
|
+
...args.functions.length ? { functions: args.functions.join("\n\n") } : {},
|
|
3471
|
+
...args.toolNames.length ? { tools: args.toolNames } : {},
|
|
3472
|
+
...args.fragments.length ? { fragments: args.fragments } : {},
|
|
3473
|
+
...args.systemFragments.length ? { system_fragments: args.systemFragments } : {},
|
|
3474
|
+
...attachments2.length ? { attachments: attachments2 } : {},
|
|
3475
|
+
...attachmentTypes.length ? { attachment_types: attachmentTypes } : {}
|
|
3476
|
+
};
|
|
3477
|
+
await templateStore.save(args.save, saved);
|
|
3478
|
+
return { exitCode: 0 };
|
|
3479
|
+
}
|
|
3480
|
+
if (stored) {
|
|
3481
|
+
try {
|
|
3482
|
+
if (!chat && !args.extract && (stored.extract_last || stored.extract)) {
|
|
3483
|
+
args.extract = stored.extract_last ? "last" : "first";
|
|
3484
|
+
args.noStream = true;
|
|
3485
|
+
}
|
|
3486
|
+
const evaluated = evaluateLlmTemplate(stored, templateUsesInput ? prompt : "", args.params, input.admitText);
|
|
3487
|
+
if (evaluated.prompt && !templateUsesInput && args.prompt) input.admit(1, true);
|
|
3488
|
+
if (evaluated.prompt) prompt = !templateUsesInput && args.prompt ? `${evaluated.prompt}
|
|
3489
|
+
${args.prompt}` : evaluated.prompt;
|
|
3490
|
+
if (args.system === void 0 && evaluated.system !== void 0) args.system = evaluated.system;
|
|
3491
|
+
} catch (error) {
|
|
3492
|
+
throw new Error(`Error: ${error instanceof Error ? error.message : "Invalid template"}`);
|
|
3493
|
+
}
|
|
3494
|
+
}
|
|
3495
|
+
if (chat && (stored ? ["exit", "quit"].includes(stripPythonWhitespace(prompt)) : chatPrompt.exit)) return { exitCode: 0 };
|
|
3496
|
+
if (!entry) throw new Error("No model selected; use --model or configure defaultModel");
|
|
3497
|
+
args.options = { ...await configuration.modelOptions(entry.model.id), ...chat ? {} : stored?.options, ...args.options };
|
|
3498
|
+
args.attachments = [
|
|
3499
|
+
...(chat ? [] : stored?.attachments ?? []).map((path) => ({ path })),
|
|
3500
|
+
...args.attachments.filter((item) => item.mimeType === void 0),
|
|
3501
|
+
...(chat ? [] : stored?.attachment_types ?? []).map((item) => ({ path: item.value, mimeType: item.type })),
|
|
3502
|
+
...args.attachments.filter((item) => item.mimeType !== void 0)
|
|
3503
|
+
];
|
|
3504
|
+
const attachments = [];
|
|
3505
|
+
const sourceAttachments = [];
|
|
3506
|
+
let composedPrompt, composedSystem;
|
|
3507
|
+
const promptFragments = [...chat ? [] : stored?.fragments ?? [], ...args.fragments];
|
|
3508
|
+
const systemFragments = [...chat ? [] : stored?.system_fragments ?? [], ...args.systemFragments];
|
|
3509
|
+
const materialize = async (source) => {
|
|
3510
|
+
const decoder2 = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true });
|
|
3511
|
+
let result = "";
|
|
3512
|
+
for await (const bytes of source.bytes) result += decoder2.decode(bytes, { stream: true });
|
|
3513
|
+
return result + decoder2.decode();
|
|
3514
|
+
};
|
|
3515
|
+
if (promptFragments.length || preparedPrompt.length) {
|
|
3516
|
+
composedPrompt = await compose(promptFragments, promptSpool ? { bytes: promptSpool.replay(), dispose: promptSpool.close } : textSource(prompt), false, preparedPrompt);
|
|
3517
|
+
if (!streamed) prompt = await materialize(composedPrompt);
|
|
3518
|
+
}
|
|
3519
|
+
if (systemFragments.length || preparedSystem.length) {
|
|
3520
|
+
composedSystem = await compose(systemFragments, textSource(args.system ?? ""), true, preparedSystem);
|
|
3521
|
+
if (!streamed) args.system = await materialize(composedSystem);
|
|
3522
|
+
}
|
|
3523
|
+
for (const attachment of args.attachments) {
|
|
3524
|
+
await step();
|
|
3525
|
+
if (attachment.path.includes("://")) {
|
|
3526
|
+
const reference = await resolveUrlAttachment({ ...context, signal }, attachment.path, attachment.mimeType);
|
|
3527
|
+
if (attachment.mimeType === void 0) admitInput(shellValueByteLength3(reference.mimeType), true);
|
|
3528
|
+
if (!acceptsMimeType(entry.model.attachmentTypes ?? [], reference.mimeType)) throw new Error(`Model ${entry.model.id} does not accept ${reference.mimeType}`);
|
|
3529
|
+
if (acceptsMimeType(["image/*"], reference.mimeType)) {
|
|
3530
|
+
if (!entry.model.attachmentUrls) throw new Error(`Model ${entry.model.id} does not support URL attachments`);
|
|
3531
|
+
if (streamed) sourceAttachments.push(reference);
|
|
3532
|
+
else attachments.push(reference);
|
|
3533
|
+
} else {
|
|
3534
|
+
const fetch = context.capabilities?.fetch;
|
|
3535
|
+
if (!fetch) throw new Error("Attachment URL loading is not configured");
|
|
3536
|
+
const source = await operation.acquire(() => createLlmUrlSource({
|
|
3537
|
+
url: reference.url,
|
|
3538
|
+
fetch,
|
|
3539
|
+
signal,
|
|
3540
|
+
maxBytes: input.remaining(!streamed),
|
|
3541
|
+
admitBytes: (bytes2) => admitInput(bytes2, !streamed)
|
|
3542
|
+
}), (source2) => source2.dispose());
|
|
3543
|
+
const identity = acceptsMimeType(["application/pdf"], reference.mimeType) ? { id: await getLlmAttachmentUrlId(reference.url, signal) } : {};
|
|
3544
|
+
if (streamed) sourceAttachments.push({ mimeType: reference.mimeType, source, ...identity });
|
|
3545
|
+
else {
|
|
3546
|
+
const chunks = [];
|
|
3547
|
+
let size = 0;
|
|
3548
|
+
for await (const chunk of source.bytes) {
|
|
3549
|
+
chunks.push(chunk);
|
|
3550
|
+
size += chunk.length;
|
|
3551
|
+
}
|
|
3552
|
+
const bytes2 = new Uint8Array(size);
|
|
3553
|
+
let offset = 0;
|
|
3554
|
+
for (const chunk of chunks) {
|
|
3555
|
+
bytes2.set(chunk, offset);
|
|
3556
|
+
offset += chunk.length;
|
|
3557
|
+
}
|
|
3558
|
+
attachments.push({ mimeType: reference.mimeType, bytes: bytes2, ...identity });
|
|
3559
|
+
}
|
|
3560
|
+
}
|
|
3561
|
+
continue;
|
|
3562
|
+
}
|
|
3563
|
+
const path = pathOf3(context, attachment.path);
|
|
3564
|
+
const stat = await interrupted(() => context.fs.stat(path, { signal }), signal);
|
|
3565
|
+
context.inputBudget?.check(shellInputBytes + stat.size);
|
|
3566
|
+
input.check(stat.size, !streamed);
|
|
3567
|
+
const remainingBytes = Math.min(
|
|
3568
|
+
input.remaining(!streamed),
|
|
3569
|
+
(context.inputBudget?.maxBytes ?? Infinity) - shellInputBytes
|
|
3570
|
+
);
|
|
3571
|
+
if (streamed) {
|
|
3572
|
+
const source = await operation.acquire(() => fileSource({ fs: context.fs, path, signal, maxBytes: remainingBytes, expectedStat: stat }), (source2) => source2.dispose());
|
|
3573
|
+
const chunks = source.bytes[Symbol.asyncIterator]();
|
|
3574
|
+
const first = await interrupted(() => chunks.next(), signal);
|
|
3575
|
+
const mimeType2 = attachment.mimeType ?? sniffMimeType(path, first.done ? new Uint8Array() : first.value);
|
|
3576
|
+
if (!acceptsMimeType(entry.model.attachmentTypes ?? [], mimeType2)) throw new Error(`Model ${entry.model.id} does not accept ${mimeType2}`);
|
|
3577
|
+
admitInput(stat.size);
|
|
3578
|
+
let closed2 = false, consumed = false;
|
|
3579
|
+
sourceAttachments.push({ mimeType: mimeType2, source: {
|
|
3580
|
+
async dispose() {
|
|
3581
|
+
closed2 = true;
|
|
3582
|
+
await source.dispose();
|
|
3583
|
+
},
|
|
3584
|
+
bytes: { async *[Symbol.asyncIterator]() {
|
|
3585
|
+
if (closed2 || consumed) throw new FsError6("EBADF", { message: "LLM attachment source is closed" });
|
|
3586
|
+
consumed = true;
|
|
3587
|
+
signal.throwIfAborted();
|
|
3588
|
+
if (!first.done) yield first.value;
|
|
3589
|
+
while (true) {
|
|
3590
|
+
if (closed2) throw new FsError6("EBADF", { message: "LLM attachment source is closed" });
|
|
3591
|
+
const next = await interrupted(() => chunks.next(), signal);
|
|
3592
|
+
if (closed2) throw new FsError6("EBADF", { message: "LLM attachment source is closed" });
|
|
3593
|
+
if (next.done) break;
|
|
3594
|
+
yield next.value;
|
|
3595
|
+
}
|
|
3596
|
+
} }
|
|
3597
|
+
} });
|
|
3598
|
+
continue;
|
|
3599
|
+
}
|
|
3600
|
+
const bytes = await interrupted(() => context.fs.readFile(path, {
|
|
3601
|
+
signal,
|
|
3602
|
+
...remainingBytes === Infinity ? {} : { maxBytes: remainingBytes }
|
|
3603
|
+
}), signal);
|
|
3604
|
+
signal.throwIfAborted();
|
|
3605
|
+
if (!(bytes instanceof Uint8Array)) throw new TypeError("Attachment read must return Uint8Array");
|
|
3606
|
+
admitInput(bytes.byteLength, true);
|
|
3607
|
+
const mimeType = attachment.mimeType ?? sniffMimeType(path, bytes);
|
|
3608
|
+
if (!acceptsMimeType(entry.model.attachmentTypes ?? [], mimeType)) throw new Error(`Model ${entry.model.id} does not accept ${mimeType}`);
|
|
3609
|
+
attachments.push({ mimeType, bytes: new Uint8Array(bytes), ...acceptsMimeType(["application/pdf"], mimeType) && !bytes.length ? { id: await attachmentBytesId(bytes, signal) } : {} });
|
|
3610
|
+
}
|
|
3611
|
+
selectedTools ??= await loadSelectedTools();
|
|
3612
|
+
attachments.push(...pluginAttachments);
|
|
3613
|
+
sourceAttachments.push(...pluginSourceAttachments);
|
|
3614
|
+
const resolvedKey = args.key === void 0 ? void 0 : await configuration.resolveKey(args.key);
|
|
3615
|
+
const request = {
|
|
3616
|
+
...args.async ? { async: true } : {},
|
|
3617
|
+
...schema === void 0 ? {} : { schema },
|
|
3618
|
+
model: entry.model.id,
|
|
3619
|
+
prompt,
|
|
3620
|
+
...args.system === void 0 ? {} : { system: args.system },
|
|
3621
|
+
attachments,
|
|
3622
|
+
options: args.options,
|
|
3623
|
+
signal,
|
|
3624
|
+
stream: !args.noStream,
|
|
3625
|
+
...resolvedKey === void 0 ? {} : { key: resolvedKey }
|
|
3626
|
+
};
|
|
3627
|
+
signal.throwIfAborted();
|
|
3628
|
+
if (args.noStream) outputSpool = await operation.acquire(() => createLlmSpool(context.fs, context.cwd, signal), (spool) => spool.close());
|
|
3629
|
+
if (selectedTools.length || chat) {
|
|
3630
|
+
const debugOutput = args.toolsDebug ? operation.child(context.stderr).output : void 0;
|
|
3631
|
+
const events = promptToolChain({
|
|
3632
|
+
...chat ? { chatMessages } : {},
|
|
3633
|
+
context: { ...context, signal },
|
|
3634
|
+
operation,
|
|
3635
|
+
service,
|
|
3636
|
+
streamed,
|
|
3637
|
+
tools: selectedTools,
|
|
3638
|
+
...debugOutput ? { debugWrite: async (bytes) => {
|
|
3639
|
+
admitOutput(bytes.length);
|
|
3640
|
+
await writeOutput(debugOutput, bytes);
|
|
3641
|
+
} } : {},
|
|
3642
|
+
...args.toolsApprove ? { beforeCall: createToolApproval({ context: { ...context, signal }, openInput: () => openStdin(true), write: (bytes) => write(bytes, true), admitInput: chat ? () => {
|
|
3643
|
+
} : admitInput }) } : {},
|
|
3644
|
+
chainLimit: args.chainLimit,
|
|
3645
|
+
maxOutputBytes: limits?.maxOutputBytes ?? Infinity,
|
|
3646
|
+
remainingInput: () => input.remaining(!streamed),
|
|
3647
|
+
admitInput,
|
|
3648
|
+
textSource,
|
|
3649
|
+
request: {
|
|
3650
|
+
...args.async ? { async: true } : {},
|
|
3651
|
+
model: request.model,
|
|
3652
|
+
options: request.options,
|
|
3653
|
+
signal,
|
|
3654
|
+
stream: request.stream,
|
|
3655
|
+
...schema === void 0 ? {} : { schema },
|
|
3656
|
+
...resolvedKey === void 0 ? {} : { key: resolvedKey },
|
|
3657
|
+
prompt: (streamed ? composedPrompt : void 0) ?? (promptSpool ? { bytes: promptSpool.replay(), dispose: promptSpool.close } : textSource(prompt)),
|
|
3658
|
+
...streamed && composedSystem ? { system: composedSystem } : args.system === void 0 ? {} : { system: textSource(args.system) },
|
|
3659
|
+
attachments: streamed ? sourceAttachments : attachments.map((attachment) => attachment.url === void 0 ? { mimeType: attachment.mimeType, ...attachment.id === void 0 ? {} : { id: attachment.id }, source: { bytes: { async *[Symbol.asyncIterator]() {
|
|
3660
|
+
yield attachment.bytes;
|
|
3661
|
+
} }, async dispose() {
|
|
3662
|
+
} } } : attachment)
|
|
3663
|
+
}
|
|
3664
|
+
});
|
|
3665
|
+
iterator = (async function* () {
|
|
3666
|
+
try {
|
|
3667
|
+
for await (const event of events) {
|
|
3668
|
+
if (event.type === "text") yield event.text;
|
|
3669
|
+
else if (event.type === "bytes") yield event.data;
|
|
3670
|
+
else if (args.usage) {
|
|
3671
|
+
usageSpool ??= await operation.acquire(() => createLlmSpool(context.fs, context.cwd, signal), (spool) => spool.close());
|
|
3672
|
+
await usageSpool.write(new TextEncoder().encode("Token usage: "));
|
|
3673
|
+
for await (const bytes of serializeLlmTokenUsage(event.response.usage, signal)) await usageSpool.write(bytes);
|
|
3674
|
+
await usageSpool.write(Uint8Array.of(10));
|
|
3675
|
+
}
|
|
3676
|
+
}
|
|
3677
|
+
} catch (error) {
|
|
3678
|
+
signal.throwIfAborted();
|
|
3679
|
+
if (outputFailed) throw error;
|
|
3680
|
+
throw new Error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
3681
|
+
}
|
|
3682
|
+
})()[Symbol.asyncIterator]();
|
|
3683
|
+
} else if (streamed) {
|
|
3684
|
+
const events = service.streamSources({
|
|
3685
|
+
...args.async ? { async: true } : {},
|
|
3686
|
+
model: request.model,
|
|
3687
|
+
options: request.options,
|
|
3688
|
+
signal,
|
|
3689
|
+
stream: request.stream,
|
|
3690
|
+
prompt: composedPrompt ?? (promptSpool ? { bytes: promptSpool.replay(), dispose: promptSpool.close } : textSource(prompt)),
|
|
3691
|
+
...schema === void 0 ? {} : { schema },
|
|
3692
|
+
...composedSystem ? { system: composedSystem } : args.system === void 0 ? {} : { system: textSource(args.system) },
|
|
3693
|
+
...resolvedKey === void 0 ? {} : { key: resolvedKey },
|
|
3694
|
+
attachments: sourceAttachments
|
|
3695
|
+
});
|
|
3696
|
+
iterator = (async function* () {
|
|
3697
|
+
for await (const event of events) {
|
|
3698
|
+
if (event.type === "text") yield event.text;
|
|
3699
|
+
else if (event.type === "bytes") yield event.data;
|
|
3700
|
+
else responseUsage = event.response.usage;
|
|
3701
|
+
}
|
|
3702
|
+
})()[Symbol.asyncIterator]();
|
|
3703
|
+
} else iterator = service.complete(request)[Symbol.asyncIterator]();
|
|
3704
|
+
const text = (entry.model.outputType ?? "text/plain").toLowerCase().startsWith("text/");
|
|
3705
|
+
let pendingSurrogate = "";
|
|
3706
|
+
while (true) {
|
|
3707
|
+
await step();
|
|
3708
|
+
const result = await interrupted(() => iterator.next(), signal);
|
|
3709
|
+
signal.throwIfAborted();
|
|
3710
|
+
if (result.done) {
|
|
3711
|
+
ended = true;
|
|
3712
|
+
if (result.value?.usage) responseUsage = result.value.usage;
|
|
3713
|
+
break;
|
|
3714
|
+
}
|
|
3715
|
+
if (text ? typeof result.value !== "string" : !(result.value instanceof Uint8Array)) throw new Error(`Provider ${entry.provider.name} returned a response chunk incompatible with ${entry.model.outputType ?? "text/plain"}`);
|
|
3716
|
+
if (typeof result.value === "string") {
|
|
3717
|
+
let chunk = pendingSurrogate + result.value;
|
|
3718
|
+
const last = chunk.charCodeAt(chunk.length - 1);
|
|
3719
|
+
pendingSurrogate = last >= 55296 && last <= 56319 ? chunk.slice(-1) : "";
|
|
3720
|
+
if (pendingSurrogate) chunk = chunk.slice(0, -1);
|
|
3721
|
+
if (chunk) await emitText(chunk);
|
|
3722
|
+
} else await write(result.value);
|
|
3723
|
+
}
|
|
3724
|
+
if (text) {
|
|
3725
|
+
if (pendingSurrogate) await emitText(pendingSurrogate);
|
|
3726
|
+
if (!args.extract) await write(Uint8Array.of(10));
|
|
3727
|
+
}
|
|
3728
|
+
if (outputSpool) for await (const chunk of outputSpool.replay(args.extract && text ? async (reader) => {
|
|
3729
|
+
const range = await findExtractedRange(reader, args.extract === "last", signal);
|
|
3730
|
+
return range && range.end > range.start ? range : void 0;
|
|
3731
|
+
} : void 0)) await writeOutput(operation.output, chunk);
|
|
3732
|
+
if (args.extract && text) await writeOutput(operation.output, Uint8Array.of(10));
|
|
3733
|
+
if (usageSpool) await pipeBytes2(usageSpool.replay(), context.stderr, signal);
|
|
3734
|
+
else if (args.usage) {
|
|
3735
|
+
await writeDiagnostic2(context.stderr, "Token usage: ", signal);
|
|
3736
|
+
await pipeBytes2(serializeLlmTokenUsage(responseUsage, signal), context.stderr, signal);
|
|
3737
|
+
await writeDiagnostic2(context.stderr, "\n", signal);
|
|
3738
|
+
}
|
|
3739
|
+
if (!chat) return { exitCode: 0 };
|
|
3740
|
+
await outputSpool?.close();
|
|
3741
|
+
outputSpool = void 0;
|
|
3742
|
+
await usageSpool?.close();
|
|
3743
|
+
usageSpool = void 0;
|
|
3744
|
+
await chatPrompt.spool.close();
|
|
3745
|
+
ended = false;
|
|
3746
|
+
iterator = void 0;
|
|
3747
|
+
responseUsage = void 0;
|
|
3748
|
+
chatTurn++;
|
|
3749
|
+
}
|
|
3750
|
+
} catch (error) {
|
|
3751
|
+
context.signal.throwIfAborted();
|
|
3752
|
+
operation.signal.throwIfAborted();
|
|
3753
|
+
controller.abort(error);
|
|
3754
|
+
if (outputFailed) throw error;
|
|
3755
|
+
await operation.close();
|
|
3756
|
+
await writeDiagnostic2(context.stderr, `${error instanceof Error || error instanceof TypeError ? error.message.slice(0, 4096) : "llm provider failed"}
|
|
3757
|
+
`, context.signal);
|
|
3758
|
+
return { exitCode: error instanceof LlmModelsUsageError || error instanceof LlmPromptUsageError ? 2 : 1 };
|
|
3759
|
+
} finally {
|
|
3760
|
+
try {
|
|
3761
|
+
await Promise.all([...functionSessions].map((session) => session.close()));
|
|
3762
|
+
} finally {
|
|
3763
|
+
controller.abort(new Error("llm request closed"));
|
|
3764
|
+
await operation.close();
|
|
3765
|
+
}
|
|
3766
|
+
}
|
|
3767
|
+
}
|
|
3768
|
+
function createLlmCommand(options = {}) {
|
|
3769
|
+
for (const [name, value] of Object.entries(options.limits ?? {})) {
|
|
3770
|
+
if (value === void 0 || value === Infinity) continue;
|
|
3771
|
+
if (!Number.isSafeInteger(value) || value < 0) throw new TypeError(`Invalid llm limit: ${name}`);
|
|
3772
|
+
}
|
|
3773
|
+
const limits = options.limits === void 0 ? void 0 : Object.freeze({ ...options.limits });
|
|
3774
|
+
if (options.service && (options.providers !== void 0 || options.defaultModel !== void 0)) throw new TypeError("Configure providers and defaultModel on the injected LLM service");
|
|
3775
|
+
const maxRemoteBytes = options.maxRemoteTemplateBytes ?? limits?.maxInputBytes ?? Infinity;
|
|
3776
|
+
const templateLoaderOptions = { maxRemoteBytes, ...options.templateLoaders ? { loaders: options.templateLoaders } : {} };
|
|
3777
|
+
const service = options.service ?? createLlmService({ ...options, providers: options.providers ?? [] });
|
|
3778
|
+
const collections = options.collections;
|
|
3779
|
+
return { name: "llm", description: "Query injected language and media models", execute: (context) => execute(context, service, limits, templateLoaderOptions, collections, options.fragmentLoaders ?? /* @__PURE__ */ new Map(), options.tools ?? /* @__PURE__ */ new Map(), options.loadTools) };
|
|
3780
|
+
}
|
|
3781
|
+
function createLlmCommands(options = {}) {
|
|
3782
|
+
return [createLlmCommand(options)];
|
|
3783
|
+
}
|
|
3784
|
+
function llmCommands(options = {}) {
|
|
3785
|
+
const definitions = createLlmCommands(options);
|
|
3786
|
+
const replace = options.replace ?? false;
|
|
3787
|
+
return { name: "llm-commands", setup(host) {
|
|
3788
|
+
if (!replace && host.commands.has("llm")) throw new Error("Command already registered: llm");
|
|
3789
|
+
for (const definition of definitions) host.commands.register(definition, { replace });
|
|
3790
|
+
} };
|
|
3791
|
+
}
|
|
3792
|
+
|
|
3793
|
+
export {
|
|
3794
|
+
serializeLlmTokenUsage,
|
|
3795
|
+
createLlmToolRegistry,
|
|
3796
|
+
selectLlmTools,
|
|
3797
|
+
LlmCancelToolCall,
|
|
3798
|
+
executeLlmToolCalls,
|
|
3799
|
+
createLlmInputBudget,
|
|
3800
|
+
streamLlmToolChain,
|
|
3801
|
+
getLlmFragmentPrefix,
|
|
3802
|
+
createLlmFragmentLoaders,
|
|
3803
|
+
loadLlmPluginFragments,
|
|
3804
|
+
createLlmUrlSource,
|
|
3805
|
+
createLlmUrlFragmentSource,
|
|
3806
|
+
createLlmFragmentSource,
|
|
3807
|
+
validateLlmTemplateParameters,
|
|
3808
|
+
llmTemplateUsesInput,
|
|
3809
|
+
evaluateLlmTemplate,
|
|
3810
|
+
createLlmTemplateStore,
|
|
3811
|
+
findExtractedRange,
|
|
3812
|
+
parseLlmSchemaDsl,
|
|
3813
|
+
resolveLlmSchemaInput,
|
|
3814
|
+
getLlmModelAliases,
|
|
3815
|
+
selectLlmModelByQuery,
|
|
3816
|
+
llmReferenceVersion,
|
|
3817
|
+
createLlmCommand,
|
|
3818
|
+
createLlmCommands,
|
|
3819
|
+
llmCommands
|
|
3820
|
+
};
|