Skip to content

Add Bedrock adaptive thinking support for Claude Opus 4.7 - #288

Closed
kernelalex wants to merge 2 commits into
vxcontrol:mainfrom
kernelalex:main
Closed

Add Bedrock adaptive thinking support for Claude Opus 4.7#288
kernelalex wants to merge 2 commits into
vxcontrol:mainfrom
kernelalex:main

Conversation

@kernelalex

@kernelalex kernelalex commented Apr 27, 2026

Copy link
Copy Markdown

Problem

AWS Bedrock Claude Opus 4.7 rejects the current reasoning payload emitted by PentAGI/langchaingo:

thinking.type.enabled with budget_tokens

Bedrock returns a 400 validation error because Opus 4.7 requires adaptive thinking:

thinking.type.adaptive with output_config.effort

The settings UI also only exposed reasoning effort and max token budget, so users could not configure Bedrock adaptive
thinking from /settings/providers.

Solution

This PR introduces explicit reasoning modes to the provider configuration and settings UI. Here’s what’s included:

New ReasoningMode type: Supports adaptive and budget options, fully wired up across GraphQL, backend config, and frontend type generation.
Updated settings UI: Provider configs now include a Reasoning Mode dropdown with Automatic, Token Budget, and Adaptive options. The max tokens field automatically hides when Adaptive is selected since it’s not applicable.
Adaptive mode enhancements: Added xhigh and max reasoning effort levels. Adaptive mode will auto-select for Bedrock’s Claude Opus and Sonnet 4.6+ models, with Opus 4.7 defaulting to xhigh.
Bedrock middleware: Intercepts adaptive-thinking Converse requests and rewrites them to properly set thinking.type=adaptive and output_config.effort.
Model metadata & docs: Added Claude Opus 4.7 to Bedrock’s model metadata and updated the corresponding documentation.
Backward compatibility: Existing budget-based reasoning setups continue to work exactly as they do now, so there are no breaking changes.

Closes #

Type of Change

  • 🐛 Bug fix (non-breaking change which fixes an issue)
  • 🚀 New feature (non-breaking change which adds functionality)
  • 💥 Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • 📚 Documentation update
  • 🔧 Configuration change
  • 🧪 Test update
  • 🛡️ Security update

Areas Affected

  • Core Services (Frontend UI/Backend API)
  • AI Agents (Researcher/Developer/Executor)
  • Security Tools Integration
  • Memory System (Vector Store/Knowledge Base)
  • Monitoring Stack (Grafana/OpenTelemetry)
  • Analytics Platform (Langfuse)
  • [ x] External Integrations (LLM/Search APIs)
  • [ x] Documentation
  • Infrastructure/DevOps

Testing and Verification

Test Configuration

PentAGI Version: Latest Release (2.0)
Docker Version: Docker version 29.3.1, build c2be9cc
Host OS: Ubuntu 24.04.4 LTS on WSL2
LLM Provider: AWS Bedrock, Claude Opus 4.7
Enabled Features: Langfuse and Grafana

Test Steps

  1. Built and ran a local PentAGI image.
  2. Configured AWS Bedrock with us.anthropic.claude-opus-4-7.
  3. Selected Reasoning Mode: Adaptive and a reasoning effort value in /settings/providers.
  4. Ran provider/agent tests from the settings UI.
  5. Verified the original Bedrock 400 validation error no longer occurs.
  6. Ran focused backend, frontend, formatting, and lint validation.

Test Results

Passed:
cd backend
go test ./pkg/providers/bedrock ./pkg/providers/pconfig ./pkg/database/converter ./pkg/graph
go vet ./pkg/providers/bedrock ./pkg/providers/pconfig ./pkg/database/converter ./pkg/graph

cd frontend
npm run build
npm run test
npx prettier --check src/pages/settings/settings-provider.tsx src/graphql/types.ts graphql-schema.graphql
npx eslint src/pages/settings/settings-provider.tsx

Security Considerations

No new dependencies, credentials, permissions, or environment variables are introduced.

