Skip to content

fix: Preserve Anthropic continuation through extra_content - #92

Merged
jiahuei merged 2 commits into
amer-hosted-web-searchfrom
feat/anthropic-extra-content
Oct 30, 2026
Merged

jiahuei merged 2 commits into
amer-hosted-web-searchfrom
feat/anthropic-extra-content

Conversation

@jiahuei

@jiahuei jiahuei commented Oct 30, 2026 •

Copy link
Copy Markdown
Member

Summary

Problem, symptoms, and diagnosis

Problem

Anthropic hosted-search continuation needs the original source encrypted_content and citation encrypted_index, together with the source details and citation excerpt. Standard Responses URL sources and annotations cannot carry all of that state. PR #74 already preserved it under provider_metadata.anthropic, but the required public extension contract is extra_content.anthropic, following the provider-namespaced convention tracked in #78. This change aligns the existing continuation mechanism with that contract.

Symptoms

  • Responses search sources and URL annotations exposed provider_metadata instead of extra_content. Consumers retaining the expected extra_content envelope would not retain the Anthropic continuation state.
  • Before the implementation change, the updated cassette-backed output assertions failed in both streaming and non-streaming modes because extra_content was absent.
  • History with missing encrypted state, or "N/A" placeholders, cannot restore Anthropic search context and is rejected before an Anthropic follow-up request. Renaming the envelope preserves real state; it does not make placeholders usable. The existing provider_metadata route already supported continuation when clients retained that envelope, so this was a public contract mismatch rather than evidence that all existing continuation was broken.

Steps taken to diagnose

  1. Compared Google's documented request-level extra_body and content-level extra_content extension surfaces with Establish tested provider compatibility for Bedrock, OpenRouter, Together AI, Gemini, and Fireworks #78 and PR feat: support hosted web search across Responses and Messages #74 at c55a6b860fc4ff222a5b6e008a11aa1068277614.
  2. Traced the existing carrier through local Responses history schemas, source/citation conversion helpers, route validation, streaming projection, SDK serialization, and next-turn ingestion. Confirmed the IR already stored these values directly in WebSearchSource and WebCitation; no new IR container was needed.
  3. Changed the output expectations to extra_content and ran the focused recorded-search parity tests before implementation. Both modes failed on the missing field, identifying the Responses boundary as the change location.
  4. Renamed the envelope and reran SDK parity and actual-output continuation tests. Verified exact reconstructed Anthropic request bodies, preserved source/citation state and linkage, and continued rejection of missing state or incompatible upstream routes.
  5. Extended the existing Responses-to-IR hosted-search test to compare complete ordered IR with and without extra_content.anthropic, directly asserting ciphertext, citation indices, source details, excerpts, and call/result linkage. Verification results are listed below; provider traffic was offline replay only.

Verification

  • PYTHONPATH=python /home/akk/jiahuei/molto/.venv/bin/python -m pytest -q tests/core/test_anthropic_web_search.py -k translates_sdk_semantics: both updated assertions failed before implementation because extra_content was absent.

  • PYTHONPATH=python /home/akk/jiahuei/molto/.venv/bin/python -m pytest -q tests/core/test_anthropic_web_search.py tests/core/test_web_search.py tests/types/test_openai_responses.py: 405 passed after implementation.

  • PYTHONPATH=python /home/akk/jiahuei/molto/.venv/bin/python -m pytest -q -o addopts='': 2,293 passed on Python 3.12.9, offline replay only. No live provider calls or cassette changes.

  • uv run --extra lint ruff check --output-format github --config pyproject.toml .: passed.

  • uv run --extra lint ruff format --diff --config pyproject.toml .: passed, 99 files already formatted. Initial changed-file formatting check identified two files, corrected with uv run --extra lint ruff format --config pyproject.toml python/molto/types/openai_responses.py tests/core/test_web_search.py.

  • npx prettier@3.8 --check .: passed. Initial changed-document check identified docs/web-search.md, corrected with npx prettier@3.8 --write docs/web-search.md.

  • git diff --check: passed. git status --short -- tests/cassettes: empty.

  • PYTHONPATH=python /home/akk/jiahuei/molto/.venv/bin/python -m pytest -q tests/adapters/test_openai_search.py tests/core/test_anthropic_web_search.py: 55 passed after adding direct IR assertions. Repository-wide Ruff and Prettier checks also passed for this test-only update; the full-suite result above predates this additional parameterized case.

@jiahuei
jiahuei merged commit dcbf1a9 into amer-hosted-web-search Oct 30, 2026
2 checks passed
@jiahuei
jiahuei deleted the feat/anthropic-extra-content branch October 30, 2026 05:06
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