Skip to content

fix: stop forcing tool_choice so Claude 5.5 models don't answer 400

isidro requested to merge fix/sonnet-55-tool-choice into main

Summary

LiteLLM is about to point the claude-sonnet alias at Sonnet 5.5, which answers 400 to tool_choice of type tool/any (checked live against claude-sonnet-5-5: tool_choice: type "tool" and "any" are not supported).

  • strategy_planner.generate_strategy, social_ops.repurpose_text / rephrase_evergreen, strategy_bridge.llm_post_generator, analyst.ClaudePlanner.plan and watcher.ClaudeClassifier.classify now call structured_output.request_tool_input: Structured Outputs with the tool schema closed, else a strict tool with tool_choice: auto and a prompt line telling the model to call it. Same return values as before.
  • request_structured keeps Structured Outputs first; its tool_use fallback no longer forces the tool.
  • New strict_tools.py (pure helpers, under strict mypy).
  • No temperature/top_p/top_k/thinking/prefill in the package; no prompt asked for a reasoning field.

Test plan

  • tests/test_sonnet55_request_contract.py: source scan plus every former forced-tool call site driven by a recording fake client (failed before the fix)
  • Full suite: 1343 passed, coverage 77.51% (ratchet 76%)
  • ruff + mypy clean
  • Live against http://localhost:4000 with claude-sonnet-5-5: watcher (Structured Outputs), analyst (tool_choice auto), strict tool + auto fallback, all returned the expected object

🤖 Generated with Claude Code

https://claude.ai/code/session_01Hdp8WThUYoNtDBJYN4fW5D

Merge request reports