Skip to content

fix(ai): round-trip Bedrock redacted reasoning - #8314

Merged
badlogic merged 1 commit into
earendil-works:mainfrom
seiji:fix/bedrock-redacted-reasoning
Aug 19, 2026
Merged

badlogic merged 1 commit into
earendil-works:mainfrom
seiji:fix/bedrock-redacted-reasoning

Conversation

@seiji

@seiji seiji commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Bedrock Converse returns encrypted reasoning as the opaque redactedContent member of reasoningContent, documented on both ReasoningContentBlock and the streaming ReasoningContentBlockDelta. OpenAI models served on Bedrock (e.g. global.openai.gpt-5.6-terra) return reasoning in this shape.

The stream handler only read reasoningContent.text and .signature, so the payload was dropped. The persisted thinking block kept an empty thinkingSignature, and convertMessages then skipped it via the thinking.trim().length === 0 guard, so replayed history lost the reasoning block entirely — including tool continuations, which Bedrock validates against the reasoning block that precedes the matching toolUse.

Fixed by buffering the delta bytes and encoding them into thinkingSignature with redacted: true, the representation the Anthropic path already uses for redacted_thinking, then lowering them back to reasoningContent.redactedContent on replay. Scratch state is stripped from every terminal path, since a stream can settle without a contentBlockStop for each block.

Added test/bedrock-redacted-reasoning.test.ts covering stream survival, payload preservation, missing contentBlockStop, deltas split across frames, and replay ordering ahead of both text and toolUse.

Verification:

  • npm test --workspace @earendil-works/pi-ai -- test/bedrock-redacted-reasoning.test.ts (6 passed)
  • npm run check
  • ./test.sh

Bedrock Converse returns encrypted reasoning from non-Anthropic models
(e.g. OpenAI GPT-5.6) as the opaque `reasoningContent.redactedContent`
member. The stream handler only read `text` and `signature`, so the
payload was dropped and replayed history lost the reasoning block.

Buffer the delta bytes, encode them into `thinkingSignature` with
`redacted: true` (the representation the Anthropic path already uses),
and lower them back to `reasoningContent.redactedContent` on the next
turn. Scratch state is stripped from every terminal path, since a
stream can settle without stopping each block.
@github-actions

Copy link
Copy Markdown
Contributor

This PR was auto-closed. Only contributors approved with lgtm can open PRs. Open an issue first and ask a maintainer for approval.

Maintainers review auto-closed issues daily. Issues that do not meet the quality bar in CONTRIBUTING.md will not be reopened or receive a reply.

If a maintainer replies lgtmi, your future issues will stay open. If a maintainer replies lgtm, your future issues and PRs will stay open. The command must be at the start of the reply (optionally after one or more @username mentions) or at the end.

See CONTRIBUTING.md.

@github-actions github-actions Bot closed this Aug 18, 2026
@badlogic badlogic reopened this Aug 19, 2026
@badlogic
badlogic merged commit d57e531 into earendil-works:main Aug 19, 2026
1 check passed
@badlogic

Copy link
Copy Markdown
Collaborator

cheers!

