adapters: consolidate status_error + conditional temperature#31
Merged
Conversation
#16: extract a single status_error(prefix, status, payload, *, secondary_keys) into adapters/base.py; anthropic/gemini/openai_compat all call it. Cap the extracted detail to 500 chars for every source (dict error.message, secondary key, string error, top-level message, raw string body) so an oversized provider error body no longer bloats ModelAnswer.error/logs/--json. Removes the three near-duplicate local _status_error helpers. #22: build_request accepts temperature: float | None; temperature is omitted from the request body when None so models that reject an explicit temperature do not 400. council.py and providers.py are untouched -- the call chain still passes a concrete float positionally, so signatures stay byte-identical and the None path is opt-in/forward-looking. Tests: shared helper (message, secondary-key fallback, string/raw/top-level, no-detail), detail cap across dict/raw/secondary sources, and temperature included-vs-omitted per adapter. 82 passed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
closes #16
closes #22
Summary
Two adapter-cluster cleanups, implemented serially against
cluster/adapters.#16 — consolidate
status_error+ cap error detail (D-3/D-4)status_error(prefix, status, payload, *, secondary_keys=())intosrc/conclave/adapters/base.py. The three near-duplicate local_status_errorhelpers inanthropic.py,gemini.py, andopenai_compat.pyare deleted; all three now call the shared helper.secondary_keyscarries the only real per-adapter difference:("type",)for Anthropic/OpenAI,("status",)for Gemini. The OpenAI top-levelmessagefallback is preserved inside the shared helper.detailis now truncated to a single_DETAIL_CAP = 500for every source — dicterror.message, the secondary-key fallback, a stringerror, a top-levelmessage, and a raw string body. Previously only the string-body path was capped (at 200), so a multi-KB dicterror.messageflowed through untruncated and bloatedModelAnswer.error, logs, and--json. Cap chosen at the top of the issue's suggested 200–500 range to retain more diagnostic context while still bounding the blast radius. The message still passes throughredact()downstream (unchanged).#22 — conditional temperature (D-11)
build_requestnow typestemperatureasfloat | None; whenNone, the param is omitted from the body (OpenAI-compattemperaturekey, Anthropictemperaturekey, GeminigenerationConfig.temperature). This lets reasoning models that reject an explicittemperatureavoid an opaque 400.council.pywas NOT touched (owned by a parallel cluster). The fix is adapter-level only:providers.pyandcouncil.pystill pass a concrete float positionally, so the upstream call-chain signatures stay byte-identical. TheNonepath is opt-in / forward-looking — exactly what the issue asks for ("allowtemperature=Noneto omit").Tests
Added to
tests/test_adapters.py: shared-helper behavior (dict message, secondary-key fallback, string/raw/top-level/no-detail), the detail cap across dict/raw/secondary-key sources, and temperature included-vs-omitted per adapter.pytest -q: 82 passed (was 68)ruff check .clean,ruff format --check .cleanFiles touched
src/conclave/adapters/{base,anthropic,gemini,openai_compat}.py,tests/test_adapters.py. No changes tocouncil.py,providers.py,cli.py,config.py,registry.py,transport.py.