@kindgi/adapter-model-anthropic 0.1.4 → 0.1.5
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 +9 -2
- package/dist/cache.d.ts +42 -0
- package/dist/cache.d.ts.map +1 -0
- package/dist/cache.js +67 -0
- package/dist/cache.js.map +1 -0
- package/dist/entry.d.ts +18 -0
- package/dist/entry.d.ts.map +1 -0
- package/dist/entry.js +42 -0
- package/dist/entry.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/provider.d.ts.map +1 -1
- package/dist/provider.js +19 -10
- package/dist/provider.js.map +1 -1
- package/dist/translate.d.ts +5 -0
- package/dist/translate.d.ts.map +1 -1
- package/dist/translate.js +5 -0
- package/dist/translate.js.map +1 -1
- package/package.json +2 -2
- package/src/cache.ts +96 -0
- package/src/entry.ts +55 -0
- package/src/index.ts +8 -0
- package/src/provider.ts +23 -18
- package/src/translate.ts +6 -0
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
|
|
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`)
|
|
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.
|
package/dist/cache.d.ts
ADDED
|
@@ -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/entry.d.ts
ADDED
|
@@ -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
|
package/dist/index.d.ts.map
CHANGED
|
@@ -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;
|
|
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"}
|
package/dist/provider.d.ts.map
CHANGED
|
@@ -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;
|
|
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
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
const { messages } =
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
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
|
|
91
|
-
...(tools !== undefined && { tools
|
|
99
|
+
messages,
|
|
100
|
+
...(tools !== undefined && { tools }),
|
|
92
101
|
...(sampling.temperature !== undefined && { temperature: sampling.temperature }),
|
|
93
102
|
...thinking,
|
|
94
103
|
}, requestOptions));
|
package/dist/provider.js.map
CHANGED
|
@@ -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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"}
|
package/dist/translate.d.ts
CHANGED
|
@@ -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
|
/**
|
package/dist/translate.d.ts.map
CHANGED
|
@@ -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
|
|
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
|
}
|
package/dist/translate.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
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
|
|
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.
|
|
3
|
+
"version": "0.1.5",
|
|
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.
|
|
31
|
+
"@kindgi/capabilities": "0.1.5",
|
|
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
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
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
|
|
190
|
-
...(tools !== undefined && { 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
|
}
|