dadezzz pushed a commit to dadezzz/forgejo-agent that referenced this pull request Aug 27, 2026
….3 (#232)

This PR contains the following updates:

| Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [@earendil-works/pi-coding-agent](https://github.com/earendil-works/pi) ([source](https://github.com/earendil-works/pi/tree/HEAD/packages/coding-agent)) | [`0.84.2` → `0.84.3`](https://renovatebot.com/diffs/npm/@earendil-works%2fpi-coding-agent/0.84.2/0.84.3) | ![age](https://developer.mend.io/api/mc/badges/age/npm/@earendil-works%2fpi-coding-agent/0.84.3?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@earendil-works%2fpi-coding-agent/0.84.2/0.84.3?slim=true) |

---

### Release Notes

<details>
<summary>earendil-works/pi (@&#8203;earendil-works/pi-coding-agent)</summary>

### [`v0.84.3`](https://github.com/earendil-works/pi/blob/HEAD/packages/coding-agent/CHANGELOG.md#0843---2026-08-24)

[Compare Source](earendil-works/pi@v0.84.2...v0.84.3)

##### New Features

- **PowerShell tool** — Use optional native PowerShell command execution on Windows. See [PowerShell Tool](docs/windows.md#powershell-tool).
- **Safer managed updates** — Stage, verify, and atomically activate updates for installer-managed installations. See [Install and Manage](docs/packages.md#install-and-manage).
- **Model and thinking controls** — Select thinking levels with `/thinking`, search defaults, keep selections session-scoped, and persist them explicitly with Ctrl+S. See [Models and Thinking](docs/keybindings.md#models-and-thinking).

##### Breaking Changes

- Renamed the inherited `GoogleThinkingLevel` type to `GoogleApiThinkingLevel` and added `ResolvedGoogleThinkingLevel` for normalized adapter levels.

##### Added

- Added an optional `powershell` tool for Windows, configurable through `defaultTools` and the SDK. See [PowerShell Tool](docs/windows.md#powershell-tool).
- Added a `/thinking` selector and searchable default choices to the model and thinking selectors; Ctrl+S saves the selected model as the global default. See [Models and Thinking](docs/keybindings.md#models-and-thinking).
- Added optional routing session IDs to exported compaction summary helpers so callers can preserve provider routing without enabling prompt cache writes.
- Added

usage notices for compaction and branch summaries when cache miss notices are enabled.

- Added `session_compact_failed` extension events so compaction failures and aborts expose their reason, retry state, source, and error message to handlers ([#&#8203;8175](earendil-works/pi#8175)).
- Added inherited provider-neutral `toolChoice` support to simple stream requests.
- Added inherited automatic Anthropic server-side refusal fallback for supported first-party models, including returned-model usage pricing ([#&#8203;8017](earendil-works/pi#8017)).
- Added inherited configurable OpenAI-compatible thinking-token budget fields for vLLM, Qwen/SGLang, and llama.cpp servers. See [OpenAI Compatibility](docs/models.md#openai-compatibility) ([#&#8203;8275](earendil-works/pi#8275) by [@&#8203;bnsd55](https://github.com/bnsd55)).
- Added inherited China-specific ZAI Coding Plan models, including GLM-4.6V vision support and API-equivalent usage cost estimates ([#&#8203;8220](earendil-works/pi#8220)).
- Added inherited `deepseek-v4-pro-0813` support to the Qwen Token Plan Individual catalog ([#&#8203;8194](earendil-works/pi#8194)).

##### Changed

- Changed experimental installer-managed installations so `pi update` stages, verifies, and atomically activates the selected release in place. See [Install and Manage](docs/packages.md#install-and-manage).
- Changed inherited built-in xAI models to use the Responses API with encrypted reasoning replay and made Grok 4.6 the default xAI model ([#&#8203;8124](earendil-works/pi#8124) by [@&#8203;Jaaneek](https://github.com/Jaaneek)).
- Changed inherited Anthropic, Azure OpenAI, Google, Mistral, and OpenAI adapters to send Pi's default `User-Agent` unless overridden ([#&#8203;8305](earendil-works/pi#8305)).
- Changed Windows and WSL keybinding defaults to avoid terminal-reserved shortcuts for image paste, model cycling, editor undo, fullscreen transcript navigation and search, and message queueing ([#&#8203;8372](earendil-works/pi#8372)).
- Changed Bun release archives to ship the native clipboard binary only inside the wrapper package, removing a duplicate platform package from each archive.
- Changed package resource glob expansion to use Node.js's built-in implementation with deterministic visible-path matching, reducing the installed runtime dependency tree.
- Changed the bundled Node.js runtime to load jiti only when importing an extension and Babel only when uncached source needs transformation, reducing CLI startup time and bundle size.
- Changed syntax highlighting to initialize only twenty common languages eagerly and defer the remaining grammars until after the initial TUI render, reducing CLI startup time.
- Changed the Node.js CLI and RPC entrypoints to load a bundled runtime, reducing startup filesystem reads while keeping the public library and legacy module paths on the modular runtime for normal dependency identity.
- Changed session sharing to render clickable terminal links, display only the canonical Radius artifact URL, and include the current system prompt and active tool definitions in Radius session shares.

##### Fixed

- Fixed failed extension factories leaving event subscriptions, provider registrations, and default flag state active ([#&#8203;8424](earendil-works/pi#8424) by [@&#8203;acmerfight](https://github.com/acmerfight)).
- Fixed `models.json` typings omitting the documented OpenAI-compatible `compat.supportsFinishReason` provider and model override ([#&#8203;8487](earendil-works/pi#8487) by [@&#8203;petrroll](https://github.com/petrroll)).
- Fixed `/model` and `/thinking` selections being persisted globally unless explicitly saved with Ctrl+S ([#&#8203;5263](earendil-works/pi#5263)).
- Fixed JSON and RPC `toolcall_start` events omitting the tool call id and name ([#&#8203;7953](earendil-works/pi#7953) by [@&#8203;christianklotz](https://github.com/christianklotz)).
- Fixed extensions failing to load when the Node.js CLI runs as a single-executable application ([#&#8203;8237](earendil-works/pi#8237)).
- Fixed nested Markdown skills inside `.agents/skills/` grouping directories not being discovered.
- Fixed compaction and branch summarization requests exposing tools to providers.
- Fixed single-object `edit` tool inputs failing validation by accepting them as one-edit arrays in both coding-agent and harness edit tools ([#&#8203;7835](earendil-works/pi#7835)).
- Fixed root Markdown files such as `README.md` and `AGENTS.md` in skill directories being reported as broken skills unless they declare valid skill frontmatter ([#&#8203;7805](earendil-works/pi#7805)).
- Fixed the default Cerebras model referencing an unavailable Z.AI model.
- Fixed inherited OpenAI-compatible Chat Completions reasoning replay to preserve and resend assistant-level `reasoning_details` verbatim and in order ([#&#8203;7994](earendil-works/pi#7994)).
- Fixed inherited Anthropic server-side fallback responses being priced with the requested model instead of the returned fallback model ([#&#8203;8285](earendil-works/pi#8285)).
- Fixed inherited GitHub Copilot login triggering model-policy rate limits by limiting policy updates, retrying model discovery once, and honoring server retry delays ([#&#8203;7850](earendil-works/pi#7850)).
- Fixed inherited Amazon Bedrock dropping and failing to replay opaque redacted reasoning from non-Anthropic models ([#&#8203;8314](earendil-works/pi#8314) by [@&#8203;seiji](https://github.com/seiji)).
- Fixed inherited Z.AI Coding Plan models deriving incomplete reasoning-effort metadata, including missing GLM-5.3 low, high, and max levels ([#&#8203;8336](earendil-works/pi#8336)).
- Fixed inherited DeepSeek V4 Flash on OpenCode and OpenCode Go omitting its supported low thinking level ([#&#8203;8181](earendil-works/pi#8181) by [@&#8203;tianshuang](https://github.com/tianshuang)).
- Fixed inherited Azure OpenAI Responses ignoring `toolChoice` in provider-specific stream requests.
- Fixed inherited Amazon Bedrock response hooks receiving only a synthesized request id instead of the raw response headers ([#&#8203;8234](earendil-works/pi#8234)).
- Fixed inherited Kimi usage reporting so top-level `cached_tokens` count as cache reads instead of normal input tokens ([#&#8203;8075](earendil-works/pi#8075)).
- Fixed inherited Google custom models ignoring `thinkingLevelMap`, which dropped extended thinking controls ([#&#8203;8135](earendil-works/pi#8135)).
- Fixed writes to `auth.json` and `models-store.json` overriding administrator-managed file permissions and ACLs ([#&#8203;7779](earendil-works/pi#7779)).
- Fixed UTF-8 BOM markers preventing frontmatter and user configuration files from loading ([#&#8203;8337](earendil-works/pi#8337)).
- Fixed invalid settings files being easy to miss during interactive startup by rendering warnings with the file path inside the TUI ([#&#8203;7829](earendil-works/pi#7829)).
- Fixed the subagent example repeatedly prompting before running project-local agents in trusted repositories ([#&#8203;8261](earendil-works/pi#8261)).
- Added `session_compact_failed` extension events so compaction failures and aborts expose their reason, retry state, source, and error message to handlers ([#&#8203;8175](earendil-works/pi#8175)).
- Fixed truncated compaction and branch summaries being persisted when generation reaches its output token limit ([#&#8203;7048](earendil-works/pi#7048)).
- Fixed npm package update checks treating older registry versions as available updates, preventing `pi update` from downgrading already-newer installed packages ([#&#8203;8226](earendil-works/pi#8226)).
- Fixed built-in llama.cpp models disappearing from `/model` when `/llama` refreshed a configured server under `PI_OFFLINE`, and included idle-slept `sleeping` router models plus autoloadable unloaded presets in the selectable catalog ([#&#8203;8167](earendil-works/pi#8167)).
- Fixed `pi.registerFlag()` accepting default values that do not match the declared flag type ([#&#8203;8064](earendil-works/pi#8064)).
- Fixed Z.AI Coding Plan defaults referencing the removed GLM-5.1 model ([#&#8203;8096](earendil-works/pi#8096)).
- Fixed repeated ambiguous truncated-response recovery being mislabeled as context overflow ([#&#8203;8130](earendil-works/pi#8130)).
- Fixed duplicate fullscreen right-click paste in VS Code-based terminals on Windows ([#&#8203;8186](earendil-works/pi#8186)).
- Fixed inherited padded text exceeding narrow terminal widths ([#&#8203;8252](earendil-works/pi#8252)).
- Fixed inherited wrapped Markdown table links leaking color into borders and neighboring cells, including tables inside blockquotes ([#&#8203;8335](earendil-works/pi#8335)).
- Fixed llama.cpp login guidance to direct users to `/llama` before `/model` when no local models are loaded ([#&#8203;8203](earendil-works/pi#8203)).
- Fixed hung pi.dev model catalog requests consuming the entire refresh deadline without retrying ([#&#8203;8198](earendil-works/pi#8198)).
- Fixed inherited Xiaomi model catalogs listing shut-down MiMo V2 models in `/model` and `--list-models` ([#&#8203;8187](earendil-works/pi#8187)).
- Fixed branch summary entries recording the navigation destination in `fromId` instead of the pre-navigation source leaf.
- Fixed threshold auto-compaction being skipped when providers omit streaming usage data ([#&#8203;8328](earendil-works/pi#8328)).
- Fixed dash-prefixed prompts being parsed as options by supporting `--` as an end-of-options delimiter ([#&#8203;7269](earendil-works/pi#7269)).

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Mend Renovate CLI](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC40Ni40IiwidXBkYXRlZEluVmVyIjoiNDQuNDYuNCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==-->
jinhuang712 pushed a commit to jinhuang712/pi that referenced this pull request Sep 11, 2026
Bedrock Converse returns encrypted reasoning from non-Anthropic models
(e.g. OpenAI GPT-5.6) as the opaque `reasoningContent.redactedContent`
member. The stream handler only read `text` and `signature`, so the
payload was dropped and replayed history lost the reasoning block.

Buffer the delta bytes, encode them into `thinkingSignature` with
`redacted: true` (the representation the Anthropic path already uses),
and lower them back to `reasoningContent.redactedContent` on the next
turn. Scratch state is stripped from every terminal path, since a
stream can settle without stopping each block.
oskarfreye pushed a commit to draht-dev/draht that referenced this pull request Oct 1, 2026
Bedrock Converse returns encrypted reasoning from non-Anthropic models
(e.g. OpenAI GPT-5.6) as the opaque `reasoningContent.redactedContent`
member. The stream handler only read `text` and `signature`, so the
payload was dropped and replayed history lost the reasoning block.

Buffer the delta bytes, encode them into `thinkingSignature` with
`redacted: true` (the representation the Anthropic path already uses),
and lower them back to `reasoningContent.redactedContent` on the next
turn. Scratch state is stripped from every terminal path, since a
stream can settle without stopping each block.
qaworkfree pushed a commit to qaworkfree/pipipiPopopo that referenced this pull request Oct 8, 2026
Bedrock Converse returns encrypted reasoning from non-Anthropic models
(e.g. OpenAI GPT-5.6) as the opaque `reasoningContent.redactedContent`
member. The stream handler only read `text` and `signature`, so the
payload was dropped and replayed history lost the reasoning block.

Buffer the delta bytes, encode them into `thinkingSignature` with
`redacted: true` (the representation the Anthropic path already uses),
and lower them back to `reasoningContent.redactedContent` on the next
turn. Scratch state is stripped from every terminal path, since a
stream can settle without stopping each block.
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