@kindgi/adapter-model-anthropic 0.1.4 → 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.
@@ -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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"}
@@ -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 +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;AAK9B,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,CAyHxF"}
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
@@ -4,6 +4,7 @@ import Anthropic from '@anthropic-ai/sdk';
4
4
  import { samplingFor } from '@kindgi/capabilities';
5
5
  import { createAttemptCounter } from '@kindgi/capabilities/attempts';
6
6
  import { nameToolsAsSent } from '@kindgi/capabilities/tool-names';
7
+ import { withPromptCache } from './cache.js';
7
8
  import { computeCostUsd, toFrameworkUsage } from './cost.js';
8
9
  import { encodeToolName, fromAnthropicResponse, mapStopReason, toAnthropicMessages, toAnthropicTools, } from './translate.js';
9
10
  /**
@@ -72,14 +73,22 @@ export function createAnthropicProvider(options) {
72
73
  const translated = toAnthropicMessages(input.messages);
73
74
  // The system prompt names the call's tools as they're sent (`acme__lookup_order`):
74
75
  // a model told to call `acme.lookup_order` calls a name it wasn't given (T311).
75
- const system = translated.system === undefined
76
- ? undefined
77
- : nameToolsAsSent(translated.system, input.tools?.map((t) => t.name) ?? [], encodeToolName);
78
- const { messages } = translated;
79
- const tools = input.tools !== undefined && input.tools.length > 0
80
- ? toAnthropicTools(input.tools)
81
- : undefined;
82
- const requestOptions = input.abortSignal !== undefined ? { signal: input.abortSignal } : {};
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
+ };
83
92
  const maxTokens = input.maxOutputTokens ?? modelInfo.maxOutputTokens ?? DEFAULT_MAX_TOKENS;
84
93
  const sampling = samplingFor(modelInfo, input);
85
94
  const thinking = input.thinking === 'lowest' ? lowestThinking(modelInfo) : {};
@@ -87,8 +96,8 @@ export function createAnthropicProvider(options) {
87
96
  model: input.model,
88
97
  max_tokens: maxTokens,
89
98
  ...(system !== undefined && { system }),
90
- messages: [...messages],
91
- ...(tools !== undefined && { tools: [...tools] }),
99
+ messages,
100
+ ...(tools !== undefined && { tools }),
92
101
  ...(sampling.temperature !== undefined && { temperature: sampling.temperature }),
93
102
  ...thinking,
94
103
  }, requestOptions));
@@ -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":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kindgi/adapter-model-anthropic",
3
- "version": "0.1.4",
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",
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/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
@@ -14,6 +14,7 @@ import { samplingFor } from '@kindgi/capabilities';
14
14
  import { createAttemptCounter } from '@kindgi/capabilities/attempts';
15
15
  import { nameToolsAsSent } from '@kindgi/capabilities/tool-names';
16
16
 
17
+ import { withPromptCache } from './cache.js';
17
18
  import { type CostRates, computeCostUsd, toFrameworkUsage } from './cost.js';
18
19
  import {
19
20
  encodeToolName,
@@ -160,22 +161,26 @@ export function createAnthropicProvider(options: AnthropicProviderOptions): Mode
160
161
  const translated = toAnthropicMessages(input.messages);
161
162
  // The system prompt names the call's tools as they're sent (`acme__lookup_order`):
162
163
  // a model told to call `acme.lookup_order` calls a name it wasn't given (T311).
163
- const system =
164
- translated.system === undefined
165
- ? undefined
166
- : nameToolsAsSent(
167
- translated.system,
168
- input.tools?.map((t) => t.name) ?? [],
169
- encodeToolName,
170
- );
171
- const { messages } = translated;
172
- const tools =
173
- input.tools !== undefined && input.tools.length > 0
174
- ? toAnthropicTools(input.tools)
175
- : undefined;
176
-
177
- const requestOptions: Record<string, unknown> =
178
- input.abortSignal !== undefined ? { signal: input.abortSignal } : {};
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
+ };
179
184
  const maxTokens = input.maxOutputTokens ?? modelInfo.maxOutputTokens ?? DEFAULT_MAX_TOKENS;
180
185
  const sampling = samplingFor(modelInfo, input);
181
186
  const thinking = input.thinking === 'lowest' ? lowestThinking(modelInfo) : {};
@@ -186,8 +191,8 @@ export function createAnthropicProvider(options: AnthropicProviderOptions): Mode
186
191
  model: input.model,
187
192
  max_tokens: maxTokens,
188
193
  ...(system !== undefined && { system }),
189
- messages: [...messages],
190
- ...(tools !== undefined && { tools: [...tools] }),
194
+ messages,
195
+ ...(tools !== undefined && { tools }),
191
196
  ...(sampling.temperature !== undefined && { temperature: sampling.temperature }),
192
197
  ...thinking,
193
198
  },
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
  }