The Bedrock request rewrite only changes the serialized Converse request body for calls explicitly configured with
Adaptive reasoning mode. It does not log request bodies or expose provider secrets.

Performance Impact

Runtime overhead is minimal: adaptive Bedrock calls perform one small JSON body rewrite before the AWS SDK sends the request.

Model-side performance may vary because adaptive thinking lets Claude choose reasoning depth based on task complexity.
This can change latency and output token usage compared with a fixed reasoning token budget.

Documentation Updates

  • README.md updates
  • API documentation updates
  • Configuration documentation updates
  • GraphQL schema updates
  • Other:

Deployment Notes

No migration or environment variable changes are required.
Existing provider configs remain backward compatible. Configs without reasoning.mode keep the previous behavior. For Claude Opus 4.7 on Bedrock, select Reasoning Mode: Adaptive and configure Reasoning Effort instead of Reasoning Max Tokens.

Checklist

Code Quality

  • My code follows the project's coding standards
  • I have added/updated necessary documentation
  • I have added tests to cover my changes
  • All new and existing tests pass
  • I have run go fmt and go vet (for Go code)
  • I have run npm run lint (for TypeScript/JavaScript code)

Security

  • I have considered security implications
  • Changes maintain or improve the security model
  • Sensitive information has been properly handled

Compatibility

  • Changes are backward compatible
  • Breaking changes are clearly marked and documented
  • Dependencies are properly updated

Documentation

  • Documentation is clear and complete
  • Comments are added for non-obvious code
  • API changes are documented

Additional Notes

Add Bedrock adaptive thinking support for Claude Opus 4.7
Adding clear support for opus 4.7 in the README.md file
sirozha added a commit that referenced this pull request Jul 11, 2026
UsesAdaptiveThinking/PrepareAdaptiveCallOptions had no test coverage after the
native-langchaingo migration removed the old transport-layer tests. Add table
tests: an adaptive-only model forces adaptive over an agent's budget choice or an
absent reasoning block, while budget-only models stay untouched.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
pull Bot pushed a commit to jw5812018/pentagi that referenced this pull request Aug 3, 2026
…control#288)

Integrates the backend half of PR vxcontrol#288 onto our branch (the frontend is
reworked separately in our codegen style), 3-way merged so the vxcontrol#233
config/models-path changes are preserved:
- adaptive_thinking.go: smithy Build middleware that rewrites the langchaingo
  Converse body from thinking{type:enabled,budget_tokens} to
  thinking{type:adaptive} + output_config.effort, wired via WithAPIOptions and
  prepareCallOptions in Call/CallEx/CallWithTools.
- pconfig: ReasoningConfig.Mode (adaptive|budget) + EffectiveMode/IsZero.
- GraphQL: ReasoningMode enum, reasoning.mode field, xhigh/max effort levels.

Drops the dead llms.WithMetadata adaptive branch from AgentConfig.BuildOptions
(nothing reads opts.Metadata on the Bedrock path; adaptive is applied per-call
by the provider) and updates the unit test accordingly.

Hardening still pending (next commit): strip temperature/top_p/top_k and set
display:summarized for adaptive requests, add Opus 4.7/4.8 catalog entries with
a model reasoning-capability descriptor + force-adaptive backstop, and a live
Bedrock repro. Until then Opus 4.7 should not be selected for an agent.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
pull Bot pushed a commit to jw5812018/pentagi that referenced this pull request Aug 3, 2026
…ntrol#288)

Makes adaptive-thinking models usable safely and adds Opus 4.7/4.8 to the
catalog so they are selectable and configurable.

