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
@@ -0,0 +1,268 @@
1
+ # frozen-string-literal: true
2
+
3
+ module Tomlrb
4
+ class Handler
5
+ attr_reader :output, :symbolize_keys
6
+
7
+ def initialize(**options)
8
+ @output = {}
9
+ @current = @output
10
+ @stack = []
11
+ @array_names = []
12
+ @current_table = []
13
+ @keys = Keys.new
14
+ @symbolize_keys = options[:symbolize_keys]
15
+ end
16
+
17
+ def set_context(identifiers, is_array_of_tables: false)
18
+ if identifiers.empty?
19
+ raise ParseError, 'Array needs a name'
20
+ end
21
+
22
+ @current_table = identifiers.dup
23
+ @keys.add_table_key identifiers, is_array_of_tables
24
+ @current = @output
25
+
26
+ deal_with_array_of_tables(identifiers, is_array_of_tables) do |identifierz|
27
+ identifierz.each do |k|
28
+ k = k.to_sym if @symbolize_keys
29
+ if @current[k].is_a?(Array)
30
+ @current = @current[k].last
31
+ else
32
+ @current[k] ||= {}
33
+ @current = @current[k]
34
+ end
35
+ end
36
+ end
37
+ end
38
+
39
+ def deal_with_array_of_tables(identifiers, is_array_of_tables)
40
+ stringified_identifier = identifiers.join('.')
41
+
42
+ if is_array_of_tables
43
+ @array_names << stringified_identifier
44
+ last_identifier = identifiers.pop
45
+ elsif @array_names.include?(stringified_identifier)
46
+ raise ParseError, 'Cannot define a normal table with the same name as an already established array'
47
+ end
48
+
49
+ yield(identifiers)
50
+
51
+ if is_array_of_tables
52
+ last_identifier = last_identifier.to_sym if @symbolize_keys
53
+ @current[last_identifier] ||= []
54
+ raise ParseError, "Cannot use key #{last_identifier} for both table and array at once" unless @current[last_identifier].respond_to?(:<<)
55
+ @current[last_identifier] << {}
56
+ @current = @current[last_identifier].last
57
+ end
58
+ end
59
+
60
+ def assign(k)
61
+ @keys.add_pair_key k, @current_table
62
+ current = @current
63
+ while (key = k.shift)
64
+ key = key.to_sym if @symbolize_keys
65
+ current = assign_key_path(current, key, k.empty?)
66
+ end
67
+ end
68
+
69
+ def push(o)
70
+ @stack << o
71
+ end
72
+
73
+ def push_inline(inline_arrays)
74
+ merged_inline = {}
75
+
76
+ inline_arrays.each do |inline_array|
77
+ current = merged_inline
78
+ value = inline_array.pop
79
+ inline_array.each_with_index do |inline_key, inline_index|
80
+ inline_key = inline_key.to_sym if @symbolize_keys
81
+ last_key = inline_index == inline_array.size - 1
82
+
83
+ if last_key
84
+ if current[inline_key].nil?
85
+ current[inline_key] = value
86
+ else
87
+ raise Key::KeyConflict, "Inline key #{inline_key} is already used"
88
+ end
89
+ else
90
+ current[inline_key] ||= {}
91
+ current = current[inline_key]
92
+ end
93
+ end
94
+ end
95
+
96
+ push(merged_inline)
97
+ end
98
+
99
+ def start_(type)
100
+ push([type])
101
+ end
102
+
103
+ def end_(type)
104
+ array = []
105
+ while (value = @stack.pop) != [type]
106
+ raise ParseError, 'Unclosed table' if @stack.empty?
107
+
108
+ array.unshift(value)
109
+ end
110
+ array
111
+ end
112
+
113
+ def validate_value(value)
114
+ if value.nil?
115
+ raise ParseError, 'Value must be present'
116
+ end
117
+ end
118
+
119
+ private
120
+
121
+ def assign_key_path(current, key, key_emptied)
122
+ if key_emptied
123
+ raise ParseError, "Cannot overwrite value with key #{key}" unless current.is_a?(Hash)
124
+
125
+ current[key] = @stack.pop
126
+ return current
127
+ end
128
+ current[key] ||= {}
129
+ current[key]
130
+ end
131
+ end
132
+
133
+ class Keys
134
+ def initialize
135
+ @keys = {}
136
+ end
137
+
138
+ def add_table_key(keys, is_array_of_tables = false)
139
+ self << [keys, [], is_array_of_tables]
140
+ end
141
+
142
+ def add_pair_key(keys, context)
143
+ self << [context, keys, false]
144
+ end
145
+
146
+ def <<(keys)
147
+ table_keys, pair_keys, is_array_of_tables = keys
148
+ current = @keys
149
+ current = append_table_keys(current, table_keys, pair_keys.empty?, is_array_of_tables)
150
+ append_pair_keys(current, pair_keys, table_keys.empty?, is_array_of_tables)
151
+ end
152
+
153
+ private
154
+
155
+ def append_table_keys(current, table_keys, pair_keys_empty, is_array_of_tables)
156
+ table_keys.each_with_index do |key, index|
157
+ declared = (index == table_keys.length - 1) && pair_keys_empty
158
+ if index.zero?
159
+ current = find_or_create_first_table_key(current, key, declared, is_array_of_tables)
160
+ else
161
+ current <<= [key, :table, declared, is_array_of_tables]
162
+ end
163
+ end
164
+
165
+ current.clear_children if is_array_of_tables
166
+ current
167
+ end
168
+
169
+ def find_or_create_first_table_key(current, key, declared, is_array_of_tables)
170
+ existed = current[key]
171
+ if existed && existed.type == :pair
172
+ raise Key::KeyConflict, "Key #{key} is already used as #{existed.type} key"
173
+ end
174
+ if existed && existed.declared? && declared && ! is_array_of_tables
175
+ raise Key::KeyConflict, "Key #{key} is already used"
176
+ end
177
+ k = existed || Key.new(key, :table, declared)
178
+ current[key] = k
179
+ k
180
+ end
181
+
182
+ def append_pair_keys(current, pair_keys, table_keys_empty, is_array_of_tables)
183
+ pair_keys.each_with_index do |key, index|
184
+ declared = index == pair_keys.length - 1
185
+ if index.zero? && table_keys_empty
186
+ current = find_or_create_first_pair_key(current, key, declared, table_keys_empty)
187
+ else
188
+ key = current << [key, :pair, declared, is_array_of_tables]
189
+ current = key
190
+ end
191
+ end
192
+ end
193
+
194
+ def find_or_create_first_pair_key(current, key, declared, table_keys_empty)
195
+ existed = current[key]
196
+ if existed && (existed.type == :pair) && declared && table_keys_empty
197
+ raise Key::KeyConflict, "Key #{key} is already used"
198
+ end
199
+ k = Key.new(key, :pair, declared)
200
+ current[key] = k
201
+ k
202
+ end
203
+ end
204
+
205
+ class Key
206
+ class KeyConflict < ParseError; end
207
+
208
+ attr_reader :key, :type
209
+
210
+ def initialize(key, type, declared = false)
211
+ @key = key
212
+ @type = type
213
+ @declared = declared
214
+ @children = {}
215
+ end
216
+
217
+ def declared?
218
+ @declared
219
+ end
220
+
221
+ def <<(key_type_declared)
222
+ key, type, declared, is_array_of_tables = key_type_declared
223
+ existed = @children[key]
224
+ validate_already_declared_as_different_key(type, declared, existed)
225
+ validate_already_declared_as_non_array_table(type, is_array_of_tables, declared, existed)
226
+ validate_path_already_created_as_different_type(type, declared, existed)
227
+ validate_path_already_declared_as_different_type(type, declared, existed)
228
+ validate_already_declared_as_same_key(declared, existed)
229
+ @children[key] = existed || self.class.new(key, type, declared)
230
+ end
231
+
232
+ def clear_children
233
+ @children.clear
234
+ end
235
+
236
+ private
237
+
238
+ def validate_already_declared_as_different_key(type, _declared, existed)
239
+ if existed && existed.declared? && existed.type != type
240
+ raise KeyConflict, "Key #{existed.key} is already used as #{existed.type} key"
241
+ end
242
+ end
243
+
244
+ def validate_already_declared_as_non_array_table(type, is_array_of_tables, declared, existed)
245
+ if declared && type == :table && existed && existed.declared? && !is_array_of_tables
246
+ raise KeyConflict, "Key #{existed.key} is already used"
247
+ end
248
+ end
249
+
250
+ def validate_path_already_created_as_different_type(type, declared, existed)
251
+ if declared && (type == :table) && existed && (existed.type == :pair) && !existed.declared?
252
+ raise KeyConflict, "Key #{existed.key} is already used as #{existed.type} key"
253
+ end
254
+ end
255
+
256
+ def validate_path_already_declared_as_different_type(type, declared, existed)
257
+ if !declared && (type == :pair) && existed && (existed.type == :pair) && existed.declared?
258
+ raise KeyConflict, "Key #{key} is already used as #{type} key"
259
+ end
260
+ end
261
+
262
+ def validate_already_declared_as_same_key(declared, existed)
263
+ if existed && !existed.declared? && declared
264
+ raise KeyConflict, "Key #{existed.key} is already used as #{existed.type} key"
265
+ end
266
+ end
267
+ end
268
+ end
@@ -0,0 +1,35 @@
1
+ # frozen-string-literal: true
2
+
3
+ require 'forwardable'
4
+
5
+ module Tomlrb
6
+ class LocalDate
7
+ extend Forwardable
8
+
9
+ def_delegators :@time, :year, :month, :day
10
+
11
+ def initialize(year, month, day)
12
+ @time = Time.new(year, month, day, 0, 0, 0, '-00:00')
13
+ end
14
+
15
+ # @param offset see {LocalDateTime#to_time}
16
+ # @return [Time] 00:00:00 of the date
17
+ def to_time(offset = '-00:00')
18
+ return @time if offset == '-00:00'
19
+ Time.new(year, month, day, 0, 0, 0, offset)
20
+ end
21
+
22
+ def to_s
23
+ @time.strftime('%F')
24
+ end
25
+
26
+ def ==(other)
27
+ other.is_a?(self.class) &&
28
+ to_time == other.to_time
29
+ end
30
+
31
+ def inspect
32
+ "#<#{self.class}: #{self}>"
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,42 @@
1
+ # frozen-string-literal: true
2
+
3
+ require 'forwardable'
4
+
5
+ module Tomlrb
6
+ class LocalDateTime
7
+ extend Forwardable
8
+
9
+ def_delegators :@time, :year, :month, :day, :hour, :min, :sec, :usec, :nsec
10
+
11
+ def initialize(year, month, day, hour, min, sec) # rubocop:disable Metrics/ParameterLists
12
+ @time = Time.new(year, month, day, hour, min, sec, '-00:00')
13
+ @sec = sec
14
+ end
15
+
16
+ # @param offset [String, Symbol, Numeric, nil] time zone offset.
17
+ # * when +String+, must be '+HH:MM' format, '-HH:MM' format, 'UTC', 'A'..'I' or 'K'..'Z'. Arguments excluding '+-HH:MM' are supporeted at Ruby >= 2.7.0
18
+ # * when +Symbol+, must be +:dst+(for summar time for local) or +:std+(for standard time).
19
+ # * when +Numeric+, it is time zone offset in second.
20
+ # * when +nil+, local time zone offset is used.
21
+ # @return [Time]
22
+ def to_time(offset = '-00:00')
23
+ return @time if offset == '-00:00'
24
+ Time.new(year, month, day, hour, min, @sec, offset)
25
+ end
26
+
27
+ def to_s
28
+ frac = (@sec - sec)
29
+ frac_str = frac.zero? ? '' : frac.to_s[1..-1]
30
+ @time.strftime('%FT%T') << frac_str
31
+ end
32
+
33
+ def ==(other)
34
+ other.is_a?(self.class) &&
35
+ to_time == other.to_time
36
+ end
37
+
38
+ def inspect
39
+ "#<#{self.class}: #{self}>"
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,40 @@
1
+ # frozen-string-literal: true
2
+
3
+ require 'forwardable'
4
+
5
+ module Tomlrb
6
+ class LocalTime
7
+ extend Forwardable
8
+
9
+ def_delegators :@time, :hour, :min, :sec, :usec, :nsec
10
+
11
+ def initialize(hour, min, sec)
12
+ @time = Time.new(0, 1, 1, hour, min, sec, '-00:00')
13
+ @sec = sec
14
+ end
15
+
16
+ # @param year [Integer]
17
+ # @param month [Integer]
18
+ # @param day [Integer]
19
+ # @param offset see {LocalDateTime#to_time}
20
+ # @return [Time] the time of the date specified by params
21
+ def to_time(year, month, day, offset = '-00:00')
22
+ Time.new(year, month, day, hour, min, @sec, offset)
23
+ end
24
+
25
+ def to_s
26
+ frac = (@sec - sec)
27
+ frac_str = frac.zero? ? '' : frac.to_s[1..-1]
28
+ @time.strftime('%T') << frac_str
29
+ end
30
+
31
+ def ==(other)
32
+ other.is_a?(self.class) &&
33
+ @time == other.to_time(0, 1, 1)
34
+ end
35
+
36
+ def inspect
37
+ "#<#{self.class}: #{self}>"
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,21 @@
1
+ # frozen-string-literal: true
2
+
3
+ require 'tomlrb/generated_parser'
4
+
5
+ class Tomlrb::Parser < Tomlrb::GeneratedParser
6
+
7
+ def initialize(tokenizer, **options)
8
+ @tokenizer = tokenizer
9
+ @handler = Tomlrb::Handler.new(**options)
10
+ super()
11
+ end
12
+
13
+ def next_token
14
+ @tokenizer.next_token
15
+ end
16
+
17
+ def parse
18
+ do_parse
19
+ @handler
20
+ end
21
+ end
@@ -0,0 +1,92 @@
1
+ # frozen-string-literal: true
2
+
3
+ require 'strscan'
4
+
5
+ module Tomlrb
6
+ class Scanner
7
+ COMMENT =
8
+ /#[^\u0000-\u0008\u000A-\u001F\u007F]*/.freeze
9
+ IDENTIFIER =
10
+ /[A-Za-z0-9_-]+/.freeze
11
+ SPACE =
12
+ /[ \t]/.freeze
13
+ NEWLINE =
14
+ /(?:[ \t]*(?:\r?\n)[ \t]*)+/.freeze
15
+ STRING_BASIC =
16
+ /(")(?:\\?[^\u0000-\u0008\u000A-\u001F\u007F])*?\1/.freeze
17
+ STRING_MULTI =
18
+ /"{3}([^\u0000-\u0008\u000B\u000C\u000E-\u001F\u007F]*?(?<!\\)"{3,5})/m.freeze
19
+ STRING_LITERAL =
20
+ /(')(?:\\?[^\u0000-\u0008\u000A-\u001F\u007F])*?\1/.freeze
21
+ STRING_LITERAL_MULTI =
22
+ /'{3}([^\u0000-\u0008\u000B\u000C\u000E-\u001F\u007F]*?'{3,5})/m.freeze
23
+ DATETIME =
24
+ /(-?\d{4})-(\d{2})-(\d{2})(?:(?:t|\s)(\d{2}):(\d{2}):(\d{2}(?:\.\d+)?))?(z|[-+]\d{2}:\d{2})?/i.freeze
25
+ LOCAL_TIME =
26
+ /(\d{2}):(\d{2}):(\d{2}(?:\.\d+)?)/.freeze
27
+ FLOAT =
28
+ /[+-]?(?:(?:\d|[1-9](?:_?\d)*)\.\d(?:_?\d)*|\d+(?=[eE]))(?:[eE][+-]?[0-9]+(_[0-9])*[0-9]*)?(?!\w)/.freeze
29
+ FLOAT_KEYWORD =
30
+ /[+-]?(?:inf|nan)\b/.freeze
31
+ INTEGER =
32
+ /[+-]?([1-9](_?\d)*|0)(?![A-Za-z0-9_-]+)/.freeze
33
+ NON_DEC_INTEGER =
34
+ /0(?:x[0-9A-Fa-f](_?[0-9A-Fa-f])*|o[0-7](_?[0-7])*|b[01](_?[01])*)/.freeze
35
+ BOOLEAN =
36
+ /true|false/.freeze
37
+ SPACED_ARRAY_OF_TABLES_START =
38
+ /^\[[ \t]+\[(#{IDENTIFIER}|#{STRING_BASIC}|#{STRING_LITERAL}|#{INTEGER}|#{NON_DEC_INTEGER}|#{FLOAT_KEYWORD}|#{BOOLEAN})\]\]$/.freeze
39
+ SPACED_ARRAY_OF_TABLES_END =
40
+ /^\[\[(#{IDENTIFIER}|#{STRING_BASIC}|#{STRING_LITERAL}|#{INTEGER}|#{NON_DEC_INTEGER}|#{FLOAT_KEYWORD}|#{BOOLEAN})\][ \t]+\]$/.freeze
41
+ SPACED_ARRAY_OF_TABLES_BOTH =
42
+ /^\[[ \t]+\[(#{IDENTIFIER}|#{STRING_BASIC}|#{STRING_LITERAL}|#{INTEGER}|#{NON_DEC_INTEGER}|#{FLOAT_KEYWORD}|#{BOOLEAN})\][ \t]+\]$/.freeze
43
+
44
+ def initialize(io)
45
+ @ss = StringScanner.new(io.read)
46
+ @eos = false
47
+ end
48
+
49
+ def next_token
50
+ case
51
+ when @ss.scan(NEWLINE) then [:NEWLINE, nil]
52
+ when @ss.scan(SPACED_ARRAY_OF_TABLES_START) then raise ParseError.new('Array of tables has spaces in starting brackets')
53
+ when @ss.scan(SPACED_ARRAY_OF_TABLES_END) then raise ParseError.new('Array of tables has spaces in ending brackets')
54
+ when @ss.scan(SPACED_ARRAY_OF_TABLES_BOTH) then raise ParseError.new('Array of tables has spaces in starting and ending brackets')
55
+ when @ss.scan(SPACE) then next_token
56
+ when @ss.scan(COMMENT) then next_token
57
+ when @ss.scan(DATETIME) then process_datetime
58
+ when @ss.scan(LOCAL_TIME) then process_local_time
59
+ when text = @ss.scan(STRING_MULTI) then [:STRING_MULTI, text[3..-4]]
60
+ when text = @ss.scan(STRING_BASIC) then [:STRING_BASIC, text[1..-2]]
61
+ when text = @ss.scan(STRING_LITERAL_MULTI) then [:STRING_LITERAL_MULTI, text[3..-4]]
62
+ when text = @ss.scan(STRING_LITERAL) then [:STRING_LITERAL, text[1..-2]]
63
+ when text = @ss.scan(FLOAT) then [:FLOAT, text]
64
+ when text = @ss.scan(FLOAT_KEYWORD) then [:FLOAT_KEYWORD, text]
65
+ when text = @ss.scan(INTEGER) then [:INTEGER, text]
66
+ when text = @ss.scan(NON_DEC_INTEGER) then [:NON_DEC_INTEGER, text]
67
+ when text = @ss.scan(BOOLEAN) then [:BOOLEAN, text]
68
+ when text = @ss.scan(IDENTIFIER) then [:IDENTIFIER, text]
69
+ when @ss.eos? then process_eos
70
+ else x = @ss.getch; [x, x]
71
+ end
72
+ end
73
+
74
+ def process_datetime
75
+ offset = @ss[7].gsub(/[zZ]/, '+00:00') if @ss[7]
76
+ args = [@ss[1], @ss[2], @ss[3], @ss[4], @ss[5], @ss[6], offset]
77
+ [:DATETIME, args]
78
+ end
79
+
80
+ def process_local_time
81
+ args = [@ss[1], @ss[2], @ss[3].to_f]
82
+ [:LOCAL_TIME, args]
83
+ end
84
+
85
+ def process_eos
86
+ return if @eos
87
+
88
+ @eos = true
89
+ [:EOS, nil]
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,40 @@
1
+ # frozen-string-literal: true
2
+
3
+ module Tomlrb
4
+ class StringUtils
5
+ SPECIAL_CHARS = {
6
+ '\\t' => "\t",
7
+ '\\b' => "\b",
8
+ '\\f' => "\f",
9
+ '\\n' => "\n",
10
+ '\\r' => "\r",
11
+ '\\"' => '"',
12
+ '\\\\' => '\\'
13
+ }.freeze
14
+
15
+ def self.multiline_replacements(str)
16
+ strip_spaces(str).gsub(/\\+\s*\n\s*/) do |matched|
17
+ if matched.match(/\\+/)[0].length.odd?
18
+ matched.gsub(/\\\s*\n\s*/, '')
19
+ else
20
+ matched
21
+ end
22
+ end
23
+ end
24
+
25
+ def self.replace_escaped_chars(str)
26
+ str.gsub(/\\(u[\da-fA-F]{4}|U[\da-fA-F]{8}|.)/) do |m|
27
+ if m.size == 2
28
+ SPECIAL_CHARS[m] || (raise Tomlrb::ParseError.new "Escape sequence #{m} is reserved")
29
+ else
30
+ m[2..-1].to_i(16).chr(Encoding::UTF_8)
31
+ end
32
+ end
33
+ end
34
+
35
+ def self.strip_spaces(str)
36
+ str[0] = '' if str[0] == "\n"
37
+ str
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,5 @@
1
+ # frozen-string-literal: true
2
+
3
+ module Tomlrb
4
+ VERSION = '2.0.3'
5
+ end
@@ -0,0 +1,49 @@
1
+ # frozen-string-literal: true
2
+
3
+ require 'time'
4
+ require 'stringio'
5
+ require 'tomlrb/version'
6
+ require 'tomlrb/local_date_time'
7
+ require 'tomlrb/local_date'
8
+ require 'tomlrb/local_time'
9
+ require 'tomlrb/string_utils'
10
+ require 'tomlrb/scanner'
11
+ require 'tomlrb/parser'
12
+ require 'tomlrb/handler'
13
+
14
+ module Tomlrb
15
+ class ParseError < StandardError; end
16
+
17
+ # Parses a valid TOML string into its Ruby data structure
18
+ #
19
+ # @param string_or_io [String, StringIO] the content
20
+ # @param options [Hash] the options hash
21
+ # @option options [Boolean] :symbolize_keys (false) whether to return the keys as symbols or strings
22
+ # @return [Hash] the Ruby data structure represented by the input
23
+ def self.parse(string_or_io, **options)
24
+ io = string_or_io.is_a?(String) ? StringIO.new(string_or_io) : string_or_io
25
+ scanner = Scanner.new(io)
26
+ parser = Parser.new(scanner, **options)
27
+ begin
28
+ handler = parser.parse
29
+ rescue Racc::ParseError => e
30
+ raise ParseError, e.message
31
+ end
32
+
33
+ handler.output
34
+ end
35
+
36
+ # Reads a file content and parses it into its Ruby data structure
37
+ #
38
+ # @param path [String] the path to the file
39
+ # @param options [Hash] the options hash
40
+ # @option options [Boolean] :symbolize_keys (false) whether to return the keys as symbols or strings
41
+ # @return [Hash] the Ruby data structure represented by the input
42
+ def self.load_file(path, **options)
43
+ # By default Ruby sets the external encoding of an IO object to the
44
+ # default external encoding. The default external encoding is set by
45
+ # locale encoding or the interpreter -E option.
46
+ tmp = File.read(path, encoding: 'utf-8')
47
+ Tomlrb.parse(tmp, **options)
48
+ end
49
+ end
@@ -33,7 +33,7 @@ class LLM::Shell
33
33
 
34
34
  def custom_prompt
35
35
  prompt = @options.delete(:prompt)
36
- File.join(LLM::Shell.home, "prompts", prompt)
36
+ File.join(LLM::Shell.home_data, "prompts", prompt)
37
37
  end
38
38
  end
39
39
  end
@@ -3,7 +3,6 @@
3
3
  class LLM::Shell
4
4
  class Renderer
5
5
  RenderError = Class.new(RuntimeError)
6
- include Command::Utils
7
6
 
8
7
  ##
9
8
  # @param [LLM::Message] message
@@ -40,8 +39,8 @@ class LLM::Shell
40
39
  body = "Tool call(s) return"
41
40
  elsif Array === content
42
41
  body = content.map { |c| render_message(c, color) }.join("\n")
43
- elsif content =~ file_pattern
44
- path = content.match(file_pattern) ? Regexp.last_match[1] : nil
42
+ elsif content =~ LLM::Shell.pattern
43
+ path = content.match(LLM::Shell.pattern) ? Regexp.last_match[1] : nil
45
44
  body = "<file path=#{path} />"
46
45
  else
47
46
  body = Markdown.render(content)