Repository navigation
refactor(llm): drop utils.get_llm and the chat shims - #384
Conversation
The judge, persona and question generators and the validator build an Invoker over dokimi.llm.LLM for every provider. The openai/anthropic branches went through ChatOpenAI/ChatAnthropic, which built the same LLM per call, so requests, cache keys and usage labels do not change; each caller keeps the providers it accepted. Removed: utils.get_llm with its bedrock_litellm_model and _read_key (no caller left after intel#376), llm._GetLLMCompat and the LLM hooks only it overrode, ChatOpenAI/ChatAnthropic. Tests patch the callers' Invoker without create=True, or read the LLM they built; the get_llm-only tests go where LLM has the same pin, and the Bedrock profile tests move to resolve_model. Refs intel#4, intel#229. Signed-off-by: Vladislav Perevezentsev <vladislav.perevezentsev@intel.com>
Signed-off-by: Vladislav Perevezentsev <vladislav.perevezentsev@intel.com>
…ching Signed-off-by: Vladislav Perevezentsev <vladislav.perevezentsev@intel.com>
Signed-off-by: Vladislav Perevezentsev <vladislav.perevezentsev@intel.com>
The four copies of the accepted-provider tuple and its error become llm.CALLER_PROVIDERS and llm.check_caller_provider. Same providers, same message; openai-codex stays out. Signed-off-by: Vladislav Perevezentsev <vladislav.perevezentsev@intel.com>
The persona generator and the validator make one call and no redraw; pairwise runs judged_reply (intel#314). Nothing is left to move. Signed-off-by: Vladislav Perevezentsev <vladislav.perevezentsev@intel.com>
The fragment said requests and cached replies do not change; that holds for the callers and the chat shims, not for get_llm's own table. Signed-off-by: Vladislav Perevezentsev <vladislav.perevezentsev@intel.com>
The provider check raises before the Invoker is built. Signed-off-by: Vladislav Perevezentsev <vladislav.perevezentsev@intel.com>
…omes from Signed-off-by: Vladislav Perevezentsev <vladislav.perevezentsev@intel.com>
|
✅ OpenCodeReview: Review complete: 0 finding(s) across 31 selected item(s). CI at Review details
|
napetrov
left a comment
There was a problem hiding this comment.
Verdict: comment only. No blocking thread; two nits, both inline. Head a8a4f1a, merge base 52fb825, lane L2.
CI: ci / Static checks is red because the job stops at "origin/main is not fetched", before ruff, mypy and the changelog check run. The failing line is the checkout guard, not a changed file. Please re-run it after a fetch; no code change is asked for.
| # | Finding | Label | Provenance | Scope | Probe |
|---|---|---|---|---|---|
| 1 | changelog ### Removed omits the removed public bedrock_litellm_model (C4) |
nit | introduced | contract | probes/a1-out.txt |
| 2 | CLI offers openai-codex (--provider), every caller refuses it |
nit | pre-existing | contract | probes/out-head.txt, probes/out-base.txt |
Coverage: checked the diff, the provider check and its callers, the changelog fragment, the removed names on both trees, the judge, persona, generator and cache probes, and ci.md. Not looked at: the full pytest suite (litellm, regex and httpx not installed here, no network), mypy, and the changelog check script.
| @@ -0,0 +1,11 @@ | |||
| ### Removed | |||
There was a problem hiding this comment.
nit: the changelog's Removed entry leaves out utils.bedrock_litellm_model, a public name this PR deletes
dokimi/changelog.d/20261104_120000_vlad-perevezentsev_drop-get-llm.md:1 (### Removed): the PR body lists utils.bedrock_litellm_model as removed (C4), but the entry names only get_llm, ChatOpenAI and ChatAnthropic. A caller that imports it gets ImportError on upgrade and finds no note about it. The only importer in the repo was its test, which this PR moves, so this is a note, not a break.
How to check: grep -l bedrock_litellm_model dokimi/changelog.d/* on head → no output; the definition is gone from dokimi/dokimi/utils.py (base: defined there; introduced; probes/a1-out.txt).
Expected: each removed public name appears in the Removed entry.
Fix: add dokimi.utils.bedrock_litellm_model to the Removed list. _read_key is private and needs no note.
There was a problem hiding this comment.
Fixed in 1f0cf48: the Removed entry names dokimi.utils.bedrock_litellm_model and points to dokimi.llm.resolve_model(m, "amazon-bedrock") in its place.
|
|
||
| #: Providers the answerer, judge and generators take: the table but openai-codex, with | ||
| #: the spellings google, gemini and vertex_ai, then the CLI backends. | ||
| CALLER_PROVIDERS: Tuple[str, ...] = ( |
There was a problem hiding this comment.
nit: --provider openai-codex is offered by the CLI, and the answerer, judge and generators refuse it
dokimi/dokimi/llm.py:102 (CALLER_PROVIDERS): the tuple leaves out openai-codex, which ANSWER_PROVIDERS (the --provider choices) still offers. The code comment calls the exclusion deliberate. Base rejects it the same way, so this is not a regression.
How to check: Answerer, PersonaGenerator and QuestionGenerator with provider openai-codex → ValueError: Unsupported provider: 'openai-codex' on head (base: the same; pre-existing; probes/out-head.txt, probes/out-base.txt).
Expected: a provider the CLI offers is either accepted by its callers or not offered.
Fix: decide one: filter --provider to CALLER_PROVIDERS, or support openai-codex in the callers. Either can go to a follow-up issue.
There was a problem hiding this comment.
Agreed, and it is pre-existing: main refuses it the same way, so I kept it out of this refactor. CALLER_PROVIDERS now at least makes the gap visible in one place. I'll open a follow-up issue listing the commands whose --provider offers openai-codex while their caller refuses it, with both options (narrow the choices to CALLER_PROVIDERS, or accept it in the callers).
main added repo_ledger.v1.json (intel#336); without it schema_compat reads the schema as removed. No conflicts. Signed-off-by: Vladislav Perevezentsev <vladislav.perevezentsev@intel.com>
Signed-off-by: Vladislav Perevezentsev <vladislav.perevezentsev@intel.com>
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #384 +/- ##
==========================================
- Coverage 94.75% 94.75% -0.01%
==========================================
Files 352 352
Lines 46507 46407 -100
Branches 7970 7949 -21
==========================================
- Hits 44070 43974 -96
+ Misses 1544 1542 -2
+ Partials 893 891 -2
🚀 New features to boost your workflow:
|
antonwolfy
left a comment
There was a problem hiding this comment.
LGTM. The refactor does what it says: the openai and anthropic callers build the same LLM the shims built, and CALLER_PROVIDERS and the error text match the four tuples they replace. One nit on the changelog.
What I ran, on a Linux review host at 1f0cf48:
make ci-local: 29 passed, 1 failed, 7 skipped. 15,694 tests passed, 10 skipped; changed-line coverage passes. The failed step is two fixture-setup timeouts intests/test_audit_test_quality.py(60 s limit, machine under load); the same file passes alone, 172 tests in 15 s, and the PR does not touch it.- Reproductions with the LLM transport mocked, for the route, key and construction behaviour of the callers.
- A mutation run: 41 mutants over the judge, answerer, both generators, the validator,
check_caller_provider,CALLER_PROVIDERS,InvokerandRequest. 40 are caught; the one survivor only empties the remedy sentence of the unsupported-provider message.
Checked, no issues
- Request parity: the removed shims went through
llm_call_with_usage, which builtLLM(model, provider, api_key, temperature, seed)with the same defaults. The request, cache key and usage labels do not change. - Provider check: the set and the message are identical to the old tuples; the judge still runs it after
check_sampling. - Bedrock:
resolve_model(m, "amazon-bedrock")gives the same route as the removedbedrock_litellm_modelon seven inputs (known bare name,anthropic.x,gemini/x, ARN,openai.*,foo/bar, unknown bare name). - Removed tests: none lost a pin the surviving
LLMtests do not hold (converse route,file:key, backoff, pricing). - Leftovers: no remaining references to the removed names except the langchain classes in the ragas path, and
.agent-eval/tasks/legacy-keys/check.py, which the description says is pinned to an older base.
Signed-off-by: Anton Volkov <antonwolfy@gmail.com>
antonwolfy
left a comment
There was a problem hiding this comment.
LGTM. I pushed a commit per nit, up to 77f8aff, which fix the nit from my review:
77f8aff:dokimi/changelog.d/20261104_120000_vlad-perevezentsev_drop-get-llm.md:10: added the openai route and the unreadablefile:key to the list of differences, in the suggested wording.
make ci-local at 77f8aff: 30 passed, 0 failed, 7 skipped.
Part of #4: Wave 4, LLM module, item 2 of the plan in #4 (comment). The rest of #229 P1-2's fix ("delete
get_llmand the five switches"); #376 fixed the bugs.No behaviour change.
Invoker(LLM(...))for every provider. Before, openai and anthropic went throughChatOpenAI/ChatAnthropic, which built the sameLLMon each call.llm.check_caller_provider, backed byllm.CALLER_PROVIDERS. The providers and the message are the same as before. The validator still accepts any provider.utils.get_llm,utils.bedrock_litellm_modelandutils._read_key: nothing in the package has called them since fix(llm): the judge, generators and validator route and key through dokimi.llm (#229 P1-2) #376;llm._GetLLMCompat, and theLLMhooks (_route,_key,_labels) that only it overrode;llm.ChatOpenAIandllm.ChatAnthropic.fake_llm/provider_calls. They went two ways instead:Invoker;Invoker(LLM(...))withlitellm.completionstubbed, so they go throughLiteLLMAdapteras production does.ChatOpenAI/ChatAnthropicwithcreate=True. They now patch the caller'sInvoker, withoutcreate=True. Withcreate=Truethe old patches would have kept passing against a missing name while the call went to the network.LLMthe caller built (model, provider, key, sampling, route) instead of checking that a mock was called.get_llm's own table are removed whereLLMalready has the same pin: ARN, converse route, key file, retry budget, pricing.resolve_model(test_get_llm_bedrock.py→test_bedrock_model_ids.py).Evidence
ChatOpenAI/ChatAnthropicandInvoker(LLM(...))give the same requests, the same response-cache file names and the same usage labels. Checked for openai (gpt-6.1-sol,glm-5.3withtemperature=0.0, seed=3) and anthropic (claude-sonnet-5-5,claude-haiku-5-5withtemperature=0.0), for draw 0 and draw 1. So a cache written by main still hits;test_llm.py::test_an_entry_main_wrote_is_hitkeeps its openai and anthropic entries.LANGCHAIN_AVAILABLE;CALLER_PROVIDERSlosesgemini;Invokerdropsdraw;LLMrecords the route as the usage model.growth_baseline.jsonis lowered:llm.py1093 → 1032 lines,QuestionValidator.__init__complexity 14 → 11.LLMin the constructor, where the shim built one on each call. Somodel=None(the parameter is typedstr, and no CLI default isNone) raises the sameTypeErrorat construction instead of at the first call. The other providers already did this on main.make ci-local: 0 failed (14849 passed); the PR-only checks (changelog fragment, comment blocks, growth against the base) pass against upstream/main.Not in this PR
llm.ask_parsed): there is nothing to move.eval/pairwise.pyalready goes throughjudged_reply, which usesask_parsed(refactor(judge): one judged-reply seam for judge, panel, pairwise, checklist #314).llm.pydocstring no longer lists them.openai-codex, which their CLI--provideroffers (ANSWER_PROVIDERS). Fixing that changes behaviour, so it is left out of this refactor;CALLER_PROVIDERSnow marks it.JUDGE_PROVIDERS(the judge flags' choices) differs from it ingemini/vertex_ai, as on main.llm.LANGCHAIN_AVAILABLEis alwaysTrue, and five test files still put stublangchain_*modules insys.modules. Only the RAGAS step uses langchain..agent-eval/tasks/legacy-keys/check.pypatchesjudge.ChatAnthropic. The task is pinned to base16e319f, where the shim exists andjudge.Invokerdoes not, so patchingInvokerwould break it on its own base. It needs the new patch only if the task is moved to a newer base.Checklist
pytestpassesruff,mypy, and schema checks passAGENTS.md.github/.licenserc.yaml)