llm-shell 0.9.2 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (258) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +61 -66
  3. data/lib/llm/shell/command.rb +40 -40
  4. data/lib/llm/shell/commands/clear_screen.rb +4 -18
  5. data/lib/llm/shell/commands/debug_mode.rb +12 -0
  6. data/lib/llm/shell/commands/dir_import.rb +4 -20
  7. data/lib/llm/shell/commands/disable_tool.rb +33 -0
  8. data/lib/llm/shell/commands/enable_tool.rb +33 -0
  9. data/lib/llm/shell/commands/file_import.rb +4 -20
  10. data/lib/llm/shell/commands/help.rb +23 -36
  11. data/lib/llm/shell/commands/show_chat.rb +4 -19
  12. data/lib/llm/shell/commands/show_version.rb +4 -20
  13. data/lib/llm/shell/commands/system_prompt.rb +4 -18
  14. data/lib/llm/shell/completion.rb +5 -5
  15. data/lib/llm/shell/config.rb +4 -5
  16. data/lib/llm/shell/formatter.rb +1 -2
  17. data/lib/llm/shell/internal/coderay/lib/coderay/duo.rb +81 -0
  18. data/lib/llm/shell/internal/coderay/lib/coderay/encoders/_map.rb +17 -0
  19. data/lib/llm/shell/internal/coderay/lib/coderay/encoders/comment_filter.rb +25 -0
  20. data/lib/llm/shell/internal/coderay/lib/coderay/encoders/count.rb +39 -0
  21. data/lib/llm/shell/internal/coderay/lib/coderay/encoders/debug.rb +49 -0
  22. data/lib/llm/shell/internal/coderay/lib/coderay/encoders/debug_lint.rb +63 -0
  23. data/lib/llm/shell/internal/coderay/lib/coderay/encoders/div.rb +23 -0
  24. data/lib/llm/shell/internal/coderay/lib/coderay/encoders/encoder.rb +190 -0
  25. data/lib/llm/shell/internal/coderay/lib/coderay/encoders/filter.rb +58 -0
  26. data/lib/llm/shell/internal/coderay/lib/coderay/encoders/html/css.rb +65 -0
  27. data/lib/llm/shell/internal/coderay/lib/coderay/encoders/html/numbering.rb +108 -0
  28. data/lib/llm/shell/internal/coderay/lib/coderay/encoders/html/output.rb +164 -0
  29. data/lib/llm/shell/internal/coderay/lib/coderay/encoders/html.rb +333 -0
  30. data/lib/llm/shell/internal/coderay/lib/coderay/encoders/json.rb +83 -0
  31. data/lib/llm/shell/internal/coderay/lib/coderay/encoders/lines_of_code.rb +45 -0
  32. data/lib/llm/shell/internal/coderay/lib/coderay/encoders/lint.rb +59 -0
  33. data/lib/llm/shell/internal/coderay/lib/coderay/encoders/null.rb +18 -0
  34. data/lib/llm/shell/internal/coderay/lib/coderay/encoders/page.rb +24 -0
  35. data/lib/llm/shell/internal/coderay/lib/coderay/encoders/span.rb +23 -0
  36. data/lib/llm/shell/internal/coderay/lib/coderay/encoders/statistic.rb +95 -0
  37. data/lib/llm/shell/internal/coderay/lib/coderay/encoders/terminal.rb +195 -0
  38. data/lib/llm/shell/internal/coderay/lib/coderay/encoders/text.rb +46 -0
  39. data/lib/llm/shell/internal/coderay/lib/coderay/encoders/token_kind_filter.rb +111 -0
  40. data/lib/llm/shell/internal/coderay/lib/coderay/encoders/xml.rb +72 -0
  41. data/lib/llm/shell/internal/coderay/lib/coderay/encoders/yaml.rb +50 -0
  42. data/lib/llm/shell/internal/coderay/lib/coderay/encoders.rb +18 -0
  43. data/lib/llm/shell/internal/coderay/lib/coderay/for_redcloth.rb +95 -0
  44. data/lib/llm/shell/internal/coderay/lib/coderay/helpers/file_type.rb +151 -0
  45. data/lib/llm/shell/internal/coderay/lib/coderay/helpers/plugin.rb +55 -0
  46. data/lib/llm/shell/internal/coderay/lib/coderay/helpers/plugin_host.rb +221 -0
  47. data/lib/llm/shell/internal/coderay/lib/coderay/helpers/word_list.rb +72 -0
  48. data/lib/llm/shell/internal/coderay/lib/coderay/scanners/_map.rb +24 -0
  49. data/lib/llm/shell/internal/coderay/lib/coderay/scanners/c.rb +189 -0
  50. data/lib/llm/shell/internal/coderay/lib/coderay/scanners/clojure.rb +217 -0
  51. data/lib/llm/shell/internal/coderay/lib/coderay/scanners/cpp.rb +217 -0
  52. data/lib/llm/shell/internal/coderay/lib/coderay/scanners/css.rb +196 -0
  53. data/lib/llm/shell/internal/coderay/lib/coderay/scanners/debug.rb +75 -0
  54. data/lib/llm/shell/internal/coderay/lib/coderay/scanners/delphi.rb +144 -0
  55. data/lib/llm/shell/internal/coderay/lib/coderay/scanners/diff.rb +221 -0
  56. data/lib/llm/shell/internal/coderay/lib/coderay/scanners/erb.rb +81 -0
  57. data/lib/llm/shell/internal/coderay/lib/coderay/scanners/go.rb +208 -0
  58. data/lib/llm/shell/internal/coderay/lib/coderay/scanners/groovy.rb +268 -0
  59. data/lib/llm/shell/internal/coderay/lib/coderay/scanners/haml.rb +168 -0
  60. data/lib/llm/shell/internal/coderay/lib/coderay/scanners/html.rb +275 -0
  61. data/lib/llm/shell/internal/coderay/lib/coderay/scanners/java/builtin_types.rb +421 -0
  62. data/lib/llm/shell/internal/coderay/lib/coderay/scanners/java.rb +174 -0
  63. data/lib/llm/shell/internal/coderay/lib/coderay/scanners/java_script.rb +236 -0
  64. data/lib/llm/shell/internal/coderay/lib/coderay/scanners/json.rb +98 -0
  65. data/lib/llm/shell/internal/coderay/lib/coderay/scanners/lua.rb +280 -0
  66. data/lib/llm/shell/internal/coderay/lib/coderay/scanners/php.rb +527 -0
  67. data/lib/llm/shell/internal/coderay/lib/coderay/scanners/python.rb +287 -0
  68. data/lib/llm/shell/internal/coderay/lib/coderay/scanners/raydebug.rb +75 -0
  69. data/lib/llm/shell/internal/coderay/lib/coderay/scanners/ruby/patterns.rb +178 -0
  70. data/lib/llm/shell/internal/coderay/lib/coderay/scanners/ruby/string_state.rb +79 -0
  71. data/lib/llm/shell/internal/coderay/lib/coderay/scanners/ruby.rb +477 -0
  72. data/lib/llm/shell/internal/coderay/lib/coderay/scanners/sass.rb +232 -0
  73. data/lib/llm/shell/internal/coderay/lib/coderay/scanners/scanner.rb +337 -0
  74. data/lib/llm/shell/internal/coderay/lib/coderay/scanners/sql.rb +169 -0
  75. data/lib/llm/shell/internal/coderay/lib/coderay/scanners/taskpaper.rb +36 -0
  76. data/lib/llm/shell/internal/coderay/lib/coderay/scanners/text.rb +26 -0
  77. data/lib/llm/shell/internal/coderay/lib/coderay/scanners/xml.rb +17 -0
  78. data/lib/llm/shell/internal/coderay/lib/coderay/scanners/yaml.rb +140 -0
  79. data/lib/llm/shell/internal/coderay/lib/coderay/scanners.rb +27 -0
  80. data/lib/llm/shell/internal/coderay/lib/coderay/styles/_map.rb +7 -0
  81. data/lib/llm/shell/internal/coderay/lib/coderay/styles/alpha.rb +153 -0
  82. data/lib/llm/shell/internal/coderay/lib/coderay/styles/style.rb +18 -0
  83. data/lib/llm/shell/internal/coderay/lib/coderay/styles.rb +15 -0
  84. data/lib/llm/shell/internal/coderay/lib/coderay/token_kinds.rb +85 -0
  85. data/lib/llm/shell/internal/coderay/lib/coderay/tokens.rb +164 -0
  86. data/lib/llm/shell/internal/coderay/lib/coderay/tokens_proxy.rb +55 -0
  87. data/lib/llm/shell/internal/coderay/lib/coderay/version.rb +3 -0
  88. data/lib/llm/shell/internal/coderay/lib/coderay.rb +284 -0
  89. data/lib/llm/shell/internal/io-line/lib/io/line/multiple.rb +19 -0
  90. data/lib/{io → llm/shell/internal/io-line/lib/io}/line.rb +2 -0
  91. data/lib/llm/shell/internal/llm.rb/lib/llm/bot/builder.rb +31 -0
  92. data/lib/llm/shell/internal/llm.rb/lib/llm/bot/conversable.rb +37 -0
  93. data/lib/llm/shell/internal/llm.rb/lib/llm/bot/prompt/completion.rb +49 -0
  94. data/lib/llm/shell/internal/llm.rb/lib/llm/bot/prompt/respond.rb +49 -0
  95. data/lib/llm/shell/internal/llm.rb/lib/llm/bot.rb +150 -0
  96. data/lib/llm/shell/internal/llm.rb/lib/llm/buffer.rb +162 -0
  97. data/lib/llm/shell/internal/llm.rb/lib/llm/client.rb +36 -0
  98. data/lib/llm/shell/internal/llm.rb/lib/llm/error.rb +49 -0
  99. data/lib/llm/shell/internal/llm.rb/lib/llm/eventhandler.rb +44 -0
  100. data/lib/llm/shell/internal/llm.rb/lib/llm/eventstream/event.rb +69 -0
  101. data/lib/llm/shell/internal/llm.rb/lib/llm/eventstream/parser.rb +88 -0
  102. data/lib/llm/shell/internal/llm.rb/lib/llm/eventstream.rb +8 -0
  103. data/lib/llm/shell/internal/llm.rb/lib/llm/file.rb +91 -0
  104. data/lib/llm/shell/internal/llm.rb/lib/llm/function.rb +177 -0
  105. data/lib/llm/shell/internal/llm.rb/lib/llm/message.rb +178 -0
  106. data/lib/llm/shell/internal/llm.rb/lib/llm/mime.rb +140 -0
  107. data/lib/llm/shell/internal/llm.rb/lib/llm/multipart.rb +101 -0
  108. data/lib/llm/shell/internal/llm.rb/lib/llm/object/builder.rb +38 -0
  109. data/lib/llm/shell/internal/llm.rb/lib/llm/object/kernel.rb +53 -0
  110. data/lib/llm/shell/internal/llm.rb/lib/llm/object.rb +89 -0
  111. data/lib/llm/shell/internal/llm.rb/lib/llm/provider.rb +352 -0
  112. data/lib/llm/shell/internal/llm.rb/lib/llm/providers/anthropic/error_handler.rb +36 -0
  113. data/lib/llm/shell/internal/llm.rb/lib/llm/providers/anthropic/files.rb +155 -0
  114. data/lib/llm/shell/internal/llm.rb/lib/llm/providers/anthropic/format/completion_format.rb +88 -0
  115. data/lib/llm/shell/internal/llm.rb/lib/llm/providers/anthropic/format.rb +29 -0
  116. data/lib/llm/shell/internal/llm.rb/lib/llm/providers/anthropic/models.rb +54 -0
  117. data/lib/llm/shell/internal/llm.rb/lib/llm/providers/anthropic/response/completion.rb +39 -0
  118. data/lib/llm/shell/internal/llm.rb/lib/llm/providers/anthropic/response/enumerable.rb +11 -0
  119. data/lib/llm/shell/internal/llm.rb/lib/llm/providers/anthropic/response/file.rb +23 -0
  120. data/lib/llm/shell/internal/llm.rb/lib/llm/providers/anthropic/response/web_search.rb +21 -0
  121. data/lib/llm/shell/internal/llm.rb/lib/llm/providers/anthropic/stream_parser.rb +66 -0
  122. data/lib/llm/shell/internal/llm.rb/lib/llm/providers/anthropic.rb +138 -0
  123. data/lib/llm/shell/internal/llm.rb/lib/llm/providers/deepseek/format/completion_format.rb +68 -0
  124. data/lib/llm/shell/internal/llm.rb/lib/llm/providers/deepseek/format.rb +27 -0
  125. data/lib/llm/shell/internal/llm.rb/lib/llm/providers/deepseek.rb +75 -0
  126. data/lib/llm/shell/internal/llm.rb/lib/llm/providers/gemini/audio.rb +73 -0
  127. data/lib/llm/shell/internal/llm.rb/lib/llm/providers/gemini/error_handler.rb +47 -0
  128. data/lib/llm/shell/internal/llm.rb/lib/llm/providers/gemini/files.rb +146 -0
  129. data/lib/llm/shell/internal/llm.rb/lib/llm/providers/gemini/format/completion_format.rb +69 -0
  130. data/lib/llm/shell/internal/llm.rb/lib/llm/providers/gemini/format.rb +39 -0
  131. data/lib/llm/shell/internal/llm.rb/lib/llm/providers/gemini/images.rb +133 -0
  132. data/lib/llm/shell/internal/llm.rb/lib/llm/providers/gemini/models.rb +60 -0
  133. data/lib/llm/shell/internal/llm.rb/lib/llm/providers/gemini/response/completion.rb +35 -0
  134. data/lib/llm/shell/internal/llm.rb/lib/llm/providers/gemini/response/embedding.rb +8 -0
  135. data/lib/llm/shell/internal/llm.rb/lib/llm/providers/gemini/response/file.rb +11 -0
  136. data/lib/llm/shell/internal/llm.rb/lib/llm/providers/gemini/response/files.rb +15 -0
  137. data/lib/llm/shell/internal/llm.rb/lib/llm/providers/gemini/response/image.rb +31 -0
  138. data/lib/llm/shell/internal/llm.rb/lib/llm/providers/gemini/response/models.rb +15 -0
  139. data/lib/llm/shell/internal/llm.rb/lib/llm/providers/gemini/response/web_search.rb +22 -0
  140. data/lib/llm/shell/internal/llm.rb/lib/llm/providers/gemini/stream_parser.rb +86 -0
  141. data/lib/llm/shell/internal/llm.rb/lib/llm/providers/gemini.rb +173 -0
  142. data/lib/llm/shell/internal/llm.rb/lib/llm/providers/llamacpp.rb +74 -0
  143. data/lib/llm/shell/internal/llm.rb/lib/llm/providers/ollama/error_handler.rb +36 -0
  144. data/lib/llm/shell/internal/llm.rb/lib/llm/providers/ollama/format/completion_format.rb +77 -0
  145. data/lib/llm/shell/internal/llm.rb/lib/llm/providers/ollama/format.rb +29 -0
  146. data/lib/llm/shell/internal/llm.rb/lib/llm/providers/ollama/models.rb +56 -0
  147. data/lib/llm/shell/internal/llm.rb/lib/llm/providers/ollama/response/completion.rb +28 -0
  148. data/lib/llm/shell/internal/llm.rb/lib/llm/providers/ollama/response/embedding.rb +9 -0
  149. data/lib/llm/shell/internal/llm.rb/lib/llm/providers/ollama/stream_parser.rb +44 -0
  150. data/lib/llm/shell/internal/llm.rb/lib/llm/providers/ollama.rb +116 -0
  151. data/lib/llm/shell/internal/llm.rb/lib/llm/providers/openai/audio.rb +91 -0
  152. data/lib/llm/shell/internal/llm.rb/lib/llm/providers/openai/error_handler.rb +46 -0
  153. data/lib/llm/shell/internal/llm.rb/lib/llm/providers/openai/files.rb +134 -0
  154. data/lib/llm/shell/internal/llm.rb/lib/llm/providers/openai/format/completion_format.rb +90 -0
  155. data/lib/llm/shell/internal/llm.rb/lib/llm/providers/openai/format/moderation_format.rb +35 -0
  156. data/lib/llm/shell/internal/llm.rb/lib/llm/providers/openai/format/respond_format.rb +72 -0
  157. data/lib/llm/shell/internal/llm.rb/lib/llm/providers/openai/format.rb +54 -0
  158. data/lib/llm/shell/internal/llm.rb/lib/llm/providers/openai/images.rb +109 -0
  159. data/lib/llm/shell/internal/llm.rb/lib/llm/providers/openai/models.rb +55 -0
  160. data/lib/llm/shell/internal/llm.rb/lib/llm/providers/openai/moderations.rb +65 -0
  161. data/lib/llm/shell/internal/llm.rb/lib/llm/providers/openai/response/audio.rb +7 -0
  162. data/lib/llm/shell/internal/llm.rb/lib/llm/providers/openai/response/completion.rb +40 -0
  163. data/lib/llm/shell/internal/llm.rb/lib/llm/providers/openai/response/embedding.rb +9 -0
  164. data/lib/llm/shell/internal/llm.rb/lib/llm/providers/openai/response/enumerable.rb +23 -0
  165. data/lib/llm/shell/internal/llm.rb/lib/llm/providers/openai/response/file.rb +7 -0
  166. data/lib/llm/shell/internal/llm.rb/lib/llm/providers/openai/response/image.rb +16 -0
  167. data/lib/llm/shell/internal/llm.rb/lib/llm/providers/openai/response/moderations.rb +34 -0
  168. data/lib/llm/shell/internal/llm.rb/lib/llm/providers/openai/response/responds.rb +48 -0
  169. data/lib/llm/shell/internal/llm.rb/lib/llm/providers/openai/response/web_search.rb +21 -0
  170. data/lib/llm/shell/internal/llm.rb/lib/llm/providers/openai/responses/stream_parser.rb +76 -0
  171. data/lib/llm/shell/internal/llm.rb/lib/llm/providers/openai/responses.rb +99 -0
  172. data/lib/llm/shell/internal/llm.rb/lib/llm/providers/openai/stream_parser.rb +86 -0
  173. data/lib/llm/shell/internal/llm.rb/lib/llm/providers/openai/vector_stores.rb +228 -0
  174. data/lib/llm/shell/internal/llm.rb/lib/llm/providers/openai.rb +206 -0
  175. data/lib/llm/shell/internal/llm.rb/lib/llm/providers/xai/images.rb +58 -0
  176. data/lib/llm/shell/internal/llm.rb/lib/llm/providers/xai.rb +72 -0
  177. data/lib/llm/shell/internal/llm.rb/lib/llm/providers/zai.rb +74 -0
  178. data/lib/llm/shell/internal/llm.rb/lib/llm/response.rb +67 -0
  179. data/lib/llm/shell/internal/llm.rb/lib/llm/schema/array.rb +26 -0
  180. data/lib/llm/shell/internal/llm.rb/lib/llm/schema/boolean.rb +13 -0
  181. data/lib/llm/shell/internal/llm.rb/lib/llm/schema/integer.rb +43 -0
  182. data/lib/llm/shell/internal/llm.rb/lib/llm/schema/leaf.rb +78 -0
  183. data/lib/llm/shell/internal/llm.rb/lib/llm/schema/null.rb +13 -0
  184. data/lib/llm/shell/internal/llm.rb/lib/llm/schema/number.rb +43 -0
  185. data/lib/llm/shell/internal/llm.rb/lib/llm/schema/object.rb +41 -0
  186. data/lib/llm/shell/internal/llm.rb/lib/llm/schema/string.rb +34 -0
  187. data/lib/llm/shell/internal/llm.rb/lib/llm/schema/version.rb +8 -0
  188. data/lib/llm/shell/internal/llm.rb/lib/llm/schema.rb +81 -0
  189. data/lib/llm/shell/internal/llm.rb/lib/llm/server_tool.rb +32 -0
  190. data/lib/llm/shell/internal/llm.rb/lib/llm/tool/param.rb +75 -0
  191. data/lib/llm/shell/internal/llm.rb/lib/llm/tool.rb +78 -0
  192. data/lib/llm/shell/internal/llm.rb/lib/llm/utils.rb +19 -0
  193. data/lib/llm/shell/internal/llm.rb/lib/llm/version.rb +5 -0
  194. data/lib/llm/shell/internal/llm.rb/lib/llm.rb +121 -0
  195. data/lib/llm/shell/internal/optparse/lib/optionparser.rb +2 -0
  196. data/lib/llm/shell/internal/optparse/lib/optparse/ac.rb +70 -0
  197. data/lib/llm/shell/internal/optparse/lib/optparse/date.rb +18 -0
  198. data/lib/llm/shell/internal/optparse/lib/optparse/kwargs.rb +27 -0
  199. data/lib/llm/shell/internal/optparse/lib/optparse/shellwords.rb +7 -0
  200. data/lib/llm/shell/internal/optparse/lib/optparse/time.rb +11 -0
  201. data/lib/llm/shell/internal/optparse/lib/optparse/uri.rb +7 -0
  202. data/lib/llm/shell/internal/optparse/lib/optparse/version.rb +80 -0
  203. data/lib/llm/shell/internal/optparse/lib/optparse.rb +2469 -0
  204. data/lib/llm/shell/internal/paint/lib/paint/constants.rb +104 -0
  205. data/lib/llm/shell/internal/paint/lib/paint/pa.rb +13 -0
  206. data/lib/llm/shell/internal/paint/lib/paint/rgb_colors.rb +14 -0
  207. data/lib/llm/shell/internal/paint/lib/paint/shortcuts.rb +100 -0
  208. data/lib/llm/shell/internal/paint/lib/paint/shortcuts_version.rb +5 -0
  209. data/lib/llm/shell/internal/paint/lib/paint/util.rb +16 -0
  210. data/lib/llm/shell/internal/paint/lib/paint/version.rb +5 -0
  211. data/lib/llm/shell/internal/paint/lib/paint.rb +261 -0
  212. data/lib/llm/shell/internal/reline/lib/reline/config.rb +378 -0
  213. data/lib/llm/shell/internal/reline/lib/reline/face.rb +199 -0
  214. data/lib/llm/shell/internal/reline/lib/reline/history.rb +76 -0
  215. data/lib/llm/shell/internal/reline/lib/reline/io/ansi.rb +322 -0
  216. data/lib/llm/shell/internal/reline/lib/reline/io/dumb.rb +120 -0
  217. data/lib/llm/shell/internal/reline/lib/reline/io/windows.rb +530 -0
  218. data/lib/llm/shell/internal/reline/lib/reline/io.rb +55 -0
  219. data/lib/llm/shell/internal/reline/lib/reline/key_actor/base.rb +37 -0
  220. data/lib/llm/shell/internal/reline/lib/reline/key_actor/composite.rb +17 -0
  221. data/lib/llm/shell/internal/reline/lib/reline/key_actor/emacs.rb +517 -0
  222. data/lib/llm/shell/internal/reline/lib/reline/key_actor/vi_command.rb +518 -0
  223. data/lib/llm/shell/internal/reline/lib/reline/key_actor/vi_insert.rb +517 -0
  224. data/lib/llm/shell/internal/reline/lib/reline/key_actor.rb +8 -0
  225. data/lib/llm/shell/internal/reline/lib/reline/key_stroke.rb +119 -0
  226. data/lib/llm/shell/internal/reline/lib/reline/kill_ring.rb +125 -0
  227. data/lib/llm/shell/internal/reline/lib/reline/line_editor.rb +2356 -0
  228. data/lib/llm/shell/internal/reline/lib/reline/unicode/east_asian_width.rb +1292 -0
  229. data/lib/llm/shell/internal/reline/lib/reline/unicode.rb +421 -0
  230. data/lib/llm/shell/internal/reline/lib/reline/version.rb +3 -0
  231. data/lib/llm/shell/internal/reline/lib/reline.rb +527 -0
  232. data/lib/llm/shell/internal/tomlrb/lib/tomlrb/generated_parser.rb +712 -0
  233. data/lib/llm/shell/internal/tomlrb/lib/tomlrb/handler.rb +268 -0
  234. data/lib/llm/shell/internal/tomlrb/lib/tomlrb/local_date.rb +35 -0
  235. data/lib/llm/shell/internal/tomlrb/lib/tomlrb/local_date_time.rb +42 -0
  236. data/lib/llm/shell/internal/tomlrb/lib/tomlrb/local_time.rb +40 -0
  237. data/lib/llm/shell/internal/tomlrb/lib/tomlrb/parser.rb +21 -0
  238. data/lib/llm/shell/internal/tomlrb/lib/tomlrb/scanner.rb +92 -0
  239. data/lib/llm/shell/internal/tomlrb/lib/tomlrb/string_utils.rb +40 -0
  240. data/lib/llm/shell/internal/tomlrb/lib/tomlrb/version.rb +5 -0
  241. data/lib/llm/shell/internal/tomlrb/lib/tomlrb.rb +49 -0
  242. data/lib/llm/shell/options.rb +1 -1
  243. data/lib/llm/shell/renderer.rb +2 -3
  244. data/lib/llm/shell/repl.rb +21 -16
  245. data/lib/llm/shell/tool.rb +42 -0
  246. data/lib/llm/shell/tools/read_file.rb +15 -0
  247. data/lib/llm/shell/tools/system.rb +17 -0
  248. data/lib/llm/shell/tools/write_file.rb +16 -0
  249. data/lib/llm/shell/version.rb +1 -1
  250. data/lib/llm/shell.rb +83 -39
  251. data/libexec/llm-shell/shell +4 -6
  252. data/llm-shell.gemspec +0 -4
  253. metadata +233 -63
  254. data/lib/llm/function.rb +0 -17
  255. data/lib/llm/shell/command/extension.rb +0 -42
  256. data/lib/llm/shell/commands/utils.rb +0 -21
  257. data/lib/llm/shell/functions/read_file.rb +0 -22
  258. data/lib/llm/shell/functions/write_file.rb +0 -22
