Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ gem 'roast-ai'

## Provider Configuration

Roast provider settings are configured in workflow `config` blocks. There is not currently a CLI flag or environment variable that changes the default provider globally; edit the workflow config to select a different provider.
Roast provider settings are configured in workflow `config` blocks. To change the default **agent** provider without editing each workflow, set the `ROAST_DEFAULT_AGENT_PROVIDER` environment variable (e.g. `export ROAST_DEFAULT_AGENT_PROVIDER=claude`). A `provider` set in a workflow's `config` always takes precedence over this variable, and an invalid value raises an error. This affects the `agent` cog only; the `chat` cog's provider is unaffected.

### Chat cog

Expand All @@ -97,7 +97,7 @@ end

### Agent cog

The `agent` cog runs local agent CLIs. It defaults to `:pi` and currently supports:
The `agent` cog runs local agent CLIs. It defaults to `:pi` (override globally with `ROAST_DEFAULT_AGENT_PROVIDER`) and currently supports:

- `:claude` - Claude Code CLI
- `:pi` - Pi CLI
Expand Down
8 changes: 5 additions & 3 deletions internal/documentation/comments/doc-comments-external.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,8 @@ shortened names can be confusing. Use the complete module path.
```ruby
# Configure the cog to use the default provider when invoking an agent
#
# The default provider used by Roast is Pi (`:pi`).
# The default provider is the one named by the `ROAST_DEFAULT_AGENT_PROVIDER` environment variable,
# or Pi (`:pi`) when that variable is unset.
#: () -> void
def use_default_provider!
@values[:provider] = nil
Expand Down Expand Up @@ -386,7 +387,8 @@ end
# Configure the cog to use a specified provider when invoking an agent
#
# The provider is the source of the agent tool itself.
# If no provider is specified, Pi (`:pi`) will be used as the default provider.
# If no provider is specified, Roast uses the provider named by the `ROAST_DEFAULT_AGENT_PROVIDER`
# environment variable, or Pi (`:pi`) when that variable is unset.
#
# A provider must be properly installed on your system in order for Roast to be able to use it.
#
Expand Down Expand Up @@ -519,7 +521,7 @@ Methods in `config_context.rbi` expose cog configuration interfaces and are the
#
# #### Configure the LLM provider
# - `provider(symbol)` - Set the agent provider (e.g., `:claude`)
# - `use_default_provider!` - Use the default provider (`:pi`)
# - `use_default_provider!` - Use the default provider (`:pi`, or `$ROAST_DEFAULT_AGENT_PROVIDER` when set)
#
# #### Configure the base command used to run the coding agent
# - `command(string_or_array)` - Set the base command for invoking the agent
Expand Down
3 changes: 2 additions & 1 deletion internal/documentation/comments/doc-comments.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ These files provide the primary interface between users and Roast. The documenta
# Configure the cog to use a specified provider when invoking an agent
#
# The provider is the source of the agent tool itself.
# If no provider is specified, Pi (`:pi`) will be used as the default provider.
# If no provider is specified, Roast uses the provider named by the `ROAST_DEFAULT_AGENT_PROVIDER`
# environment variable, or Pi (`:pi`) when that variable is unset.
#
# A provider must be properly installed on your system in order for Roast to be able to use it.
#
Expand Down
21 changes: 18 additions & 3 deletions lib/roast/cogs/agent/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,19 @@ class Agent < Cog
class Config < Cog::Config
VALID_PROVIDERS = [:pi, :claude].freeze #: Array[Symbol]

# Environment variable that overrides the built-in default agent provider.
#
# When an agent cog does not explicitly configure a provider, Roast uses the provider named by
# this variable, falling back to the built-in default (`VALID_PROVIDERS.first`, i.e. `:pi`) when it
# is unset or blank. The value is normalized (surrounding whitespace stripped, then downcased)
# before lookup, and an explicit `provider` configured on the cog always takes precedence over it.
DEFAULT_PROVIDER_ENV_VAR = "ROAST_DEFAULT_AGENT_PROVIDER" #: String

# Configure the cog to use a specified provider when invoking an agent
#
# The provider is the source of the agent tool itself.
# If no provider is specified, Pi (`:pi`) will be used as the default provider.
# If no provider is specified, Roast uses the provider named by the `ROAST_DEFAULT_AGENT_PROVIDER`
# environment variable, or Pi (`:pi`) when that variable is unset.
#
# A provider must be properly installed on your system in order for Roast to be able to use it.
#
Expand All @@ -24,7 +33,8 @@ def provider(provider)

# Configure the cog to use the default provider when invoking an agent
#
# The default provider used by Roast is Pi (`:pi`).
# The default provider is the one named by the `ROAST_DEFAULT_AGENT_PROVIDER` environment variable,
# or Pi (`:pi`) when that variable is unset.
#
# The provider must be properly installed on your system in order for Roast to be able to use it.
#
Expand All @@ -38,6 +48,10 @@ def use_default_provider!

# Get the validated provider name that the cog is configured to use when invoking an agent
#
# The provider is resolved in order of precedence: the provider explicitly configured on the cog,
# then the `ROAST_DEFAULT_AGENT_PROVIDER` environment variable (normalized by stripping surrounding
# whitespace and downcasing), then the built-in default (`VALID_PROVIDERS.first`, i.e. `:pi`).
#
# Note: this method will return the name of a valid provider or raise an `InvalidConfigError`.
# It will __not__, however, validate that the agent is properly installed on your system.
# If the agent is not properly installed, you will likely experience a failure when Roast attempts to
Expand All @@ -49,7 +63,8 @@ def use_default_provider!
#
#: () -> Symbol
def valid_provider!
provider = @values[:provider] || VALID_PROVIDERS.first
env_default = ENV[DEFAULT_PROVIDER_ENV_VAR].presence&.strip&.downcase&.to_sym
provider = @values[:provider] || env_default || VALID_PROVIDERS.first
unless VALID_PROVIDERS.include?(provider)
raise InvalidConfigError, "'#{provider}' is not a valid provider. Available providers include: #{VALID_PROVIDERS.join(", ")}"
end
Expand Down
2 changes: 1 addition & 1 deletion sorbet/rbi/shims/lib/roast/config_context.rbi
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ module Roast
#
# #### Configure the agent provider
# - `provider(symbol)` - Set the agent provider (e.g., `:claude`)
# - `use_default_provider!` - Use the default provider (`:pi`)
# - `use_default_provider!` - Use the default provider (`:pi`, or `$ROAST_DEFAULT_AGENT_PROVIDER` when set)
#
# #### Configure the base command used to run the coding agent
# - `command(string_or_array)` - Set the base command for invoking the agent
Expand Down
44 changes: 42 additions & 2 deletions test/roast/cogs/agent/config_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,15 @@ def setup
@config.provider(:fake_provider)
@config.use_default_provider!

assert_equal @default_provider, @config.valid_provider!
with_env(Agent::Config::DEFAULT_PROVIDER_ENV_VAR, nil) do
assert_equal @default_provider, @config.valid_provider!
end
end

test "valid_provider! returns default when not set" do
assert_equal @default_provider, @config.valid_provider!
with_env(Agent::Config::DEFAULT_PROVIDER_ENV_VAR, nil) do
assert_equal @default_provider, @config.valid_provider!
end
end

test "valid_provider! raises on invalid provider" do
Expand All @@ -38,6 +42,42 @@ def setup
assert_match(/invalid_provider.*not a valid provider/, error.message)
end

test "valid_provider! uses ROAST_DEFAULT_AGENT_PROVIDER when no provider is configured" do
with_env(Agent::Config::DEFAULT_PROVIDER_ENV_VAR, "claude") do
assert_equal :claude, @config.valid_provider!
end
end

test "explicitly configured provider takes precedence over ROAST_DEFAULT_AGENT_PROVIDER" do
@config.provider(:claude)

with_env(Agent::Config::DEFAULT_PROVIDER_ENV_VAR, "pi") do
assert_equal :claude, @config.valid_provider!
end
end

test "valid_provider! falls back to the built-in default when ROAST_DEFAULT_AGENT_PROVIDER is blank" do
with_env(Agent::Config::DEFAULT_PROVIDER_ENV_VAR, "") do
assert_equal @default_provider, @config.valid_provider!
end
end

test "valid_provider! normalizes ROAST_DEFAULT_AGENT_PROVIDER casing and surrounding whitespace" do
with_env(Agent::Config::DEFAULT_PROVIDER_ENV_VAR, " CLAUDE ") do
assert_equal :claude, @config.valid_provider!
end
end

test "valid_provider! raises when ROAST_DEFAULT_AGENT_PROVIDER names an invalid provider" do
with_env(Agent::Config::DEFAULT_PROVIDER_ENV_VAR, "unknown_provider") do
error = assert_raises(Cog::Config::InvalidConfigError) do
@config.valid_provider!
end

assert_match(/unknown_provider.*not a valid provider/, error.message)
end
end

# Command configuration tests
test "command sets command value" do
@config.command("test-command")
Expand Down
2 changes: 1 addition & 1 deletion tutorial/02_chaining_cogs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ execute do
end
```

The `agent` cog is backed by a locally installed coding agent -- Pi is the default provider.
The `agent` cog is backed by a locally installed coding agent -- Pi is the default provider (set `ROAST_DEFAULT_AGENT_PROVIDER` to change it globally, e.g. to `claude`).
You'll need to have Pi installed and configured correctly for this cog to run.

### Specifying a Model
Expand Down
Loading