- middleware: strip temperature/top_p/top_k and set thinking.display=summarized
  when rewriting to adaptive. Opus 4.7+ reject sampling params (AWS: "no longer
  supported", 400) and default display to "omitted" (empty reasoning text).
- models.yml: add us.anthropic.claude-opus-4-7 and us.anthropic.claude-opus-4-8,
  plus a ModelReasoningInfo capability descriptor (mode + allowed efforts) on the
  adaptive models (4.6/4.7/4.8/sonnet-4.6).
- provider backstop: force adaptive for adaptive-only models (Opus 4.7/4.8)
  regardless of agent config, so selecting them cannot 400 on budget thinking.
  The capability descriptor is the single source of truth (no model-name regex).

Verified: unit tests cover the body rewrite (sampling strip + display); a live
Bedrock run of the adaptive path on us.anthropic.claude-opus-4-6-v1 passed 21/23
(the 2 failures were 429 throttling, not the mechanism). Opus 4.7/4.8 could not
be exercised live -- this AWS account lacks model access (403), not a code
issue; their correctness rests on the AWS docs + the 4.6 live run + unit tests.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
pull Bot pushed a commit to jw5812018/pentagi that referenced this pull request Aug 3, 2026
…ntrol#288)

Adds ModelReasoningInfo (mode + allowed efforts) to the GraphQL ModelConfig so
the frontend can gate the reasoning mode/effort UI by each model's declared
capability instead of a model-name regex. New ModelReasoningMode enum
(budget | adaptive | adaptive_only) mirrors the models.yml descriptor; the
converter maps pconfig adaptive-only -> GraphQL adaptive_only.

Backend groundwork for the Layer 2 frontend adaptive-thinking UI.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
pull Bot pushed a commit to jw5812018/pentagi that referenced this pull request Aug 3, 2026
Adds reasoning { mode efforts } to the modelConfigFragment and regenerates
GraphQL types, so the provider settings UI can gate the reasoning mode/effort
controls by each model's declared capability (ModelReasoningMode incl.
adaptive_only) instead of a model-name regex.

Groundwork for the adaptive-thinking settings UI port.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
pull Bot pushed a commit to jw5812018/pentagi that referenced this pull request Aug 3, 2026
…efs vxcontrol#288)

ModelConfig has custom UnmarshalYAML/UnmarshalJSON/MarshalYAML/MarshalJSON that
map fields by hand, so the reasoning capability descriptor added earlier was
silently dropped on load (Reasoning stayed nil). That made the Bedrock
adaptive-only backstop a no-op (modelReasoningMode never saw adaptive-only).
Handle `reasoning` in all four marshalers, mirroring `price`, plus a round-trip
regression test. Found via the anthropic adaptive integration test.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
pull Bot pushed a commit to jw5812018/pentagi that referenced this pull request Aug 3, 2026
Extends adaptive-thinking support from Bedrock to the direct Anthropic provider.
langchaingo emits only budget thinking, so adaptive is applied by rewriting the
request body — for Anthropic via an http RoundTripper (the Messages API carries
thinking and sampling params at the top level), wired through the injectable
http.Client. prepareCallOptions forces adaptive for adaptive-only models (the
models.yml capability descriptor is the single source of truth) and stashes the
effort in context for the transport.

- adaptive_thinking.go: RoundTripper + rewrite (thinking->adaptive,
  output_config.effort, display=summarized, strip temperature/top_p/top_k).
- models.yml: add claude-opus-4-7 / claude-opus-4-8 (adaptive-only) + reasoning
  descriptors on the adaptive models (4.6/sonnet-4.6).
- Verified by a credit-free httptest integration test asserting the rewritten
  body on the wire; the shape is also accepted by the real Anthropic API. Full
  live e2e pending account credits/model access.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
pull Bot pushed a commit to jw5812018/pentagi that referenced this pull request Aug 3, 2026
…xcontrol#288)

Ports the per-agent reasoning UI to support adaptive thinking, gated by each
model's declared capability (the reasoning fragment) instead of a model-name
regex:
- new ReasoningFields component: a reasoning Mode select (adaptive | budget,
  shown only for adaptive-capable models, locked to adaptive for adaptive-only)
  and an effort select whose options follow the model's allowed efforts
  (incl. xhigh/max).
- getReasoningEffort handles xhigh/max; getReasoningMode + the form schema and
  transformFormToGraphQL carry the chosen mode through to the API.

Verified locally: tsc --noEmit and eslint clean. Runtime verification on the
stack (Layer 3) is the next step.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
pull Bot pushed a commit to jw5812018/pentagi that referenced this pull request Aug 3, 2026
…ontrol#288)