@@ -21,11 +21,9 @@ class LLM::Shell
21
21
  # Performs initial setup
22
22
  # @return [void]
23
23
  def setup
24
- LLM::Shell.commands.each { |file| require file }
25
- Readline.completion_proc = Completion.to_proc
26
- chat options.prompt, role: options.default.role
27
- files.each { chat ["--- START: #{_1} ---", File.read(_1), "--- END: #{_1} ---"].join("\n") }
28
- bot.messages.each(&:read!)
24
+ Reline.completion_proc = Completion.to_proc
25
+ chat(options.prompt, role: options.default.role).flush
26
+ unread.each(&:read!)
29
27
  clear_screen
30
28
  end
31
29
 
@@ -52,15 +50,13 @@ class LLM::Shell
52
50
  private
53
51
 
54
52
  def read
55
- input = Readline.readline("llm> ", true) || throw(:exit, 0)
53
+ input = Reline.readline("llm> ", true) || throw(:exit, 0)
56
54
  words = input.split(" ")
57
- if LLM.commands[words[0]]
58
- cmd = LLM.commands[words[0]]
55
+ if cmd = LLM::Shell.find_command(words[0])
59
56
  argv = words[1..]
60
- cmd.setup(bot, io)
61
- cmd.call(*argv)
57
+ cmd.new(bot, io).call(*argv)
62
58
  else
