src/core/driver.py (around line 516, at b0e3435) sends tool_choice={"type": "any"} on
every messages.create call, including the follow-up calls inside the tool loop. Two
consequences, one old and one new:
1. On current Claude models the driver can never return a text answer. With
{"type":"any"}, every response is forced to contain a tool_use block, so the loop at
driver.py:~250-283 runs until max_iterations, and the text extraction after it finds no
text blocks — the user gets the "unable to generate a proper response" fallback. Observed
against claude-fable-5, 5 runs each of two README questions ("What companies are in the
technology sector?" and a Q1-2025 revenue question): 0/5 and 0/5 produced any text; each
run made six forced SQL_QueryReadonly calls (SELECT * FROM companies WHERE sector = 'Technology', then narrower variants) before hitting the cap. Input tokens per call grew
from 1,123 to 3,301 across the forced turns.
2. On Claude Fable 5.1 (released 2026-09-01) the same request is rejected outright:
tool_choice: type "tool" and "any" are not supported for this model.
HTTP 400, invalid_request_error, quoted verbatim from a recorded response; 10/10 runs.
Anthropic documents this as a breaking change for the Fable 5.1 generation ("forced tool
use returns an error"), with tool_choice: auto plus a prompt instruction as the
replacement.
Reproduction
Set CLAUDE_MODEL=claude-fable-5-1 (or claude-fable-5 for the silent variant) and ask
any question through the driver with the SQL tools loaded — e.g. the README's "What
companies are in the technology sector?". The failing request is the messages.create
call in src/core/driver.py (~line 516), which passes tool_choice={"type": "any"}.
Suggested fix
Drop tool_choice (the default is auto) and keep the existing system-prompt line that
already tells the model it MUST use the SQL tools — that is exactly the workaround
Anthropic's migration guide recommends.
Run records (every request/response, 5 runs per case per model) are public:
https://github.com/atilavahedian/upshift/blob/main/reports/fable-5-1-upgrade.md — the runs
were made with upshift, a tool I'm building that diffs agent behavior across model
versions; the records stand on their own.
src/core/driver.py(around line 516, at b0e3435) sendstool_choice={"type": "any"}onevery
messages.createcall, including the follow-up calls inside the tool loop. Twoconsequences, one old and one new:
1. On current Claude models the driver can never return a text answer. With
{"type":"any"}, every response is forced to contain atool_useblock, so the loop atdriver.py:~250-283runs untilmax_iterations, and the text extraction after it finds notext blocks — the user gets the "unable to generate a proper response" fallback. Observed
against
claude-fable-5, 5 runs each of two README questions ("What companies are in thetechnology sector?" and a Q1-2025 revenue question): 0/5 and 0/5 produced any text; each
run made six forced
SQL_QueryReadonlycalls (SELECT * FROM companies WHERE sector = 'Technology', then narrower variants) before hitting the cap. Input tokens per call grewfrom 1,123 to 3,301 across the forced turns.
2. On Claude Fable 5.1 (released 2026-09-01) the same request is rejected outright:
HTTP 400,
invalid_request_error, quoted verbatim from a recorded response; 10/10 runs.Anthropic documents this as a breaking change for the Fable 5.1 generation ("forced tool
use returns an error"), with
tool_choice: autoplus a prompt instruction as thereplacement.
Reproduction
Set
CLAUDE_MODEL=claude-fable-5-1(orclaude-fable-5for the silent variant) and askany question through the driver with the SQL tools loaded — e.g. the README's "What
companies are in the technology sector?". The failing request is the
messages.createcall in
src/core/driver.py(~line 516), which passestool_choice={"type": "any"}.Suggested fix
Drop
tool_choice(the default isauto) and keep the existing system-prompt line thatalready tells the model it MUST use the SQL tools — that is exactly the workaround
Anthropic's migration guide recommends.
Run records (every request/response, 5 runs per case per model) are public:
https://github.com/atilavahedian/upshift/blob/main/reports/fable-5-1-upgrade.md — the runs
were made with upshift, a tool I'm building that diffs agent behavior across model
versions; the records stand on their own.