Switching an agent's model left the prior reasoning.mode/effort in the form
(onOptionSelect only reset price), so a stale budget mode or an effort the new
model doesn't support could be persisted. Now the model picker also resets
reasoning: adaptive-only models lock to adaptive, others clear mode + effort.

Verified: tsc --noEmit + eslint clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
pull Bot pushed a commit to jw5812018/pentagi that referenced this pull request Aug 3, 2026
…easoning (refs vxcontrol#288)

Closes audit-found coverage gaps:
- bedrock: TestBackstopForcesAdaptiveForAdaptiveOnlyModel (adaptive-only model
  forces adaptive with no agent reasoning block) + a negative case for a
  non-reasoning model. The Anthropic backstop already had an httptest test;
  Bedrock had none.
- pconfig: ReasoningConfig.EffectiveMode (incl. max_tokens->budget inference)
  and IsZero.
- converter: ConvertModels reasoning mapping (pconfig adaptive-only ->
  GraphQL adaptive_only, efforts passthrough, nil for no descriptor).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
pull Bot pushed a commit to jw5812018/pentagi that referenced this pull request Aug 3, 2026
vxcontrol#288)

The component declared control as Control<FormData> (z.output, required
name/type) but receives the form's Control<FormInput> (z.input, optional
name/type), which `tsc -b` (the production build typecheck) rejects with
"Type 'undefined' is not assignable to type 'string'". `tsc --noEmit -p
tsconfig.json` did not catch it; `pnpm run build` (tsc -b && vite build) now
passes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
pull Bot pushed a commit to jw5812018/pentagi that referenced this pull request Aug 3, 2026
…reset shows (refs vxcontrol#288)

The ReasoningFields mode/effort selects used `defaultValue`, making them
uncontrolled — Radix reads it once on mount, so the `setValue` resets in
onOptionSelect (reset reasoning on model change) updated form state but never
the visible selection. Result: after switching models the selectors showed
stale values (e.g. mode "Adaptive" when the field was cleared to null; effort
left blank when a stale 4.7/4.8 "xhigh" had no item under opus-4-6). Switch to
controlled `value` so the display follows the reset. Also drop a dead
empty-comment block in onOptionSelect.

Found during Layer 3 live verification on the docker stack.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
pull Bot pushed a commit to jw5812018/pentagi that referenced this pull request Aug 3, 2026
…xcontrol#288)

onOptionSelect reset reasoning.mode and reasoning.effort when the agent model
changes but left reasoning.maxTokens untouched, so a budget token value set for
a previous model leaked into the next one (e.g. switching from a budget-capable
model to an adaptive-only model kept the stale value in the form). Reset it
alongside mode/effort. Found during comprehensive provider QA.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
pull Bot pushed a commit to jw5812018/pentagi that referenced this pull request Aug 3, 2026
…control#288)

The GraphQL createProvider/updateProvider path applied no field validation, so
a direct API call (bypassing the browser's native HTML5 form validation) could
persist nonsensical values (temperature 99, negative price, an inverted
min/max length window, a reasoning budget over the 32000 engine cap).

Add ProviderConfig.Validate()/AgentConfig.Validate(), called after
patchProviderConfig in both CreateProvider and UpdateProvider. It is deliberately
permissive — 0 means "unset" and provider-specific tuning ranges remain the LLM
API's responsibility — so it only rejects universally-invalid values and never a
valid provider-specific config. Found during comprehensive provider QA.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
pull Bot pushed a commit to jw5812018/pentagi that referenced this pull request Aug 3, 2026
…daptive, range refines (refs vxcontrol#288)

Three QA-found edge cases in the provider form:
- Choosing "Use <x> as custom" set the model without running onOptionSelect, so
  reasoning/price stayed stale for the typed model. Fire onOptionSelect with the
  synthetic option so they reset like a dropdown pick.
- Selecting effort max/xhigh on an adaptive-capable model with mode unset left
  the backend with no way to route the reasoning (it dropped it). Auto-set mode
  to Adaptive, since max/xhigh are adaptive-thinking effort levels.
- Add zod cross-field refines (minLength<=maxLength, reasoning.maxTokens<=32000)
  that native HTML5 validation can't express, mirroring the new backend checks.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
pull Bot pushed a commit to jw5812018/pentagi that referenced this pull request Aug 3, 2026
…es (refs vxcontrol#288, vxcontrol#328)

Code review found the providers were fully wired in code but missing from
several user-facing surfaces:

- MiniMax (vxcontrol#328): add to .env.example, docker-compose env passthrough,
  backend/docs/config.md env table, README provider list + a MiniMax
  configuration section, and backend/docs/database.md PROVIDER_TYPE enum.
- Claude Opus 4.7/4.8 (vxcontrol#288): add to the README Claude and Bedrock model
  catalogs and correct the model counts (10→11 Claude, 21→24 Bedrock); note
  4.7/4.8 are adaptive-thinking-only in the Adaptive Thinking section.
- llms_how_to.md: scope the "Temperature=1.0" rule to budget thinking and add
  an adaptive-thinking caveat (4.7/4.8 reject sampling params), so the guide no
  longer contradicts the shipped adaptive code path.
- docker-compose: point the Bedrock config/models default mount at the tracked
  examples/configs/bedrock-glm-flash.* files (the README-documented path) so a
  plain `docker compose up` no longer creates empty placeholder directories.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
pull Bot pushed a commit to jw5812018/pentagi that referenced this pull request Aug 3, 2026
…k/anthropic (refs vxcontrol#288)

The bedrock and anthropic adaptive_thinking.go files carried ~96 byte-identical
lines (prepareCallOptions, usesAdaptiveThinking, modelReasoningMode,
reasoningConfigForType, agentConfigForType, the effort context key), and
agentConfigForType was a third copy of the agent-type switch pconfig already
owns in GetPriceInfoForType.

Move the model-agnostic logic onto pconfig.ProviderConfig:
AgentConfigForType (now also backing GetPriceInfoForType), UsesAdaptiveThinking,
PrepareAdaptiveCallOptions, and the WithAdaptiveEffort/AdaptiveEffortFromContext
context helpers. Each provider now keeps only its transport-specific pieces:
the smithy Build middleware (bedrock) / http RoundTripper (anthropic) and
rewriteAdaptiveThinkingBody. Also drop the dead delete(payload,"top_k") in the
anthropic rewrite — langchaingo's Messages payload only serializes
temperature/top_p. Backstop tests rewired to the pconfig API; all provider tests
+ go vet pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
pull Bot pushed a commit to jw5812018/pentagi that referenced this pull request Aug 3, 2026
… exhaustive, trim comments (refs vxcontrol#288, vxcontrol#328)

Review nits:
- schema.resolvers.go: log (not swallow) bedrock.DefaultModels errors so an
  invalid BEDROCK_MODELS_PATH no longer yields a silently-empty model list.
- settings-providers.tsx: derive the create-provider type list from an
  exhaustive Record<ProviderType,string> so a future ProviderType is a compile
  error here instead of silently missing from the menu.
- trim two doc comments (convertModelReasoningMode, ReasoningFields) to lead
  with the load-bearing contract instead of restating the name.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
pull Bot pushed a commit to jw5812018/pentagi that referenced this pull request Aug 3, 2026
…(refs vxcontrol#288)

The added Claude/Bedrock rows put "✅ adaptive-only" in the narrow Thinking
column, which broke the source pipe alignment of the carefully-padded tables.
Use a plain ✅ in the Thinking column (the adaptive-only detail already lives in
the Use Case text and the Adaptive Thinking note) and re-pad the rows so the
columns line up again.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@asdek

asdek commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

hey @kernelalex
thank you for the PR! we moved your changes by cherry-pick to the main branch.

also, the actual main branch and the latest docker image tag have changes for supporting opus-4.x, opus-5, sonnet-5 and fable-5 anthropic models, please check the code state

@asdek asdek closed this Aug 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants