Class: LLM::Repl::Command

Inherits:
Object
  • Object
show all
Defined in:
lib/llm/repl/command.rb

Overview

The LLM::Repl::Command class is the superclass of all read-eval-print loop commands. A command has a name, and a description. This basic version does not implement parameters. A command is accessible via the / prefix: eg /exit.

Direct Known Subclasses

Help

Defined Under Namespace

Classes: Compact, Exit, Parameter, Quit

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(repl) ⇒ LLM::Repl::Command

Parameters:



173
174
175
176
# File 'lib/llm/repl/command.rb', line 173

def initialize(repl)
  @repl = repl
  @agent = repl.agent
end

Instance Attribute Details

#agentLLM::Agent (readonly)

Returns:



168
169
170
# File 'lib/llm/repl/command.rb', line 168

def agent
  @agent
end

#replLLM::Repl (readonly)

Returns:



164
165
166
# File 'lib/llm/repl/command.rb', line 164

def repl
  @repl
end

Class Method Details

.complete(str) ⇒ Array<String>

Returns An array of command names who match the input string.

Parameters:

  • str (String)

    An input string

Returns:

  • (Array<String>)

    An array of command names who match the input string



19
20
21
22
23
# File 'lib/llm/repl/command.rb', line 19

def self.complete(str)
  registry.keys.select do |name|
    name.start_with?(str[1..])
  end
end

.description(description = UNDEFINED) ⇒ String

Set or get a command description.

Parameters:

  • description (String) (defaults to: UNDEFINED)

    The command description.

Returns:

  • (String)


123
124
125
126
# File 'lib/llm/repl/command.rb', line 123

def self.description(description = UNDEFINED)
  return @description if description == UNDEFINED
  @description = description
end

.find_by(input: UNDEFINED, name: UNDEFINED) ⇒ LLM::Repl::Command?

Note:

The input string must be prefixed with "/" or it won't be matched. The match is made against the string before the first space - so "/exit foo" will match the "exit" command but "/exitnow" will not.

Find a command by a name, or by an input string.

Examples:

find by name

LLM::Repl::Command.find_by(name: "exit")

find by input string

LLM::Repl::Command.find_by(input: "/exit")

Parameters:

  • input (String) (defaults to: UNDEFINED)
  • name (String) (defaults to: UNDEFINED)

Returns:



72
73
74
75
76
77
78
79
80
81
82
# File 'lib/llm/repl/command.rb', line 72

def self.find_by(input: UNDEFINED, name: UNDEFINED)
  if input != UNDEFINED
    return nil unless input[0] == "/"
    n, = input.split(" ")
    registry.values.find { n[1..] == _1.name }
  elsif name != UNDEFINED
    registry.values.find { name == _1.name }
  else
    raise ArgumentError, "provide either an input or a name"
  end
end

.helpvoid

This method returns an undefined value.

Display a formatted help message for this command. Uses a single #write call to output the command name, description, and parameter details.



192
193
194
195
196
197
198
199
200
201
202
203
204
205
# File 'lib/llm/repl/command.rb', line 192

def self.help
  lines = []
  lines << "Command: #{name}"
  lines << "Description: #{description}"
  unless parameters.empty?
    lines << ""
    lines << "Parameters:"
    parameters.each_value do |param|
      tag = param.required? ? "(required)" : "(optional)"
      lines << "  #{param.name} [#{param.type}] - #{param.description} #{tag}"
    end
  end
  lines.join("\n")
end

.inherited(outer) ⇒ void

This method returns an undefined value.

Parameters:



88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/llm/repl/command.rb', line 88

def self.inherited(outer)
  LLM.lock(:inherited) do
    @registry[outer] = outer
    outer.instance_variable_set(:@parameters, {})
    outer.define_singleton_method(:inherited) do |inner|
      SINGLETON.inherited(inner)
      inner.instance_variable_set(:@name, outer.instance_variable_get(:@name))
      inner.instance_variable_set(:@description, outer.instance_variable_get(:@description))
      inner.instance_variable_set(:@parameters, outer.instance_variable_get(:@parameters))
    end
  end
end

.name(name = UNDEFINED) ⇒ String

Set or get a command name.

Parameters:

  • name (String) (defaults to: UNDEFINED)

    The command name.

Returns:

  • (String)


113
114
115
116
# File 'lib/llm/repl/command.rb', line 113

def self.name(name = UNDEFINED)
  return @name if name == UNDEFINED
  @name = name
end

.parameter(name, type, description, options = {}) ⇒ void

This method returns an undefined value.

Parameters:

  • name (Symbol)
  • type (Class)
  • description (String)
  • options (Hash) (defaults to: {})


134
135
136
137
138
139
140
# File 'lib/llm/repl/command.rb', line 134

def self.parameter(name, type, description, options = {})
  @parameters[name] = Parameter.new(
    name, type,
    description, options,
    @parameters.size, nil
  )
end

.parametersHash

Returns:

  • (Hash)


144
145
146
# File 'lib/llm/repl/command.rb', line 144

def self.parameters
  @parameters
end

.registryArray<LLM::Repl::Command]

Returns Array<LLM::Repl::Command].

Returns:



103
104
105
# File 'lib/llm/repl/command.rb', line 103

def self.registry
  @registry.transform_keys(&:name)
end

.required(names) ⇒ void

This method returns an undefined value.

Parameters:

  • names (Array<Symbol>)

    One or more required names



152
153
154
155
156
157
158
159
160
# File 'lib/llm/repl/command.rb', line 152

def self.required(names)
  names.each do |name|
    if @parameters.key?(name)
      @parameters[name].required!
    else
      raise LLM::Error, "'#{name}' is not a known parameter"
    end
  end
end

Instance Method Details

#callObject

This method should be implemented by subclasses.

Raises:

  • (NotImplementedError)


210
211
212
# File 'lib/llm/repl/command.rb', line 210

def call(...)
  raise NotImplementedError, "#{self.class}#call is not implemented"
end

#parametersHash<Symbol, Parameter>

Returns:



216
217
218
# File 'lib/llm/repl/command.rb', line 216

def parameters
  self.class.parameters
end

#write(str, who: "command(#{self.class.name}): ") ⇒ void

This method returns an undefined value.

Write a string to the transcript

Parameters:

  • str (String)


182
183
184
185
# File 'lib/llm/repl/command.rb', line 182

def write(str, who: "command(#{self.class.name}): ")
  @repl.write(who, Curses::A_BOLD)
  @repl.write(str)
end