@kindgi/adapter-model-anthropic
npm install @kindgi/adapter-model-anthropic · source
Anthropic ModelProvider for @kindgi/capabilities. Wraps the official @anthropic-ai/sdk client behind the framework's provider-neutral interface and calls the Anthropic Messages API. One provider exposes every model listed in its metadata.models[]; ModelCallInput.model picks the model per call.
Purpose
Section titled “Purpose”Translate between the framework's ModelCallInput / ModelCallResult and a non-streaming messages.create call:
systemmessages are lifted into the top-levelsystemparameter (several are joined with a blank line).toolmessages becometool_resultblocks folded into user turns, and assistanttoolCallsbecometool_useblocks.- Tool names are encoded
.→__on send and decoded on receive, because the Messages API rejects dots in tool names (acme.orders.lookup↔acme__orders__lookup). Tool ids must not contain a literal__. max_tokensis always sent, since Anthropic requires it:input.maxOutputTokens, else the model'sModelInfo.maxOutputTokens, else4096.temperatureis sent when set, andabortSignalis passed to the request.stop_reasonmapsend_turn/stop_sequence/pause_turn→stop,max_tokens→length,tool_use→tool-use,refusal→content-filter, anything else →stop.- Cost accounting that includes prompt caching. Anthropic reports four counters (
input_tokens,output_tokens,cache_creation_input_tokens,cache_read_input_tokens), andcostUsdbills each at its own rate:(input × rate + cacheCreation × rate × creationMultiplier + cacheRead × rate × readMultiplier + output × outputRate) / 1000. The multiplier defaults match the 5-minute cache tier (creation1.25, read0.1); setpromptCacheCreationMultiplier: 2in a model'scostfor the 1-hour tier.usage.promptTokensincludes cache writes and reads;usage.cachedTokensreports the cache reads when there are any.
Exports
Section titled “Exports”createAnthropicProvider(options)— returns aModelProviderwhosemetadataisoptions.metadata.invoke()throws wheninput.modelis not one ofmetadata.models[].name.AnthropicProviderOptions:apiKey: string | (() => string | Promise<string>)— a static key, or a resolver called on everyinvoke(). The SDK client is cached and rebuilt only when the resolved key changes, so a rotated secret takes effect on the next call. A per-tenant registry can register one provider per tenant whose resolver reads that tenant's secret.metadata—ProviderMetadatawhosemodels[]areAnthropicModelInfo. Caller-supplied, because the API does not report pricing, context windows or features.baseURL?— override the API host (proxy, gateway, region routing).clientOptions?— other@anthropic-ai/sdkclient options (timeout,maxRetries,defaultHeaders,fetch, …);apiKeyandbaseURLare excluded.client?— an injected SDK client, used as-is;apiKey,baseURLandclientOptionsare then ignored. Useful in tests.
AnthropicModelInfo—ModelInfowhosecostalso acceptspromptCacheCreationMultiplier?andpromptCacheReadMultiplier?.- Cost helpers —
computeCostUsd(usage, rates),toFrameworkUsage(usage),CostRates,DEFAULT_CACHE_CREATION_MULTIPLIER_5MIN(1.25),DEFAULT_CACHE_READ_MULTIPLIER(0.1). - Translation helpers —
toAnthropicMessages(messages),toAnthropicTools(tools),fromAnthropicResponse(response),mapStopReason(reason). ModelProvider— type re-export from@kindgi/capabilities.
Example
Section titled “Example”import { createProviderRegistry } from '@kindgi/capabilities';import { createAnthropicProvider } from '@kindgi/adapter-model-anthropic';
const anthropic = createAnthropicProvider({ // Resolved on every call; `readTenantSecret` stands for your secret store lookup. apiKey: () => readTenantSecret(tenantId, 'anthropic-api-key'), metadata: { id: 'anthropic', region: 'us-east-1', models: [ { name: 'claude-opus-4-7', contextWindow: 200_000, features: ['tool-use'], maxOutputTokens: 8_192, // Rates from the provider's published pricing; cache multipliers default to the 5-minute tier. cost: { promptUsdPer1kTokens: 0.005, completionUsdPer1kTokens: 0.025 }, }, ], },});
const { registry } = createProviderRegistry();registry.register(tenantId, anthropic);
const result = await anthropic.invoke({ model: 'claude-opus-4-7', messages: [ { role: 'system', content: 'You are the acme support assistant.' }, { role: 'user', content: 'Summarise order 1042 in one sentence.' }, ], maxOutputTokens: 256,});console.log(result.message.content, result.usage, result.costUsd);A single-key deployment passes apiKey: process.env.ANTHROPIC_API_KEY (checked for undefined first) instead of a resolver.
Non-goals
Section titled “Non-goals”- Streaming.
invoke()resolves with the complete response; streaming would need a differentModelProviderinterface. - Extended thinking.
ModelMessagehas no thinking field;thinkingblocks in responses are dropped. - Image inputs.
ModelMessagecontent is text only. - Structured output.
structuredOutputonModelCallInputis ignored. - Retry logic in the adapter. Retries and timeouts are the SDK client's (
clientOptions.maxRetries,clientOptions.timeout).
Related
Section titled “Related”@kindgi/capabilities—ModelProvider,ProviderMetadata, and the provider registry.@kindgi/adapter-model-openai-compat— the same interface for OpenAI-compatible endpoints.@kindgi/adapter-model-in-process— local models inside the Node.js process.