cloudwego / cloudwego/eino-ext

feat(claude): support adaptive thinking for Opus 4.7+ models

Open
#780 0 comments 1 reaction 0 assignees View on GitHub
Dominant language
Go
Stars
811
Forks
368
Avg merge
16h 22m
Merged PRs (30d)
13

Description

**Is your feature request related to a problem? Please describe.**

The `components/model/claude` adapter currently only emits the legacy extended-thinking request body:

```json
{ "thinking": { "type": "enabled", "budget_tokens": 16000 } }
```

Claude Opus 4.7 (and newer models that ship with the new thinking API) rejects that shape with:

```
invalid_request_error: "thinking.type.enabled" is not supported for this model.
Use "thinking.type.adaptive" and "output_config.effort" to control thinking behavior.
```

So any deployment using `claude.WithThinking(...)` breaks the moment it's pointed at Opus 4.7+.

Reproducible with the current adapter + `ANTHROPIC_MODEL=claude-opus-4-7`:

```go
claude.WithThinking(&claude.Thinking{Enable: true, BudgetTokens: 16000})
// → HTTP 400 from Anthropic's /v1/messages
```

**Describe the solution you'd like**

Add an opt-in adaptive mode to the existing `Thinking` struct so callers can target Opus 4.7+ without forking. Backward compatible: empty mode keeps the legacy `OfEnabled` behavior for every existing user.

- `Thinking.Mode` (`ThinkingModeEnabled` default, `ThinkingModeAdaptive` for Opus 4.7+).
- `Thinking.Effort` (`"low" | "medium" | "high" | "max"`) → populates `params.OutputConfig.Effort`.
- Dispatch in `genMessageNewParams`: emit `OfAdaptive` vs `OfEnabled` based on `Mode`. `Effort` applies to both.

References from Anthropic:

- Extended thinking guide: https://docs.anthropic.com/en/docs/build-with-claude/extended-thinking
- `/v1/messages` API reference (thinking param shapes): https://docs.anthropic.com/en/api/messages
- The Go SDK already exposes the needed types as of v1.25+: `anthropic.ThinkingConfigAdaptiveParam`, `anthropic.OutputConfigParam`, `anthropic.OutputConfigEffort{Low,Medium,High,Max}` (already a direct dep of the adapter — no new module dep needed).

**Describe alternatives you've considered**

- Forking the adapter / `replace` directive — works but every consumer needs its own fork.
- Disabling thinking when talking to Opus 4.7 — loses the whole reason to use the flagship model.
- `Config.AdditionalRequestFields` — would let a caller inject `thinking.type=adaptive`, but the SDK struct wins on the JSON merge path (the union is set before the additional fields), so this isn't actually a clean workaround today.

**Additional context**

Happy to open a PR (or a followup with tests + README snippets) once maintainers confirm the design direction.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.