Class: Omnibot::Agent
- Inherits:
-
Object
- Object
- Omnibot::Agent
- Defined in:
- lib/omnibot/agent.rb
Defined Under Namespace
Classes: TurnLimit
Constant Summary collapse
- FAST_REPLY =
:__omnibot_fast_reply
Instance Attribute Summary collapse
-
#context ⇒ Object
readonly
Returns the value of attribute context.
Class Method Summary collapse
- .extract(input, schema:, context: {}) ⇒ Object
- .fast_path(&block) ⇒ Object
- .fast_paths ⇒ Object
- .inherited(subclass) ⇒ Object
- .instructions(value = nil) ⇒ Object
-
.max_turns(value = nil) ⇒ Object
Bounds the number of tool executions in a run, not conversation rounds — the before_tool_call hook counts each call, so parallel tool calls in a single round each count separately.
- .model(value = nil) ⇒ Object
- .run(message, history: [], context: {}, stream: nil) ⇒ Object
- .tool(name_or_class, description = nil, &block) ⇒ Object
- .tools ⇒ Object
Instance Method Summary collapse
- #extract(input, schema:) ⇒ Object
-
#initialize(context = {}) ⇒ Agent
constructor
A new instance of Agent.
-
#reply(text) ⇒ Object
Called from within a fast_path block to short-circuit the run loop.
- #run(message, history: [], stream: nil) ⇒ Object
-
#tools_for(_context) ⇒ Object
Override in subclasses to gate tools per run (context-aware).
Constructor Details
#initialize(context = {}) ⇒ Agent
Returns a new instance of Agent.
51 52 53 |
# File 'lib/omnibot/agent.rb', line 51 def initialize(context = {}) @context = context end |
Instance Attribute Details
#context ⇒ Object (readonly)
Returns the value of attribute context.
49 50 51 |
# File 'lib/omnibot/agent.rb', line 49 def context @context end |
Class Method Details
.extract(input, schema:, context: {}) ⇒ Object
44 45 46 |
# File 'lib/omnibot/agent.rb', line 44 def extract(input, schema:, context: {}) new(context).extract(input, schema: schema) end |
.fast_path(&block) ⇒ Object
29 |
# File 'lib/omnibot/agent.rb', line 29 def fast_path(&block) = fast_paths << block |
.fast_paths ⇒ Object
28 |
# File 'lib/omnibot/agent.rb', line 28 def fast_paths = @fast_paths ||= [] |
.inherited(subclass) ⇒ Object
31 32 33 34 35 36 37 38 |
# File 'lib/omnibot/agent.rb', line 31 def inherited(subclass) super subclass.instance_variable_set(:@model, @model) subclass.instance_variable_set(:@instructions, @instructions) subclass.instance_variable_set(:@max_turns, @max_turns) subclass.instance_variable_set(:@tools, tools.dup) subclass.instance_variable_set(:@fast_paths, fast_paths.dup) end |
.instructions(value = nil) ⇒ Object
12 13 14 |
# File 'lib/omnibot/agent.rb', line 12 def instructions(value = nil) value ? @instructions = value : @instructions end |
.max_turns(value = nil) ⇒ Object
Bounds the number of tool executions in a run, not conversation rounds — the before_tool_call hook counts each call, so parallel tool calls in a single round each count separately.
19 20 21 |
# File 'lib/omnibot/agent.rb', line 19 def max_turns(value = nil) value ? @max_turns = value : (@max_turns || 5) end |
.model(value = nil) ⇒ Object
8 9 10 |
# File 'lib/omnibot/agent.rb', line 8 def model(value = nil) value ? @model = value : (@model || Omnibot.config.default_model) end |
.run(message, history: [], context: {}, stream: nil) ⇒ Object
40 41 42 |
# File 'lib/omnibot/agent.rb', line 40 def run(, history: [], context: {}, stream: nil) new(context).run(, history: history, stream: stream) end |
.tool(name_or_class, description = nil, &block) ⇒ Object
23 24 25 |
# File 'lib/omnibot/agent.rb', line 23 def tool(name_or_class, description = nil, &block) tools << (block ? Tool.from_block(name_or_class, description, &block) : name_or_class) end |
.tools ⇒ Object
27 |
# File 'lib/omnibot/agent.rb', line 27 def tools = @tools ||= [] |
Instance Method Details
#extract(input, schema:) ⇒ Object
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/omnibot/agent.rb', line 71 def extract(input, schema:) chat = Omnibot.chat_factory.call(model: self.class.model, agent_class: self.class) chat.with_instructions(interpolated_instructions) if self.class.instructions chat.with_schema(schema) response = instrument_llm { chat.ask(input.to_s) } parse_extraction(response.content) do |error| repair = instrument_llm do chat.ask("Your previous output was not valid JSON (#{error.}). " \ "Respond again with ONLY valid JSON matching the schema.") end parse_extraction(repair.content) do |_error| raise ExtractionError, "extraction failed after repair: #{repair.content.to_s.truncate(200)}" end end end |
#reply(text) ⇒ Object
Called from within a fast_path block to short-circuit the run loop.
69 |
# File 'lib/omnibot/agent.rb', line 69 def reply(text) = throw(FAST_REPLY, text) |
#run(message, history: [], stream: nil) ⇒ Object
55 56 57 58 59 60 61 62 63 |
# File 'lib/omnibot/agent.rb', line 55 def run(, history: [], stream: nil) ActiveSupport::Notifications.instrument("omnibot.agent.run", agent: self.class) do |payload| payload[:fast_path] = false result = run_loop(, history, stream) payload[:fast_path] = result.fast_path? payload[:usage] = result.usage result end end |
#tools_for(_context) ⇒ Object
Override in subclasses to gate tools per run (context-aware).
66 |
# File 'lib/omnibot/agent.rb', line 66 def tools_for(_context) = self.class.tools |