cadrumo.adapters.outbound.llm.providers.anthropic module

Anthropic Messages API adapter for the LLM outbound port.

Implements the ProviderAdapter contract by translating a normalized ProviderRequest into an anthropic.AsyncAnthropic messages.create call and converting the response (or any provider error) into the substrate’s typed completion / error envelope. Network I/O is async; all SDK exceptions are mapped to LLMProviderError, LLMRateLimitError, or LLMConfigError.

build_user_content(request)[source]

Render one request’s user turn as the Messages API expects it.

A text-only request keeps the bare-string content the API has always accepted. A multimodal request becomes a content-block list: one base64 image block per input, each declaring the media type its producer stamped, followed by a single text block carrying the prompt.

Images come BEFORE the text deliberately – that is the ordering Anthropic documents for best results, and it reads correctly too: the question is asked about documents the model has already been shown.

Split out from AnthropicAdapter.complete() so the shape can be asserted without an API key, a network call, or the optional SDK – the payload is the whole contract here, and a shape defect is invisible in a mocked response.

Parameters:

request (ProviderRequest) – Normalized provider request.

Return type:

str | list[ImageBlockParam | TextBlockParam]

Returns:

The prompt string when the request carries no images; otherwise the image-then-text content-block list.

build_message_kwargs(request)[source]

Build the exact keyword arguments sent to messages.create.

Extracted for the same reason build_user_content() was: the wire shape becomes assertable without an API key, a network call, or a stubbed SDK. A parameter’s ABSENCE cannot be tested while the payload exists only as inlined keyword arguments at the call site, and absence is exactly the claim that matters – a defaulted parameter and an omitted one are different requests, and the newer models reject the first.

Absence is expressed by not adding the key at all, never by passing None: the SDK forwards an explicit None as a JSON null, which is a stated value and draws the same rejection the number would.

Also collapses the system/no-system branch this call site used to duplicate. That duplication is why temperature appeared twice, and why changing it once would have left the other path sending it.

Return type:

_MessageCreateKwargs

Parameters:

request (ProviderRequest)

class AnthropicAdapter(api_key, timeout_s)[source]

Bases: ProviderAdapter

Provider adapter that talks to Anthropic’s Messages API.

Holds a bound anthropic.AsyncAnthropic client configured with the operator’s API key and a per-call timeout. The provider class attribute identifies this adapter to LLMClient, which builds it behind the optional-SDK import boundary – not to the sibling adapters.outbound.llm package, which since the split owns the persistence-backed stores and constructs no adapter.

Variables:

provider – The LLMProvider tag selecting this adapter.

Parameters:
  • api_key (str)

  • timeout_s (int)

provider: LLMProvider
supports_images: bool
async complete(request)[source]

Execute a completion request against Anthropic and normalize the result.

Issues a messages.create call (with or without a system prompt), concatenates every anthropic.types.TextBlock in the response, and returns a ProviderCompletion. SDK errors are mapped to the substrate’s typed exception hierarchy.

Parameters:

request (ProviderRequest) – Normalized provider request carrying the model id, prompt, optional system prompt, sampling parameters, and a request-id used as Anthropic metadata.user_id.

Return type:

ProviderCompletion

Returns:

A ProviderCompletion with the joined text, model id echoed by the server, token usage, and the provider’s request id.

Raises:
  • LLMTransientTransportError – On connection and timeout failures, and on 5xx API status codes – the retryable half of the boundary, classified here exactly as the httpx adapters classify the same two conditions, so the retry decision does not depend on which vendor happened to be configured.

  • LLMProviderError – On authentication failures, bad requests, and other non-2xx API status codes.