Class: LLM::Agent
- Inherits:
-
Object
- Object
- LLM::Agent
- Defined in:
- lib/llm/agent.rb
Overview
LLM::Agent provides a class-level DSL for defining reusable, preconfigured assistants with defaults for model, tools, schema, and instructions.
It wraps the same stateful runtime surface as LLM::Context: message history, usage, persistence, streaming parameters, and provider-backed requests still flow through an underlying context. The defining behavior of an agent is that it automatically resolves pending tool calls for you during ‘talk` and `respond`, instead of leaving tool loops to the caller.
Notes:
-
Instructions are injected once unless a system message is already present.
-
An agent automatically executes tool loops (unlike LLM::Context).
-
The automatic tool loop enables the wrapped context’s ‘guard` by default. The built-in LLM::LoopGuard detects repeated tool-call patterns and blocks stuck execution before more tool work is queued.
-
The default tool attempt budget is ‘25`. After that, the agent sends advisory tool errors back through the model and keeps the loop in-band. Set `tool_attempts: nil` to disable that advisory behavior.
-
Tool loop execution can be configured with ‘concurrency :call`, `:thread`, `:task`, `:fiber`, or `:ractor`.
Instance Attribute Summary collapse
-
#llm ⇒ LLM::Provider
readonly
Returns a provider.
Class Method Summary collapse
-
.concurrency(concurrency = nil) ⇒ Symbol, ...
Set or get the tool execution concurrency.
-
.confirm(*tool_names, &block) ⇒ Array<String>, ...
Set or get the tool names that require confirmation before they can run.
-
.instructions(instructions = nil) ⇒ String?
Set or get the default instructions.
-
.model(model = nil, &block) ⇒ String?
Set or get the default model.
-
.schema(schema = nil, &block) ⇒ #to_json?
Set or get the default schema.
-
.skills(*skills, &block) ⇒ Array<String>?
Set or get the default skills.
-
.stream(stream = nil, &block) ⇒ Object, ...
Set or get the default stream.
-
.tools(*tools, &block) ⇒ Array<LLM::Function>
Set or get the default tools.
-
.tracer(tracer = nil, &block) ⇒ LLM::Tracer, ...
Set or get the default tracer.
Instance Method Summary collapse
- #ask(prompt, params = {}) ⇒ Object
-
#concurrency ⇒ Symbol, ...
Returns the configured tool execution concurrency.
- #context_window ⇒ Integer
- #cost ⇒ LLM::Cost
- #deserialize(**kw) ⇒ Object (also: #restore)
- #functions ⇒ Array<LLM::Function>
-
#image_url(url) ⇒ LLM::Object
Returns a tagged object.
-
#initialize(llm, params = {}) ⇒ Agent
constructor
A new instance of Agent.
- #inspect ⇒ String
-
#interrupt! ⇒ nil
(also: #cancel!)
Interrupt the active request, if any.
-
#local_file(path) ⇒ LLM::Object
Returns a tagged object.
- #messages ⇒ LLM::Buffer<LLM::Message>
- #mode ⇒ Symbol
-
#model ⇒ String
Returns the model an Agent is actively using.
-
#on_tool_confirmation(fn, strategy) ⇒ LLM::Function::Return
This method is called when confirmation is required before a tool can run.
- #params ⇒ Hash
- #prompt(&b) ⇒ LLM::Prompt (also: #build_prompt)
-
#remote_file(res) ⇒ LLM::Object
Returns a tagged object.
- #returns ⇒ Array<LLM::Function::Return>
- #serialize(**kw) ⇒ void (also: #save)
-
#stream ⇒ LLM::Stream, ...
Returns a stream object, or nil.
-
#talk(prompt, params = {}) ⇒ LLM::Response
Maintain a conversation via the chat completions API.
- #to_h ⇒ Hash
- #to_json ⇒ String
-
#tracer ⇒ LLM::Tracer
Returns an LLM tracer.
- #usage ⇒ LLM::Object
- #wait ⇒ Array<LLM::Function::Return>
Constructor Details
#initialize(llm, params = {}) ⇒ Agent
Returns a new instance of Agent.
208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 |
# File 'lib/llm/agent.rb', line 208 def initialize(llm, params = {}) @llm = llm fields = %i[model skills schema tracer stream tools concurrency instructions confirm] fields_ivar = %i[tracer concurrency instructions confirm] fields.each do |field| resolvable = params.key?(field) ? params.delete(field) : self.class.public_send(field) resolve_symbol = !%i[concurrency].include?(field) resolved = resolvable != nil ? resolve_option(self, resolvable, resolve_symbol:) : resolvable resolved = [*resolved].map(&:to_s) if field == :confirm && resolved if field == :model params[field] = resolved unless resolved.nil? || params.key?(field) elsif resolved && !fields_ivar.include?(field) params[field] ||= resolved elsif fields_ivar.include?(field) instance_variable_set(:"@#{field}", resolved) end end @ctx = LLM::Context.new(llm, {guard: true}.merge(params)) end |
Instance Attribute Details
#llm ⇒ LLM::Provider (readonly)
Returns a provider
43 44 45 |
# File 'lib/llm/agent.rb', line 43 def llm @llm end |
Class Method Details
.concurrency(concurrency = nil) ⇒ Symbol, ...
Set or get the tool execution concurrency.
119 120 121 122 |
# File 'lib/llm/agent.rb', line 119 def self.concurrency(concurrency = nil) return @concurrency if concurrency.nil? @concurrency = concurrency end |
.confirm(*tool_names, &block) ⇒ Array<String>, ...
Set or get the tool names that require confirmation before they can run.
When a single Symbol is given, it is stored as-is and resolved at initialization time by calling the method with that name on the agent instance. This allows dynamic tool confirmation lists.
185 186 187 188 189 190 191 192 |
# File 'lib/llm/agent.rb', line 185 def self.confirm(*tool_names, &block) return @confirm if tool_names.empty? && !block if tool_names.size == 1 && tool_names.grep(Symbol).any? @confirm = tool_names.first else @confirm = block || tool_names.flatten.map(&:to_s) end end |
.instructions(instructions = nil) ⇒ String?
Set or get the default instructions
99 100 101 102 |
# File 'lib/llm/agent.rb', line 99 def self.instructions(instructions = nil) return @instructions if instructions.nil? @instructions = instructions end |
.model(model = nil, &block) ⇒ String?
Set or get the default model
51 52 53 54 |
# File 'lib/llm/agent.rb', line 51 def self.model(model = nil, &block) return @model if model.nil? && !block @model = block || model end |
.schema(schema = nil, &block) ⇒ #to_json?
Set or get the default schema
88 89 90 91 |
# File 'lib/llm/agent.rb', line 88 def self.schema(schema = nil, &block) return @schema if schema.nil? && !block @schema = block || schema end |
.skills(*skills, &block) ⇒ Array<String>?
Set or get the default skills
73 74 75 76 77 78 79 80 |
# File 'lib/llm/agent.rb', line 73 def self.skills(*skills, &block) return @skills if skills.empty? && !block if skills.size == 1 and skills.grep(Symbol).any? @skills = skills.first else @skills = block || skills.flatten end end |
.stream(stream = nil, &block) ⇒ Object, ...
Set or get the default stream.
When a block is provided, it is stored and evaluated lazily against the agent instance during initialization so it can build a fresh stream for each agent.
159 160 161 162 |
# File 'lib/llm/agent.rb', line 159 def self.stream(stream = nil, &block) return @stream if stream.nil? && !block @stream = block || stream end |
.tools(*tools, &block) ⇒ Array<LLM::Function>
Set or get the default tools
62 63 64 65 |
# File 'lib/llm/agent.rb', line 62 def self.tools(*tools, &block) return @tools || [] if tools.empty? && !block @tools = block || tools.flatten end |
.tracer(tracer = nil, &block) ⇒ LLM::Tracer, ...
Set or get the default tracer.
When a block is provided, it is stored and evaluated lazily against the agent instance during initialization so it can build a tracer from the resolved provider.
139 140 141 142 |
# File 'lib/llm/agent.rb', line 139 def self.tracer(tracer = nil, &block) return @tracer if tracer.nil? && !block @tracer = block || tracer end |
Instance Method Details
#ask(prompt, params = {}) ⇒ Object
250 251 252 |
# File 'lib/llm/agent.rb', line 250 def ask(prompt, params = {}) run_loop(prompt, params, :ask) end |
#concurrency ⇒ Symbol, ...
Returns the configured tool execution concurrency.
360 361 362 |
# File 'lib/llm/agent.rb', line 360 def concurrency @concurrency end |
#context_window ⇒ Integer
374 375 376 |
# File 'lib/llm/agent.rb', line 374 def context_window @ctx.context_window end |
#deserialize(**kw) ⇒ Object Also known as: restore
416 417 418 |
# File 'lib/llm/agent.rb', line 416 def deserialize(**kw) @ctx.deserialize(**kw) end |
#functions ⇒ Array<LLM::Function>
262 263 264 |
# File 'lib/llm/agent.rb', line 262 def functions @tracer ? @llm.with_tracer(@tracer) { @ctx.functions } : @ctx.functions end |
#image_url(url) ⇒ LLM::Object
Returns a tagged object
308 309 310 |
# File 'lib/llm/agent.rb', line 308 def image_url(url) @ctx.image_url(url) end |
#inspect ⇒ String
400 401 402 403 |
# File 'lib/llm/agent.rb', line 400 def inspect "#<#{LLM::Utils.object_id(self)} " \ "@llm=#{@llm.class}, @mode=#{mode.inspect}, @messages=#{.inspect}>" end |
#interrupt! ⇒ nil Also known as: cancel!
Interrupt the active request, if any.
289 290 291 |
# File 'lib/llm/agent.rb', line 289 def interrupt! @ctx.interrupt! end |
#local_file(path) ⇒ LLM::Object
Returns a tagged object
317 318 319 |
# File 'lib/llm/agent.rb', line 317 def local_file(path) @ctx.local_file(path) end |
#mode ⇒ Symbol
353 354 355 |
# File 'lib/llm/agent.rb', line 353 def mode @ctx.mode end |
#model ⇒ String
Returns the model an Agent is actively using
347 348 349 |
# File 'lib/llm/agent.rb', line 347 def model @ctx.model end |
#on_tool_confirmation(fn, strategy) ⇒ LLM::Function::Return
This method is called when confirmation is required before a tool can run.
432 433 434 |
# File 'lib/llm/agent.rb', line 432 def on_tool_confirmation(fn, strategy) fn.cancel end |
#params ⇒ Hash
381 382 383 |
# File 'lib/llm/agent.rb', line 381 def params @ctx.params end |
#prompt(&b) ⇒ LLM::Prompt Also known as: build_prompt
298 299 300 |
# File 'lib/llm/agent.rb', line 298 def prompt(&b) @ctx.prompt(&b) end |
#remote_file(res) ⇒ LLM::Object
Returns a tagged object
326 327 328 |
# File 'lib/llm/agent.rb', line 326 def remote_file(res) @ctx.remote_file(res) end |
#returns ⇒ Array<LLM::Function::Return>
269 270 271 |
# File 'lib/llm/agent.rb', line 269 def returns @ctx.returns end |
#serialize(**kw) ⇒ void Also known as: save
This method returns an undefined value.
408 409 410 |
# File 'lib/llm/agent.rb', line 408 def serialize(**kw) @ctx.serialize(**kw) end |
#stream ⇒ LLM::Stream, ...
Returns a stream object, or nil
340 341 342 |
# File 'lib/llm/agent.rb', line 340 def stream @ctx.stream end |
#talk(prompt, params = {}) ⇒ LLM::Response
Maintain a conversation via the chat completions API. This method immediately sends a request to the LLM and returns the response.
244 245 246 |
# File 'lib/llm/agent.rb', line 244 def talk(prompt, params = {}) run_loop(prompt, params, :talk) end |
#to_h ⇒ Hash
388 389 390 |
# File 'lib/llm/agent.rb', line 388 def to_h @ctx.to_h end |
#to_json ⇒ String
394 395 396 |
# File 'lib/llm/agent.rb', line 394 def to_json(...) LLM.json.dump(to_h, ...) end |
#tracer ⇒ LLM::Tracer
Returns an LLM tracer
333 334 335 |
# File 'lib/llm/agent.rb', line 333 def tracer @tracer || @ctx.tracer end |
#wait ⇒ Array<LLM::Function::Return>
276 277 278 |
# File 'lib/llm/agent.rb', line 276 def wait(...) @tracer ? @llm.with_tracer(@tracer) { @ctx.wait(...) } : @ctx.wait(...) end |