63
- chat input.tap { clear_screen }
59
+ chat(input.tap { clear_screen }, tools:)
64
60
  io.rewind.print(Paint["Thinking", :bold])
65
61
  unread.tap { io.rewind }
66
62
  end
@@ -71,10 +67,12 @@ class LLM::Shell
71
67
  cancels = []
72
68
  results = []
73
69
  functions.each do |function|
70
+ args = function.arguments.to_json
74
71
  print Paint["system", :bold, :red], " says: ", "\n"
75
- print "function: ", function.name, "\n"
76
- print "arguments: ", function.arguments.to_h.size, "\n"
77
- input = Readline.readline("Do you want to call it ? ", true)
72
+ print "function ".ljust(20), function.name, "\n"
73
+ print "arguments ".ljust(20), ((args.size >= 80) ? "#{args[0..79]} ...}" : args), "\n"
74
+ print "argument count".ljust(20), function.arguments.to_h.size, "\n\n"
75
+ input = Reline.readline("Should we proceed? ", true)
78
76
  puts
79
77
  if %w(y yes yep yeah ok).include?(input)
80
78
  callables << function
@@ -84,7 +82,7 @@ class LLM::Shell
84
82
  end
85
83
  results.concat callables.map(&:call)
86
84
  results.concat cancels.map(&:cancel)
