Needs work
Project:
Anthropic Provider
Version:
1.3.x-dev
Component:
Code
Priority:
Normal
Category:
Feature request
Assigned:
Unassigned
Reporter:
Created:
19 May 2026 at 20:16 UTC
Updated:
20 May 2026 at 17:41 UTC
Jump to comment: Most recent
Comments
Comment #2
camoa commentedComment #3
camoa commentedMR pushed to
3590963-add-prompt-caching(7 commits, targets1.3.x). Summary of what landed and how it was verified.What was built
Prompt caching
#states-gated on the toggle.TextBlockParamwithcache_controlattached — caching a bare string does nothing, the breakpoint has to sit on a content block. A top-levelcache_controlmarker is also set so the SDK places a second breakpoint on the last message block.extended-cache-ttl-2025-04-11beta header; the provider attaches it per-request viaRequestOptions::extraHeadersonly when 1h is selected. The SDK does not auto-attach it.cache_creation_input_tokensis surfaced throughChatOutput::getMetadata()['cache_creation_tokens'], complementing thecache_read_input_tokens→TokenUsageDto::cachedreporting from #3572402.PDF input
buildMessageContent()detectsapplication/pdffiles on aChatMessageand emits a typedDocumentBlockParamwithBase64PDFSource— mirroring the existing image-input path.getConfiguredModels()gains a provider-internalanthropic:pdf_inputcapability filter, gated on the typedModelCapabilities->pdfInput->supportedflag with a last-known-good regex fallback.SDK maintenance
^0.16to>=0.16,<1.0so the rolling 0.x line is picked up. Tested against the currentv0.23.0.method_exists()guard (drupal/ai ^1.3guarantees the method); PHPStan level 8 flagged it.How it was tested
Same approach as #3572402 — unit tests for logic, then a live end-to-end pass against a real Anthropic key on DDEV, because unit tests verify logic but only real API calls verify contracts.
src/andtests/; PHPStan level 8 clean.phpunit.xml.distwas added (the drupalci template prefers it over core's) with a<source>block scoping coverage to./src. Module line coverage 46.7%; the streaming iterator went from 0% to 97.6%. The admin form and the native-HTTP paths remain uncovered — those need Kernel/Functional tests and are tracked as follow-up.cache_creation_input_tokens = 1262,cache_read = 0.cache_read_input_tokens = 1262,cache_creationabsent.cache_creation = 1362.One bug surfaced during the live pass and was fixed in the same branch: top-level
cache_controlalone does not cache the system prompt — the SDK's auto-placement targets the last message block, which is normally below Anthropic's 1024-token cache minimum. The fix sends the system prompt as a typed cacheable block.Out of scope
ChatMessagecarries a PDFDocumentFile, the provider sends it correctly. It does not add a way for an end user to attach a PDF. The AI API Explorer's Chat Generator has a file field, but it hard-wraps uploads asImageFile; DeepChat has no document-upload wiring. So PDF input is programmatic-only today (see the usage comment below). A PDF upload UI is an upstream change toai_api_explorer/ai_chatbot, not to this provider.ChatMessage; deferred rather than shipped behind a magic-string convention.Comment #4
camoa commentedHow to use these features
Prompt caching
/admin/config/ai/providers/anthropic).Once enabled, every native chat request marks the system prompt as a cache breakpoint. The first call with a given prefix writes the cache; subsequent calls within the TTL read from it at a reduced input-token cost. Caching pays off when the same large system prompt or context is reused across requests — short prompts below Anthropic's minimum cacheable size are simply not cached by the API.
A per-request override is available for code-level callers: set
configuration['prompt_cache'](and optionallyconfiguration['prompt_cache_ttl']) on the provider instance — it takes precedence over the form setting.Reading cache token usage
With AI Logging enabled, each logged response carries the cache accounting:
TokenUsageDto::cached— tokens served from cache (the saving on a hit).ChatOutput::getMetadata()['cache_creation_tokens']— tokens billed to write the cache (present on the first call of a cycle).PDF input
PDF input is programmatic only. There is currently no UI in the AI module to attach a PDF to a chat — the AI API Explorer's file field wraps every upload as an
ImageFile, and DeepChat has no document-upload wiring. A UI path is an upstream change toai_api_explorer/ai_chatbot. What this issue ships is the provider plumbing: when aChatMessagecarries a PDFDocumentFile, the provider sends it correctly.To use it from code (a custom module, an AI Agent, an automator), attach a
DocumentFileto theChatMessage— the same shape used for images, with theapplication/pdfMIME type:use Drupal\ai\OperationType\Chat\ChatInput; use Drupal\ai\OperationType\Chat\ChatMessage; use Drupal\ai\OperationType\GenericType\DocumentFile; $message = new ChatMessage('user', 'Summarise the attached document.'); $message->setFile(new DocumentFile( file_get_contents('/path/to/report.pdf'), 'application/pdf', 'report.pdf', )); $input = new ChatInput([$message]); $output = $provider->chat($input, 'claude-sonnet-4-5-20250929');The provider converts the file into a typed
DocumentBlockParamand Claude reads both the text and the visual layout of the PDF. PDF input works on Claude 4.x models (Opus, Sonnet, Haiku); to restrict a model list to PDF-capable models, request theanthropic:pdf_inputcapability when callinggetConfiguredModels().Note: PDFs are passed to Anthropic byte-for-byte without inspection. Treat PDFs from untrusted sources as you would untrusted text — they can carry adversarial instructions. This caution is also shown on the provider settings form.
Comment #6
camoa commentedComment #7
marcus_johansson commentedAdded some comments - also the phpunit and cspell has failures.
Comment #8
marcus_johansson commented