Class: Omakase::Agent
- Inherits:
-
Object
- Object
- Omakase::Agent
- Defined in:
- lib/omakase/agent.rb
Overview
Fields are state, methods are what the model can call, generates declares
the methods the model implements.
Class Method Summary collapse
- .chat_options ⇒ Object
-
.describe(text) ⇒ Object
Documents the method defined next — the docstring Ruby does not have.
- .descriptions ⇒ Object
-
.generates(name, prompt = nil, returns: nil, strategy: nil, &schema) ⇒ Object
Without a prompt, the method name is the prompt.
- .generations ⇒ Object
- .instructions(text = nil) ⇒ Object
-
.mcp(name, **options) ⇒ Object
An MCP server's tools, as methods on the agent.
-
.model(id = nil, **options) ⇒ Object
The model and any RubyLLM chat option.
-
.skill(path) ⇒ Object
A skill directory — a SKILL.md with YAML front matter.
- .strategy(name = nil) ⇒ Object
Instance Method Summary collapse
-
#chat ⇒ Object
A fresh conversation per call.
-
#doc(object) ⇒ Object
For generated code meeting an object whose type it does not know.
-
#finish(value) ⇒ Object
How generated code answers: with the value itself.
-
#initialize(chat: nil) ⇒ Agent
constructor
chat:injects a prepared RubyLLM::Chat — the seam for tests. - #p(*args) ⇒ Object (also: #pp)
- #print(*args) ⇒ Object
-
#puts(*args) ⇒ Object
Printing from generated code goes to the observation, not to the process's stdout — and the buffer is per thread, so concurrent agents stay separate.
Constructor Details
#initialize(chat: nil) ⇒ Agent
chat: injects a prepared RubyLLM::Chat — the seam for tests.
87 88 89 |
# File 'lib/omakase/agent.rb', line 87 def initialize(chat: nil) @chat = chat end |
Class Method Details
.chat_options ⇒ Object
61 |
# File 'lib/omakase/agent.rb', line 61 def = @chat_options ||= {} |
.describe(text) ⇒ Object
Documents the method defined next — the docstring Ruby does not have.
41 42 43 |
# File 'lib/omakase/agent.rb', line 41 def describe(text) @pending_description = text end |
.descriptions ⇒ Object
59 |
# File 'lib/omakase/agent.rb', line 59 def descriptions = @descriptions ||= {} |
.generates(name, prompt = nil, returns: nil, strategy: nil, &schema) ⇒ Object
Without a prompt, the method name is the prompt.
46 47 48 49 50 51 52 53 54 55 |
# File 'lib/omakase/agent.rb', line 46 def generates(name, prompt = nil, returns: nil, strategy: nil, &schema) generations[name] = Generation.new( name:, prompt: prompt || humanize(name), schema: Schema.define(returns:, &schema), strategy: Strategies.fetch(strategy || self.strategy) ) define_method(name) { |**inputs| generate(name, inputs) } define_singleton_method(name) { |**inputs| new.public_send(name, **inputs) } end |
.generations ⇒ Object
57 |
# File 'lib/omakase/agent.rb', line 57 def generations = @generations ||= {} |
.instructions(text = nil) ⇒ Object
18 19 20 21 22 |
# File 'lib/omakase/agent.rb', line 18 def instructions(text = nil) return @instructions.to_s if text.nil? @instructions = text end |
.mcp(name, **options) ⇒ Object
An MCP server's tools, as methods on the agent. Options are passed to
ruby_llm-mcp verbatim: mcp :files, transport_type: :stdio, config: {command: "npx", …}.
32 33 34 35 |
# File 'lib/omakase/agent.rb', line 32 def mcp(name, **) require "ruby_llm/mcp" MCP.attach(self, RubyLLM::MCP.add_client(name: name.to_s, **)) end |
.model(id = nil, **options) ⇒ Object
The model and any RubyLLM chat option. Naming a provider takes the model id on trust, since providers like OpenRouter or Ollama serve ids that are not in RubyLLM's registry.
11 12 13 14 15 16 |
# File 'lib/omakase/agent.rb', line 11 def model(id = nil, **) return if id.nil? && .empty? = {assume_model_exists: true, **} if [:provider] @chat_options = {model: id, **}.compact end |
.skill(path) ⇒ Object
A skill directory — a SKILL.md with YAML front matter. Its description joins the agent's capabilities; its body arrives when the model asks.
39 40 |
# File 'lib/omakase/agent.rb', line 39 def skill(path) = Skills.attach(self, path) # Documents the method defined next — the docstring Ruby does not have. |
.strategy(name = nil) ⇒ Object
24 25 26 27 28 |
# File 'lib/omakase/agent.rb', line 24 def strategy(name = nil) return @strategy || :code_act if name.nil? @strategy = name end |
Instance Method Details
#chat ⇒ Object
A fresh conversation per call.
92 |
# File 'lib/omakase/agent.rb', line 92 def chat = @chat || RubyLLM.chat(**self.class.) |
#doc(object) ⇒ Object
For generated code meeting an object whose type it does not know.
95 |
# File 'lib/omakase/agent.rb', line 95 def doc(object) = puts(Doc.of(object)) |
#finish(value) ⇒ Object
How generated code answers: with the value itself.
98 |
# File 'lib/omakase/agent.rb', line 98 def finish(value) = throw(Executor::RESULT, value) |
#p(*args) ⇒ Object Also known as: pp
106 107 108 109 |
# File 'lib/omakase/agent.rb', line 106 def p(*args) args.each { |arg| omakase_output.puts(arg.inspect) } args.size <= 1 ? args.first : args end |
#print(*args) ⇒ Object
104 |
# File 'lib/omakase/agent.rb', line 104 def print(*args) = omakase_output.print(*args) |
#puts(*args) ⇒ Object
Printing from generated code goes to the observation, not to the process's stdout — and the buffer is per thread, so concurrent agents stay separate.
102 |
# File 'lib/omakase/agent.rb', line 102 def puts(*args) = omakase_output.puts(*args) |