Problem / Motivation
The module currently pins anthropic-ai/sdk: ^0.29
(live-verified installed at v0.29.1). Packagist latest is
v0.32.0 (released 2026-06-29). Sites installing our
1.3.0-beta2 release get the older SDK.
The 0.30.0 release contains a targeted fix that
matters for our provider:
"streaming returns error statuses instead of throwing"
— when the Anthropic API returns HTTP 4xx/5xx during a streaming
request, the SDK now surfaces a typed
APIStatusException subclass (with retry support and typed
ErrorType body) instead of the misleading
APIConnectionException the pre-0.30 stack threw. Sites on
^0.29 miss this fix and get a lower-fidelity error surface
on streaming failures.
Proposed resolution
Bump the composer constraint ^0.29 → ^0.32
in the module composer.json. That is the whole functional
change: the fix is entirely upstream at the HTTP transport layer, and
consuming it needs no code change in our provider.
A source-inspection probe on the v0.30.0 tag confirmed
Anthropic\Messages\RawMessageStreamEvent::variants()
is byte-for-byte identical to 0.29.x — the same six event variants
(message_start, message_delta,
message_stop, content_block_start,
content_block_delta, content_block_stop) with
no error variant added. Our
AnthropicStreamedChatMessageIterator is
unchanged. The 0.30 fix is a one-line addition
('http_errors' => false) in the SDK's
StreamingHttpClient::sendRequest, so Guzzle returns a
ResponseInterface to the SDK's existing retry loop
instead of throwing on 4xx/5xx.
Alongside the bump, add one PHPUnit test method to
the existing AnthropicProviderNativeChatTest filling a
combination-coverage gap: SdkRateLimitException +
typed ErrorType::RATE_LIMIT_ERROR. Prior sibling tests
covered either SdkBadRequestException +
RATE_LIMIT_ERROR or SdkRateLimitException
with no typed body — this fills the gap the 0.30 transport fix makes
real (streaming 429 → typed rate-limit body).
Scope
Two-file MR on 1.3.x:
composer.json— one-line constraint bump.tests/src/Unit/Plugin/AiProvider/AnthropicProviderNativeChatTest.php
— one new test method (reuses existingmockSdkException()
helper +invoke()reflection helper; no new mock
framework, no new fixture pattern).
Explicitly out of scope for this MR:
- Wiring
system.messagestreaming events —
confirmed Beta Managed Agents only, not on our chat path. - Wiring other additive 0.31 / 0.32 surfaces
(web_fetch_20260318tool,
count_tokensuser-profile IDs). - Phase 3 features (compaction, token counting, citations).
- SRP refactor of
AnthropicProvider.php.
Verification
Local drupalci-parity gates that we could run: all
GREEN. Full module unit suite (84 tests, 153 assertions)
green on v0.32.0. Composer --dry-run: 1 update, 0
installs, 0 removals — no new packages, no transitive changes.
Gates deferred to drupalci pipeline: phpstan (local
workspace env has an unrelated contrib module with a broken
autoloader that phpstan-drupal hits at bootstrap; CI env is clean),
cspell, PHPUnit concurrent variant, opt-in
Previous-Major / Next-Minor / Max-PHP variants.
Remaining tasks
- Open MR against
1.3.xfrom an issue fork. - Verify drupalci pipeline green.
- Community review / RTBC.
- Merge + release
1.3.0-beta3.
AI-Generated: Yes
Used Claude Opus 4.8 to draft the PHPUnit regression test method
covering the missing
(SdkRateLimitException + typed
RATE_LIMIT_ERROR) combination. Adversarially reviewed via
the drupal-ai-contrib:fresh-context-reviewer agent, which
caught an overclaim in the initial docblock; corrected before submit.
The SDK constraint bump itself is a human maintainer decision.
Dependencies, logic, security, and GPL compatibility verified. Full
contributor responsibility assumed.
Issue fork ai_provider_anthropic-3607715
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #3
camoa commentedComment #4
marcus_johansson commentedComment #6
camoa commentedComment #8
camoa commented