87
- bot.chat(results)
85
+ bot.chat(results).flush
88
86
  end
89
87
 
90
88
  def emit
@@ -94,12 +92,19 @@ class LLM::Shell
94
92
  end unless unread.empty?
95
93
  end
96
94
 
95
+ ##
96
+ # @return [Array<LLM::Tool>]
97
+ def tools
98
+ LLM::Shell
99
+ .tools
100
+ .select(&:enabled?)
101
+ end
102
+
97
103
  attr_reader :bot, :console, :io, :default, :options
98
104
 
99
105
  def formatter(messages) = Formatter.new(messages)
100
106
  def unread = bot.messages.unread
101
107
  def functions = bot.functions
102
- def files = @options.files
103
108
  def clear_screen = console.clear_screen
104
109
  def chat(...) = bot.chat(...)
105
110
  end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ class LLM::Tool
4
+ module Patch
5
+ ##
6
+ # Returns true for an enabled tool
7
+ # @return [Boolean]
8
+ def enabled?
9
+ @enabled
10
+ end
11
+
12
+ ##
13
+ # Enable the tool
14
+ # @return [void]
15
+ def enable!
16
+ @enabled = true
17
+ end
18
+
19
+ ##
20
+ # Disable the tool
21
+ # @return [void]
22
+ def disable!
23
+ @enabled = false
24
+ end
25
+
26
+ ##
27
+ # @return [Boolean]
28
+ def builtin?
29
+ path, _ = instance_method(:call).source_location
30
+ path&.include?(LLM::Shell.root)
31
+ end
32
+ end
33
+
34
+ m = method(:inherited)
35
+ define_singleton_method(:inherited) do |tool|
36
+ LLM::Shell.tools << tool
37
+ m.call(tool)
38
+ tool.enable!
39
+ end
40
+
41
+ extend Patch
42
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LLM::Shell::Tools
4
+ class ReadFile < LLM::Tool
5
+ name "read-file"
6
+ description "Read the contents of a file"
7
+ param :path, String, "The path to a file", required: true
8
+
9
+ def call(path:)
10
+ {ok: true, content: File.read(path)}
11
+ rescue => ex
12
+ {ok: false, error: {class: ex.class.to_s, message: ex.message}}
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LLM::Shell::Tools
4
+ class System < LLM::Tool
5
+ name "system"
6
+ description "Run a system command"
7
+ param :command, String, "The command to execute", required: true
8
+
9
+ def call(command:)
10
+ ro, wo = IO.pipe
11
+ re, we = IO.pipe
12
+ Process.wait Process.spawn(command, out: wo, err: we)
13
+ [wo, we].each(&:close)
14
+ {stderr: re.read, stdout: ro.read}
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LLM::Shell::Tools
4
+ class WriteFile < LLM::Tool
5
+ name "write-file"
6
+ description "Write the contents of a file"
7
+ param :path, String, "The path to a file", required: true
8
+ param :content, String, "The contents of a file", required: true
9
+
10
+ def call(path:, content:)
11
+ {ok: true, content: File.binwrite(path, content)}
12
+ rescue => ex
13
+ {ok: false, error: {class: ex.class.to_s, message: ex.message}}
14
+ end
15
+ end
16
+ end
@@ -4,5 +4,5 @@ module LLM
4
4
  end unless defined?(LLM)
