@kindgi/adapter-model-anthropic 0.1.4-rc.5 → 0.1.4
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 +1 -1
- package/dist/cost.d.ts +11 -0
- package/dist/cost.d.ts.map +1 -1
- package/dist/cost.js +8 -2
- package/dist/cost.js.map +1 -1
- package/dist/provider.d.ts +4 -5
- package/dist/provider.d.ts.map +1 -1
- package/dist/provider.js +32 -3
- package/dist/provider.js.map +1 -1
- package/package.json +2 -2
- package/src/cost.ts +21 -2
- package/src/provider.ts +41 -8
package/README.md
CHANGED
|
@@ -74,7 +74,7 @@ A single-key deployment passes `apiKey: process.env.ANTHROPIC_API_KEY` (checked
|
|
|
74
74
|
- **Streaming.** `invoke()` resolves with the complete response; streaming would need a different `ModelProvider` interface.
|
|
75
75
|
- **Extended thinking.** `ModelMessage` has no thinking field; `thinking` blocks in responses are dropped.
|
|
76
76
|
- **Image inputs.** `ModelMessage` content is text only.
|
|
77
|
-
- **Structured output.** `structuredOutput` on `ModelCallInput` is ignored.
|
|
77
|
+
- **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
78
|
- **Retry logic in the adapter.** Retries and timeouts are the SDK client's (`clientOptions.maxRetries`, `clientOptions.timeout`).
|
|
79
79
|
|
|
80
80
|
## Related
|
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
|
package/dist/cost.d.ts.map
CHANGED
|
@@ -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;
|
|
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
|
|
37
|
-
|
|
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;
|
|
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"}
|
package/dist/provider.d.ts
CHANGED
|
@@ -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`.
|
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;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"}
|
package/dist/provider.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
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';
|
|
5
7
|
import { computeCostUsd, toFrameworkUsage } from './cost.js';
|
|
6
|
-
import { fromAnthropicResponse, mapStopReason, toAnthropicMessages, toAnthropicTools, } from './translate.js';
|
|
8
|
+
import { encodeToolName, fromAnthropicResponse, mapStopReason, toAnthropicMessages, toAnthropicTools, } from './translate.js';
|
|
7
9
|
/**
|
|
8
10
|
* Adapter-level fallback when neither `ModelCallInput.maxOutputTokens`
|
|
9
11
|
* nor the picked `ModelInfo.maxOutputTokens` is set. Anthropic requires
|
|
@@ -67,19 +69,28 @@ export function createAnthropicProvider(options) {
|
|
|
67
69
|
}
|
|
68
70
|
const startedAt = Date.now();
|
|
69
71
|
const client = await resolveClient();
|
|
70
|
-
const
|
|
72
|
+
const translated = toAnthropicMessages(input.messages);
|
|
73
|
+
// The system prompt names the call's tools as they're sent (`acme__lookup_order`):
|
|
74
|
+
// 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;
|
|
71
79
|
const tools = input.tools !== undefined && input.tools.length > 0
|
|
72
80
|
? toAnthropicTools(input.tools)
|
|
73
81
|
: undefined;
|
|
74
82
|
const requestOptions = input.abortSignal !== undefined ? { signal: input.abortSignal } : {};
|
|
75
83
|
const maxTokens = input.maxOutputTokens ?? modelInfo.maxOutputTokens ?? DEFAULT_MAX_TOKENS;
|
|
84
|
+
const sampling = samplingFor(modelInfo, input);
|
|
85
|
+
const thinking = input.thinking === 'lowest' ? lowestThinking(modelInfo) : {};
|
|
76
86
|
const counted = await attempts.count(() => client.messages.create({
|
|
77
87
|
model: input.model,
|
|
78
88
|
max_tokens: maxTokens,
|
|
79
89
|
...(system !== undefined && { system }),
|
|
80
90
|
messages: [...messages],
|
|
81
91
|
...(tools !== undefined && { tools: [...tools] }),
|
|
82
|
-
...(
|
|
92
|
+
...(sampling.temperature !== undefined && { temperature: sampling.temperature }),
|
|
93
|
+
...thinking,
|
|
83
94
|
}, requestOptions));
|
|
84
95
|
const response = counted.value;
|
|
85
96
|
const durationMs = Date.now() - startedAt;
|
|
@@ -100,8 +111,26 @@ export function createAnthropicProvider(options) {
|
|
|
100
111
|
// An injected client sends with its own fetch: nothing was counted.
|
|
101
112
|
...(counted.attempts > 0 && { attempts: counted.attempts }),
|
|
102
113
|
rawUsage: { ...response.usage },
|
|
114
|
+
...(sampling.warnings.length > 0 && { warnings: sampling.warnings }),
|
|
103
115
|
};
|
|
104
116
|
},
|
|
105
117
|
};
|
|
106
118
|
}
|
|
119
|
+
/**
|
|
120
|
+
* The request fields for a model's least thinking (`ModelCallInput.thinking:
|
|
121
|
+
* 'lowest'`). A thinking type that turns it off (Haiku 5.5's `disabled`,
|
|
122
|
+
* Sonnet 5.5's `between_tools`) is taken only at effort `high` or below,
|
|
123
|
+
* so it goes with effort `low`; a model that always thinks (Opus 5.5) gets
|
|
124
|
+
* the effort alone. The SDK's types predate both fields; the API takes them
|
|
125
|
+
* as sent.
|
|
126
|
+
*/
|
|
127
|
+
function lowestThinking(model) {
|
|
128
|
+
const lowest = model.thinking?.lowest;
|
|
129
|
+
if (lowest === undefined)
|
|
130
|
+
return {};
|
|
131
|
+
if (lowest === 'disabled' || lowest === 'between_tools') {
|
|
132
|
+
return { thinking: { type: lowest }, output_config: { effort: 'low' } };
|
|
133
|
+
}
|
|
134
|
+
return { output_config: { effort: lowest } };
|
|
135
|
+
}
|
|
107
136
|
//# sourceMappingURL=provider.js.map
|
package/dist/provider.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provider.js","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,iCAAiC;AAEjC,OAAO,SAAS,MAAM,mBAAmB,CAAC;AAS1C,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"provider.js","sourceRoot":"","sources":["../src/provider.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.4",
|
|
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.4",
|
|
32
32
|
"@anthropic-ai/sdk": "^0.68.0"
|
|
33
33
|
},
|
|
34
34
|
"engines": {
|
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
|
|
49
|
-
|
|
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/provider.ts
CHANGED
|
@@ -10,10 +10,13 @@ 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 { type CostRates, computeCostUsd, toFrameworkUsage } from './cost.js';
|
|
16
18
|
import {
|
|
19
|
+
encodeToolName,
|
|
17
20
|
fromAnthropicResponse,
|
|
18
21
|
mapStopReason,
|
|
19
22
|
toAnthropicMessages,
|
|
@@ -24,16 +27,14 @@ import {
|
|
|
24
27
|
* Anthropic-specific `ModelInfo` extension. Widens the framework's
|
|
25
28
|
* `ModelInfo.cost` with the two Anthropic prompt-cache multipliers
|
|
26
29
|
* (`promptCacheCreationMultiplier`, `promptCacheReadMultiplier`) that
|
|
27
|
-
* `computeCostUsd` uses to bill cache activity per invocation
|
|
30
|
+
* `computeCostUsd` uses to bill cache activity per invocation, and a
|
|
31
|
+
* `longContext` tier for a model that prices long prompts higher.
|
|
28
32
|
*
|
|
29
33
|
* When either multiplier is omitted the framework falls back to
|
|
30
34
|
* Anthropic's 5-minute-tier defaults (1.25 / 0.1) inside `cost.ts`.
|
|
31
35
|
*/
|
|
32
36
|
export interface AnthropicModelInfo extends ModelInfo {
|
|
33
|
-
readonly cost: ModelInfo['cost'] &
|
|
34
|
-
readonly promptCacheCreationMultiplier?: number;
|
|
35
|
-
readonly promptCacheReadMultiplier?: number;
|
|
36
|
-
};
|
|
37
|
+
readonly cost: ModelInfo['cost'] & Omit<CostRates, keyof ModelInfo['cost']>;
|
|
37
38
|
}
|
|
38
39
|
|
|
39
40
|
/**
|
|
@@ -156,7 +157,18 @@ export function createAnthropicProvider(options: AnthropicProviderOptions): Mode
|
|
|
156
157
|
const startedAt = Date.now();
|
|
157
158
|
const client = await resolveClient();
|
|
158
159
|
|
|
159
|
-
const
|
|
160
|
+
const translated = toAnthropicMessages(input.messages);
|
|
161
|
+
// The system prompt names the call's tools as they're sent (`acme__lookup_order`):
|
|
162
|
+
// 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;
|
|
160
172
|
const tools =
|
|
161
173
|
input.tools !== undefined && input.tools.length > 0
|
|
162
174
|
? toAnthropicTools(input.tools)
|
|
@@ -165,6 +177,8 @@ export function createAnthropicProvider(options: AnthropicProviderOptions): Mode
|
|
|
165
177
|
const requestOptions: Record<string, unknown> =
|
|
166
178
|
input.abortSignal !== undefined ? { signal: input.abortSignal } : {};
|
|
167
179
|
const maxTokens = input.maxOutputTokens ?? modelInfo.maxOutputTokens ?? DEFAULT_MAX_TOKENS;
|
|
180
|
+
const sampling = samplingFor(modelInfo, input);
|
|
181
|
+
const thinking = input.thinking === 'lowest' ? lowestThinking(modelInfo) : {};
|
|
168
182
|
|
|
169
183
|
const counted = await attempts.count(() =>
|
|
170
184
|
client.messages.create(
|
|
@@ -174,7 +188,8 @@ export function createAnthropicProvider(options: AnthropicProviderOptions): Mode
|
|
|
174
188
|
...(system !== undefined && { system }),
|
|
175
189
|
messages: [...messages],
|
|
176
190
|
...(tools !== undefined && { tools: [...tools] }),
|
|
177
|
-
...(
|
|
191
|
+
...(sampling.temperature !== undefined && { temperature: sampling.temperature }),
|
|
192
|
+
...thinking,
|
|
178
193
|
},
|
|
179
194
|
requestOptions,
|
|
180
195
|
),
|
|
@@ -200,7 +215,25 @@ export function createAnthropicProvider(options: AnthropicProviderOptions): Mode
|
|
|
200
215
|
// An injected client sends with its own fetch: nothing was counted.
|
|
201
216
|
...(counted.attempts > 0 && { attempts: counted.attempts }),
|
|
202
217
|
rawUsage: { ...response.usage },
|
|
218
|
+
...(sampling.warnings.length > 0 && { warnings: sampling.warnings }),
|
|
203
219
|
};
|
|
204
220
|
},
|
|
205
221
|
};
|
|
206
222
|
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* The request fields for a model's least thinking (`ModelCallInput.thinking:
|
|
226
|
+
* 'lowest'`). A thinking type that turns it off (Haiku 5.5's `disabled`,
|
|
227
|
+
* Sonnet 5.5's `between_tools`) is taken only at effort `high` or below,
|
|
228
|
+
* so it goes with effort `low`; a model that always thinks (Opus 5.5) gets
|
|
229
|
+
* the effort alone. The SDK's types predate both fields; the API takes them
|
|
230
|
+
* as sent.
|
|
231
|
+
*/
|
|
232
|
+
function lowestThinking(model: ModelInfo): Record<string, unknown> {
|
|
233
|
+
const lowest = model.thinking?.lowest;
|
|
234
|
+
if (lowest === undefined) return {};
|
|
235
|
+
if (lowest === 'disabled' || lowest === 'between_tools') {
|
|
236
|
+
return { thinking: { type: lowest }, output_config: { effort: 'low' } };
|
|
237
|
+
}
|
|
238
|
+
return { output_config: { effort: lowest } };
|
|
239
|
+
}
|