Skip to content

adapters: consolidate status_error + conditional temperature#31

Merged
ernestprovo23 merged 2 commits into
mainfrom
cluster/adapters
Jun 9, 2026
Merged

adapters: consolidate status_error + conditional temperature#31
ernestprovo23 merged 2 commits into
mainfrom
cluster/adapters

Conversation

@ernestprovo23

Copy link
Copy Markdown
Member

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)

  • Extracted one shared status_error(prefix, status, payload, *, secondary_keys=()) into src/conclave/adapters/base.py. The three near-duplicate local _status_error helpers in anthropic.py, gemini.py, and openai_compat.py are deleted; all three now call the shared helper.
  • secondary_keys carries the only real per-adapter difference: ("type",) for Anthropic/OpenAI, ("status",) for Gemini. The OpenAI top-level message fallback is preserved inside the shared helper.
  • D-3 fix: the extracted detail is now truncated to a single _DETAIL_CAP = 500 for every source — dict error.message, the secondary-key fallback, a string error, a top-level message, and a raw string body. Previously only the string-body path was capped (at 200), so a multi-KB dict error.message flowed through untruncated and bloated ModelAnswer.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 through redact() downstream (unchanged).

#22 — conditional temperature (D-11)

  • build_request now types temperature as float | None; when None, the param is omitted from the body (OpenAI-compat temperature key, Anthropic temperature key, Gemini generationConfig.temperature). This lets reasoning models that reject an explicit temperature avoid an opaque 400.
  • council.py was NOT touched (owned by a parallel cluster). The fix is adapter-level only: providers.py and council.py still pass a concrete float positionally, so the upstream call-chain signatures stay byte-identical. The None path is opt-in / forward-looking — exactly what the issue asks for ("allow temperature=None to 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 . clean

Files touched

src/conclave/adapters/{base,anthropic,gemini,openai_compat}.py, tests/test_adapters.py. No changes to council.py, providers.py, cli.py, config.py, registry.py, transport.py.

ernestprovo23 and others added 2 commits June 8, 2026 22:21
#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.
@ernestprovo23 ernestprovo23 merged commit abe1a40 into main Jun 9, 2026
5 checks passed
@ernestprovo23 ernestprovo23 deleted the cluster/adapters branch June 10, 2026 00:08
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.

adapters send temperature unconditionally (forward-looking 400 risk) status_error: cap dict error detail + consolidate 3 duplicate helpers

1 participant