5
5
 
6
6
  class LLM::Shell
7
- VERSION = "0.9.2"
7
+ VERSION = "0.10.0"
8
8
  end
data/lib/llm/shell.rb CHANGED
@@ -1,16 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "optparse"
4
- require "readline"
5
- require "yaml"
6
- require "llm"
7
- require "paint"
3
+ module LLM
4
+ $:.unshift(*Dir[File.join(__dir__, "shell", "internal", "*", "lib")])
5
+ require "optparse"
6
+ require "io/line"
7
+ require "paint"
8
+ require "reline"
9
+ require "coderay"
10
+ require "llm"
11
+ require "tomlrb"
12
+ end
8
13
 
9
14
  class LLM::Shell
10
- require_relative "function"
11
- require_relative "../io/line"
15
+ require_relative "shell/tool"
12
16
  require_relative "shell/command"
13
- require_relative "shell/command/extension"
14
17
  require_relative "shell/markdown"
15
18
  require_relative "shell/renderer"
16
19
  require_relative "shell/formatter"
@@ -22,48 +25,81 @@ class LLM::Shell
22
25
  require_relative "shell/version"
23
26
 
24
27
  ##
25
- # Load all commands
26
- Dir[File.join(__dir__, "shell", "commands", "*.rb")].each { require(_1) }
28
+ # Returns the lib/ directory
29
+ # @return [String]
30
+ def self.root
31
+ __dir__
32
+ end
27
33
 
