Issue #3590963: Bump SDK constraint and drop method_exists defensive check
Phase 2 of the Anthropic provider native-SDK work (#3590963): prompt caching admin UI + PDF document input. Builds on Phase 1 (#3572402, merged in d1e078a1). Targets 1.3.x; fast-forward mergeable.
What this delivers
Prompt caching
- Admin UI: "Enable prompt caching" toggle and TTL selector (5m / 1h),
#states-gated in the provider settings form. - System prompt sent as a typed
TextBlockParamwithcache_controlwhen caching is on (caching a bare string is a no-op; the breakpoint must sit on a content block). - 1h TTL is GA and works without any beta header (verified live).
cache_creation_input_tokenssurfaced throughChatOutput::getMetadata()['cache_creation_tokens'].
PDF input
buildMessageContent()detectsapplication/pdffiles on aChatMessageand emits a typedDocumentBlockParam+Base64PDFSource.getConfiguredModels()gains aChatWithPdfcapability filter (using theAiModelCapability::ChatWithPdfenum case shipped in drupal/ai 1.4).
SDK + infrastructure
anthropic-ai/sdkconstraint^0.16→^0.29(running and live-tested on v0.29.1). Cross-version audit of v0.24–v0.29.1 against every typed symbol we touch surfaced exactly one breaking change in our zone (v0.25 added a requiredoutputTokensDetailsparam toUsage::with()/MessageDeltaUsage::with()); production code is unaffected (only reads usage), and the two mock-usage builders in the unit tests passNULLfor the new param. The floor sits at^0.29rather than the strict minimum (^0.25) because that is the version end-to-end verified live (1h TTL, 5m TTL, PDF round-trip), and a lower floor would assert behavior on intermediate releases (v0.25–v0.28) that have not been exercised.drupal/aibumped to^1.4.0to use the nativeAiModelCapability::ChatWithPdfenum case.- Module-local
phpunit.xml.distwith scoped<source>coverage.
Verification
- PHPCS (Drupal + DrupalPractice) on
src/andtests/: clean. - PHPStan level 8: clean.
- PHPUnit: drupalci pipeline on this MR is the authoritative gate (not re-run locally for this iteration).
- Live end-to-end on a real key (DDEV): cache write/hit on Sonnet 4.5, 1h TTL accepted, PDF round-trip on Sonnet 4.5 / Opus 4.7 / Haiku 4.5. Details in the issue comments.
Not in scope
- PDF upload UI. Phase 2 ships provider plumbing; an end-user upload path is an upstream
ai_api_explorer/ai_chatbotchange. - Per-block cache breakpoints. Needs an upstream
ChatMessagemarking mechanism. - Compaction, token counting, citations. A later phase.
- Mid-conversation system blocks (v0.25 SDK feature). Looks like a candidate to replace the hand-built single-block system caching; tracking as a Phase 3 follow-up.
AI-Generated: Yes (Claude Code with Claude Opus 4.7 and 4.8 used for architecture, implementation, and test scaffolding across Phases 1 and 2. Live E2E validation and code review performed against each iteration; final review by maintainer.)
Closes #3590963
Edited by Carlos Ospina