package llm // adaptiveThinking records which models accept thinking: {"type":"adaptive"}. // It is a per-model table for the same reason prices is: the answer differs by // model and a wrong one is not a rounding error. claude-haiku-4-5 answers a // request carrying adaptive thinking with // // 400 invalid_request_error: adaptive thinking is not supported on this model // // which kills the agent before its first turn — which is exactly what the // explore subagent preset, pinned to haiku, did on every spawn. // // Only ids confirmed to accept adaptive thinking are listed. Absence is not a // claim that the model rejects it, only that this build has not confirmed it. var adaptiveThinking = map[string]bool{ "claude-opus-5": true, "claude-opus-4-8": true, "claude-opus-4-7": true, "claude-sonnet-5": true, } // SupportsAdaptiveThinking reports whether model accepts an adaptive thinking // parameter. Callers omit the field entirely when it does not. // // An unlisted id — a gateway serving a model this build has never heard of, a // family released after it — is treated as unsupported. The two mistakes are // not symmetric: sending adaptive to a model that lacks it is a hard 400 that // ends the run before any work happens, where omitting it on a model that would // have taken it only costs the thinking. The recoverable failure is the one to // default to. Flagships stay on the list, so the main session is unaffected. // // basePrice is the pricing table's normaliser, and the decoration it strips — // a -YYYYMMDD or -latest suffix, a bracketed context-window variant — is the // same decoration a capability lookup has to see past. /v1/models hands out // claude-opus-5-20251101, and that is the same model as claude-opus-5. func SupportsAdaptiveThinking(model string) bool { return adaptiveThinking[basePrice(model)] }