28
34
  ##
29
- # Opens a pager
30
- # @return [void]
31
- def self.pager(...)
32
- IO.popen("less -FRX", "w", ...)
35
+ # Returns the directory where configuration files are kept
36
+ # @return [String]
37
+ def self.home_config
38
+ if ENV.key?("XDG_CONFIG_HOME")
39
+ ENV["XDG_CONFIG_HOME"]
40
+ else
41
+ File.join Dir.home, ".config"
42
+ end
33
43
  end
34
44
 
35
45
  ##
46
+ # Returns the directory where commands and tools are kept
36
47
  # @return [String]
37
- def self.home
38
- File.join Dir.home, ".llm-shell"
48
+ def self.home_data
49
+ if ENV.key?("XDG_DATA_HOME")
50
+ File.join ENV["XDG_DATA_HOME"], ".llm-shell"
51
+ else
52
+ File.join Dir.home, ".local", "share", ".llm-shell"
53
+ end
39
54
  end
40
55
 
41
56
  ##
42
- # @return [Array<String>]
57
+ # @return [Array<LLM::Command>]
58
+ def self.commands
59
+ @commands ||= []
60
+ end
61
+
62
+ ##
63
+ # @return [Array<LLM::Tool>]
43
64
  def self.tools
44
- Dir[*TOOLGLOBS]
65
+ @tools ||= []
45
66
  end
