Class: Raif::Agent
- Inherits:
-
ApplicationRecord
- Object
- ApplicationRecord
- Raif::Agent
- Includes:
- Concerns::AgentInferenceStats, Concerns::HasAvailableModelTools, Concerns::HasLlm, Concerns::HasPromptTemplates, Concerns::HasRequestedLanguage, Concerns::HasRuntimeDuration, Concerns::InvokesModelTools, Concerns::LlmPromptCaching, Concerns::RunWith
- Defined in:
- app/models/raif/agent.rb
Direct Known Subclasses
Instance Attribute Summary collapse
-
#on_conversation_history_entry ⇒ Object
Returns the value of attribute on_conversation_history_entry.
Instance Method Summary collapse
- #final_iteration? ⇒ Boolean
-
#model_tool_invocation_counts ⇒ Object
Per-tool invocation counts for the admin agent show page, keyed by tool class name (e.g. "Raif::ModelTools::ProviderManaged::WebSearch") so the
_listpartial can look upcounts[tool_class.name]. -
#run!(&block) ⇒ Raif::Agent
Runs the agent and returns a Raif::Agent.
Methods included from Concerns::RunWith
deserialize_run_with_value, gid_string?, locate_gid, serialize_run_with_value
Methods included from Concerns::AgentInferenceStats
#total_completion_tokens, #total_cost, #total_output_token_cost, #total_prompt_token_cost, #total_prompt_tokens, #total_tokens_sum
Methods included from Concerns::HasRuntimeDuration
#runtime_duration, #runtime_duration_seconds, #runtime_ended_at
Methods included from Concerns::HasAvailableModelTools
Methods included from Concerns::HasRequestedLanguage
#requested_language_name, #system_prompt_language_preference
Methods included from Concerns::HasLlm
Methods included from Concerns::HasPromptTemplates
Methods inherited from ApplicationRecord
table_name_prefix, where_json_not_blank
Instance Attribute Details
#on_conversation_history_entry ⇒ Object
Returns the value of attribute on_conversation_history_entry.
73 74 75 |
# File 'app/models/raif/agent.rb', line 73 def on_conversation_history_entry @on_conversation_history_entry end |
Instance Method Details
#final_iteration? ⇒ Boolean
159 160 161 |
# File 'app/models/raif/agent.rb', line 159 def final_iteration? iteration_count == max_iterations end |
#model_tool_invocation_counts ⇒ Object
Per-tool invocation counts for the admin agent show page, keyed by tool
class name (e.g. "Raif::ModelTools::ProviderManaged::WebSearch") so the
_list partial can look up counts[tool_class.name].
Combines two sources:
- Developer-managed tools persist as Raif::ModelToolInvocation rows via Raif::ModelTool.invoke_tool.
- Provider-managed tools (e.g. Anthropic / OpenAI web_search) never reach
that path - they live as
server_tool_use/web_search_callblocks in each completion'sresponse_arrayand are surfaced via ModelCompletion#provider_managed_tool_calls.
174 175 176 177 178 179 180 181 182 183 184 185 186 187 |
# File 'app/models/raif/agent.rb', line 174 def model_tool_invocation_counts counts = raif_model_tool_invocations.group(:tool_type).count raif_model_completions.find_each do |completion| Array(completion.provider_managed_tool_calls).each do |call| tool_klass = completion.available_model_tools_map[call["tool_name"]] next unless tool_klass counts[tool_klass.name] = (counts[tool_klass.name] || 0) + 1 end end counts end |
#run!(&block) ⇒ Raif::Agent
Runs the agent and returns a Raif::Agent. If a block is given, it will be called each time a new entry is added to the agent's conversation history. The block will receive the Raif::Agent and the new entry as arguments: agent = Raif::Agent.new( task: task, tools: [Raif::ModelTools::WikipediaSearch, Raif::ModelTools::FetchUrl], creator: creator )
agent.run! do |conversation_history_entry| Turbo::StreamsChannel.broadcast_append_to( :my_agent_channel, target: "agent-progress", partial: "my_partial_displaying_agent_progress", locals: { agent: agent, conversation_history_entry: conversation_history_entry } ) end
The conversation_history_entry will be a hash with "role" and "content" keys: { "role" => "assistant", "content" => "a message here" }
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 |
# File 'app/models/raif/agent.rb', line 98 def run!(&block) self.on_conversation_history_entry = block_given? ? block : nil self.started_at = Time.current save! logger.debug <<~DEBUG -------------------------------- Starting Agent Run -------------------------------- System Prompt: #{system_prompt} Task: #{task} DEBUG add_conversation_history_entry(Raif::Messages::UserMessage.new(content: task).to_h) while iteration_count < max_iterations update_columns(iteration_count: iteration_count + 1) # Update the system prompt on each iteration in case it has changed since the last iteration self.system_prompt = build_system_prompt # Hook for subclasses to perform actions before the LLM chat (e.g., add warnings) before_iteration_llm_chat model_completion = llm.chat( messages: conversation_history, source: self, system_prompt: system_prompt, available_model_tools: native_model_tools, tool_choice: tool_choice_for_iteration, anthropic_prompt_caching_enabled: self.class.anthropic_prompt_caching_enabled, bedrock_prompt_caching_enabled: self.class.bedrock_prompt_caching_enabled ) logger.debug <<~DEBUG -------------------------------- Agent iteration #{iteration_count} Messages: #{JSON.pretty_generate(conversation_history)} Response: #{model_completion.raw_response} -------------------------------- DEBUG process_iteration_model_completion(model_completion) break if final_answer.present? || failed? end finalize_run! final_answer rescue StandardError => e self.failed_at ||= Time.current self.failure_reason ||= e. save! raise end |