Step summarizer, memory chunking and Flash operator fallback hardcode the Google provider, bypassing artemis.jsonc
- Dominant language
- Python
- Stars
- 5.9k
- Forks
- 516
- Avg merge
- 22m
- Merged PRs (30d)
- 5
Description
## Summary
Several runtime code paths instantiate a Google LLM directly via `get_google_llm()` instead of resolving the provider configured in `config/artemis.jsonc`. As a result, configuring a non-Google provider for **every** node (e.g. `"provider": "openai"` pointed at an OpenAI-compatible gateway, or `"provider": "anthropic"`) is not sufficient to run a Flash task: the run still tries to construct `ChatGoogleGenerativeAI` and aborts when no Google API key is present.
The README advertises Gemini, Claude and GPT-4o support, and `ModelFactory` / `get_llm(ctx, name=...)` already handle provider selection correctly, so this looks like a handful of call sites that bypass the router rather than a design limitation.
Related: #41 (unit tests requiring Gemini credentials) is a sibling symptom on the test side.
## Affected code (at `371aa6d`)
| File | Line | What it does |
|---|---|---|
| `artemis/agents/flash/summarizer.py` | 169, 173 | `VisualStepSummarizer` calls `get_google_llm(model_name=target_model, ...)` whenever a summarizer model name is configured, and again in the `except` fallback. Setting `agent.flash.step_summarizer.model` therefore forces the Google provider regardless of the rest of the config. |
| `artemis/memory/chunking.py` | 328, 335 | `StepCapsuleLens._get_llm()` / `_get_fallback_llm()` always call `get_google_llm(...)` for `agent.memory.chunking.model` and its fallback. |
| `artemis/agents/flash/runner.py` | 287 | Operator LLM fallback (when `get_llm(ctx, name="operator")` raises) is hardcoded to `get_google_llm(model_name="gemini-2.5-flash")`. |
| `artemis/config/llm.py` | 120-131 | `lightweight_judge_default()` (pixel safety net / planner validation judges) hardcodes `provider="google"`, and there is no `artemis.jsonc` key to override the judge provider. |
`StepSummarizerConfig` and `MemoryChunkingConfig` (`artemis/config/agent.py`) only carry a `model` name and no `provider`, which is probably why those call sites assume Google.
## Steps to reproduce
1. In `config/artemis.jsonc`, set `default`, every entry under `nodes`, `agent.flash.step_summarizer` and `agent.memory.chunking` to a non-Google provider, e.g. `"provider": "openai"` with `OPENAI_API_KEY` / `OPENAI_BASE_URL` pointing at an OpenAI-compatible endpoint.
2. Leave `GEMINI_API_KEY` and `GOOGLE_API_KEY` unset.
3. Run any Flash task, e.g. `uv run artemis run "Open the Settings app"` (or `mobile_run_task` through the MCP server).
**Observed:** the task fails while constructing `ChatGoogleGenerativeAI` (no API key) from the step summarizer / memory chunking / operator fallback paths, even though no node is configured to use Google.
**Expected:** no Google client is created when no node is configured for Google; the configured provider is honored everywhere.
## Suggested fix
- Replace the direct `get_google_llm()` calls in `summarizer.py`, `chunking.py` and `runner.py` with provider-aware resolution: either `get_llm(ctx, name=...)` against a named node, or `ModelFactory.create_model(ModelEndpoint(provider=, model=...))`.
- Add an optional `provider` field to `StepSummarizerConfig` and `MemoryChunkingConfig`, defaulting to the `default` node's provider when omitted.
- Let `lightweight_judge_default()` inherit the configured default provider (or expose a judge override in `artemis.jsonc`).
## Workaround
Locally re-pointing the five call sites to the OpenAI factory and setting every node to `provider: "openai"` makes Flash tasks complete end-to-end with zero Google calls (verified on a physical Android device), so the rest of the pipeline is already provider-agnostic.
I have a fix along the lines above and will open a PR referencing this issue.
## Environment
- ARTEMIS `main` @ `371aa6d` (2026-09-11)
- Python 3.12, Windows 11, `uv sync` install
Contributor guide
Research direction
Start by reading the provider-aware paths in ModelFactory and get_llm, then inspect the listed call sites in artemis/agents/flash/summarizer.py, artemis/memory/chunking.py, artemis/agents/flash/runner.py, and artemis/config/llm.py. Reproduce with the non-Google artemis.jsonc configuration and run the Flash task. Done means configured providers are honored across these paths and no Google client is created when Google is not configured.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- ai, backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 35/100