@kindgi/adapter-model-anthropic 0.1.4-rc.5 → 0.1.5-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -6,16 +6,23 @@ Anthropic `ModelProvider` for [`@kindgi/capabilities`](../../capabilities/). Wra
6
6
 
7
7
  Translate between the framework's `ModelCallInput` / `ModelCallResult` and a non-streaming `messages.create` call:
8
8
 
9
- - `system` messages are lifted into the top-level `system` parameter (several are joined with a blank line). `tool` messages become `tool_result` blocks folded into user turns, and assistant `toolCalls` become `tool_use` blocks.
9
+ - `system` messages are lifted into the top-level `system` parameter, each its own text block, in order. `tool` messages become `tool_result` blocks folded into user turns, and assistant `toolCalls` become `tool_use` blocks.
10
10
  - 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 `__`.
11
11
  - `max_tokens` is always sent, since Anthropic requires it: `input.maxOutputTokens`, else the model's `ModelInfo.maxOutputTokens`, else `4096`. `temperature` is sent when set, and `abortSignal` is passed to the request.
12
12
  - `stop_reason` maps `end_turn` / `stop_sequence` / `pause_turn` → `stop`, `max_tokens` → `length`, `tool_use` → `tool-use`, `refusal` → `content-filter`, anything else → `stop`.
13
13
  - Cost accounting that includes prompt caching. Anthropic reports four counters (`input_tokens`, `output_tokens`, `cache_creation_input_tokens`, `cache_read_input_tokens`), and `costUsd` bills each at its own rate:
14
14
  `(input × rate + cacheCreation × rate × creationMultiplier + cacheRead × rate × readMultiplier + output × outputRate) / 1000`.