46
67
 
47
68
  ##
48
- # @return [Array<String>]
49
- def self.commands
50
- Dir[File.join(home, "commands", "*.rb")]
69
+ # Returns an instance of {LLM::Command LLM::Command}, or nil.
70
+ # @return [LLM::Command, nil]
71
+ def self.find_command(name)
72
+ commands.find { _1.name == name }
51
73
  end
52
74
 
53
- TOOLGLOBS = [
54
- File.join(home, "tools", "*.rb"),
55
- File.join(__dir__, "shell", "functions", "*.rb")
56
- ].freeze
57
- private_constant :TOOLGLOBS
75
+ ##
76
+ # @return [Regexp]
77
+ def self.pattern
78
+ /\A<file path=(.+?)>/
79
+ end
58
80
 
59
81
  ##
60
- # @param [Hash] options
82
+ # Opens a pager
83
+ # @return [void]
84
+ def self.pager(...)
85
+ IO.popen("less -FRX", "w", ...)
86
+ end
87
+
88
+ ##
89
+ # Load commands & tools
90
+ Dir[File.join(home_data, "commands", "*.rb")].each { require(_1) }
91
+ Dir[File.join(home_data, "tools", "*.rb")].each { require(_1) }
92
+ Dir[File.join(root, "shell", "commands", "*.rb")].each { require(_1) }
93
+ Dir[File.join(root, "shell", "tools", "*.rb")].each { require(_1) }
94
+
95
+ ##
96
+ # @param [Hash] opts
61
97
  # @return [LLM::Shell]
