adachsoft/ai-integration-anthropic

Anthropic Claude tool-calling SPI adapter for adachsoft/ai-integration.

Maintainers

Package info

gitlab.com/a.adach/ai-integration-anthropic

Issues

pkg:composer/adachsoft/ai-integration-anthropic

Transparency log

Statistics

Installs: 27

Dependents: 0

Suggesters: 0

Stars: 0

v0.7.0 2026-08-21 15:59 UTC

This package is auto-updated.

Last update: 2026-08-21 14:08:45 UTC


README

Integration of Anthropic Claude (tool calling) with the adachsoft/ai-integration library.

Requirements

  • PHP >= 8.3
  • guzzlehttp/guzzle ^7.0 || ^8.0
  • adachsoft/ai-integration ^0.8.0

Installation

composer require adachsoft/ai-integration-anthropic

Basic usage

Example of wiring the Anthropic SPI provider with the tool-calling facade from adachsoft/ai-integration:

use AdachSoft\AiIntegration\PublicApi\Builder\ToolCallingChatFacadeBuilder;
use AdachSoft\AiIntegrationAnthropic\AnthropicToolCallingChatSpiFactory;

$apiKey = getenv('ANTHROPIC_KEY');

$factory = new AnthropicToolCallingChatSpiFactory();

$builder = new ToolCallingChatFacadeBuilder();
$builder->withSpiProvider('anthropic', $factory->create($apiKey));

$facade = $builder->build();

Transport modes

AnthropicToolCallingChatSpiFactory::create() supports two transport modes:

  • non_streaming (default) - legacy buffered mode using classic non-streaming HTTP response read.
  • streaming - request is sent as SSE stream and reconstructed back to the Anthropic JSON response format.

Factory parameters (transportMode, streamingPerChunkTimeoutSeconds) define application-level defaults. Per-request parameters have higher priority and can override these defaults:

  • ai_integration-transport_mode (non_streaming or streaming)
  • ai_integration-streaming_per_chunk_timeout_seconds (positive integer, only for effective streaming mode)

Example request-level override:

$request = new ToolCallingChatSpiRequest(
    model: 'claude-sonnet-4-20250514',
    messages: $messages,
    tools: $tools,
    parameters: [
        'ai_integration-transport_mode' => 'streaming',
        'ai_integration-streaming_per_chunk_timeout_seconds' => 45,
    ],
);

ToolCallingContext::$timeoutSeconds keeps the same SPI meaning in both modes: it is the total request timeout. In streaming mode, idle timeout between chunks is configured separately via ai_integration-streaming_per_chunk_timeout_seconds (or factory default).

Streaming mode requires allow_url_fopen=1. If it is disabled, the adapter throws a fail-fast SpiException with guidance to enable allow_url_fopen or switch to non_streaming.

With default non_streaming, long-running generations may again be exposed to idle connection drops in some environments. When this matters, enable streaming explicitly per request.

Anthropic cache configuration

This package exposes explicit cache configuration via ToolCallingChatSpiRequest::$parameters. All cache-related keys are prefixed with ai_integration-.

Supported cache sections:

  • ai_integration-cache_system – cache for the system prompt (off, 5min, 1hour).
  • ai_integration-cache_tools – cache for tool definitions (off, 5min, 1hour).
  • ai_integration-cache_messages – cache for conversation messages (off, 5min, 1hour).
  • ai_integration-cache_automatic – Anthropic automatic cache mode (off, 5min, 1hour).

When ai_integration-cache_messages is enabled (5min or 1hour), you can select strategy with:

  • ai_integration-cache_messages_strategy – supported strategies:
    • off
    • first_user
    • last_user
    • threshold_tokens

Additional parameters for threshold_tokens strategy:

  • ai_integration-cache_messages_threshold_tokens – positive integer threshold (default 5000).
  • ai_integration-cache_messages_last_cached_message_id – optional last cached user message identifier.

The cache layer is opt-in and non-intrusive: if you do not provide any ai_integration-* keys, cache behaviour is disabled.

ai_integration-cache_automatic is mutually exclusive with explicit cache TTL keys (cache_system, cache_tools, cache_messages). If both modes are enabled, configuration validation fails before request execution.

Response metadata

Cache-aware responses may include these metadata keys:

  • raw_response
  • raw_usage
  • cache_breakpoint_message_id

Billing token counters are exposed through tokenUsage->details, not response metadata.

Token usage details

tokenUsage->details contains every numeric field from Anthropic's usage object, recursively flattened with _ (up to three nested levels). Known cache fields include:

Detail keyMeaning
cache_creation_input_tokensAggregate input tokens written to cache
cache_read_input_tokensInput tokens read from cache
cache_creation_ephemeral_5m_input_tokensInput tokens written with a five-minute TTL
cache_creation_ephemeral_1h_input_tokensInput tokens written with a one-hour TTL

The set of detail keys is open: new numeric fields returned by Anthropic are exposed automatically. totalTokens includes base input tokens, cache-write tokens, cache-read tokens and output tokens because these input categories are mutually exclusive in the Anthropic API.

Request cost

The Anthropic usage mapping can be passed to the optional cost bridge and registered on the facade:

use AdachSoft\AiIntegration\PublicApi\Builder\ToolCallingChatFacadeBuilder;
use AdachSoft\AiIntegrationCost\PublicApi\Factory\SpiCostCalculatorFactory;
use AdachSoft\AiIntegrationCost\PublicApi\Vo\UsageKindMapVo;
use AdachSoft\AiIntegrationAnthropic\Cost\AnthropicUsageKindMap;

$costCalculator = SpiCostCalculatorFactory::create(
    $pricingProvider,
    new UsageKindMapVo(
        AnthropicUsageKindMap::mappings(),
        AnthropicUsageKindMap::ignoredDetailKeys(),
    ),
);

$facade = ToolCallingChatFacadeBuilder::create()
    ->withSpiProvider('anthropic', $anthropicProvider)
    ->withCostCalculator($costCalculator)
    ->build();
$response = $facade->chat($request);
$cost = $response->cost;

When cost->details['is_complete'] is false, the amount is understated. A non-empty unknown_usage_keys list identifies a billing item that is not covered by the usage mapping.

For full details (TTL semantics, beta headers, strategy behaviour and payload rules), see:

  • docs/CACHE_STRATEGIES.md
  • docs/architecture.md

Tests

The default phpunit.xml configuration defines two test suites:

  • unit – standard tests.
  • production – production/integration tests that require external credentials.

Example commands:

# All tests
vendor/bin/phpunit

# Unit tests only
vendor/bin/phpunit --testsuite unit

# Production tests only
ANTHROPIC_KEY=... vendor/bin/phpunit --testsuite production