The Coach loop's final round sent toolChoice "none" without the tool
definitions. With tool_use/tool_result blocks in the history Anthropic
refuses such a request (400), and OpenAI Chat Completions refuses
tool_choice without tools, so every budget, time, cap and no-progress stop
ended in an error on those wires. The final round now carries the tools
with toolChoice "none", which every wire accepts, thinking included.
Codex kept reasoning items as provider state even when the request asked
for no encrypted reasoning; replaying such an item under store:false is a
400. Items are kept only when the request included
reasoning.encrypted_content and the item carries it.
The reasoning dialect cache learned from any 4xx that mentioned
reasoning or thinking (auth, rate limits, model names such as
deepseek-reasoner) and from replay errors, and kept the downgrade for the
life of the process. Learning now requires an HTTP 400 that refuses a
sent parameter, ignores replay errors and the model name, and a learned
downgrade expires after an hour.
The chat route hands the turn the level resolveCoachTurnReasoningLevel
returns: the stored Coach preference, absent read as medium, after the
operator's switch and cap. The turn still applies the operator-paid
ceiling once its chain is known. The controls loader no longer throws
when the request cache cannot serve it; it fails closed to off. The
admin guard pins the route to the resolver.
Add resolveReasoning, the one decision for how hard a call may think:
the operator's switch, then the provider's ability, then the requested
level (the person's Coach preference, or a background job's own level),
then the operator's cap, then a medium ceiling when the operator pays.
The answer names the layer that decided it.
loadReasoningControls reads the two app_settings columns, memoised per
request, read afresh in background runs, and fails closed to "off".
loadCoachReasoningState resolves the published Coach state from the
memoised provider presence; resolveJobReasoning resolves one background
call and never fails it.
A guard proves the switch and the cap over the whole input space and
requires every call that carries reasoning to take it from the
resolver.
reasoningSupport() reads what each provider can do with reasoning from the provider type and model name: effort, summaries, live summaries, state that must travel between tool rounds, and whether off is a real off. Unknown names are treated optimistically.
The dialect cache records what an endpoint refused (keyed by provider, endpoint and model) so a client retries with the lesser request once and never pays the refused round-trip again. Downgrades are marked on the wide event with meta keys only.
Add the shared contract the reasoning release builds on, with no change
to how a turn runs today.
- Schema: operator reasoning controls on app_settings (0376), the
encrypted trail text on coach_messages (0377), and source,
last_used_at and source_message_id on coach_facts (0378).
- Provider contract: CompletionParams.reasoning and onReasoning,
CompletionResult.reasoning and providerState, AiMessage.providerState.
- Reasoning levels, thinking budgets and the background-job table in
src/lib/ai/reasoning/levels.ts; coachPrefsJson.reasoning, absent
meaning medium, salvaged field by field like every other pref.
- Stream: activity, memoryNote and planProposal frames, done.stop and
done.withheldResults, result.interim, a compare chart kind, eight
table refs, three more clarification kinds with an assumed choice,
the change_assumption chip, and assumptions, activity, stop,
memoryNote and planProposal on the provenance. Zod mirror, type
parity and the native-client key rule cover every new frame.
- Chat request: memoryDecision and planDecision, parsed and not yet
acted on.
- Stub contracts for the memory functions and the activity recorder,
inert until their implementations land.
- Backup, restore and rotation carry the new columns; a fact's message
reference is resolved against the restored messages like its
conversation reference.
- Message keys for the trail, memory, plans, assumptions, replies,
interim tables, comparison charts and reasoning settings in all seven
locales, each reachable from a catalog and checked both ways.