Skip to content

feat(advisor) 2/4: preserve advisor blocks in ChatResponse round-trip - #177

Merged
ericleepi314 merged 1 commit into
advisor/01-foundationfrom
advisor/02-provider-preservation
May 19, 2026
Merged

feat(advisor) 2/4: preserve advisor blocks in ChatResponse round-trip#177
ericleepi314 merged 1 commit into
advisor/01-foundationfrom
advisor/02-provider-preservation

Conversation

@ericleepi314

Copy link
Copy Markdown
Collaborator

2/4 in the /advisor stack. Stacked on #176.

Summary

The Anthropic provider's _build_chat_response projects the SDK stream into (content, tool_uses, ...) for the agent loop, but drops everything else — including server-side advisor blocks. Once PR 3 wires activation, those blocks need to round-trip through history so the next turn's API call sees a matched server_tool_use(name=advisor) + advisor_tool_result pair.

  • src/providers/base.py — adds ChatResponse.raw_content_blocks: Optional[list[dict]] = None, the channel for passthrough blocks the projector chose not to flatten.
  • src/providers/anthropic_provider.py — extends _build_chat_response to collect blocks where type == 'advisor_tool_result' or (type == 'server_tool_use' and name == 'advisor'), serialize via block.model_dump(exclude_none=True), and attach to raw_content_blocks. The SDK's lenient construct_type preserves the original fields on unknown discriminators (verified empirically against anthropic==0.88.0).

Other server tools (web_search, code_execution, etc.) are deliberately NOT scooped up — they have their own SDK projection.

Stack

Test plan

  • tests/test_advisor_chat_response_roundtrip.py — 6 tests: builds a real SDK ParsedMessage via accumulate_event for each discriminated advisor_tool_result content shape (advisor_result, advisor_redacted_result, advisor_tool_result_error), the orphan case, the non-advisor server-tool exclusion, and a mixed-block case.
  • Pins the SDK round-trip contract — a future SDK upgrade (Pydantic v3, stricter discriminator handler) that silently drops extra fields on unknown discriminators would fail the encrypted_content and error_code assertions locally.

🤖 Generated with Claude Code

Stacked on #PR1. The Anthropic provider's `_build_chat_response`
projects the SDK stream into `(content, tool_uses, ...)` for the
agent loop, but drops everything else — including server-side advisor
blocks. Once the next stack layer wires activation, those blocks need
to round-trip through history so the next turn's API call sees a
matched `server_tool_use(name=advisor)` + `advisor_tool_result` pair.

- `src/providers/base.py`: adds
  `ChatResponse.raw_content_blocks: Optional[list[dict]] = None`,
  the channel for passthrough blocks the projector chose not to
  flatten.
- `src/providers/anthropic_provider.py`: extends `_build_chat_response`
  to collect blocks where `type=='advisor_tool_result'` or
  `(type=='server_tool_use' and name=='advisor')`, serialize via
  `block.model_dump(exclude_none=True)`, and attach to
  `raw_content_blocks`. The SDK's lenient `construct_type` preserves
  the original fields on unknown discriminators (verified
  empirically against `anthropic==0.88.0`), so the round-trip is
  faithful.

Other server tools (web_search, code_execution, etc.) are
deliberately NOT scooped up — they have their own SDK projection.

## Test plan
- [x] `tests/test_advisor_chat_response_roundtrip.py` (6 tests):
      builds a real SDK ParsedMessage via `accumulate_event` for
      each of the three discriminated `advisor_tool_result` content
      shapes (`advisor_result`, `advisor_redacted_result`,
      `advisor_tool_result_error`), the orphan case, the non-advisor
      server-tool exclusion, and a mixed-block case (text + tool_use
      + advisor pair).
- [x] Pins the SDK round-trip contract — a future SDK upgrade (e.g.
      Pydantic v3, stricter discriminator handler) that silently
      drops extra fields on unknown discriminators would fail the
      `encrypted_content` and `error_code` assertions locally.
- [x] No regressions in adjacent provider tests.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@ericleepi314
ericleepi314 merged commit caee8b2 into advisor/01-foundation May 19, 2026
ericleepi314 added a commit that referenced this pull request Jul 7, 2026
…vation

feat(advisor) 2/4: preserve advisor blocks in ChatResponse round-trip
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.

1 participant