Skip to content

adding default provider - #67

Merged
thorrester merged 1 commit into
mainfrom
provider-default
May 12, 2026
Merged

adding default provider#67
thorrester merged 1 commit into
mainfrom
provider-default

Conversation

@thorrester

@thorrester thorrester commented May 12, 2026

Copy link
Copy Markdown
Member

Pull Request

Short Summary

Makes provider optional on Prompt(...), Agent(...), and spec YAML by reading POTATO_HEAD_DEFAULT_PROVIDER from the environment when no explicit provider is given. Previously every call site had to specify it; now you can set it once per deployment and omit it everywhere.

Context

When using Potato Head in a service that only ever talks to one LLM provider, requiring provider= on every Prompt or Agent is pure boilerplate. This PR pushes resolution into a central path — explicit arg wins, env var fallback, hard error if neither is set.

The core change lives in Provider::resolve() and Provider::resolve_from_py() in potato-type. Both Python entry points (Prompt.__init__, Agent.__init__) and the spec loader now call through these instead of Provider::from_string() directly. If resolution fails, the new MissingProviderError tells the caller exactly which env var to set:

No provider specified. Pass `provider=` explicitly or set the POTATO_HEAD_DEFAULT_PROVIDER env var.

Before:

# Required on every call
p = Prompt(messages=..., model="gpt-4o", provider="openai")
a = Agent(provider="openai")
# Required in every agent spec
provider: openai
model: gpt-4o

After:

export POTATO_HEAD_DEFAULT_PROVIDER=openai
p = Prompt(messages=..., model="gpt-4o")   # resolves from env
a = Agent()                                  # resolves from env
# provider key is now optional
model: gpt-4o

Explicit values still take precedence — env var is only the fallback. Whitespace-only values (both explicit and env) are treated as unset.

File Change
crates/potato_type/src/lib.rs Adds DEFAULT_ENV_VAR, from_env_default(), resolve(), resolve_from_py()
crates/potato_type/src/error.rs Adds MissingProviderError variant
crates/potato_type/src/prompt/interface.rs provider field/arg → Option<String> / Option<&Bound<PyAny>>; calls Provider::resolve()
crates/potato_agent/src/agents/agent.rs provider PyO3 arg → optional; calls Provider::resolve_from_py()
crates/potato_spec/src/spec.rs AgentSpec.providerOption<String> with #[serde(default)]
crates/potato_spec/src/loader.rs Calls Provider::resolve() instead of from_string(); adds env-var-aware tests
py-potato/python/potato_head/_potato_head.pyi provider stubs updated to Provider | str | None = None
py-potato/tests/prompt/test_default_provider.py New Python tests: env fallback, explicit override, error path
py-potato/docs/prompts.md Documents the new optional behavior

Is this a Breaking Change?

No. provider was a required argument in both Python and the spec format; it's now optional with an explicit-wins fallback. Callers that already pass provider= continue to work without modification. The only behavior change is that omitting provider no longer raises a type error at the call site — it raises MissingProviderError at resolution time if the env var is also absent, with a clearer message than before.

@thorrester
thorrester merged commit 845bec6 into main May 12, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant