Skip to content

feat: per-task LLM model selection + backup-model fallback (closes #15)#31

Merged
PRATHAMESH75 merged 2 commits into
mainfrom
feat/15-per-task-model-fallback
Jun 21, 2026
Merged

feat: per-task LLM model selection + backup-model fallback (closes #15)#31
PRATHAMESH75 merged 2 commits into
mainfrom
feat/15-per-task-model-fallback

Conversation

@PRATHAMESH75

Copy link
Copy Markdown
Owner

Summary

Closes #15. Lets each agent task pick its own model and adds graceful fallback to a backup model when a call fails.

Stacked on #30 (fix/17-llm-output-guardrails) because both touch the same llm_client.py methods. Base will auto-retarget to main once #30 merges; review/merge #30 first.

Changes

  • config.py
    • LLM_TASK_MODELS — per-task overrides via LLM_MODEL_<TASK> env vars (profile, config, report, ontology, sentiment, tools).
    • Config.model_for_task(task) — resolves task override → global LLM_MODEL_NAME.
    • LLM_FALLBACK_MODEL / LLM_FALLBACK_BASE_URL / LLM_FALLBACK_API_KEY + Config.llm_settings(task) returning a directly-constructable settings dict.
  • llm_client.py
    • LLMClient.for_task(task, **overrides) factory.
    • Optional backup model (may live on a different provider). chat() selects the model per call and, on a primary failure, retries once against the fallback. Skipped when the fallback is unset or identical to the primary.
  • Wiringreport_agent/ontology_generator/zep_toolsLLMClient.for_task(...); oasis_profile_generator/simulation_config_generator/sentiment_analyzerConfig.model_for_task(...).
  • .env.example — documented all new vars.

Acceptance criteria

  • Model can be configured per agent task
  • Failed calls fall back to a configured backup model

Testing

  • New tests/test_llm_task_config.py (11 tests): per-task resolution + global fallback, llm_settings with/without fallback, for_task model selection + override precedence, fallback engagement on primary failure, primary-success path (backup untouched), error propagation when no/identical fallback.
  • Full backend suite: 40 passed.

🤖 Generated with Claude Code

All agents previously ran off a single global LLM config, even though profile
gen, report writing, and sentiment classification have very different
cost/quality needs — and a failed call had no graceful recovery.

- Config: LLM_TASK_MODELS (LLM_MODEL_<TASK> env overrides) with model_for_task()
  resolving per-task -> global default, plus LLM_FALLBACK_* and an llm_settings()
  helper that returns a directly-constructable settings dict.
- LLMClient: new for_task(task) factory and an optional backup model. chat()
  now selects the model per call and, on a primary failure, retries once against
  the configured fallback model (which may live on a different provider). The
  fallback is skipped when unset or identical to the primary.
- Wired task sites: report/ontology/tools -> LLMClient.for_task(); profile/
  config/sentiment -> Config.model_for_task().
- Documented the new env vars in .env.example.
- tests/test_llm_task_config.py: per-task resolution, fallback engagement,
  primary-success path, error propagation when no/identical fallback.

Stacked on the #17 guardrail branch (shared llm_client.py changes).

Co-Authored-By: PRATHAMESH75 <prathamesh290504@gmail.com>
@PRATHAMESH75 PRATHAMESH75 changed the base branch from fix/17-llm-output-guardrails to main June 21, 2026 03:43
@PRATHAMESH75 PRATHAMESH75 merged commit d51b3b9 into main Jun 21, 2026
2 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.

Per-task model/provider config + fallback

1 participant