Class: Riffer::Agent
- Inherits:
-
Object
- Object
- Riffer::Agent
- Extended by:
- Helpers::ClassNameConverter, Helpers::Validations
- Includes:
- Messages::Converter
- Defined in:
- lib/riffer/agent.rb
Overview
Riffer::Agent is the base class for all agents in the Riffer framework.
Provides orchestration for LLM calls, tool use, and message management. Subclass this to create your own agents.
See Riffer::Messages and Riffer::Providers.
class MyAgent < Riffer::Agent
model 'openai/gpt-4o'
instructions 'You are a helpful assistant.'
end
agent = MyAgent.new
agent.generate('Hello!')
Instance Attribute Summary collapse
-
#messages ⇒ Object
readonly
The message history for the agent.
-
#token_usage ⇒ Object
readonly
Cumulative token usage across all LLM calls.
Class Method Summary collapse
-
.all ⇒ Object
Returns all agent subclasses.
-
.find(identifier) ⇒ Object
Finds an agent class by identifier.
-
.generate ⇒ Object
Generates a response using a new agent instance.
-
.identifier(value = nil) ⇒ Object
Gets or sets the agent identifier.
-
.instructions(instructions_text = nil) ⇒ Object
Gets or sets the agent instructions.
-
.model(model_string = nil) ⇒ Object
Gets or sets the model string (e.g., “openai/gpt-4o”).
-
.model_options(options = nil) ⇒ Object
Gets or sets model options passed to generate_text/stream_text.
-
.provider_options(options = nil) ⇒ Object
Gets or sets provider options passed to the provider client.
-
.stream ⇒ Object
Streams a response using a new agent instance.
-
.uses_tools(tools_or_lambda = nil) ⇒ Object
Gets or sets the tools used by this agent.
Instance Method Summary collapse
-
#generate(prompt_or_messages, tool_context: nil) ⇒ Object
Generates a response from the agent.
-
#initialize ⇒ Agent
constructor
Initializes a new agent.
-
#on_message(&block) ⇒ Object
Registers a callback to be invoked when messages are added during generation.
-
#stream(prompt_or_messages, tool_context: nil) ⇒ Object
Streams a response from the agent.
Methods included from Messages::Converter
Constructor Details
#initialize ⇒ Agent
Initializes a new agent.
Raises Riffer::ArgumentError if the configured model string is invalid (must be “provider/model” format).
134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
# File 'lib/riffer/agent.rb', line 134 def initialize @messages = [] @message_callbacks = [] @token_usage = nil @model_string = self.class.model @instructions_text = self.class.instructions provider_name, model_name = @model_string.split("/", 2) raise Riffer::ArgumentError, "Invalid model string: #{@model_string}" unless [provider_name, model_name].all? { |part| part.is_a?(String) && !part.strip.empty? } @provider_name = provider_name @model_name = model_name end |
Instance Attribute Details
#messages ⇒ Object (readonly)
The message history for the agent.
Returns Array of Riffer::Messages::Base.
123 124 125 |
# File 'lib/riffer/agent.rb', line 123 def @messages end |
#token_usage ⇒ Object (readonly)
Cumulative token usage across all LLM calls.
Returns Riffer::TokenUsage or nil.
128 129 130 |
# File 'lib/riffer/agent.rb', line 128 def token_usage @token_usage end |
Class Method Details
.all ⇒ Object
Returns all agent subclasses.
Returns Array of Class - all agent subclasses.
101 102 103 |
# File 'lib/riffer/agent.rb', line 101 def all subclasses end |
.find(identifier) ⇒ Object
Finds an agent class by identifier.
- identifier
-
String - the identifier to search for
Returns Class or nil - the agent class, or nil if not found.
94 95 96 |
# File 'lib/riffer/agent.rb', line 94 def find(identifier) subclasses.find { |agent_class| agent_class.identifier == identifier.to_s } end |
.generate ⇒ Object
Generates a response using a new agent instance.
See #generate for parameters and return value.
108 109 110 |
# File 'lib/riffer/agent.rb', line 108 def generate(...) new.generate(...) end |
.identifier(value = nil) ⇒ Object
Gets or sets the agent identifier.
- value
-
String or nil - the identifier to set, or nil to get
Returns String - the agent identifier.
32 33 34 35 |
# File 'lib/riffer/agent.rb', line 32 def identifier(value = nil) return @identifier || class_name_to_path(name) if value.nil? @identifier = value.to_s end |
.instructions(instructions_text = nil) ⇒ Object
Gets or sets the agent instructions.
- instructions_text
-
String or nil - the instructions to set, or nil to get
Returns String - the agent instructions.
53 54 55 56 57 |
# File 'lib/riffer/agent.rb', line 53 def instructions(instructions_text = nil) return @instructions if instructions_text.nil? validate_is_string!(instructions_text, "instructions") @instructions = instructions_text end |
.model(model_string = nil) ⇒ Object
Gets or sets the model string (e.g., “openai/gpt-4o”).
- model_string
-
String or nil - the model string to set, or nil to get
Returns String - the model string.
42 43 44 45 46 |
# File 'lib/riffer/agent.rb', line 42 def model(model_string = nil) return @model if model_string.nil? validate_is_string!(model_string, "model") @model = model_string end |
.model_options(options = nil) ⇒ Object
Gets or sets model options passed to generate_text/stream_text.
- options
-
Hash or nil - the options to set, or nil to get
Returns Hash - the model options.
74 75 76 77 |
# File 'lib/riffer/agent.rb', line 74 def ( = nil) return @model_options || {} if .nil? @model_options = end |
.provider_options(options = nil) ⇒ Object
Gets or sets provider options passed to the provider client.
- options
-
Hash or nil - the options to set, or nil to get
Returns Hash - the provider options.
64 65 66 67 |
# File 'lib/riffer/agent.rb', line 64 def ( = nil) return @provider_options || {} if .nil? @provider_options = end |
.stream ⇒ Object
Streams a response using a new agent instance.
See #stream for parameters and return value.
115 116 117 |
# File 'lib/riffer/agent.rb', line 115 def stream(...) new.stream(...) end |
.uses_tools(tools_or_lambda = nil) ⇒ Object
Gets or sets the tools used by this agent.
- tools_or_lambda
-
Array of Tool classes, Proc, or nil - tools array or lambda returning tools
Returns Array, Proc, or nil - the tools configuration.
84 85 86 87 |
# File 'lib/riffer/agent.rb', line 84 def uses_tools(tools_or_lambda = nil) return @tools_config if tools_or_lambda.nil? @tools_config = tools_or_lambda end |
Instance Method Details
#generate(prompt_or_messages, tool_context: nil) ⇒ Object
Generates a response from the agent.
- prompt_or_messages
-
String or Array - a string prompt or array of message hashes/objects
- tool_context
-
Object or nil - optional context object passed to all tool calls
Returns String - the final response content.
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 |
# File 'lib/riffer/agent.rb', line 155 def generate(, tool_context: nil) @tool_context = tool_context @resolved_tools = nil () loop do response = call_llm (response) track_token_usage(response.token_usage) break unless has_tool_calls?(response) execute_tool_calls(response) end extract_final_response end |
#on_message(&block) ⇒ Object
Registers a callback to be invoked when messages are added during generation.
- block
-
Block - callback receiving a Riffer::Messages::Base subclass
Raises Riffer::ArgumentError if no block is given.
Returns self for method chaining.
238 239 240 241 242 |
# File 'lib/riffer/agent.rb', line 238 def (&block) raise Riffer::ArgumentError, "on_message requires a block" unless block_given? @message_callbacks << block self end |
#stream(prompt_or_messages, tool_context: nil) ⇒ Object
Streams a response from the agent.
- prompt_or_messages
-
String or Array - a string prompt or array of message hashes/objects
- tool_context
-
Object or nil - optional context object passed to all tool calls
Returns Enumerator - an enumerator yielding stream events.
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 |
# File 'lib/riffer/agent.rb', line 179 def stream(, tool_context: nil) @tool_context = tool_context @resolved_tools = nil () Enumerator.new do |yielder| loop do accumulated_content = "" accumulated_tool_calls = [] accumulated_token_usage = nil current_tool_call = nil call_llm_stream.each do |event| yielder << event case event when Riffer::StreamEvents::TextDelta accumulated_content += event.content when Riffer::StreamEvents::TextDone accumulated_content = event.content when Riffer::StreamEvents::ToolCallDelta current_tool_call ||= {item_id: event.item_id, name: event.name, arguments: ""} current_tool_call[:arguments] += event.arguments_delta current_tool_call[:name] ||= event.name when Riffer::StreamEvents::ToolCallDone accumulated_tool_calls << { id: event.item_id, call_id: event.call_id, name: event.name, arguments: event.arguments } current_tool_call = nil when Riffer::StreamEvents::TokenUsageDone accumulated_token_usage = event.token_usage end end response = Riffer::Messages::Assistant.new( accumulated_content, tool_calls: accumulated_tool_calls, token_usage: accumulated_token_usage ) (response) track_token_usage(accumulated_token_usage) break unless has_tool_calls?(response) execute_tool_calls(response) end end end |