62
- def initialize(options)
63
- @config = Config.new(options[:provider])
64
- @options = Options.new @config.merge(options), Default.new(options[:provider])
65
- @bot = LLM::Bot.new(llm, {tools:}.merge(@options.bot))
66
- @repl = REPL.new(bot: @bot, options: @options)
98
+ def initialize(opts)
99
+ @config = Config.new(opts[:provider])
100
+ @options = Options.new @config.merge(opts), Default.new(opts[:provider])
101
+ @bot = LLM::Bot.new(llm, options.bot)
102
+ @repl = REPL.new(bot:, options:)
67
103
  end
68
104
 
69
105
  ##
@@ -76,13 +112,21 @@ class LLM::Shell
76
112
 
77
113
  private
78
114
 
79
- def tools
80
- LLM::Shell.tools.map do |path|
81
- eval File.read(path), TOPLEVEL_BINDING, path, 1
82
- end.grep(LLM::Function)
115
+ attr_reader :options, :bot, :repl
116
+
117
+ ##
118
+ # @return [Method]
119
+ def provider
120
+ LLM.method(options.provider)
83
121
  end
84
122
 
85
- attr_reader :options, :bot, :repl
86
- def provider = LLM.method(options.provider)
87
- def llm = provider.call(**options.llm)
123
+ ##
124
+ # @return [LLM::Provider]
125
+ def llm
126
+ provider.call(**options.llm)
127
+ end
88
128
  end
129
+
130
+ module LLM
131
+ Command = LLM::Shell::Command
132
+ end
@@ -1,8 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- require_relative "../../lib/llm/shell"
5
-
6
4
  def main(argv)
7
5
  if argv.include?("-v") || argv.include?("--version")
8
6
  puts LLM::Shell::VERSION
@@ -26,20 +24,20 @@ def option_parser
26
24
  o.on("-m [MODEL]", "--model [MODEL]", "Optional. The name of a model.", Array)
27
25
  o.on("-h [HOST]", "--host [HOST]", "Optional. Sometimes required by ollama.", String)
28
26
  o.on("-o [PORT]", "--port [PORT]", "Optional. Sometimes required by ollama.", Integer)
29
- o.on("-f [GLOB]", "--files [GLOB]", "Optional. Glob pattern(s) separated by a comma.", Array)
30
27
  o.on("-r [PROMPT]", "--prompt [PROMPT]", "Optional. The prompt to use.", String)
31
28
  o.on("-v", "--version", "Optional. Print the version and exit.")
32
29
  end
33
30
  end
34
31
 
35
32
  excode = catch(:exit) do
33
+ require_relative "../../lib/llm/shell"
36
34
  main(ARGV)
37
- 0
35
+ throw(:exit, 0)
38
36
  rescue => ex
39
37
  print Paint[ex.class, :red, :bold], "\n"
40
38
  print ex.message, "\n\n"
41
39
  print Paint["Backtrace", :bold], "\n"
42
- print ex.backtrace[0..5].join("\n"), "\n"
43
- 1
40
+ print ex.backtrace[0..7].join("\n"), "\n"
41
+ throw(:exit, 1)
44
42
  end
45
43
  exit excode
data/llm-shell.gemspec CHANGED
@@ -28,11 +28,7 @@ Gem::Specification.new do |spec|
28
28
  ]
29
29
  spec.require_paths = ["lib"]
30
30
  spec.executables = ["llm-shell"]
31
- spec.add_dependency "llm.rb", "~> 0.13"
32
- spec.add_dependency "paint", "~> 2.1"
33
31
  spec.add_dependency "redcarpet", "~> 3.6"
34
- spec.add_dependency "coderay", "~> 1.1"
35
- spec.add_dependency "reline", "~> 0.6"
36
32
  spec.add_development_dependency "webmock", "~> 3.24.0"
37
33
  spec.add_development_dependency "yard", "~> 0.9.37"
38
34
  spec.add_development_dependency "kramdown", "~> 2.4"