15
- The multiplier defaults match the 5-minute cache tier (creation `1.25`, read `0.1`); set `promptCacheCreationMultiplier: 2` in a model's `cost` for the 1-hour tier. `usage.promptTokens` includes cache writes and reads; `usage.cachedTokens` reports the cache reads when there are any.
15
+ The multiplier defaults match the 5-minute cache tier (creation `1.25`, read `0.1`). Claude Opus 5.5 and Sonnet 5.5 read at `0.05`: set `promptCacheReadMultiplier: 0.05` in their `cost` (the `anthropic` preset does). `usage.promptTokens` includes cache writes and reads; `usage.cacheReadTokens` and `usage.cacheWriteTokens` report them.
16
+ - **Prompt caching.** Anthropic caches only the prefixes a request marks with `cache_control`, so the adapter marks up to three (`withPromptCache`), each with the 5-minute cache:
17
+ - the last tool (the tool definitions);
18
+ - the first system block (the agent's prompt; later system blocks, such as retrieved context, change from turn to turn);
19
+ - the last block of the last message, when another call will send this prefix again: the call has tools (the next step of a tool loop) or the conversation has an earlier answer (its next turn). A one-off call (no tools, no earlier answer, e.g. a judge) leaves its message unmarked: writing a tail that's never read again would only cost more.
20
+
21
+ The next call in a turn then reads the prefix at the read rate and writes only what's new. A prefix shorter than the model's minimum (from 512 tokens on the Claude 5.5 models) isn't cached and costs nothing extra. How Anthropic keeps cached prompts, and their eligibility for zero data retention: Anthropic's [prompt caching](https://platform.claude.com/docs/en/build-with-claude/prompt-caching) and [API and data retention](https://platform.claude.com/docs/en/manage-claude/api-and-data-retention) pages.
16
22
 
17
23
  ## Exports
18
24
 
25
+ - **`anthropicAdapterEntry`** (`ANTHROPIC_ADAPTER_ID`) — the `AdapterFactoryEntry` a runtime registers. **`anthropicAdapterFactory`** builds the provider from a registration whose `secret_ref` names its Anthropic API key (resolved on every call); without one it throws, and **`anthropicCheckConfig(input)`** reports the same problem (`secret_ref`) without building anything.
19
26
  - **`createAnthropicProvider(options)`** — returns a `ModelProvider` whose `metadata` is `options.metadata`. `invoke()` throws when `input.model` is not one of `metadata.models[].name`.
20
27
  - **`AnthropicProviderOptions`**:
21
28
  - `apiKey: string | (() => string | Promise<string>)` — a static key, or a resolver called on every `invoke()`. 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.
@@ -74,7 +81,7 @@ A single-key deployment passes `apiKey: process.env.ANTHROPIC_API_KEY` (checked
74
81
  - **Streaming.** `invoke()` resolves with the complete response; streaming would need a different `ModelProvider` interface.
75
82
  - **Extended thinking.** `ModelMessage` has no thinking field; `thinking` blocks in responses are dropped.
76
83
  - **Image inputs.** `ModelMessage` content is text only.
77
- - **Structured output.** `structuredOutput` on `ModelCallInput` is ignored.
84
+ - **Structured output.** `structuredOutput` on `ModelCallInput` is ignored. No Kindgi caller sends it today: an agent's typed output is checked by parse and repair on every provider, so the anthropic preset's models still declare `structured-output` (they can follow a JSON schema natively).
78
85
  - **Retry logic in the adapter.** Retries and timeouts are the SDK client's (`clientOptions.maxRetries`, `clientOptions.timeout`).
79
86
 
80
87
  ## Related
@@ -0,0 +1,42 @@
1
+ import type Anthropic from '@anthropic-ai/sdk';
2
+ /**
3
+ * Prompt caching. Anthropic caches only the prompt prefixes a request
4
+ * marks with `cache_control`, and a later request that starts with the
5
+ * same bytes reads them at a fraction of the input price (0.1x; 0.05x on
6
+ * Claude Opus 5.5 and Sonnet 5.5). A marked prefix costs 1.25x the first
7
+ * time it's written. The prompt renders in the order tools, system,
8
+ * messages, and the adapter marks up to three breakpoints:
9
+ *
10
+ * - the last tool: the tool definitions, the same for every call an
11
+ * agent makes;
12
+ * - the first system block: the agent's own prompt. Later system blocks
13
+ * (retrieved context) change from turn to turn, so they stay after it;
14
+ * - the last block of the last message, when another call will re-send
15
+ * this prefix: a call with tools (the next step of a tool loop sends
16
+ * everything again plus the results) or a conversation with an earlier
17
+ * answer (its next turn does). A one-off call (no tools, no earlier
18
+ * answer, e.g. a judge) leaves its message unmarked: its tail is never
19
+ * sent again, so a write would only cost more.
20
+ *
21
+ * Each breakpoint uses the 5-minute cache (the default `ephemeral` TTL);
22
+ * the steps of an agent turn are seconds apart. A prefix shorter than the
23
+ * model's minimum (512 to 4,096 tokens) isn't cached and costs nothing
24
+ * extra. How Anthropic keeps cached prompts, and their eligibility for
25
+ * zero data retention: https://platform.claude.com/docs/en/build-with-claude/prompt-caching
26
+ * and https://platform.claude.com/docs/en/manage-claude/api-and-data-retention.
27
+ */
28
+ export declare const PROMPT_CACHE: Anthropic.CacheControlEphemeral;
29
+ export interface CacheableRequest {
30
+ /** The call's system messages, in order, each its own block. */
31
+ readonly systemParts: readonly string[];
32
+ readonly tools: readonly Anthropic.Tool[] | undefined;
33
+ readonly messages: readonly Anthropic.MessageParam[];
34
+ }
35
+ export interface CachedRequest {
36
+ readonly system: Anthropic.TextBlockParam[] | undefined;
37
+ readonly tools: Anthropic.Tool[] | undefined;
38
+ readonly messages: Anthropic.MessageParam[];
39
+ }
40
+ /** The request's parts, with the cache breakpoints above. The inputs aren't changed. */
41
+ export declare function withPromptCache(request: CacheableRequest): CachedRequest;
42
+ //# sourceMappingURL=cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,SAAS,MAAM,mBAAmB,CAAC;AAE/C;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,YAAY,EAAE,SAAS,CAAC,qBAA6C,CAAC;AAEnF,MAAM,WAAW,gBAAgB;IAC/B,gEAAgE;IAChE,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IACxC,QAAQ,CAAC,KAAK,EAAE,SAAS,SAAS,CAAC,IAAI,EAAE,GAAG,SAAS,CAAC;IACtD,QAAQ,CAAC,QAAQ,EAAE,SAAS,SAAS,CAAC,YAAY,EAAE,CAAC;CACtD;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC,cAAc,EAAE,GAAG,SAAS,CAAC;IACxD,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC,IAAI,EAAE,GAAG,SAAS,CAAC;IAC7C,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC,YAAY,EAAE,CAAC;CAC7C;AAED,wFAAwF;AACxF,wBAAgB,eAAe,CAAC,OAAO,EAAE,gBAAgB,GAAG,aAAa,CAiBxE"}
package/dist/cache.js ADDED
@@ -0,0 +1,67 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // Copyright (C) 2026 Kindgi Inc.
3
+ /**
4
+ * Prompt caching. Anthropic caches only the prompt prefixes a request
5
+ * marks with `cache_control`, and a later request that starts with the
6
+ * same bytes reads them at a fraction of the input price (0.1x; 0.05x on
7
+ * Claude Opus 5.5 and Sonnet 5.5). A marked prefix costs 1.25x the first
8
+ * time it's written. The prompt renders in the order tools, system,
9
+ * messages, and the adapter marks up to three breakpoints:
10
+ *
11
+ * - the last tool: the tool definitions, the same for every call an
12
+ * agent makes;
13
+ * - the first system block: the agent's own prompt. Later system blocks
14
+ * (retrieved context) change from turn to turn, so they stay after it;
15
+ * - the last block of the last message, when another call will re-send
16
+ * this prefix: a call with tools (the next step of a tool loop sends
17
+ * everything again plus the results) or a conversation with an earlier
18
+ * answer (its next turn does). A one-off call (no tools, no earlier
19
+ * answer, e.g. a judge) leaves its message unmarked: its tail is never
20
+ * sent again, so a write would only cost more.
21
+ *
22
+ * Each breakpoint uses the 5-minute cache (the default `ephemeral` TTL);
23
+ * the steps of an agent turn are seconds apart. A prefix shorter than the
24
+ * model's minimum (512 to 4,096 tokens) isn't cached and costs nothing
25
+ * extra. How Anthropic keeps cached prompts, and their eligibility for
26
+ * zero data retention: https://platform.claude.com/docs/en/build-with-claude/prompt-caching
27
+ * and https://platform.claude.com/docs/en/manage-claude/api-and-data-retention.
28
+ */
29
+ export const PROMPT_CACHE = { type: 'ephemeral' };
30
+ /** The request's parts, with the cache breakpoints above. The inputs aren't changed. */
31
+ export function withPromptCache(request) {
32
+ const tools = request.tools === undefined || request.tools.length === 0
33
+ ? undefined
34
+ : request.tools.map((tool, i, all) => i === all.length - 1 ? { ...tool, cache_control: PROMPT_CACHE } : tool);
35
+ const system = request.systemParts.length === 0
36
+ ? undefined
37
+ : request.systemParts.map((text, i) => i === 0 ? { type: 'text', text, cache_control: PROMPT_CACHE } : { type: 'text', text });
38
+ const continues = tools !== undefined || request.messages.some((m) => m.role === 'assistant');
39
+ const messages = continues ? markLastMessage(request.messages) : [...request.messages];
40
+ return { system, tools, messages };
41
+ }
42
+ /**
43
+ * The messages with a breakpoint on the last block of the last one that
44
+ * can carry it: text (not empty), a tool call, a tool result.
45
+ */
46
+ function markLastMessage(messages) {
47
+ const out = [...messages];
48
+ const last = out[out.length - 1];
49
+ if (last === undefined)
50
+ return out;
51
+ const blocks = typeof last.content === 'string' ? [{ type: 'text', text: last.content }] : [...last.content];
52
+ for (let i = blocks.length - 1; i >= 0; i -= 1) {
53
+ const block = blocks[i];
54
+ if (cacheable(block)) {
55
+ blocks[i] = { ...block, cache_control: PROMPT_CACHE };
56
+ out[out.length - 1] = { ...last, content: blocks };
57
+ return out;
58
+ }
59
+ }
60
+ return out;
61
+ }
62
+ function cacheable(block) {
63
+ if (block.type === 'text')
64
+ return block.text.length > 0;
65
+ return block.type === 'tool_use' || block.type === 'tool_result';
66
+ }
67
+ //# sourceMappingURL=cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.js","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"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"}
package/dist/cost.d.ts CHANGED
@@ -21,6 +21,17 @@ export interface CostRates {
21
21
  readonly completionUsdPer1kTokens: number;
22
22
  readonly promptCacheCreationMultiplier?: number;
23
23
  readonly promptCacheReadMultiplier?: number;
24
+ /**
25
+ * Long-context pricing: when a call's prompt (regular, cache-write and
26
+ * cache-read tokens together) exceeds `thresholdTokens`, the whole call
27
+ * bills at these rates, the cache multipliers applying to the long
28
+ * prompt rate. Claude Haiku 5.5 is 5x past a 100,000-token prompt.
29
+ */
30
+ readonly longContext?: {
31
+ readonly thresholdTokens: number;
32
+ readonly promptUsdPer1kTokens: number;
33
+ readonly completionUsdPer1kTokens: number;
34
+ };
24
35
  }
25
36
  /**
26
37
  * Compute the USD cost of a single Anthropic invocation from the
@@ -1 +1 @@
1
- {"version":3,"file":"cost.d.ts","sourceRoot":"","sources":["../src/cost.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,SAAS,MAAM,mBAAmB,CAAC;AAC/C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,sCAAsC,OAAO,CAAC;AAC3D,eAAO,MAAM,6BAA6B,MAAM,CAAC;AAEjD,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,oBAAoB,EAAE,MAAM,CAAC;IACtC,QAAQ,CAAC,wBAAwB,EAAE,MAAM,CAAC;IAC1C,QAAQ,CAAC,6BAA6B,CAAC,EAAE,MAAM,CAAC;IAChD,QAAQ,CAAC,yBAAyB,CAAC,EAAE,MAAM,CAAC;CAC7C;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,GAAG,MAAM,CAoB/E;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,SAAS,CAAC,KAAK,GAAG,aAAa,CAUtE"}
1
+ {"version":3,"file":"cost.d.ts","sourceRoot":"","sources":["../src/cost.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,SAAS,MAAM,mBAAmB,CAAC;AAC/C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,sCAAsC,OAAO,CAAC;AAC3D,eAAO,MAAM,6BAA6B,MAAM,CAAC;AAEjD,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,oBAAoB,EAAE,MAAM,CAAC;IACtC,QAAQ,CAAC,wBAAwB,EAAE,MAAM,CAAC;IAC1C,QAAQ,CAAC,6BAA6B,CAAC,EAAE,MAAM,CAAC;IAChD,QAAQ,CAAC,yBAAyB,CAAC,EAAE,MAAM,CAAC;IAC5C;;;;;OAKG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE;QACrB,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;QACjC,QAAQ,CAAC,oBAAoB,EAAE,MAAM,CAAC;QACtC,QAAQ,CAAC,wBAAwB,EAAE,MAAM,CAAC;KAC3C,CAAC;CACH;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,GAAG,MAAM,CA4B/E;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,SAAS,CAAC,KAAK,GAAG,aAAa,CAUtE"}
package/dist/cost.js CHANGED
@@ -33,8 +33,14 @@ export const DEFAULT_CACHE_READ_MULTIPLIER = 0.1;
33
33
  * rates without double-counting.
34
34
  */
35
35
  export function computeCostUsd(usage, rates) {
36
- const inputRate = rates.promptUsdPer1kTokens;
37
- const outputRate = rates.completionUsdPer1kTokens;
36
+ const promptTokens = usage.input_tokens +
37
+ (usage.cache_creation_input_tokens ?? 0) +
38
+ (usage.cache_read_input_tokens ?? 0);
39
+ const long = rates.longContext !== undefined && promptTokens > rates.longContext.thresholdTokens
40
+ ? rates.longContext
41
+ : undefined;
42
+ const inputRate = long?.promptUsdPer1kTokens ?? rates.promptUsdPer1kTokens;
43
+ const outputRate = long?.completionUsdPer1kTokens ?? rates.completionUsdPer1kTokens;
38
44
  const creationMultiplier = rates.promptCacheCreationMultiplier ?? DEFAULT_CACHE_CREATION_MULTIPLIER_5MIN;
39
45
  const readMultiplier = rates.promptCacheReadMultiplier ?? DEFAULT_CACHE_READ_MULTIPLIER;
40
46
  const inputTokens = usage.input_tokens;
package/dist/cost.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cost.js","sourceRoot":"","sources":["../src/cost.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,iCAAiC;AAKjC;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,sCAAsC,GAAG,IAAI,CAAC;AAC3D,MAAM,CAAC,MAAM,6BAA6B,GAAG,GAAG,CAAC;AASjD;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,cAAc,CAAC,KAAsB,EAAE,KAAgB;IACrE,MAAM,SAAS,GAAG,KAAK,CAAC,oBAAoB,CAAC;IAC7C,MAAM,UAAU,GAAG,KAAK,CAAC,wBAAwB,CAAC;IAClD,MAAM,kBAAkB,GACtB,KAAK,CAAC,6BAA6B,IAAI,sCAAsC,CAAC;IAChF,MAAM,cAAc,GAAG,KAAK,CAAC,yBAAyB,IAAI,6BAA6B,CAAC;IAExF,MAAM,WAAW,GAAG,KAAK,CAAC,YAAY,CAAC;IACvC,MAAM,YAAY,GAAG,KAAK,CAAC,aAAa,CAAC;IACzC,MAAM,aAAa,GAAG,KAAK,CAAC,2BAA2B,IAAI,CAAC,CAAC;IAC7D,MAAM,SAAS,GAAG,KAAK,CAAC,uBAAuB,IAAI,CAAC,CAAC;IAErD,MAAM,SAAS,GACb,CAAC,WAAW,GAAG,SAAS;QACtB,aAAa,GAAG,SAAS,GAAG,kBAAkB;QAC9C,SAAS,GAAG,SAAS,GAAG,cAAc,CAAC;QACzC,IAAI,CAAC;IACP,MAAM,UAAU,GAAG,CAAC,YAAY,GAAG,UAAU,CAAC,GAAG,IAAI,CAAC;IAEtD,OAAO,SAAS,GAAG,UAAU,CAAC;AAChC,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAsB;IACrD,MAAM,UAAU,GAAG,KAAK,CAAC,2BAA2B,CAAC;IACrD,MAAM,SAAS,GAAG,KAAK,CAAC,uBAAuB,CAAC;IAChD,OAAO;QACL,YAAY,EAAE,KAAK,CAAC,YAAY,GAAG,CAAC,UAAU,IAAI,CAAC,CAAC,GAAG,CAAC,SAAS,IAAI,CAAC,CAAC;QACvE,gBAAgB,EAAE,KAAK,CAAC,aAAa;QACrC,iDAAiD;QACjD,GAAG,CAAC,OAAO,SAAS,KAAK,QAAQ,IAAI,EAAE,eAAe,EAAE,SAAS,EAAE,CAAC;QACpE,GAAG,CAAC,OAAO,UAAU,KAAK,QAAQ,IAAI,EAAE,gBAAgB,EAAE,UAAU,EAAE,CAAC;KACxE,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"cost.js","sourceRoot":"","sources":["../src/cost.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,iCAAiC;AAKjC;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,sCAAsC,GAAG,IAAI,CAAC;AAC3D,MAAM,CAAC,MAAM,6BAA6B,GAAG,GAAG,CAAC;AAoBjD;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,cAAc,CAAC,KAAsB,EAAE,KAAgB;IACrE,MAAM,YAAY,GAChB,KAAK,CAAC,YAAY;QAClB,CAAC,KAAK,CAAC,2BAA2B,IAAI,CAAC,CAAC;QACxC,CAAC,KAAK,CAAC,uBAAuB,IAAI,CAAC,CAAC,CAAC;IACvC,MAAM,IAAI,GACR,KAAK,CAAC,WAAW,KAAK,SAAS,IAAI,YAAY,GAAG,KAAK,CAAC,WAAW,CAAC,eAAe;QACjF,CAAC,CAAC,KAAK,CAAC,WAAW;QACnB,CAAC,CAAC,SAAS,CAAC;IAChB,MAAM,SAAS,GAAG,IAAI,EAAE,oBAAoB,IAAI,KAAK,CAAC,oBAAoB,CAAC;IAC3E,MAAM,UAAU,GAAG,IAAI,EAAE,wBAAwB,IAAI,KAAK,CAAC,wBAAwB,CAAC;IACpF,MAAM,kBAAkB,GACtB,KAAK,CAAC,6BAA6B,IAAI,sCAAsC,CAAC;IAChF,MAAM,cAAc,GAAG,KAAK,CAAC,yBAAyB,IAAI,6BAA6B,CAAC;IAExF,MAAM,WAAW,GAAG,KAAK,CAAC,YAAY,CAAC;IACvC,MAAM,YAAY,GAAG,KAAK,CAAC,aAAa,CAAC;IACzC,MAAM,aAAa,GAAG,KAAK,CAAC,2BAA2B,IAAI,CAAC,CAAC;IAC7D,MAAM,SAAS,GAAG,KAAK,CAAC,uBAAuB,IAAI,CAAC,CAAC;IAErD,MAAM,SAAS,GACb,CAAC,WAAW,GAAG,SAAS;QACtB,aAAa,GAAG,SAAS,GAAG,kBAAkB;QAC9C,SAAS,GAAG,SAAS,GAAG,cAAc,CAAC;QACzC,IAAI,CAAC;IACP,MAAM,UAAU,GAAG,CAAC,YAAY,GAAG,UAAU,CAAC,GAAG,IAAI,CAAC;IAEtD,OAAO,SAAS,GAAG,UAAU,CAAC;AAChC,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAsB;IACrD,MAAM,UAAU,GAAG,KAAK,CAAC,2BAA2B,CAAC;IACrD,MAAM,SAAS,GAAG,KAAK,CAAC,uBAAuB,CAAC;IAChD,OAAO;QACL,YAAY,EAAE,KAAK,CAAC,YAAY,GAAG,CAAC,UAAU,IAAI,CAAC,CAAC,GAAG,CAAC,SAAS,IAAI,CAAC,CAAC;QACvE,gBAAgB,EAAE,KAAK,CAAC,aAAa;QACrC,iDAAiD;QACjD,GAAG,CAAC,OAAO,SAAS,KAAK,QAAQ,IAAI,EAAE,eAAe,EAAE,SAAS,EAAE,CAAC;QACpE,GAAG,CAAC,OAAO,UAAU,KAAK,QAAQ,IAAI,EAAE,gBAAgB,EAAE,UAAU,EAAE,CAAC;KACxE,CAAC;AACJ,CAAC"}
@@ -0,0 +1,18 @@
1
+ import { type AdapterConfigCheckInput, type AdapterConfigProblem, type AdapterFactory, type AdapterFactoryEntry } from '@kindgi/capabilities';
2
+ /** The id the runtime registers this adapter under. */
3
+ export declare const ANTHROPIC_ADAPTER_ID = "@kindgi/adapter-model-anthropic";
4
+ /**
5
+ * The runtime's factory. A provider registered with it names its Anthropic
6
+ * API key in `secret_ref`, resolved on every call, so a rotated key takes
7
+ * effect on the next one.
8
+ */
9
+ export declare const anthropicAdapterFactory: AdapterFactory;
10
+ /**
11
+ * What's wrong with a registration for this adapter, read without building
12
+ * it (`AdapterFactoryEntry.checkConfig`): it needs a `secret_ref`. The
13
+ * problem's message is the error the factory throws for it.
14
+ */
15
+ export declare function anthropicCheckConfig(input: AdapterConfigCheckInput): readonly AdapterConfigProblem[];
16
+ /** The entry a runtime registers: the factory, and its static check. */
17
+ export declare const anthropicAdapterEntry: AdapterFactoryEntry;
18
+ //# sourceMappingURL=entry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entry.d.ts","sourceRoot":"","sources":["../src/entry.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,KAAK,uBAAuB,EAC5B,KAAK,oBAAoB,EACzB,KAAK,cAAc,EACnB,KAAK,mBAAmB,EAEzB,MAAM,sBAAsB,CAAC;AAI9B,uDAAuD;AACvD,eAAO,MAAM,oBAAoB,oCAAoC,CAAC;AAEtE;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,EAAE,cAQrC,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,uBAAuB,GAC7B,SAAS,oBAAoB,EAAE,CAGjC;AAED,wEAAwE;AACxE,eAAO,MAAM,qBAAqB,EAAE,mBAKnC,CAAC"}
package/dist/entry.js ADDED
@@ -0,0 +1,42 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // Copyright (C) 2026 Kindgi Inc.
3
+ import { adapterConfigError, } from '@kindgi/capabilities';
4
+ import { createAnthropicProvider } from './provider.js';
5
+ /** The id the runtime registers this adapter under. */
6
+ export const ANTHROPIC_ADAPTER_ID = '@kindgi/adapter-model-anthropic';
7
+ /**
8
+ * The runtime's factory. A provider registered with it names its Anthropic
9
+ * API key in `secret_ref`, resolved on every call, so a rotated key takes
10
+ * effect on the next one.
11
+ */
12
+ export const anthropicAdapterFactory = (input) => {
13
+ const problem = keyProblem(input.resolveApiKey !== undefined);
14
+ if (problem !== undefined)
15
+ throw adapterConfigError(ANTHROPIC_ADAPTER_ID, input.metadata.id, problem);
16
+ return createAnthropicProvider({
17
+ apiKey: input.resolveApiKey,
18
+ metadata: input.metadata,
19
+ });
20
+ };
21
+ /**
22
+ * What's wrong with a registration for this adapter, read without building
23
+ * it (`AdapterFactoryEntry.checkConfig`): it needs a `secret_ref`. The
24
+ * problem's message is the error the factory throws for it.
25
+ */
26
+ export function anthropicCheckConfig(input) {
27
+ const problem = keyProblem(input.hasSecretRef);
28
+ return problem !== undefined ? [problem] : [];
29
+ }
30
+ /** The entry a runtime registers: the factory, and its static check. */
31
+ export const anthropicAdapterEntry = {
32
+ adapterId: ANTHROPIC_ADAPTER_ID,
33
+ capabilityKind: 'llm-inference',
34
+ factory: anthropicAdapterFactory,
35
+ checkConfig: anthropicCheckConfig,
36
+ };
37
+ function keyProblem(hasSecretRef) {
38
+ if (hasSecretRef)
39
+ return undefined;
40
+ return { path: '/secret_ref', message: 'needs secret_ref: its Anthropic API key.' };
41
+ }
42
+ //# sourceMappingURL=entry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entry.js","sourceRoot":"","sources":["../src/entry.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,iCAAiC;AAEjC,OAAO,EAKL,kBAAkB,GACnB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAExD,uDAAuD;AACvD,MAAM,CAAC,MAAM,oBAAoB,GAAG,iCAAiC,CAAC;AAEtE;;;;GAIG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAmB,CAAC,KAAK,EAAE,EAAE;IAC/D,MAAM,OAAO,GAAG,UAAU,CAAC,KAAK,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC;IAC9D,IAAI,OAAO,KAAK,SAAS;QACvB,MAAM,kBAAkB,CAAC,oBAAoB,EAAE,KAAK,CAAC,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;IAC7E,OAAO,uBAAuB,CAAC;QAC7B,MAAM,EAAE,KAAK,CAAC,aAAsC;QACpD,QAAQ,EAAE,KAAK,CAAC,QAAQ;KACzB,CAAC,CAAC;AACL,CAAC,CAAC;AAEF;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAClC,KAA8B;IAE9B,MAAM,OAAO,GAAG,UAAU,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IAC/C,OAAO,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AAChD,CAAC;AAED,wEAAwE;AACxE,MAAM,CAAC,MAAM,qBAAqB,GAAwB;IACxD,SAAS,EAAE,oBAAoB;IAC/B,cAAc,EAAE,eAAe;IAC/B,OAAO,EAAE,uBAAuB;IAChC,WAAW,EAAE,oBAAoB;CAClC,CAAC;AAEF,SAAS,UAAU,CAAC,YAAqB;IACvC,IAAI,YAAY;QAAE,OAAO,SAAS,CAAC;IACnC,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,0CAA0C,EAAE,CAAC;AACtF,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,7 +1,10 @@
1
1
  export { createAnthropicProvider } from './provider.js';
2
+ export { ANTHROPIC_ADAPTER_ID, anthropicAdapterEntry, anthropicAdapterFactory, anthropicCheckConfig, } from './entry.js';
2
3
  export type { AnthropicModelInfo, AnthropicProviderOptions } from './provider.js';
3
4
  export { DEFAULT_CACHE_CREATION_MULTIPLIER_5MIN, DEFAULT_CACHE_READ_MULTIPLIER, computeCostUsd, toFrameworkUsage, } from './cost.js';
4
5
  export type { CostRates } from './cost.js';
6
+ export { PROMPT_CACHE, withPromptCache } from './cache.js';
7
+ export type { CacheableRequest, CachedRequest } from './cache.js';
5
8
  export { fromAnthropicResponse, mapStopReason, toAnthropicMessages, toAnthropicTools, } from './translate.js';
6
9
  export type { ModelProvider } from '@kindgi/capabilities';
7
10
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AACxD,YAAY,EAAE,kBAAkB,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AAClF,OAAO,EACL,sCAAsC,EACtC,6BAA6B,EAC7B,cAAc,EACd,gBAAgB,GACjB,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EACL,qBAAqB,EACrB,aAAa,EACb,mBAAmB,EACnB,gBAAgB,GACjB,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AACxD,OAAO,EACL,oBAAoB,EACpB,qBAAqB,EACrB,uBAAuB,EACvB,oBAAoB,GACrB,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,kBAAkB,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AAClF,OAAO,EACL,sCAAsC,EACtC,6BAA6B,EAC7B,cAAc,EACd,gBAAgB,GACjB,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC3D,YAAY,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAClE,OAAO,EACL,qBAAqB,EACrB,aAAa,EACb,mBAAmB,EACnB,gBAAgB,GACjB,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC"}
package/dist/index.js CHANGED
@@ -1,6 +1,8 @@
1
1
  // SPDX-License-Identifier: Apache-2.0
2
2
  // Copyright (C) 2026 Kindgi Inc.
3
3
  export { createAnthropicProvider } from './provider.js';
4
+ export { ANTHROPIC_ADAPTER_ID, anthropicAdapterEntry, anthropicAdapterFactory, anthropicCheckConfig, } from './entry.js';
4
5
  export { DEFAULT_CACHE_CREATION_MULTIPLIER_5MIN, DEFAULT_CACHE_READ_MULTIPLIER, computeCostUsd, toFrameworkUsage, } from './cost.js';
6
+ export { PROMPT_CACHE, withPromptCache } from './cache.js';
5
7
  export { fromAnthropicResponse, mapStopReason, toAnthropicMessages, toAnthropicTools, } from './translate.js';
6
8
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,iCAAiC;AAEjC,OAAO,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAExD,OAAO,EACL,sCAAsC,EACtC,6BAA6B,EAC7B,cAAc,EACd,gBAAgB,GACjB,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,qBAAqB,EACrB,aAAa,EACb,mBAAmB,EACnB,gBAAgB,GACjB,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,iCAAiC;AAEjC,OAAO,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AACxD,OAAO,EACL,oBAAoB,EACpB,qBAAqB,EACrB,uBAAuB,EACvB,oBAAoB,GACrB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,sCAAsC,EACtC,6BAA6B,EAC7B,cAAc,EACd,gBAAgB,GACjB,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE3D,OAAO,EACL,qBAAqB,EACrB,aAAa,EACb,mBAAmB,EACnB,gBAAgB,GACjB,MAAM,gBAAgB,CAAC"}
@@ -1,19 +1,18 @@
1
1
  import Anthropic from '@anthropic-ai/sdk';
2
2
  import type { ModelInfo, ModelProvider, ProviderMetadata } from '@kindgi/capabilities';
3
+ import { type CostRates } from './cost.js';
3
4
  /**
4
5
  * Anthropic-specific `ModelInfo` extension. Widens the framework's
5
6
  * `ModelInfo.cost` with the two Anthropic prompt-cache multipliers
6
7
  * (`promptCacheCreationMultiplier`, `promptCacheReadMultiplier`) that
7
- * `computeCostUsd` uses to bill cache activity per invocation.
8
+ * `computeCostUsd` uses to bill cache activity per invocation, and a
9
+ * `longContext` tier for a model that prices long prompts higher.
8
10
  *
9
11
  * When either multiplier is omitted the framework falls back to
10
12
  * Anthropic's 5-minute-tier defaults (1.25 / 0.1) inside `cost.ts`.
11
13
  */
12
14
  export interface AnthropicModelInfo extends ModelInfo {
13
- readonly cost: ModelInfo['cost'] & {
14
- readonly promptCacheCreationMultiplier?: number;
15
- readonly promptCacheReadMultiplier?: number;
16
- };
15
+ readonly cost: ModelInfo['cost'] & Omit<CostRates, keyof ModelInfo['cost']>;
17
16
  }
18
17
  /**
19
18
  * Configuration for the Anthropic `ModelProvider`.
@@ -1 +1 @@
1
- {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"AAGA,OAAO,SAAS,MAAM,mBAAmB,CAAC;AAE1C,OAAO,KAAK,EAGV,SAAS,EACT,aAAa,EACb,gBAAgB,EACjB,MAAM,sBAAsB,CAAC;AAW9B;;;;;;;;GAQG;AACH,MAAM,WAAW,kBAAmB,SAAQ,SAAS;IACnD,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,MAAM,CAAC,GAAG;QACjC,QAAQ,CAAC,6BAA6B,CAAC,EAAE,MAAM,CAAC;QAChD,QAAQ,CAAC,yBAAyB,CAAC,EAAE,MAAM,CAAC;KAC7C,CAAC;CACH;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,CAAC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;IAC3D;;;;;;OAMG;IACH,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC,gBAAgB,EAAE,QAAQ,CAAC,GAAG;QACpD,QAAQ,CAAC,MAAM,EAAE,SAAS,kBAAkB,EAAE,CAAC;KAChD,CAAC;IACF,8DAA8D;IAC9D,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B;;;OAGG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,IAAI,CAC3B,WAAW,CAAC,qBAAqB,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,EACvD,QAAQ,GAAG,SAAS,CACrB,CAAC;IACF;;;;OAIG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC;CAC7B;AASD;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,wBAAwB,GAAG,aAAa,CA0GxF"}
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"AAGA,OAAO,SAAS,MAAM,mBAAmB,CAAC;AAE1C,OAAO,KAAK,EAGV,SAAS,EACT,aAAa,EACb,gBAAgB,EACjB,MAAM,sBAAsB,CAAC;AAM9B,OAAO,EAAE,KAAK,SAAS,EAAoC,MAAM,WAAW,CAAC;AAS7E;;;;;;;;;GASG;AACH,MAAM,WAAW,kBAAmB,SAAQ,SAAS;IACnD,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,SAAS,EAAE,MAAM,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;CAC7E;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,CAAC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;IAC3D;;;;;;OAMG;IACH,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC,gBAAgB,EAAE,QAAQ,CAAC,GAAG;QACpD,QAAQ,CAAC,MAAM,EAAE,SAAS,kBAAkB,EAAE,CAAC;KAChD,CAAC;IACF,8DAA8D;IAC9D,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B;;;OAGG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,IAAI,CAC3B,WAAW,CAAC,qBAAqB,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,EACvD,QAAQ,GAAG,SAAS,CACrB,CAAC;IACF;;;;OAIG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC;CAC7B;AASD;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,wBAAwB,GAAG,aAAa,CA6HxF"}
package/dist/provider.js CHANGED
@@ -1,9 +1,12 @@
1
1
  // SPDX-License-Identifier: Apache-2.0
2
2
  // Copyright (C) 2026 Kindgi Inc.
3
3
  import Anthropic from '@anthropic-ai/sdk';
4
+ import { samplingFor } from '@kindgi/capabilities';
4
5
  import { createAttemptCounter } from '@kindgi/capabilities/attempts';
6
+ import { nameToolsAsSent } from '@kindgi/capabilities/tool-names';
7
+ import { withPromptCache } from './cache.js';
5
8
  import { computeCostUsd, toFrameworkUsage } from './cost.js';
6
- import { fromAnthropicResponse, mapStopReason, toAnthropicMessages, toAnthropicTools, } from './translate.js';
9
+ import { encodeToolName, fromAnthropicResponse, mapStopReason, toAnthropicMessages, toAnthropicTools, } from './translate.js';
7
10
  /**
8
11
  * Adapter-level fallback when neither `ModelCallInput.maxOutputTokens`
9
12
  * nor the picked `ModelInfo.maxOutputTokens` is set. Anthropic requires
@@ -67,19 +70,36 @@ export function createAnthropicProvider(options) {
67
70
  }
68
71
  const startedAt = Date.now();
69
72
  const client = await resolveClient();
70
- const { system, messages } = toAnthropicMessages(input.messages);
71
- const tools = input.tools !== undefined && input.tools.length > 0
72
- ? toAnthropicTools(input.tools)
73
- : undefined;
74
- const requestOptions = input.abortSignal !== undefined ? { signal: input.abortSignal } : {};
73
+ const translated = toAnthropicMessages(input.messages);
74
+ // The system prompt names the call's tools as they're sent (`acme__lookup_order`):
75
+ // a model told to call `acme.lookup_order` calls a name it wasn't given (T311).
76
+ const toolNames = input.tools?.map((t) => t.name) ?? [];
77
+ // Cache breakpoints on the tools, the agent's prompt and, when the call
78
+ // can continue, the conversation so far (`withPromptCache`).
79
+ const { system, tools, messages } = withPromptCache({
80
+ systemParts: translated.systemParts.map((part) => nameToolsAsSent(part, toolNames, encodeToolName)),
81
+ tools: input.tools !== undefined && input.tools.length > 0
82
+ ? toAnthropicTools(input.tools)
83
+ : undefined,
84
+ messages: translated.messages,
85
+ });
86
+ // `traceparent` is a header on this request only, when the caller
87
+ // sets it (the provider's registration opted in); never logged.
88
+ const requestOptions = {
89
+ ...(input.abortSignal !== undefined && { signal: input.abortSignal }),
90
+ ...(input.traceparent !== undefined && { headers: { traceparent: input.traceparent } }),
91
+ };
75
92
  const maxTokens = input.maxOutputTokens ?? modelInfo.maxOutputTokens ?? DEFAULT_MAX_TOKENS;
93
+ const sampling = samplingFor(modelInfo, input);
94
+ const thinking = input.thinking === 'lowest' ? lowestThinking(modelInfo) : {};
76
95
  const counted = await attempts.count(() => client.messages.create({
77
96
  model: input.model,
78
97
  max_tokens: maxTokens,
79
98
  ...(system !== undefined && { system }),
80
- messages: [...messages],
81
- ...(tools !== undefined && { tools: [...tools] }),
82
- ...(input.temperature !== undefined && { temperature: input.temperature }),
99
+ messages,
100
+ ...(tools !== undefined && { tools }),
101
+ ...(sampling.temperature !== undefined && { temperature: sampling.temperature }),
102
+ ...thinking,
83
103
  }, requestOptions));
84
104
  const response = counted.value;
85
105
  const durationMs = Date.now() - startedAt;
@@ -100,8 +120,26 @@ export function createAnthropicProvider(options) {
100
120
  // An injected client sends with its own fetch: nothing was counted.
101
121
  ...(counted.attempts > 0 && { attempts: counted.attempts }),
102
122
  rawUsage: { ...response.usage },
123
+ ...(sampling.warnings.length > 0 && { warnings: sampling.warnings }),
103
124
  };
104
125
  },
105
126
  };
106
127
  }
128
+ /**
129
+ * The request fields for a model's least thinking (`ModelCallInput.thinking:
130
+ * 'lowest'`). A thinking type that turns it off (Haiku 5.5's `disabled`,
131
+ * Sonnet 5.5's `between_tools`) is taken only at effort `high` or below,
132
+ * so it goes with effort `low`; a model that always thinks (Opus 5.5) gets
133
+ * the effort alone. The SDK's types predate both fields; the API takes them
134
+ * as sent.
135
+ */
136
+ function lowestThinking(model) {
137
+ const lowest = model.thinking?.lowest;
138
+ if (lowest === undefined)
139
+ return {};
140
+ if (lowest === 'disabled' || lowest === 'between_tools') {
141
+ return { thinking: { type: lowest }, output_config: { effort: 'low' } };
142
+ }
143
+ return { output_config: { effort: lowest } };
144
+ }
107
145
  //# sourceMappingURL=provider.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"provider.js","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"provider.js","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"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"}
@@ -31,9 +31,14 @@ export declare function decodeToolName(name: string): string;
31
31
  * merge into a single user message (matching the framework's
32
32
  * dispatch-tools handler which appends one tool message per call
33
33
  * after an assistant `tool_use` turn).
34
+ *
35
+ * `systemParts` keeps the system messages apart, in order, so each can be
36
+ * its own block: the first (the agent's prompt) is the stable one a cache
37
+ * breakpoint goes on (`withPromptCache`).
34
38
  */
35
39
  export declare function toAnthropicMessages(messages: readonly ModelMessage[]): {
36
40
  readonly system: string | undefined;
41
+ readonly systemParts: readonly string[];
37
42
  readonly messages: readonly Anthropic.MessageParam[];
38
43
  };
39
44
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"translate.d.ts","sourceRoot":"","sources":["../src/translate.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,SAAS,MAAM,mBAAmB,CAAC;AAE/C,OAAO,KAAK,EACV,eAAe,EACf,YAAY,EAEZ,mBAAmB,EACpB,MAAM,sBAAsB,CAAC;AAE9B;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,SAAS,YAAY,EAAE,GAAG;IACtE,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,QAAQ,CAAC,QAAQ,EAAE,SAAS,SAAS,CAAC,YAAY,EAAE,CAAC;CACtD,CAmDA;AAsBD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,SAAS,mBAAmB,EAAE,GAAG,SAAS,SAAS,CAAC,IAAI,EAAE,CAMjG;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,SAAS,CAAC,OAAO,GAAG,YAAY,CAyB/E;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,SAAS,CAAC,OAAO,CAAC,aAAa,CAAC,GACvC,eAAe,CAAC,cAAc,CAAC,CAejC"}
1
+ {"version":3,"file":"translate.d.ts","sourceRoot":"","sources":["../src/translate.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,SAAS,MAAM,mBAAmB,CAAC;AAE/C,OAAO,KAAK,EACV,eAAe,EACf,YAAY,EAEZ,mBAAmB,EACpB,MAAM,sBAAsB,CAAC;AAE9B;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,SAAS,YAAY,EAAE,GAAG;IACtE,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IACxC,QAAQ,CAAC,QAAQ,EAAE,SAAS,SAAS,CAAC,YAAY,EAAE,CAAC;CACtD,CAoDA;AAsBD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,SAAS,mBAAmB,EAAE,GAAG,SAAS,SAAS,CAAC,IAAI,EAAE,CAMjG;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,SAAS,CAAC,OAAO,GAAG,YAAY,CAyB/E;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,SAAS,CAAC,OAAO,CAAC,aAAa,CAAC,GACvC,eAAe,CAAC,cAAc,CAAC,CAejC"}
package/dist/translate.js CHANGED
@@ -35,6 +35,10 @@ export function decodeToolName(name) {
35
35
  * merge into a single user message (matching the framework's
36
36
  * dispatch-tools handler which appends one tool message per call
37
37
  * after an assistant `tool_use` turn).
38
+ *
39
+ * `systemParts` keeps the system messages apart, in order, so each can be
40
+ * its own block: the first (the agent's prompt) is the stable one a cache
41
+ * breakpoint goes on (`withPromptCache`).
38
42
  */
39
43
  export function toAnthropicMessages(messages) {
40
44
  const systemParts = [];
@@ -85,6 +89,7 @@ export function toAnthropicMessages(messages) {
85
89
  }
86
90
  return {
87
91
  system: systemParts.length > 0 ? systemParts.join('\n\n') : undefined,
92
+ systemParts,
88
93
  messages: out,
89
94
  };
90
95
  }
@@ -1 +1 @@
1
- {"version":3,"file":"translate.js","sourceRoot":"","sources":["../src/translate.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"translate.js","sourceRoot":"","sources":["../src/translate.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,iCAAiC;AAWjC;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;AACnC,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;AAClC,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,mBAAmB,CAAC,QAAiC;IAKnE,MAAM,WAAW,GAAa,EAAE,CAAC;IACjC,MAAM,GAAG,GAA6B,EAAE,CAAC;IAEzC,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC3B,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC1B,IAAI,GAAG,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC;gBAAE,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YAC1D,SAAS;QACX,CAAC;QACD,IAAI,GAAG,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YACxB,gBAAgB,CAAC,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;YAC7D,SAAS;QACX,CAAC;QACD,IAAI,GAAG,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YAC7B,MAAM,MAAM,GAAkC,EAAE,CAAC;YACjD,IAAI,GAAG,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC;gBAAE,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;YAC7E,IAAI,GAAG,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;gBAChC,KAAK,MAAM,EAAE,IAAI,GAAG,CAAC,SAAS,EAAE,CAAC;oBAC/B,MAAM,CAAC,IAAI,CAAC;wBACV,IAAI,EAAE,UAAU;wBAChB,EAAE,EAAE,EAAE,CAAC,EAAE;wBACT,oDAAoD;wBACpD,sDAAsD;wBACtD,gDAAgD;wBAChD,IAAI,EAAE,cAAc,CAAC,EAAE,CAAC,IAAI,CAAC;wBAC7B,KAAK,EAAE,EAAE,CAAC,SAAS;qBACpB,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;YACD,8DAA8D;YAC9D,uDAAuD;YACvD,4DAA4D;YAC5D,qDAAqD;YACrD,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACtB,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;YACnD,CAAC;YACD,SAAS;QACX,CAAC;QACD,kBAAkB;QAClB,MAAM,UAAU,GAAmC;YACjD,IAAI,EAAE,aAAa;YACnB,WAAW,EAAE,GAAG,CAAC,UAAU,IAAI,EAAE;YACjC,OAAO,EAAE,GAAG,CAAC,OAAO;SACrB,CAAC;QACF,gBAAgB,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;IACtC,CAAC;IAED,OAAO;QACL,MAAM,EAAE,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS;QACrE,WAAW;QACX,QAAQ,EAAE,GAAG;KACd,CAAC;AACJ,CAAC;AAED,SAAS,gBAAgB,CACvB,GAA6B,EAC7B,MAA8C;IAE9C,MAAM,IAAI,GAAG,GAAG,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACjC,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QAC/C,MAAM,QAAQ,GAAG,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAChD,IAAI,CAAC,OAAO,GAAG,CAAC,GAAG,QAAQ,EAAE,GAAG,MAAM,CAAC,CAAC;QACxC,OAAO;IACT,CAAC;IACD,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC;AACnD,CAAC;AAED,SAAS,gBAAgB,CACvB,OAA0C;IAE1C,IAAI,OAAO,OAAO,KAAK,QAAQ;QAAE,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;IAC1E,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC;AACtB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAqC;IACpE,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACvB,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC;QAC5B,WAAW,EAAE,CAAC,CAAC,WAAW;QAC1B,YAAY,EAAE,CAAC,CAAC,WAAyC;KAC1D,CAAC,CAAC,CAAC;AACN,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CAAC,QAA2B;IAC/D,MAAM,SAAS,GAAa,EAAE,CAAC;IAC/B,MAAM,SAAS,GAAoB,EAAE,CAAC;IAEtC,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;QACrC,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAC1B,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC7B,CAAC;aAAM,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YACrC,SAAS,CAAC,IAAI,CAAC;gBACb,EAAE,EAAE,KAAK,CAAC,EAAE;gBACZ,oEAAoE;gBACpE,+DAA+D;gBAC/D,IAAI,EAAE,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC;gBAChC,SAAS,EAAE,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,CAAsC;aACpE,CAAC,CAAC;QACL,CAAC;QACD,mEAAmE;IACrE,CAAC;IAED,MAAM,OAAO,GAAiB;QAC5B,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3B,GAAG,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,SAAS,EAAE,CAAC;KAC3C,CAAC;IACF,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,aAAa,CAC3B,MAAwC;IAExC,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,UAAU,CAAC;QAChB,KAAK,eAAe,CAAC;QACrB,KAAK,YAAY;YACf,OAAO,MAAM,CAAC;QAChB,KAAK,YAAY;YACf,OAAO,QAAQ,CAAC;QAClB,KAAK,UAAU;YACb,OAAO,UAAU,CAAC;QACpB,KAAK,SAAS;YACZ,OAAO,gBAAgB,CAAC;QAC1B;YACE,OAAO,MAAM,CAAC;IAClB,CAAC;AACH,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kindgi/adapter-model-anthropic",
3
- "version": "0.1.4-rc.5",
3
+ "version": "0.1.5-rc.0",
4
4
  "description": "Anthropic ModelProvider for @kindgi/capabilities. Wraps @anthropic-ai/sdk with the framework's provider-neutral interface: message-trail ↔ Messages API translation, prompt-caching-aware cost accounting, and lazy API-key resolution so per-tenant registries can close over a SecretStore scope. Non-streaming, tool-use enabled. Wire per-tenant in the provider registry (see @kindgi/capabilities).",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -28,7 +28,7 @@
28
28
  "README.md"
29
29
  ],
30
30
  "dependencies": {
31
- "@kindgi/capabilities": "0.1.4-rc.5",
31
+ "@kindgi/capabilities": "0.1.5-rc.0",
32
32
  "@anthropic-ai/sdk": "^0.68.0"
33
33
  },
34
34
  "engines": {
package/src/cache.ts ADDED
@@ -0,0 +1,96 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // Copyright (C) 2026 Kindgi Inc.
3
+
4
+ import type Anthropic from '@anthropic-ai/sdk';
5
+
6
+ /**
7
+ * Prompt caching. Anthropic caches only the prompt prefixes a request
8
+ * marks with `cache_control`, and a later request that starts with the
9
+ * same bytes reads them at a fraction of the input price (0.1x; 0.05x on
10
+ * Claude Opus 5.5 and Sonnet 5.5). A marked prefix costs 1.25x the first
11
+ * time it's written. The prompt renders in the order tools, system,
12
+ * messages, and the adapter marks up to three breakpoints:
13
+ *
14
+ * - the last tool: the tool definitions, the same for every call an
15
+ * agent makes;
16
+ * - the first system block: the agent's own prompt. Later system blocks
17
+ * (retrieved context) change from turn to turn, so they stay after it;
18
+ * - the last block of the last message, when another call will re-send
19
+ * this prefix: a call with tools (the next step of a tool loop sends
20
+ * everything again plus the results) or a conversation with an earlier
21
+ * answer (its next turn does). A one-off call (no tools, no earlier
22
+ * answer, e.g. a judge) leaves its message unmarked: its tail is never
23
+ * sent again, so a write would only cost more.
24
+ *
25
+ * Each breakpoint uses the 5-minute cache (the default `ephemeral` TTL);
26
+ * the steps of an agent turn are seconds apart. A prefix shorter than the
27
+ * model's minimum (512 to 4,096 tokens) isn't cached and costs nothing
28
+ * extra. How Anthropic keeps cached prompts, and their eligibility for
29
+ * zero data retention: https://platform.claude.com/docs/en/build-with-claude/prompt-caching
30
+ * and https://platform.claude.com/docs/en/manage-claude/api-and-data-retention.
31
+ */
32
+ export const PROMPT_CACHE: Anthropic.CacheControlEphemeral = { type: 'ephemeral' };
33
+
34
+ export interface CacheableRequest {
35
+ /** The call's system messages, in order, each its own block. */
36
+ readonly systemParts: readonly string[];
37
+ readonly tools: readonly Anthropic.Tool[] | undefined;
38
+ readonly messages: readonly Anthropic.MessageParam[];
39
+ }
40
+
41
+ export interface CachedRequest {
42
+ readonly system: Anthropic.TextBlockParam[] | undefined;
43
+ readonly tools: Anthropic.Tool[] | undefined;
44
+ readonly messages: Anthropic.MessageParam[];
45
+ }
46
+
47
+ /** The request's parts, with the cache breakpoints above. The inputs aren't changed. */
48
+ export function withPromptCache(request: CacheableRequest): CachedRequest {
49
+ const tools =
50
+ request.tools === undefined || request.tools.length === 0
51
+ ? undefined
52
+ : request.tools.map((tool, i, all) =>
53
+ i === all.length - 1 ? { ...tool, cache_control: PROMPT_CACHE } : tool,
54
+ );
55
+ const system =
56
+ request.systemParts.length === 0
57
+ ? undefined
58
+ : request.systemParts.map(
59
+ (text, i): Anthropic.TextBlockParam =>
60
+ i === 0 ? { type: 'text', text, cache_control: PROMPT_CACHE } : { type: 'text', text },
61
+ );
62
+ const continues = tools !== undefined || request.messages.some((m) => m.role === 'assistant');
63
+ const messages = continues ? markLastMessage(request.messages) : [...request.messages];
64
+ return { system, tools, messages };
65
+ }
66
+
67
+ /**
68
+ * The messages with a breakpoint on the last block of the last one that
69
+ * can carry it: text (not empty), a tool call, a tool result.
70
+ */
71
+ function markLastMessage(messages: readonly Anthropic.MessageParam[]): Anthropic.MessageParam[] {
72
+ const out = [...messages];
73
+ const last = out[out.length - 1];
74
+ if (last === undefined) return out;
75
+ const blocks: Anthropic.ContentBlockParam[] =
76
+ typeof last.content === 'string' ? [{ type: 'text', text: last.content }] : [...last.content];
77
+ for (let i = blocks.length - 1; i >= 0; i -= 1) {
78
+ const block = blocks[i] as Anthropic.ContentBlockParam;
79
+ if (cacheable(block)) {
80
+ blocks[i] = { ...block, cache_control: PROMPT_CACHE };
81
+ out[out.length - 1] = { ...last, content: blocks };
82
+ return out;
83
+ }
84
+ }
85
+ return out;
86
+ }
87
+
88
+ function cacheable(
89
+ block: Anthropic.ContentBlockParam,
90
+ ): block is
91
+ | Anthropic.TextBlockParam
92
+ | Anthropic.ToolUseBlockParam
93
+ | Anthropic.ToolResultBlockParam {
94
+ if (block.type === 'text') return block.text.length > 0;
95
+ return block.type === 'tool_use' || block.type === 'tool_result';
96
+ }
package/src/cost.ts CHANGED
@@ -26,6 +26,17 @@ export interface CostRates {
26
26
  readonly completionUsdPer1kTokens: number;
27
27
  readonly promptCacheCreationMultiplier?: number;
28
28
  readonly promptCacheReadMultiplier?: number;
29
+ /**
30
+ * Long-context pricing: when a call's prompt (regular, cache-write and
31
+ * cache-read tokens together) exceeds `thresholdTokens`, the whole call
32
+ * bills at these rates, the cache multipliers applying to the long
33
+ * prompt rate. Claude Haiku 5.5 is 5x past a 100,000-token prompt.
34
+ */
35
+ readonly longContext?: {
36
+ readonly thresholdTokens: number;
37
+ readonly promptUsdPer1kTokens: number;
38
+ readonly completionUsdPer1kTokens: number;
39
+ };
29
40
  }
30
41
 
31
42
  /**
@@ -45,8 +56,16 @@ export interface CostRates {
45
56
  * rates without double-counting.
46
57
  */
47
58
  export function computeCostUsd(usage: Anthropic.Usage, rates: CostRates): number {
48
- const inputRate = rates.promptUsdPer1kTokens;
49
- const outputRate = rates.completionUsdPer1kTokens;
59
+ const promptTokens =
60
+ usage.input_tokens +
61
+ (usage.cache_creation_input_tokens ?? 0) +
62
+ (usage.cache_read_input_tokens ?? 0);
63
+ const long =
64
+ rates.longContext !== undefined && promptTokens > rates.longContext.thresholdTokens
65
+ ? rates.longContext
66
+ : undefined;
67
+ const inputRate = long?.promptUsdPer1kTokens ?? rates.promptUsdPer1kTokens;
68
+ const outputRate = long?.completionUsdPer1kTokens ?? rates.completionUsdPer1kTokens;
50
69
  const creationMultiplier =
51
70
  rates.promptCacheCreationMultiplier ?? DEFAULT_CACHE_CREATION_MULTIPLIER_5MIN;
52
71
  const readMultiplier = rates.promptCacheReadMultiplier ?? DEFAULT_CACHE_READ_MULTIPLIER;
package/src/entry.ts ADDED
@@ -0,0 +1,55 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // Copyright (C) 2026 Kindgi Inc.
3
+
4
+ import {
5
+ type AdapterConfigCheckInput,
6
+ type AdapterConfigProblem,
7
+ type AdapterFactory,
8
+ type AdapterFactoryEntry,
9
+ adapterConfigError,
10
+ } from '@kindgi/capabilities';
11
+
12
+ import { createAnthropicProvider } from './provider.js';
13
+
14
+ /** The id the runtime registers this adapter under. */
15
+ export const ANTHROPIC_ADAPTER_ID = '@kindgi/adapter-model-anthropic';
16
+
17
+ /**
18
+ * The runtime's factory. A provider registered with it names its Anthropic
19
+ * API key in `secret_ref`, resolved on every call, so a rotated key takes
20
+ * effect on the next one.
21
+ */
22
+ export const anthropicAdapterFactory: AdapterFactory = (input) => {
23
+ const problem = keyProblem(input.resolveApiKey !== undefined);
24
+ if (problem !== undefined)
25
+ throw adapterConfigError(ANTHROPIC_ADAPTER_ID, input.metadata.id, problem);
26
+ return createAnthropicProvider({
27
+ apiKey: input.resolveApiKey as () => Promise<string>,
28
+ metadata: input.metadata,
29
+ });
30
+ };
31
+
32
+ /**
33
+ * What's wrong with a registration for this adapter, read without building
34
+ * it (`AdapterFactoryEntry.checkConfig`): it needs a `secret_ref`. The
35
+ * problem's message is the error the factory throws for it.
36
+ */
37
+ export function anthropicCheckConfig(
38
+ input: AdapterConfigCheckInput,
39
+ ): readonly AdapterConfigProblem[] {
40
+ const problem = keyProblem(input.hasSecretRef);
41
+ return problem !== undefined ? [problem] : [];
42
+ }
43
+
44
+ /** The entry a runtime registers: the factory, and its static check. */
45
+ export const anthropicAdapterEntry: AdapterFactoryEntry = {
46
+ adapterId: ANTHROPIC_ADAPTER_ID,
47
+ capabilityKind: 'llm-inference',
48
+ factory: anthropicAdapterFactory,
49
+ checkConfig: anthropicCheckConfig,
50
+ };
51
+
52
+ function keyProblem(hasSecretRef: boolean): AdapterConfigProblem | undefined {
53
+ if (hasSecretRef) return undefined;
54
+ return { path: '/secret_ref', message: 'needs secret_ref: its Anthropic API key.' };
55
+ }
package/src/index.ts CHANGED
@@ -2,6 +2,12 @@
2
2
  // Copyright (C) 2026 Kindgi Inc.
3
3
 
4
4
  export { createAnthropicProvider } from './provider.js';
5
+ export {
6
+ ANTHROPIC_ADAPTER_ID,
7
+ anthropicAdapterEntry,
8
+ anthropicAdapterFactory,
9
+ anthropicCheckConfig,
10
+ } from './entry.js';
5
11
  export type { AnthropicModelInfo, AnthropicProviderOptions } from './provider.js';
6
12
  export {
7
13
  DEFAULT_CACHE_CREATION_MULTIPLIER_5MIN,
@@ -10,6 +16,8 @@ export {
10
16
  toFrameworkUsage,
11
17
  } from './cost.js';
12
18
  export type { CostRates } from './cost.js';
19
+ export { PROMPT_CACHE, withPromptCache } from './cache.js';
20
+ export type { CacheableRequest, CachedRequest } from './cache.js';
13
21
  export {
14
22
  fromAnthropicResponse,
15
23
  mapStopReason,
package/src/provider.ts CHANGED
@@ -10,10 +10,14 @@ import type {
10
10
  ModelProvider,
11
11
  ProviderMetadata,
12
12
  } from '@kindgi/capabilities';
13
+ import { samplingFor } from '@kindgi/capabilities';
13
14
  import { createAttemptCounter } from '@kindgi/capabilities/attempts';
15
+ import { nameToolsAsSent } from '@kindgi/capabilities/tool-names';
14
16
 
15
- import { computeCostUsd, toFrameworkUsage } from './cost.js';
17
+ import { withPromptCache } from './cache.js';
18
+ import { type CostRates, computeCostUsd, toFrameworkUsage } from './cost.js';
16
19
  import {
20
+ encodeToolName,
17
21
  fromAnthropicResponse,
18
22
  mapStopReason,
19
23
  toAnthropicMessages,
@@ -24,16 +28,14 @@ import {
24
28
  * Anthropic-specific `ModelInfo` extension. Widens the framework's
25
29
  * `ModelInfo.cost` with the two Anthropic prompt-cache multipliers
26
30
  * (`promptCacheCreationMultiplier`, `promptCacheReadMultiplier`) that
27
- * `computeCostUsd` uses to bill cache activity per invocation.
31
+ * `computeCostUsd` uses to bill cache activity per invocation, and a
32
+ * `longContext` tier for a model that prices long prompts higher.
28
33
  *
29
34
  * When either multiplier is omitted the framework falls back to
30
35
  * Anthropic's 5-minute-tier defaults (1.25 / 0.1) inside `cost.ts`.
31
36
  */
32
37
  export interface AnthropicModelInfo extends ModelInfo {
33
- readonly cost: ModelInfo['cost'] & {
34
- readonly promptCacheCreationMultiplier?: number;
35
- readonly promptCacheReadMultiplier?: number;
36
- };
38
+ readonly cost: ModelInfo['cost'] & Omit<CostRates, keyof ModelInfo['cost']>;
37
39
  }
38
40
 
39
41
  /**
@@ -156,15 +158,32 @@ export function createAnthropicProvider(options: AnthropicProviderOptions): Mode
156
158
  const startedAt = Date.now();
157
159
  const client = await resolveClient();
158
160
 
159
- const { system, messages } = toAnthropicMessages(input.messages);
160
- const tools =
161
- input.tools !== undefined && input.tools.length > 0
162
- ? toAnthropicTools(input.tools)
163
- : undefined;
164
-
165
- const requestOptions: Record<string, unknown> =
166
- input.abortSignal !== undefined ? { signal: input.abortSignal } : {};
161
+ const translated = toAnthropicMessages(input.messages);
162
+ // The system prompt names the call's tools as they're sent (`acme__lookup_order`):
163
+ // a model told to call `acme.lookup_order` calls a name it wasn't given (T311).
164
+ const toolNames = input.tools?.map((t) => t.name) ?? [];
165
+ // Cache breakpoints on the tools, the agent's prompt and, when the call
166
+ // can continue, the conversation so far (`withPromptCache`).
167
+ const { system, tools, messages } = withPromptCache({
168
+ systemParts: translated.systemParts.map((part) =>
169
+ nameToolsAsSent(part, toolNames, encodeToolName),
170
+ ),
171
+ tools:
172
+ input.tools !== undefined && input.tools.length > 0
173
+ ? toAnthropicTools(input.tools)
174
+ : undefined,
175
+ messages: translated.messages,
176
+ });
177
+
178
+ // `traceparent` is a header on this request only, when the caller
179
+ // sets it (the provider's registration opted in); never logged.
180
+ const requestOptions: Record<string, unknown> = {
181
+ ...(input.abortSignal !== undefined && { signal: input.abortSignal }),
182
+ ...(input.traceparent !== undefined && { headers: { traceparent: input.traceparent } }),
183
+ };
167
184
  const maxTokens = input.maxOutputTokens ?? modelInfo.maxOutputTokens ?? DEFAULT_MAX_TOKENS;
185
+ const sampling = samplingFor(modelInfo, input);
186
+ const thinking = input.thinking === 'lowest' ? lowestThinking(modelInfo) : {};
168
187
 
169
188
  const counted = await attempts.count(() =>
170
189
  client.messages.create(
@@ -172,9 +191,10 @@ export function createAnthropicProvider(options: AnthropicProviderOptions): Mode
172
191
  model: input.model,
173
192
  max_tokens: maxTokens,
174
193
  ...(system !== undefined && { system }),
175
- messages: [...messages],
176
- ...(tools !== undefined && { tools: [...tools] }),
177
- ...(input.temperature !== undefined && { temperature: input.temperature }),
194
+ messages,
195
+ ...(tools !== undefined && { tools }),
196
+ ...(sampling.temperature !== undefined && { temperature: sampling.temperature }),
197
+ ...thinking,
178
198
  },
179
199
  requestOptions,
180
200
  ),
@@ -200,7 +220,25 @@ export function createAnthropicProvider(options: AnthropicProviderOptions): Mode
200
220
  // An injected client sends with its own fetch: nothing was counted.
201
221
  ...(counted.attempts > 0 && { attempts: counted.attempts }),
202
222
  rawUsage: { ...response.usage },
223
+ ...(sampling.warnings.length > 0 && { warnings: sampling.warnings }),
203
224
  };
204
225
  },
205
226
  };
206
227
  }
228
+
229
+ /**
230
+ * The request fields for a model's least thinking (`ModelCallInput.thinking:
231
+ * 'lowest'`). A thinking type that turns it off (Haiku 5.5's `disabled`,
232
+ * Sonnet 5.5's `between_tools`) is taken only at effort `high` or below,
233
+ * so it goes with effort `low`; a model that always thinks (Opus 5.5) gets
234
+ * the effort alone. The SDK's types predate both fields; the API takes them
235
+ * as sent.
236
+ */
237
+ function lowestThinking(model: ModelInfo): Record<string, unknown> {
238
+ const lowest = model.thinking?.lowest;
239
+ if (lowest === undefined) return {};
240
+ if (lowest === 'disabled' || lowest === 'between_tools') {
241
+ return { thinking: { type: lowest }, output_config: { effort: 'low' } };
242
+ }
243
+ return { output_config: { effort: lowest } };
244
+ }
package/src/translate.ts CHANGED
@@ -47,9 +47,14 @@ export function decodeToolName(name: string): string {
47
47
  * merge into a single user message (matching the framework's
48
48
  * dispatch-tools handler which appends one tool message per call
49
49
  * after an assistant `tool_use` turn).
50
+ *
51
+ * `systemParts` keeps the system messages apart, in order, so each can be
52
+ * its own block: the first (the agent's prompt) is the stable one a cache
53
+ * breakpoint goes on (`withPromptCache`).
50
54
  */
51
55
  export function toAnthropicMessages(messages: readonly ModelMessage[]): {
52
56
  readonly system: string | undefined;
57
+ readonly systemParts: readonly string[];
53
58
  readonly messages: readonly Anthropic.MessageParam[];
54
59
  } {
55
60
  const systemParts: string[] = [];
@@ -100,6 +105,7 @@ export function toAnthropicMessages(messages: readonly ModelMessage[]): {
100
105
 
101
106
  return {
102
107
  system: systemParts.length > 0 ? systemParts.join('\n\n') : undefined,
108
+ systemParts,
103
109
  messages: out,
104
110
  };
105
111
  }