Module: Brute
- Defined in:
- lib/brute/patches/buffer_nil_guard.rb,
lib/brute.rb,
lib/brute.rb,
lib/brute/diff.rb,
lib/brute/hooks.rb,
lib/brute/skill.rb,
lib/brute/session.rb,
lib/brute/version.rb,
lib/brute/pipeline.rb,
lib/brute/compactor.rb,
lib/brute/doom_loop.rb,
lib/brute/todo_store.rb,
lib/brute/tools/shell.rb,
lib/brute/agent_stream.rb,
lib/brute/orchestrator.rb,
lib/brute/prompts/base.rb,
lib/brute/message_store.rb,
lib/brute/system_prompt.rb,
lib/brute/tools/fs_read.rb,
lib/brute/tools/fs_undo.rb,
lib/brute/prompts/skills.rb,
lib/brute/snapshot_store.rb,
lib/brute/tools/delegate.rb,
lib/brute/tools/fs_patch.rb,
lib/brute/tools/fs_write.rb,
lib/brute/tools/question.rb,
lib/brute/middleware/base.rb,
lib/brute/middleware/otel.rb,
lib/brute/providers/shell.rb,
lib/brute/tools/fs_remove.rb,
lib/brute/tools/fs_search.rb,
lib/brute/tools/net_fetch.rb,
lib/brute/tools/todo_read.rb,
lib/brute/middleware/retry.rb,
lib/brute/prompts/autonomy.rb,
lib/brute/prompts/identity.rb,
lib/brute/tools/todo_write.rb,
lib/brute/prompts/max_steps.rb,
lib/brute/middleware/tracing.rb,
lib/brute/prompts/code_style.rb,
lib/brute/prompts/git_safety.rb,
lib/brute/prompts/tool_usage.rb,
lib/brute/file_mutation_queue.rb,
lib/brute/middleware/llm_call.rb,
lib/brute/prompts/conventions.rb,
lib/brute/prompts/doing_tasks.rb,
lib/brute/prompts/environment.rb,
lib/brute/prompts/objectivity.rb,
lib/brute/middleware/otel/span.rb,
lib/brute/prompts/build_switch.rb,
lib/brute/prompts/instructions.rb,
lib/brute/providers/models_dev.rb,
lib/brute/prompts/plan_reminder.rb,
lib/brute/prompts/proactiveness.rb,
lib/brute/prompts/frontend_tasks.rb,
lib/brute/prompts/tone_and_style.rb,
lib/brute/prompts/code_references.rb,
lib/brute/prompts/task_management.rb,
lib/brute/prompts/editing_approach.rb,
lib/brute/providers/shell_response.rb,
lib/brute/middleware/token_tracking.rb,
lib/brute/middleware/tool_use_guard.rb,
lib/brute/middleware/otel/tool_calls.rb,
lib/brute/middleware/compaction_check.rb,
lib/brute/middleware/message_tracking.rb,
lib/brute/middleware/otel/token_usage.rb,
lib/brute/patches/anthropic_tool_role.rb,
lib/brute/prompts/editing_constraints.rb,
lib/brute/prompts/security_and_safety.rb,
lib/brute/middleware/otel/tool_results.rb,
lib/brute/middleware/doom_loop_detection.rb,
lib/brute/middleware/session_persistence.rb,
lib/brute/middleware/tool_error_tracking.rb,
lib/brute/middleware/reasoning_normalizer.rb
Overview
Monkey-patch: Fix Anthropic tool result message role.
llm.rb stores tool results as messages with role=“tool” (via @llm.tool_role). Anthropic’s API requires tool result messages to have role=“user” with tool_result content blocks. The Completion adapter already correctly formats the content (Function::Return -> “tool_result”, …), but passes through the “tool” role unchanged — which Anthropic rejects.
This patch overrides adapt_message to set role=“user” when the message content contains tool returns.
Defined Under Namespace
Modules: Diff, FileMutationQueue, Hooks, Middleware, Patches, Prompts, Providers, Skill, SnapshotStore, TodoStore, Tools Classes: AgentStream, Compactor, DoomLoopDetector, MessageStore, Orchestrator, Pipeline, Session, SystemPrompt
Constant Summary collapse
- TOOLS =
The complete set of tools available to the agent.
[ Tools::FSRead, Tools::FSWrite, Tools::FSPatch, Tools::FSRemove, Tools::FSSearch, Tools::FSUndo, Tools::Shell, Tools::NetFetch, Tools::TodoWrite, Tools::TodoRead, Tools::Delegate, Tools::Question ].freeze
- PROVIDERS =
{ 'anthropic' => ->(key) { LLM.anthropic(key: key).tap { Patches::AnthropicToolRole.apply! } }, 'openai' => ->(key) { LLM.openai(key: key) }, 'google' => ->(key) { LLM.google(key: key) }, 'deepseek' => ->(key) { LLM.deepseek(key: key) }, 'ollama' => ->(key) { LLM.ollama(key: key) }, 'xai' => ->(key) { LLM.xai(key: key) }, 'opencode_zen' => ->(key) { LLM::OpencodeZen.new(key: key) }, 'opencode_go' => ->(key) { LLM::OpencodeGo.new(key: key) }, 'shell' => ->(_key) { Providers::Shell.new }, }.freeze
- VERSION =
"0.4.1"
Class Method Summary collapse
-
.agent(cwd: Dir.pwd, model: nil, tools: TOOLS, session: nil, reasoning: {}, agent_name: nil, **callbacks) ⇒ Object
Create a new orchestrator with sensible defaults.
-
.api_key_for(name) ⇒ Object
Look up the API key for a given provider name.
-
.configured_providers ⇒ Object
List provider names that have API keys configured in the environment.
-
.provider ⇒ Object
Default provider, resolved from environment.
- .provider=(p) ⇒ Object
-
.provider_for(name) ⇒ Object
Build a provider instance for the given name using available API keys.
Class Method Details
.agent(cwd: Dir.pwd, model: nil, tools: TOOLS, session: nil, reasoning: {}, agent_name: nil, **callbacks) ⇒ Object
Create a new orchestrator with sensible defaults.
130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/brute.rb', line 130 def self.agent(cwd: Dir.pwd, model: nil, tools: TOOLS, session: nil, reasoning: {}, agent_name: nil, **callbacks) Orchestrator.new( provider: provider, model: model, tools: tools, cwd: cwd, session: session, reasoning: reasoning, agent_name: agent_name, **callbacks ) end |
.api_key_for(name) ⇒ Object
Look up the API key for a given provider name.
174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 |
# File 'lib/brute.rb', line 174 def self.api_key_for(name) # Shell provider needs no key. return "none" if name == "shell" # OpenCode providers: check OPENCODE_API_KEY, fall back to "public" for anonymous access. if name == "opencode_zen" || name == "opencode_go" return ENV["OPENCODE_API_KEY"] || "public" end # Explicit generic key always works return ENV["LLM_API_KEY"] if ENV["LLM_API_KEY"] case name when "anthropic" then ENV["ANTHROPIC_API_KEY"] when "openai" then ENV["OPENAI_API_KEY"] when "google" then ENV["GOOGLE_API_KEY"] end end |
.configured_providers ⇒ Object
List provider names that have API keys configured in the environment. The shell provider is always available (no key needed).
157 158 159 |
# File 'lib/brute.rb', line 157 def self.configured_providers PROVIDERS.keys.select { |name| api_key_for(name) } end |
.provider ⇒ Object
Default provider, resolved from environment.
121 122 123 |
# File 'lib/brute.rb', line 121 def self.provider @provider ||= resolve_provider end |
.provider=(p) ⇒ Object
125 126 127 |
# File 'lib/brute.rb', line 125 def self.provider=(p) @provider = p end |
.provider_for(name) ⇒ Object
Build a provider instance for the given name using available API keys. Returns nil if no key is found.
163 164 165 166 167 168 169 170 171 |
# File 'lib/brute.rb', line 163 def self.provider_for(name) key = api_key_for(name) return nil unless key factory = PROVIDERS[name] return nil unless factory factory.call(key) end |