Fractal Provider Changes
Start Here
- Inspect the current branch and worktree with
git status --short; preserve unrelated user changes.
- Read
src/fractal/providers.py, src/fractal/onboarding.py, src/fractal/config.py, tests/test_providers.py, tests/test_cli_config.py, and README.md.
- For model IDs, check current provider documentation or catalogs before editing. Do not rely on memory for active model names.
- Decide whether the task is only a model-menu update or a new provider/runtime behavior.
Provider Registry Pattern
Most provider changes live in src/fractal/providers.py.
- Add a provider id constant near the existing provider constants.
- Add the provider to
_PROVIDERS with a ProviderDefinition.
- Use
default_model for the default menu selection.
- Use
model_options for curated alternatives only; do not duplicate default_model.
- Use
restricted_models only when Fractal must reject all other model IDs at runtime.
- Set
model_prefix to the DSPy/LiteLLM provider prefix when runtime strings need normalization, such as openai, anthropic, or openrouter.
- Keep
model_options curated. It is a setup menu, not an exhaustive provider catalog.
Provider behavior choices:
- API key plus LiteLLM-compatible string: reuse
ApiKeyStringLMBehavior.
- OpenAI-compatible custom endpoint: follow
CustomOpenAICompatibleBehavior.
- CLI/OAuth-backed provider: add a dedicated behavior class that validates shape, checks readiness without leaking secrets, and builds the runtime LM object.
Secrets must not be stored in Fractal config. Store references only: env var names, auth source names, or paths to external auth stores.
Model ID Rules
- OpenAI API options should be OpenAI model IDs without
openai/; _normalize_model adds the prefix.
- Anthropic options should be Claude API IDs without
anthropic/; _normalize_model adds the prefix.
- OpenRouter options should be OpenRouter catalog IDs like
openai/gpt-5.5 or anthropic/claude-sonnet-4.6; _normalize_model adds openrouter/.
- Custom OpenAI-compatible endpoints cannot have a complete static model catalog. Keep a custom model entry in onboarding.
- If a provider has a dynamic catalog, do not hardcode the full live response into
model_options; pick stable, coding-relevant defaults and document that the list is curated.
Onboarding And Config
New providers appear in setup through list_providers(). Update onboarding only when the provider needs extra inputs beyond base URL and API-key env var.
- Provider/model menus use
model_choices().
- The line-mode fallback must keep working for non-TTY tests and automation.
- For any new config fields, update
ProviderConfig, redaction/rendering, schema validation, and tests.
- Never add raw secret fields such as tokens, API keys, passwords, or credentials to config.
Tests
Add or update focused tests before broad tests:
tests/test_providers.py: registry membership, model_choices, model normalization, shape validation, credential readiness, and unsupported model errors.
tests/test_cli_config.py: setup output/input flow, model selection, config writes, and secret redaction.
- If config schema changes, update
tests/test_config.py.
- If runtime behavior changes outside provider resolution, add narrow smoke/runtime coverage.
Validation commands:
.venv/bin/python -m pytest tests/test_providers.py tests/test_cli_config.py
.venv/bin/python -m pytest
Docs
Update README.md when a provider, auth source, default credential reference, or setup model menu changes. State when a menu is curated rather than exhaustive.
Commit And PR Workflow
Only commit when the user asks.
- Re-check
git status --short and stage only files changed for this task.
- Commit with a provider-scoped message, for example
Add <provider> provider support or Update <provider> model options.
- Push the current branch only when the user asks.
- Open a PR only when the user asks, using the repo's normal CLI if available, usually
gh pr create --fill.
- In the PR body, include provider behavior, auth/secrets handling, model sources, and tests run.
If current branch ownership is unclear, ask before creating, switching, pushing, or opening a PR.
1---2name: fractal-add-provider3description: Guide contributors through adding or updating Fractal model providers, provider auth wiring, and provider model options. Use when adding a Fractal provider, changing provider defaults/model_options/restricted_models, updating setup model menus, or preparing provider-related commits and PRs.4---56# Fractal Provider Changes78## Start Here9101. Inspect the current branch and worktree with `git status --short`; preserve unrelated user changes.112. Read `src/fractal/providers.py`, `src/fractal/onboarding.py`, `src/fractal/config.py`, `tests/test_providers.py`, `tests/test_cli_config.py`, and `README.md`.123. For model IDs, check current provider documentation or catalogs before editing. Do not rely on memory for active model names.134. Decide whether the task is only a model-menu update or a new provider/runtime behavior.1415## Provider Registry Pattern1617Most provider changes live in `src/fractal/providers.py`.1819- Add a provider id constant near the existing provider constants.20- Add the provider to `_PROVIDERS` with a `ProviderDefinition`.21- Use `default_model` for the default menu selection.22- Use `model_options` for curated alternatives only; do not duplicate `default_model`.23- Use `restricted_models` only when Fractal must reject all other model IDs at runtime.24- Set `model_prefix` to the DSPy/LiteLLM provider prefix when runtime strings need normalization, such as `openai`, `anthropic`, or `openrouter`.25- Keep `model_options` curated. It is a setup menu, not an exhaustive provider catalog.2627Provider behavior choices:2829- API key plus LiteLLM-compatible string: reuse `ApiKeyStringLMBehavior`.30- OpenAI-compatible custom endpoint: follow `CustomOpenAICompatibleBehavior`.31- CLI/OAuth-backed provider: add a dedicated behavior class that validates shape, checks readiness without leaking secrets, and builds the runtime LM object.3233Secrets must not be stored in Fractal config. Store references only: env var names, auth source names, or paths to external auth stores.3435## Model ID Rules3637- OpenAI API options should be OpenAI model IDs without `openai/`; `_normalize_model` adds the prefix.38- Anthropic options should be Claude API IDs without `anthropic/`; `_normalize_model` adds the prefix.39- OpenRouter options should be OpenRouter catalog IDs like `openai/gpt-5.5` or `anthropic/claude-sonnet-4.6`; `_normalize_model` adds `openrouter/`.40- Custom OpenAI-compatible endpoints cannot have a complete static model catalog. Keep a custom model entry in onboarding.41- If a provider has a dynamic catalog, do not hardcode the full live response into `model_options`; pick stable, coding-relevant defaults and document that the list is curated.4243## Onboarding And Config4445New providers appear in setup through `list_providers()`. Update onboarding only when the provider needs extra inputs beyond base URL and API-key env var.4647- Provider/model menus use `model_choices()`.48- The line-mode fallback must keep working for non-TTY tests and automation.49- For any new config fields, update `ProviderConfig`, redaction/rendering, schema validation, and tests.50- Never add raw secret fields such as tokens, API keys, passwords, or credentials to config.5152## Tests5354Add or update focused tests before broad tests:5556- `tests/test_providers.py`: registry membership, `model_choices`, model normalization, shape validation, credential readiness, and unsupported model errors.57- `tests/test_cli_config.py`: setup output/input flow, model selection, config writes, and secret redaction.58- If config schema changes, update `tests/test_config.py`.59- If runtime behavior changes outside provider resolution, add narrow smoke/runtime coverage.6061Validation commands:6263```bash64.venv/bin/python -m pytest tests/test_providers.py tests/test_cli_config.py65.venv/bin/python -m pytest66```6768## Docs6970Update `README.md` when a provider, auth source, default credential reference, or setup model menu changes. State when a menu is curated rather than exhaustive.7172## Commit And PR Workflow7374Only commit when the user asks.75761. Re-check `git status --short` and stage only files changed for this task.772. Commit with a provider-scoped message, for example `Add <provider> provider support` or `Update <provider> model options`.783. Push the current branch only when the user asks.794. Open a PR only when the user asks, using the repo's normal CLI if available, usually `gh pr create --fill`.805. In the PR body, include provider behavior, auth/secrets handling, model sources, and tests run.8182If current branch ownership is unclear, ask before creating, switching, pushing, or opening a PR.