Skip to content

fix(diagnosis): pin temperature=0 + repair via tool_result turn (#63)#79

Merged
JumpTechCode merged 2 commits into
mainfrom
fix/diagnosis-temperature-determinism
Jun 16, 2026
Merged

fix(diagnosis): pin temperature=0 + repair via tool_result turn (#63)#79
JumpTechCode merged 2 commits into
mainfrom
fix/diagnosis-temperature-determinism

Conversation

@JumpTechCode

Copy link
Copy Markdown
Collaborator

Summary

Closes #63. Two correctness/honesty fixes to the single-shot diagnosis path.

1. temperature=0

The Anthropic call set no temperature/top_p/seed, so it ran at the API default (1.0) — yet the README called the path "deterministic". Pin temperature=0 for run-to-run stability (the API exposes no seed; this is as close as a single-shot call gets) and soften the README claim to "run at temperature 0".

2. Repair as a real tool_result turn

On a schema ValidationError, the retry previously concatenated the error onto the user string and re-sent a fresh single-user-turn request. Now it replays a proper multi-turn exchange:

user(original) → assistant[tool_use id/name/input] → user[tool_result is_error=True: <validation error>]
  • New RepairTurn dataclass + repair param threaded through diagnose_call/_call_with_retry/_stream_once.
  • LLMResult gains tool_use_id (captured from the returned block) so the assistant turn can be replayed by id.
  • The agent no longer mutates the user prompt.

Eval-gate safety

Cassette keys are (prompt_version, model_id, case_id, shot_index)independent of the request body — so adding temperature / changing messages invalidates no cassettes and the replay-based eval gate is unaffected. No re-recording needed.

Tests

  • test_stream_call_sets_temperature_zero
  • test_llm_result_carries_tool_use_id
  • test_repair_builds_tool_result_turn (asserts the full wire shape: roles, tool_use id/name/input, tool_result tool_use_id + is_error)
  • test_retry_passes_repair_turn_with_prior_tool_use_id (agent wiring)

492 unit tests pass; ruff + mypy --strict clean. Reviewed: the repair exchange is API-valid (matched tool_use/tool_result ids, ends on a user turn under forced tool_choice), and temperature=0 is valid for the pinned claude-sonnet-4-5.

JumpTechCode and others added 2 commits June 16, 2026 00:19
Two correctness/honesty fixes for the single-shot diagnosis path:

- The Anthropic call set no temperature, so it ran at the API default (1.0)
  despite the README calling the path "deterministic". Pin temperature=0 for
  run-to-run stability (the API exposes no seed; this is as close as a
  single-shot call gets) and soften the README claim to "run at temperature 0".

- On a schema ValidationError the retry concatenated the error onto the user
  string and re-sent a fresh single-user-turn request. Replace that with a
  proper multi-turn repair exchange: replay the model's prior tool_use turn and
  answer it with a tool_result (is_error=True) carrying the validation error.
  Adds a RepairTurn dataclass + repair param threaded through the client, and
  captures the tool_use block id on LLMResult so the turn can be replayed.

Cassette keys are (prompt_version, model_id, case_id, shot_index) — independent
of the request body — so no cassettes need re-recording and the eval gate is
unaffected. Tests assert temperature=0, the tool_use_id capture, the repair
wire shape, and that the agent passes a RepairTurn on retry.

Closes #63

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@JumpTechCode
JumpTechCode merged commit cf3a269 into main Jun 16, 2026
6 checks passed
@JumpTechCode
JumpTechCode deleted the fix/diagnosis-temperature-determinism branch June 16, 2026 06:36
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.

Diagnosis: 'deterministic' is false — no temperature set; repair appended to user string instead of a tool_result turn

1 participant