llm-shell 0.9.2 → 0.11.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.
- checksums.yaml +4 -4
- data/LICENSE +21 -0
- data/README.md +24 -165
- data/exe/llm-shell +7 -0
- data/llm-shell.gemspec +26 -36
- metadata +32 -198
- data/bin/llm-shell +0 -21
- data/lib/io/line.rb +0 -26
- data/lib/llm/function.rb +0 -17
- data/lib/llm/shell/command/extension.rb +0 -42
- data/lib/llm/shell/command.rb +0 -88
- data/lib/llm/shell/commands/clear_screen.rb +0 -32
- data/lib/llm/shell/commands/dir_import.rb +0 -49
- data/lib/llm/shell/commands/file_import.rb +0 -41
- data/lib/llm/shell/commands/help.rb +0 -66
- data/lib/llm/shell/commands/show_chat.rb +0 -46
- data/lib/llm/shell/commands/show_version.rb +0 -33
- data/lib/llm/shell/commands/system_prompt.rb +0 -35
- data/lib/llm/shell/commands/utils.rb +0 -21
- data/lib/llm/shell/completion.rb +0 -40
- data/lib/llm/shell/config.rb +0 -35
- data/lib/llm/shell/default.rb +0 -23
- data/lib/llm/shell/formatter.rb +0 -42
- data/lib/llm/shell/functions/read_file.rb +0 -22
- data/lib/llm/shell/functions/write_file.rb +0 -22
- data/lib/llm/shell/markdown.rb +0 -83
- data/lib/llm/shell/options.rb +0 -39
- data/lib/llm/shell/renderer.rb +0 -52
- data/lib/llm/shell/repl.rb +0 -106
- data/lib/llm/shell/version.rb +0 -8
- data/lib/llm/shell.rb +0 -88
- data/lib/llm-shell.rb +0 -3
- data/libexec/llm-shell/shell +0 -45
- data/share/llm-shell/prompts/default.txt +0 -21
data/lib/llm/function.rb
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
class LLM::Function
|
|
4
|
-
##
|
|
5
|
-
# Returns true when a function is a built-in function
|
|
6
|
-
# @return [Boolean]
|
|
7
|
-
def builtin?
|
|
8
|
-
@builtin
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
##
|
|
12
|
-
# Mark a function as a built-in function
|
|
13
|
-
# @return [void]
|
|
14
|
-
def builtin!
|
|
15
|
-
@builtin = true
|
|
16
|
-
end
|
|
17
|
-
end
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
class LLM::Shell::Command
|
|
4
|
-
##
|
|
5
|
-
# The {LLM::Shell::Command::Extension LLM::Shell::Command::Extension}
|
|
6
|
-
# module extends the `LLM` constant with methods that can provide shell
|
|
7
|
-
# commands for an active llm-shell session.
|
|
8
|
-
#
|
|
9
|
-
# @example hello command
|
|
10
|
-
# LLM.command(:hello) do |cmd|
|
|
11
|
-
# cmd.define do |name|
|
|
12
|
-
# io.rewind.print("Hello #{name}")
|
|
13
|
-
# end
|
|
14
|
-
# end
|
|
15
|
-
module Extension
|
|
16
|
-
##
|
|
17
|
-
# @example
|
|
18
|
-
# LLM.command(:hello) do |cmd|
|
|
19
|
-
# cmd.define do |name|
|
|
20
|
-
# io.rewind.print("Hello #{name}")
|
|
21
|
-
# end
|
|
22
|
-
# end
|
|
23
|
-
# @param [String] name
|
|
24
|
-
# The name of the command
|
|
25
|
-
# @yieldparam [LLM::Shell::Command] cmd
|
|
26
|
-
# Yields an instance of LLM::Shell::Command
|
|
27
|
-
# @return [void]
|
|
28
|
-
def command(name)
|
|
29
|
-
cmd = LLM::Shell::Command.new
|
|
30
|
-
cmd.name(name)
|
|
31
|
-
yield cmd
|
|
32
|
-
commands[cmd.name] = cmd
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
##
|
|
36
|
-
# @return [Hash<String, LLM::Shell::Command>]
|
|
37
|
-
def commands
|
|
38
|
-
@commands ||= {}
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
LLM.extend(Extension)
|
|
42
|
-
end
|
data/lib/llm/shell/command.rb
DELETED
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
class LLM::Shell
|
|
4
|
-
class Command
|
|
5
|
-
require_relative "commands/utils"
|
|
6
|
-
|
|
7
|
-
##
|
|
8
|
-
# @api private
|
|
9
|
-
class Context < Struct.new(:bot, :io)
|
|
10
|
-
def pager(...)
|
|
11
|
-
LLM::Shell.pager(...)
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
##
|
|
16
|
-
# Returns the underlying command object
|
|
17
|
-
# @return [Class, #call]
|
|
18
|
-
attr_reader :object
|
|
19
|
-
|
|
20
|
-
##
|
|
21
|
-
# Set or get the command name
|
|
22
|
-
# @param [String, nil] name
|
|
23
|
-
# The name of the command
|
|
24
|
-
# @return [String]
|
|
25
|
-
def name(name = nil)
|
|
26
|
-
if name
|
|
27
|
-
@name = name
|
|
28
|
-
else
|
|
29
|
-
@name
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
##
|
|
34
|
-
# Set or get the command description
|
|
35
|
-
# @param [String, nil] desc
|
|
36
|
-
# The description of the command
|
|
37
|
-
# @return [String]
|
|
38
|
-
def description(desc = nil)
|
|
39
|
-
if desc
|
|
40
|
-
@description = desc
|
|
41
|
-
else
|
|
42
|
-
@description
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
##
|
|
47
|
-
# Setup the command context
|
|
48
|
-
# @return [void]
|
|
49
|
-
def setup(bot, io)
|
|
50
|
-
@context = Context.new(bot, io)
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
##
|
|
54
|
-
# Define the command
|
|
55
|
-
# @return [void]
|
|
56
|
-
def define(klass = nil, &b)
|
|
57
|
-
@object = klass || b
|
|
58
|
-
end
|
|
59
|
-
alias_method :register, :define
|
|
60
|
-
|
|
61
|
-
##
|
|
62
|
-
# Call the command
|
|
63
|
-
# @reurn [void]
|
|
64
|
-
def call(*argv)
|
|
65
|
-
if @context.nil?
|
|
66
|
-
raise "context has not been setup"
|
|
67
|
-
elsif Class === @object
|
|
68
|
-
@object.new(@context).call(*argv)
|
|
69
|
-
else
|
|
70
|
-
@context.instance_exec(*argv, &@object)
|
|
71
|
-
end
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
##
|
|
75
|
-
# @return [Boolean]
|
|
76
|
-
# Returns true if this is a builtin command
|
|
77
|
-
def builtin?
|
|
78
|
-
@builtin
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
##
|
|
82
|
-
# Mark this command as builtin command
|
|
83
|
-
# @return [void]
|
|
84
|
-
def builtin!
|
|
85
|
-
@builtin = true
|
|
86
|
-
end
|
|
87
|
-
end
|
|
88
|
-
end
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
class LLM::Shell::Command
|
|
4
|
-
class ClearScreen
|
|
5
|
-
require_relative "utils"
|
|
6
|
-
include Utils
|
|
7
|
-
|
|
8
|
-
##
|
|
9
|
-
# @param [LLM::Shell::Context] context
|
|
10
|
-
# The context of the command
|
|
11
|
-
# @return [LLM::Shell::Command::ClearScreen]
|
|
12
|
-
def initialize(context)
|
|
13
|
-
@context = context
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
##
|
|
17
|
-
# Clears the screen
|
|
18
|
-
# @return [void]
|
|
19
|
-
def call = clear_screen
|
|
20
|
-
|
|
21
|
-
private
|
|
22
|
-
|
|
23
|
-
def console = IO.console
|
|
24
|
-
def clear_screen = console.clear_screen
|
|
25
|
-
|
|
26
|
-
LLM.command "clear-screen" do |cmd|
|
|
27
|
-
cmd.description "Clear the screen"
|
|
28
|
-
cmd.register(self)
|
|
29
|
-
cmd.builtin!
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
end
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
class LLM::Shell::Command
|
|
4
|
-
class DirImport
|
|
5
|
-
require_relative "utils"
|
|
6
|
-
include Utils
|
|
7
|
-
|
|
8
|
-
##
|
|
9
|
-
# Completes a path with a wildcard.
|
|
10
|
-
# @param path [String]
|
|
11
|
-
# The path to complete.
|
|
12
|
-
# @return [Array<String>]
|
|
13
|
-
# Returns the completed path(s)
|
|
14
|
-
def self.complete(path)
|
|
15
|
-
Dir["#{path}*"]
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
##
|
|
19
|
-
# @param [LLM::Shell::Context] context
|
|
20
|
-
# The context of the command
|
|
21
|
-
# @return [LLM::Shell::Command::DirImport]
|
|
22
|
-
def initialize(context)
|
|
23
|
-
@context = context
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
##
|
|
27
|
-
# Recursively imports all files in a directory.
|
|
28
|
-
# @return [void]
|
|
29
|
-
def call(dir)
|
|
30
|
-
Dir.entries(dir).each do |file|
|
|
31
|
-
if file == "." || file == ".."
|
|
32
|
-
next
|
|
33
|
-
elsif File.directory? File.join(dir, file)
|
|
34
|
-
call File.join(dir, file)
|
|
35
|
-
else
|
|
36
|
-
import File.join(dir, file)
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
private
|
|
42
|
-
|
|
43
|
-
LLM.command "dir-import" do |cmd|
|
|
44
|
-
cmd.description "Share a directory with the LLM"
|
|
45
|
-
cmd.register(self)
|
|
46
|
-
cmd.builtin!
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
|
-
end
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
class LLM::Shell::Command
|
|
4
|
-
class FileImport
|
|
5
|
-
require_relative "utils"
|
|
6
|
-
include Utils
|
|
7
|
-
|
|
8
|
-
##
|
|
9
|
-
# Completes a path with a wildcard.
|
|
10
|
-
# @param path [String]
|
|
11
|
-
# The path to complete.
|
|
12
|
-
# @return [Array<String>]
|
|
13
|
-
# Returns the completed path(s)
|
|
14
|
-
def self.complete(path)
|
|
15
|
-
Dir["#{path}*"]
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
##
|
|
19
|
-
# @param [LLM::Shell::Context] context
|
|
20
|
-
# The context of the command
|
|
21
|
-
# @return [LLM::Shell::Command::FileImport]
|
|
22
|
-
def initialize(context)
|
|
23
|
-
@context = context
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
##
|
|
27
|
-
# Imports one or more globbed files.
|
|
28
|
-
# @return [void]
|
|
29
|
-
def call(*files)
|
|
30
|
-
Dir[*files].each { import(_1) }
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
private
|
|
34
|
-
|
|
35
|
-
LLM.command "file-import" do |cmd|
|
|
36
|
-
cmd.description "Share a file with the LLM"
|
|
37
|
-
cmd.register(self)
|
|
38
|
-
cmd.builtin!
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
end
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
class LLM::Shell::Command
|
|
4
|
-
class Help
|
|
5
|
-
require_relative "utils"
|
|
6
|
-
include Utils
|
|
7
|
-
|
|
8
|
-
##
|
|
9
|
-
# @param [LLM::Shell::Context] context
|
|
10
|
-
# The context of the command
|
|
11
|
-
# @return [LLM::Shell::Command::Help]
|
|
12
|
-
def initialize(context)
|
|
13
|
-
@context = context
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
##
|
|
17
|
-
# Prints help
|
|
18
|
-
# @return [void]
|
|
19
|
-
def call
|
|
20
|
-
pager do |io|
|
|
21
|
-
render_commands(io)
|
|
22
|
-
render_functions(io)
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
private
|
|
27
|
-
|
|
28
|
-
def render_commands(io)
|
|
29
|
-
io.print(Paint["Commands", :bold, :underline], "\n\n")
|
|
30
|
-
io.print(Paint["Builtin", :bold], "\n\n")
|
|
31
|
-
render_group commands.select(&:builtin?), io, :cyan
|
|
32
|
-
io.print(Paint["User", :bold], "\n\n")
|
|
33
|
-
render_group commands.reject(&:builtin?), io, :cyan
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def render_functions(io)
|
|
37
|
-
io.print(Paint["Functions", :bold, :underline], "\n\n")
|
|
38
|
-
io.print(Paint["Builtin", :bold], "\n\n")
|
|
39
|
-
render_group functions.select(&:builtin?), io, :blue
|
|
40
|
-
io.print(Paint["User", :bold], "\n\n")
|
|
41
|
-
render_group functions.reject(&:builtin?), io, :blue
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def render_group(commands, io, bgcolor)
|
|
45
|
-
if commands.empty?
|
|
46
|
-
io.print(Paint["None available", :yellow], "\n\n")
|
|
47
|
-
else
|
|
48
|
-
commands.each.with_index(1) do |command, index|
|
|
49
|
-
io.print(name(command, index, bgcolor), "\n")
|
|
50
|
-
io.print(desc(command), "\n\n")
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
def commands = LLM.commands.values.sort_by(&:name)
|
|
56
|
-
def functions = LLM.functions.values.sort_by(&:name)
|
|
57
|
-
def name(command, index, bgcolor) = [Paint[" #{index} ", :white, bgcolor, :bold], " ", Paint[command.name, :bold]].join
|
|
58
|
-
def desc(command) = command.description || "No description"
|
|
59
|
-
|
|
60
|
-
LLM.command "help" do |cmd|
|
|
61
|
-
cmd.description "Show the help menu"
|
|
62
|
-
cmd.register(self)
|
|
63
|
-
cmd.builtin!
|
|
64
|
-
end
|
|
65
|
-
end
|
|
66
|
-
end
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
class LLM::Shell::Command
|
|
4
|
-
class ShowChat
|
|
5
|
-
require_relative "utils"
|
|
6
|
-
include Utils
|
|
7
|
-
|
|
8
|
-
##
|
|
9
|
-
# @param [LLM::Shell::Context] context
|
|
10
|
-
# The context of the command
|
|
11
|
-
# @return [LLM::Shell::Command::ShowChat]
|
|
12
|
-
def initialize(context)
|
|
13
|
-
@context = context
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
##
|
|
17
|
-
# Emits the full chat history to standard output
|
|
18
|
-
# @return [void]
|
|
19
|
-
def call
|
|
20
|
-
clear_screen
|
|
21
|
-
emit
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
private
|
|
25
|
-
|
|
26
|
-
def emit
|
|
27
|
-
pager do |io|
|
|
28
|
-
messages.each.with_index do |message, index|
|
|
29
|
-
next if index <= 1
|
|
30
|
-
io << render(message) << "\n"
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
def console = IO.console
|
|
36
|
-
def clear_screen = console.clear_screen
|
|
37
|
-
def messages = bot.messages
|
|
38
|
-
def render(message) = LLM::Shell::Renderer.new(message).render
|
|
39
|
-
|
|
40
|
-
LLM.command "show-chat" do |cmd|
|
|
41
|
-
cmd.description "Show the chat"
|
|
42
|
-
cmd.register(self)
|
|
43
|
-
cmd.builtin!
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
end
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
class LLM::Shell::Command
|
|
4
|
-
class ShowVersion
|
|
5
|
-
require_relative "utils"
|
|
6
|
-
include Utils
|
|
7
|
-
|
|
8
|
-
##
|
|
9
|
-
# @param [LLM::Shell::Context] context
|
|
10
|
-
# The context of the command
|
|
11
|
-
# @return [LLM::Shell::Command::ShowVersion]
|
|
12
|
-
def initialize(context)
|
|
13
|
-
@context = context
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
##
|
|
17
|
-
# Shows the current llm-shell version
|
|
18
|
-
# @return [void]
|
|
19
|
-
def call
|
|
20
|
-
pager do |io|
|
|
21
|
-
io.write("llm-shell version: #{LLM::Shell::VERSION}\n")
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
private
|
|
26
|
-
|
|
27
|
-
LLM.command "show-version" do |cmd|
|
|
28
|
-
cmd.description "Show the llm-shell version"
|
|
29
|
-
cmd.register(self)
|
|
30
|
-
cmd.builtin!
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
end
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
class LLM::Shell::Command
|
|
4
|
-
class SystemPrompt
|
|
5
|
-
require_relative "utils"
|
|
6
|
-
include Utils
|
|
7
|
-
|
|
8
|
-
##
|
|
9
|
-
# @param [LLM::Shell::Context] context
|
|
10
|
-
# The context of the command
|
|
11
|
-
# @return [LLM::Shell::Command::SystemPrompt]
|
|
12
|
-
def initialize(context)
|
|
13
|
-
@context = context
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
##
|
|
17
|
-
# Emits the system prompt to standard output
|
|
18
|
-
# @return [void]
|
|
19
|
-
def call
|
|
20
|
-
pager do |io|
|
|
21
|
-
io.write render(bot.messages[0])
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
private
|
|
26
|
-
|
|
27
|
-
def render(message) = LLM::Shell::Renderer.new(message).render
|
|
28
|
-
|
|
29
|
-
LLM.command "system-prompt" do |cmd|
|
|
30
|
-
cmd.description "Show the system prompt"
|
|
31
|
-
cmd.register(self)
|
|
32
|
-
cmd.builtin!
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
end
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
class LLM::Shell::Command
|
|
4
|
-
module Utils
|
|
5
|
-
private
|
|
6
|
-
|
|
7
|
-
def import(file)
|
|
8
|
-
return unless File.file?(file)
|
|
9
|
-
bot.chat [
|
|
10
|
-
"<file path=\"#{file}\">",
|
|
11
|
-
File.read(file),
|
|
12
|
-
"</file>"
|
|
13
|
-
].join("\n")
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
def bot = @context.bot
|
|
17
|
-
def io = @context.io
|
|
18
|
-
def pager(...) = @context.pager(...)
|
|
19
|
-
def file_pattern = /\A<file path=(.+?)>/
|
|
20
|
-
end
|
|
21
|
-
end
|
data/lib/llm/shell/completion.rb
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
class LLM::Shell
|
|
4
|
-
class Completion
|
|
5
|
-
##
|
|
6
|
-
# Returns a proc suitable for Readline completion.
|
|
7
|
-
# @return [Proc]
|
|
8
|
-
def self.to_proc
|
|
9
|
-
new.to_proc
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
##
|
|
13
|
-
# @return [LLM::Shell::Completion]
|
|
14
|
-
def initialize
|
|
15
|
-
@commands = LLM.commands
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
##
|
|
19
|
-
# Returns a proc suitable for Readline completion.
|
|
20
|
-
# @return [Proc]
|
|
21
|
-
def to_proc
|
|
22
|
-
method(:complete).to_proc
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
private
|
|
26
|
-
|
|
27
|
-
def complete(input)
|
|
28
|
-
words = Readline.line_buffer.split(" ")
|
|
29
|
-
command = words[0]
|
|
30
|
-
if commands[command]
|
|
31
|
-
object = commands[command].object
|
|
32
|
-
object.respond_to?(:complete) ? object.complete(input) : []
|
|
33
|
-
else
|
|
34
|
-
commands.keys.grep(/\A#{command}/)
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
attr_reader :commands
|
|
39
|
-
end
|
|
40
|
-
end
|
data/lib/llm/shell/config.rb
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
class LLM::Shell
|
|
4
|
-
class Config
|
|
5
|
-
##
|
|
6
|
-
# @param [String] provider
|
|
7
|
-
# @return [LLM::Shell::Config]
|
|
8
|
-
def initialize(provider)
|
|
9
|
-
@provider = provider
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
##
|
|
13
|
-
# @return [Hash]
|
|
14
|
-
def merge(other)
|
|
15
|
-
to_h.merge(other)
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
##
|
|
19
|
-
# @return [Hash]
|
|
20
|
-
def to_h
|
|
21
|
-
yaml[@provider] || {}
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
private
|
|
25
|
-
|
|
26
|
-
def yaml
|
|
27
|
-
return {} unless File.readable?(path)
|
|
28
|
-
@yaml ||= YAML.load_file(path)
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
def path
|
|
32
|
-
File.join LLM::Shell.home, "config.yml"
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
end
|
data/lib/llm/shell/default.rb
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
class LLM::Shell
|
|
4
|
-
class Default
|
|
5
|
-
def initialize(provider)
|
|
6
|
-
@provider = provider
|
|
7
|
-
end
|
|
8
|
-
|
|
9
|
-
def prompt
|
|
10
|
-
File.join(SHAREDIR, "prompts", "default.txt")
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def role
|
|
14
|
-
case @provider
|
|
15
|
-
when "openai", "ollama" then :system
|
|
16
|
-
else :user
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
SHAREDIR = File.join(__dir__, "..", "..", "..", "share", "llm-shell")
|
|
21
|
-
private_constant :SHAREDIR
|
|
22
|
-
end
|
|
23
|
-
end
|
data/lib/llm/shell/formatter.rb
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
class LLM::Shell
|
|
4
|
-
class Formatter
|
|
5
|
-
FormatError = Class.new(RuntimeError)
|
|
6
|
-
include Command::Utils
|
|
7
|
-
|
|
8
|
-
def initialize(messages)
|
|
9
|
-
@messages = messages.reject(&:tool_call?)
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
def format!(role)
|
|
13
|
-
case role
|
|
14
|
-
when :user then format_user(messages)
|
|
15
|
-
when :assistant then format_assistant(messages)
|
|
16
|
-
else raise FormatError.new("#{role} is not known")
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
private
|
|
21
|
-
|
|
22
|
-
def format_user(messages)
|
|
23
|
-
messages.filter_map do |message|
|
|
24
|
-
next unless message.user?
|
|
25
|
-
next unless String === message.content
|
|
26
|
-
next unless message.content !~ file_pattern
|
|
27
|
-
render(message.tap(&:read!))
|
|
28
|
-
end.join("\n")
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
def format_assistant(messages)
|
|
32
|
-
messages.filter_map do |message|
|
|
33
|
-
next unless message.assistant?
|
|
34
|
-
next unless String === message.content
|
|
35
|
-
render(message.tap(&:read!))
|
|
36
|
-
end.join("\n")
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
attr_reader :messages
|
|
40
|
-
def render(message) = Renderer.new(message).render
|
|
41
|
-
end
|
|
42
|
-
end
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module LLM::Shell::Functions
|
|
4
|
-
class ReadFile
|
|
5
|
-
def call(path:)
|
|
6
|
-
{ok: true, content: File.read(path)}
|
|
7
|
-
rescue => ex
|
|
8
|
-
{ok: false, error: {class: ex.class.to_s, message: ex.message}}
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
private
|
|
12
|
-
|
|
13
|
-
LLM.function(:read_file) do |fn|
|
|
14
|
-
fn.description "Read the contents of a file"
|
|
15
|
-
fn.params do |schema|
|
|
16
|
-
schema.object(path: schema.string.required)
|
|
17
|
-
end
|
|
18
|
-
fn.register(self)
|
|
19
|
-
fn.builtin!
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
end
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module LLM::Shell::Functions
|
|
4
|
-
class WriteFile
|
|
5
|
-
def call(path:, content:)
|
|
6
|
-
{ok: true, content: File.binwrite(path, content)}
|
|
7
|
-
rescue => ex
|
|
8
|
-
{ok: false, error: {class: ex.class.to_s, message: ex.message}}
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
private
|
|
12
|
-
|
|
13
|
-
LLM.function(:write_file) do |fn|
|
|
14
|
-
fn.description "Write the contents of a file"
|
|
15
|
-
fn.params do |schema|
|
|
16
|
-
schema.object(path: schema.string.required, content: schema.string.required)
|
|
17
|
-
end
|
|
18
|
-
fn.register(self)
|
|
19
|
-
fn.builtin!
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
end
|