agent: pass adaptive thinking config to SDK query()#104
Conversation
Opus 4.7 (and likely future models) reject the legacy
`thinking.type: enabled` shape in API requests. Without an explicit
`thinking` option on the SDK query(), the bundled CLI falls back to
that legacy shape and the API returns a 400:
invalid_request_error: "thinking.type.enabled" is not supported
for this model. Use "thinking.type.adaptive" and
"output_config.effort" to control thinking behavior.
Pass `thinking: { type: "adaptive" }` from chat-query.ts and
judge-query.ts so the SDK forwards the supported shape on every
query, regardless of which Opus or Sonnet variant is configured.
The existing `effort` option continues to control thinking depth
under the adaptive contract.
|
@codex please review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4bdc5698dd
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| }, | ||
| persistSession: true, | ||
| effort: deps.config.effort, | ||
| thinking: { type: "adaptive" as const }, |
There was a problem hiding this comment.
Pass adaptive thinking in handleMessage SDK query
This patch adds thinking: { type: "adaptive" } for runForChat, but the primary AgentRuntime.handleMessage() path still calls query() without a thinking option in src/agent/runtime.ts (the call used by Slack/trigger/scheduler/MCP entry points). For deployments on claude-opus-4-7, those requests will continue to use the SDK's legacy default shape and still fail with the same 400 error this commit is trying to eliminate, so the fix is incomplete for production channels.
Useful? React with 👍 / 👎.
Round 1 of #104 review caught the runtime.ts handleMessage call site was untouched, leaving inbound Slack/trigger/scheduler/MCP requests on Opus 4.7 still defaulting to the legacy thinking.type.enabled shape that returns 400 invalid_request_error. Mirror the explicit adaptive shape on this third call site so every entry point that reaches the SDK query() forwards the supported request shape. Also patch reflection-subprocess.ts, the fourth query() site, which runs on the same Opus tier during memory drains and would 400 the same way without the adaptive thinking option.
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 81cbfb4c0b
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| permissionMode: "bypassPermissions", | ||
| allowDangerouslySkipPermissions: true, | ||
| tools: ["Read", "Write", "Edit", "Glob", "Grep"], | ||
| thinking: { type: "adaptive" as const }, |
There was a problem hiding this comment.
Avoid forcing adaptive thinking on Haiku 4.5 tier
The reflection subprocess now unconditionally sends thinking: { type: "adaptive" }, but this path defaults to the haiku tier (TIER_MODELS.haiku maps to claude-haiku-4-5 in src/evolution/judge-models.ts), and 4.5-era models require manual thinking (enabled + budget_tokens) rather than adaptive mode. In that configuration, the query will fail with a 400 and the drain is marked as a skipped transient failure, so memory reflection can silently stop working until escalation. Please gate the thinking config by model capability (or move the haiku tier to an adaptive-capable model).
Useful? React with 👍 / 👎.
Round 2 found unconditional adaptive thinking breaks Haiku 4.5 in the reflection subprocess (and any future haiku-tier callsite). Adaptive is supported on Sonnet 4.6 and Opus 4.7; Haiku 4.5 needs the legacy enabled + budget_tokens shape. The fix replaces the four scattered adaptive-stamp lines with a single-source-of-truth getThinkingConfig(model) helper so every call site picks the right shape based on its model. Verified end-to-end against the live Anthropic API on opus-4-7, sonnet-4-6, and haiku-4-5: opus rejects enabled (400), haiku rejects adaptive (400), sonnet accepts both. The helper maps each model family to the shape the API actually accepts, defaulting unknown models to adaptive because every model since Opus 4.7 has been adaptive-only. Helper is covered by 12 new unit tests against the full matrix; chat, judge, runtime, and reflection callsites now spread it instead of hard-coding a literal.
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8c9c335619
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| "claude-haiku-4", | ||
| "claude-haiku-3", | ||
| "claude-sonnet-3", | ||
| "claude-sonnet-4-5", |
There was a problem hiding this comment.
Match Claude 3.x IDs when selecting manual thinking
getThinkingConfig only checks claude-haiku-3* / claude-sonnet-3* prefixes, but Anthropic’s actual 3.x IDs are claude-3-5-haiku-* and claude-3-7-sonnet-*; those values currently fall through to the adaptive default and will send thinking: { type: "adaptive" } to models that require manual thinking (enabled + budget), causing runtime 400s for valid legacy model configurations. This regression is easy to trigger by setting model to a real 3.x ID (e.g. claude-3-5-haiku-20241022).
Useful? React with 👍 / 👎.
Summary
Opus 4.7 (and likely future models) reject the legacy
thinking.type: enabledshape in API requests. Without an explicitthinkingoption on the SDKquery(), the bundled CLI falls back to that legacy shape and the API returns a 400:This patch passes
thinking: { type: "adaptive" }explicitly from both SDK call sites (chat agent and judge subprocess) so the supported request shape is forwarded on every call regardless of which model variant is configured. The existingeffortoption continues to control thinking depth under the adaptive contract.Changes
src/agent/chat-query.ts: addthinking: { type: "adaptive" as const }toquery()options.src/agent/judge-query.ts: same in the judge subprocessquery()options.Test plan
bun run lintcleanbun run typecheckcleanbun test src/agent/90/90 passWhy this is small
The SDK already accepts adaptive thinking; the API already requires it for newer models. The only change is making the request shape explicit instead of relying on a CLI default that's no longer correct for Opus 4.7.