@alvin0/ai-agent-sdk-provider-anthropic 0.1.3 → 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 +59 -3
- package/dist/index.d.ts +58 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +94 -64
- package/dist/index.js.map +1 -1
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -5,9 +5,15 @@ Runtime: **Universal** (Edge/Worker, browser, Deno, Bun, and Node).
|
|
|
5
5
|
Compatible gateways can configure `baseUrl`, `models`, `fetch`, and `headers`
|
|
6
6
|
(a string record or synchronous function returning one per operation).
|
|
7
7
|
Generation uses the Messages protocol.
|
|
8
|
-
Header names are case-insensitive
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
Header names are case-insensitive. A `headers` entry overrides what the SDK
|
|
9
|
+
would otherwise send for that name (`accept`, `content-type`, `user-agent`,
|
|
10
|
+
`anthropic-version`/`anthropic-beta`) — only a connection-level name `fetch`
|
|
11
|
+
itself forbids (`host`, `content-length`, …) or a credential-shaped name (must
|
|
12
|
+
go through `apiKey`/`authHeader` instead, so it can be redacted in logs) stays
|
|
13
|
+
rejected. Supply credentials with `apiKey`; use `version` and `beta` for
|
|
14
|
+
Anthropic protocol headers, or `authHeader: 'bearer'` when a gateway in front
|
|
15
|
+
of Anthropic expects `Authorization: Bearer` instead of this API's own
|
|
16
|
+
`x-api-key`. Static records are copied.
|
|
11
17
|
Trusted local HTTP gateways require `allowInsecureHttp: true`.
|
|
12
18
|
|
|
13
19
|
```sh
|
|
@@ -29,3 +35,53 @@ and require an explicit `apiKey`; environment lookup belongs to a Node wrapper.
|
|
|
29
35
|
|
|
30
36
|
Composition: `runtime.providers`. Lifecycle: `inert-runtime-owned-registration`;
|
|
31
37
|
the runtime activates and removes the captured provider registration.
|
|
38
|
+
|
|
39
|
+
## Connecting a compatible endpoint
|
|
40
|
+
|
|
41
|
+
This package speaks the Anthropic Messages wire, so any endpoint that speaks it
|
|
42
|
+
back is reachable by configuration alone — Anthropic itself, DeepSeek's
|
|
43
|
+
`/anthropic` compatibility surface, Kimi, MiniMax, GLM, or a local gateway:
|
|
44
|
+
|
|
45
|
+
```ts
|
|
46
|
+
import { envCredential } from '@alvin0/ai-agent-sdk-auth-node'
|
|
47
|
+
|
|
48
|
+
anthropicPlugin({
|
|
49
|
+
id: 'kimi',
|
|
50
|
+
displayName: 'Kimi',
|
|
51
|
+
baseUrl: 'https://api.moonshot.ai/anthropic',
|
|
52
|
+
apiKey: envCredential('KIMI_API_KEY'),
|
|
53
|
+
authHeader: 'bearer', // this endpoint expects Authorization: Bearer, not x-api-key
|
|
54
|
+
})
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Effort reaches `output_config.effort` verbatim by default (current GA models).
|
|
58
|
+
For an older model or a gateway that only understands a thinking-token budget,
|
|
59
|
+
set `reasoningFormat: 'thinking-budget'` plus `thinkingBudgets` to map each
|
|
60
|
+
effort id to a token count instead. `path`/`query` override the request path
|
|
61
|
+
and add query-string parameters, the same way as the other two providers in
|
|
62
|
+
this SDK.
|
|
63
|
+
|
|
64
|
+
## Prompt caching
|
|
65
|
+
|
|
66
|
+
Set `promptCaching: true` to place Anthropic `cache_control` breakpoints on the
|
|
67
|
+
stable request prefix: the system prompt, the final tool definition, and the
|
|
68
|
+
conversation through the second-to-last message. `promptCachingTtl` accepts
|
|
69
|
+
`'5m'` or `'1h'`; leaving it unset uses the API default.
|
|
70
|
+
|
|
71
|
+
Caching is opt-in because compatible Messages gateways do not all implement
|
|
72
|
+
this extension. If a gateway returns a 400 that specifically names
|
|
73
|
+
`cache_control`, the adapter retries once without breakpoints and remembers the
|
|
74
|
+
downgrade. Unrelated request errors still surface normally.
|
|
75
|
+
|
|
76
|
+
## Default configuration precedence
|
|
77
|
+
|
|
78
|
+
`contextWindow` and `maxTokens` resolve top-to-bottom, first match wins:
|
|
79
|
+
per-call `maxTokens` → **model** (`models[].contextWindow`,
|
|
80
|
+
`models[].maxTokens`) → **route** (`defaultContextWindow`/`defaultMaxTokens` on
|
|
81
|
+
this plugin) → **runtime** (`createAgentRuntime({ defaults })`) → **SDK
|
|
82
|
+
constant** (`200_000` context; `max_tokens` is REQUIRED by this API, so an
|
|
83
|
+
unset value falls back to the protocol's own constant rather than being
|
|
84
|
+
omitted — the one exception to "unset means not sent" in this SDK). This
|
|
85
|
+
package's adapter never guesses a vendor's real context window for an
|
|
86
|
+
uncatalogued model id; declare it via `models: [{ id, contextWindow }]` when
|
|
87
|
+
the SDK default doesn't match reality.
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { ModelProviderPlugin, RetryPolicyConfig } from "@alvin0/ai-agent-sdk-core";
|
|
1
|
+
import { ModelAdapter, ModelProviderPlugin, RetryPolicyConfig } from "@alvin0/ai-agent-sdk-core";
|
|
3
2
|
import { ComposableModelProviderPlugin, CredentialInput, ModelTarget } from "@alvin0/ai-agent-sdk-core/provider";
|
|
4
|
-
import {
|
|
3
|
+
import { CredentialSource, HeaderContext, ProviderCatalogModel, ProviderRequestLogger, ProviderResponseLogger, RequestContext } from "@alvin0/ai-agent-sdk-provider-http";
|
|
4
|
+
import { ANTHROPIC_VERSION, AnthropicDialect, AnthropicReasoningFormat, AnthropicReasoningState, DEFAULT_THINKING_BUDGETS, ThinkingBudgets, ThinkingBudgets as ThinkingBudgets$1, anthropicMessagesProtocol } from "@alvin0/ai-agent-sdk-protocol-anthropic-messages";
|
|
5
5
|
//#region src/adapter.d.ts
|
|
6
6
|
/** The Anthropic API base. */
|
|
7
7
|
declare const ANTHROPIC_BASE_URL = "https://api.anthropic.com";
|
|
@@ -13,10 +13,27 @@ interface AnthropicAdapterOptions {
|
|
|
13
13
|
apiKey: AnthropicCredential;
|
|
14
14
|
/** Endpoint base; defaults to {@link ANTHROPIC_BASE_URL}. */
|
|
15
15
|
baseUrl?: string;
|
|
16
|
+
/**
|
|
17
|
+
* Name this endpoint uses in diagnostics and error messages. Defaults to
|
|
18
|
+
* `'Anthropic'`; set it to the real vendor name (e.g. `'Kimi'`) when pointing
|
|
19
|
+
* this provider at a compatible gateway, so a rejection names who rejected it.
|
|
20
|
+
*/
|
|
21
|
+
displayName?: string;
|
|
16
22
|
/** Extra endpoint headers, captured once per operation. Reserved names and collisions fail. */
|
|
17
|
-
headers?: Readonly<Record<string, string>> | (() => Readonly<Record<string, string>>);
|
|
23
|
+
headers?: Readonly<Record<string, string>> | ((ctx: HeaderContext) => Readonly<Record<string, string>>);
|
|
18
24
|
/** Permit cleartext HTTP explicitly for trusted local gateways. */
|
|
19
25
|
allowInsecureHttp?: boolean;
|
|
26
|
+
/** Override the request path this protocol would otherwise pick (e.g. a gateway deployment path). */
|
|
27
|
+
path?: string;
|
|
28
|
+
/** Extra query-string parameters, or a resolver for them. Never for secrets. */
|
|
29
|
+
query?: Readonly<Record<string, string>> | (() => Readonly<Record<string, string>>);
|
|
30
|
+
/**
|
|
31
|
+
* Fields to deep-merge into the serialized body. The caller's value always
|
|
32
|
+
* wins, even over a field the SDK set. A `null` value deletes the field.
|
|
33
|
+
*/
|
|
34
|
+
body?: Readonly<Record<string, unknown>>;
|
|
35
|
+
/** Last-resort hook with full authority over the body, run after `body` is merged in. */
|
|
36
|
+
transformRequest?: (body: unknown, ctx: RequestContext) => unknown;
|
|
20
37
|
/** API version header; defaults to {@link ANTHROPIC_VERSION}. */
|
|
21
38
|
version?: string;
|
|
22
39
|
/** Opt-in beta features, sent as `anthropic-beta`. */
|
|
@@ -28,8 +45,41 @@ interface AnthropicAdapterOptions {
|
|
|
28
45
|
* stale built-in list would name retired models.
|
|
29
46
|
*/
|
|
30
47
|
models?: readonly ProviderCatalogModel[];
|
|
31
|
-
/**
|
|
48
|
+
/**
|
|
49
|
+
* Which field carries reasoning effort. Defaults to `'output-config'`
|
|
50
|
+
* (current GA models): the caller's effort string reaches
|
|
51
|
+
* `output_config.effort` verbatim — pure pass-through, no SDK conversion.
|
|
52
|
+
* Set `'thinking-budget'` for an older model or a gateway that only
|
|
53
|
+
* understands a token budget; then effort is converted via `thinkingBudgets`
|
|
54
|
+
* instead of being sent raw.
|
|
55
|
+
*/
|
|
56
|
+
reasoningFormat?: AnthropicReasoningFormat;
|
|
57
|
+
/** Effort id to thinking-token budget; only consulted under `reasoningFormat: 'thinking-budget'`. */
|
|
32
58
|
thinkingBudgets?: ThinkingBudgets$1;
|
|
59
|
+
/**
|
|
60
|
+
* Extended-thinking mode, sent only when set. Independent of effort under
|
|
61
|
+
* `'output-config'` — omission leaves the model's own default thinking
|
|
62
|
+
* behavior alone rather than the SDK guessing one from the effort.
|
|
63
|
+
*/
|
|
64
|
+
thinking?: 'adaptive' | 'disabled';
|
|
65
|
+
/**
|
|
66
|
+
* Mark the stable prefix of every request (system prompt, tool
|
|
67
|
+
* definitions, every message but the newest) as a `cache_control`
|
|
68
|
+
* breakpoint, so a long conversation reads its own unchanged history back
|
|
69
|
+
* at a steep discount instead of paying to reprocess it on every turn.
|
|
70
|
+
*
|
|
71
|
+
* Off by default: this is an Anthropic-specific extension, and a gateway
|
|
72
|
+
* behind this same adapter that speaks the Messages API but does not
|
|
73
|
+
* understand `cache_control` should not be asked to guess. If a live
|
|
74
|
+
* dispatch is ever rejected specifically for it, this adapter turns
|
|
75
|
+
* caching off for itself, permanently, and retries once without it — it
|
|
76
|
+
* never fails a call over an optimization the caller opted into.
|
|
77
|
+
*/
|
|
78
|
+
promptCaching?: boolean;
|
|
79
|
+
/** Cache breakpoint lifetime. Defaults to this API's own default (5 minutes). */
|
|
80
|
+
promptCachingTtl?: '5m' | '1h';
|
|
81
|
+
/** How the API key travels. Defaults to `'x-api-key'`, this API's own header. */
|
|
82
|
+
authHeader?: 'x-api-key' | 'bearer';
|
|
33
83
|
/**
|
|
34
84
|
* Output cap when neither caller nor catalog names one.
|
|
35
85
|
*
|
|
@@ -52,6 +102,8 @@ interface AnthropicAdapterOptions {
|
|
|
52
102
|
retryPolicy?: RetryPolicyConfig;
|
|
53
103
|
/** Optional exact wire-request logger; credentials are redacted. */
|
|
54
104
|
requestLogger?: ProviderRequestLogger;
|
|
105
|
+
/** Optional exact wire-response logger, fired once a stream ends. */
|
|
106
|
+
responseLogger?: ProviderResponseLogger;
|
|
55
107
|
fetch?: typeof globalThis.fetch;
|
|
56
108
|
}
|
|
57
109
|
/**
|
|
@@ -59,7 +111,7 @@ interface AnthropicAdapterOptions {
|
|
|
59
111
|
* @param options - credential, endpoint, and thinking-budget overrides.
|
|
60
112
|
* @returns the adapter, ready to register.
|
|
61
113
|
*/
|
|
62
|
-
declare function anthropicAdapter(options: AnthropicAdapterOptions):
|
|
114
|
+
declare function anthropicAdapter(options: AnthropicAdapterOptions): ModelAdapter;
|
|
63
115
|
interface AnthropicPluginOptions extends AnthropicAdapterOptions {
|
|
64
116
|
/** Registry routes installed by the plugin. Defaults to `['anthropic']`. */
|
|
65
117
|
readonly routes?: readonly string[];
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/adapter.ts"],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/adapter.ts"],"mappings":";;;;;;cA4Ca;;KAOD,sBAAsB;;UAgBjB;;EAEf,QAAQ;;EAER;;;;;;EAMA;;EAEA,UAAU,SAAS,4BAA4B,KAAK,kBAAkB,SAAS;;EAE/E;;EAEA;;EAEA,QAAQ,SAAS,iCAAiC,SAAS;;;;;EAK3D,OAAO,SAAS;;EAEhB,oBAAoB,eAAe,KAAK;;EAExC;;EAEA;;;;;;;EAOA,kBAAkB;;;;;;;;;EASlB,kBAAkB;;EAElB,kBAAkB;;;;;;EAMlB;;;;;;;;;;;;;;EAcA;;EAEA;;EAEA;;;;;;EAMA;;EAEA;;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;EAEA,cAAc;;EAEd,gBAAgB;;EAEhB,iBAAiB;EACjB,eAAe,WAAW;;;;;;;iBAQZ,iBAAiB,SAAS,0BAA0B;UA6BnD,+BAA+B;;WAErC;;UAGM,iCAAiC,KAAK;WAC5C,wBAAwB;WACxB,QAAQ;WACR;WACA;;;iBAIK,gBACd,SAAS,2BACR;WAA2C;;iBAC9B,gBAAgB,SAAS,yBAAyB"}
|
package/dist/index.js
CHANGED
|
@@ -1,30 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { ReasoningEffortId } from "@alvin0/ai-agent-sdk-core";
|
|
1
|
+
import { ModelAdapter, ModelError, ReasoningEffortId } from "@alvin0/ai-agent-sdk-core";
|
|
3
2
|
import { defineModelProviderPlugin } from "@alvin0/ai-agent-sdk-core/provider";
|
|
3
|
+
import { FieldFallbackAdapter, createHttpProvider, createRuntimeHttpProvider, endpointHeaders } from "@alvin0/ai-agent-sdk-provider-http";
|
|
4
4
|
import { ANTHROPIC_VERSION, DEFAULT_THINKING_BUDGETS, anthropicMessagesProtocol, anthropicMessagesProtocol as anthropicMessagesProtocol$1 } from "@alvin0/ai-agent-sdk-protocol-anthropic-messages";
|
|
5
5
|
|
|
6
|
-
//#region src/context-policy.ts
|
|
7
|
-
const STANDARD_1M = Object.fromEntries([
|
|
8
|
-
"claude-opus-4-6",
|
|
9
|
-
"claude-opus-4-7",
|
|
10
|
-
"claude-opus-4-8",
|
|
11
|
-
"claude-opus-5",
|
|
12
|
-
"claude-sonnet-4-6",
|
|
13
|
-
"claude-sonnet-5",
|
|
14
|
-
"claude-fable-5",
|
|
15
|
-
"claude-fable-5-1",
|
|
16
|
-
"claude-mythos-5",
|
|
17
|
-
"claude-mythos-5-1",
|
|
18
|
-
"claude-mythos-preview"
|
|
19
|
-
].map((id) => [id, {
|
|
20
|
-
defaultContextWindow: 1e6,
|
|
21
|
-
maxContextWindow: 1e6
|
|
22
|
-
}]));
|
|
23
|
-
function anthropicContextPolicy(options) {
|
|
24
|
-
return createModelContextPolicy(options.baseUrl === void 0 || options.baseUrl.replace(/\/$/, "") === "https://api.anthropic.com" ? STANDARD_1M : {}, options.models, options.defaultContextWindow);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
//#endregion
|
|
28
6
|
//#region src/adapter.ts
|
|
29
7
|
/** The Anthropic API base. */
|
|
30
8
|
const ANTHROPIC_BASE_URL = "https://api.anthropic.com";
|
|
@@ -42,35 +20,28 @@ function reasoningInfo(budgets) {
|
|
|
42
20
|
* @returns the adapter, ready to register.
|
|
43
21
|
*/
|
|
44
22
|
function anthropicAdapter(options) {
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
budgets: options.thinkingBudgets ?? DEFAULT_THINKING_BUDGETS,
|
|
48
|
-
...options.version === void 0 ? {} : { version: options.version },
|
|
49
|
-
...options.beta === void 0 ? {} : { beta: options.beta }
|
|
50
|
-
};
|
|
51
|
-
return createHttpProvider({
|
|
52
|
-
displayName: "Anthropic",
|
|
23
|
+
const build = (promptCachingOverride) => createHttpProvider({
|
|
24
|
+
displayName: options.displayName ?? "Anthropic",
|
|
53
25
|
protocol: anthropicMessagesProtocol$1,
|
|
54
26
|
baseUrl: options.baseUrl ?? "https://api.anthropic.com",
|
|
55
|
-
auth:
|
|
56
|
-
|
|
57
|
-
name: "x-api-key",
|
|
58
|
-
value: options.apiKey,
|
|
59
|
-
label: "the `apiKey` option"
|
|
60
|
-
},
|
|
61
|
-
dialect,
|
|
27
|
+
auth: authOf(options),
|
|
28
|
+
dialect: dialectOf(options, promptCachingOverride),
|
|
62
29
|
describeModel: (info, effective) => ({
|
|
63
|
-
...
|
|
30
|
+
...info,
|
|
64
31
|
reasoning: info.reasoning ?? reasoningInfo(effective.budgets)
|
|
65
32
|
}),
|
|
66
33
|
...options.models === void 0 ? {} : { models: options.models },
|
|
67
|
-
defaultMaxTokens: options.defaultMaxTokens
|
|
68
|
-
defaultContextWindow: options.defaultContextWindow
|
|
34
|
+
...options.defaultMaxTokens === void 0 ? {} : { defaultMaxTokens: options.defaultMaxTokens },
|
|
35
|
+
...options.defaultContextWindow === void 0 ? {} : { defaultContextWindow: options.defaultContextWindow },
|
|
69
36
|
...options.streamIdleTimeoutMs === void 0 ? {} : { streamIdleTimeoutMs: options.streamIdleTimeoutMs },
|
|
70
37
|
...transportLimits(options),
|
|
71
38
|
...options.retryPolicy === void 0 ? {} : { retryPolicy: options.retryPolicy },
|
|
72
|
-
...options.requestLogger === void 0 ? {} : { requestLogger: options.requestLogger }
|
|
39
|
+
...options.requestLogger === void 0 ? {} : { requestLogger: options.requestLogger },
|
|
40
|
+
...options.responseLogger === void 0 ? {} : { responseLogger: options.responseLogger }
|
|
73
41
|
});
|
|
42
|
+
const primary = build();
|
|
43
|
+
if (options.promptCaching !== true) return primary;
|
|
44
|
+
return new FieldFallbackAdapter(primary, build(false), { isFieldRejection: isCacheControlRejection });
|
|
74
45
|
}
|
|
75
46
|
function anthropicPlugin(options) {
|
|
76
47
|
if (!usesRuntimeComposition(options)) return legacyAnthropicPlugin(options);
|
|
@@ -79,7 +50,7 @@ function anthropicPlugin(options) {
|
|
|
79
50
|
return defineModelProviderPlugin({
|
|
80
51
|
id,
|
|
81
52
|
family: "anthropic",
|
|
82
|
-
displayName: "Anthropic",
|
|
53
|
+
displayName: options.displayName ?? "Anthropic",
|
|
83
54
|
routes,
|
|
84
55
|
...runtimeDefaultModel(options.defaultModel, routes),
|
|
85
56
|
setup(registrar) {
|
|
@@ -96,42 +67,35 @@ function legacyAnthropicPlugin(options) {
|
|
|
96
67
|
const adapter = anthropicAdapter(options);
|
|
97
68
|
return Object.freeze({
|
|
98
69
|
id: "anthropic",
|
|
99
|
-
displayName: "Anthropic",
|
|
70
|
+
displayName: options.displayName ?? "Anthropic",
|
|
100
71
|
setup(registrar) {
|
|
101
72
|
registrar.registerAdapter(routes, adapter);
|
|
102
73
|
}
|
|
103
74
|
});
|
|
104
75
|
}
|
|
105
76
|
function createRuntimeAnthropicAdapter(options) {
|
|
106
|
-
const
|
|
107
|
-
|
|
108
|
-
budgets: options.thinkingBudgets ?? DEFAULT_THINKING_BUDGETS,
|
|
109
|
-
...options.version === void 0 ? {} : { version: options.version },
|
|
110
|
-
...options.beta === void 0 ? {} : { beta: options.beta }
|
|
111
|
-
};
|
|
112
|
-
return createRuntimeHttpProvider({
|
|
113
|
-
displayName: "Anthropic",
|
|
77
|
+
const build = (promptCachingOverride) => createRuntimeHttpProvider({
|
|
78
|
+
displayName: options.displayName ?? "Anthropic",
|
|
114
79
|
protocol: anthropicMessagesProtocol$1,
|
|
115
80
|
baseUrl: options.baseUrl ?? "https://api.anthropic.com",
|
|
116
|
-
auth:
|
|
117
|
-
|
|
118
|
-
name: "x-api-key",
|
|
119
|
-
value: options.apiKey,
|
|
120
|
-
label: "the `apiKey` option"
|
|
121
|
-
},
|
|
122
|
-
dialect,
|
|
81
|
+
auth: authOf(options),
|
|
82
|
+
dialect: dialectOf(options, promptCachingOverride),
|
|
123
83
|
describeModel: (info, effective) => ({
|
|
124
|
-
...
|
|
84
|
+
...info,
|
|
125
85
|
reasoning: info.reasoning ?? reasoningInfo(effective.budgets)
|
|
126
86
|
}),
|
|
127
87
|
...options.models === void 0 ? {} : { models: options.models },
|
|
128
|
-
defaultMaxTokens: options.defaultMaxTokens
|
|
129
|
-
defaultContextWindow: options.defaultContextWindow
|
|
88
|
+
...options.defaultMaxTokens === void 0 ? {} : { defaultMaxTokens: options.defaultMaxTokens },
|
|
89
|
+
...options.defaultContextWindow === void 0 ? {} : { defaultContextWindow: options.defaultContextWindow },
|
|
130
90
|
...options.streamIdleTimeoutMs === void 0 ? {} : { streamIdleTimeoutMs: options.streamIdleTimeoutMs },
|
|
131
91
|
...transportLimits(options),
|
|
132
92
|
...options.retryPolicy === void 0 ? {} : { retryPolicy: options.retryPolicy },
|
|
133
|
-
...options.requestLogger === void 0 ? {} : { requestLogger: options.requestLogger }
|
|
93
|
+
...options.requestLogger === void 0 ? {} : { requestLogger: options.requestLogger },
|
|
94
|
+
...options.responseLogger === void 0 ? {} : { responseLogger: options.responseLogger }
|
|
134
95
|
});
|
|
96
|
+
const primary = build();
|
|
97
|
+
if (options.promptCaching !== true) return primary;
|
|
98
|
+
return new FieldFallbackAdapter(primary, build(false), { isFieldRejection: isCacheControlRejection });
|
|
135
99
|
}
|
|
136
100
|
function usesRuntimeComposition(options) {
|
|
137
101
|
if ("id" in options || "defaultModel" in options) return true;
|
|
@@ -147,10 +111,76 @@ function runtimeDefaultModel(value, routes) {
|
|
|
147
111
|
id: value
|
|
148
112
|
}) };
|
|
149
113
|
}
|
|
114
|
+
/**
|
|
115
|
+
* This API's own header is `x-api-key`, unlike most others' `authorization:
|
|
116
|
+
* Bearer` — but a gateway sitting in front of it may expect Bearer instead.
|
|
117
|
+
*/
|
|
118
|
+
/**
|
|
119
|
+
* Generic over the credential type on purpose: the two call sites accept
|
|
120
|
+
* DIFFERENT ones — the legacy adapter takes {@link AnthropicCredential}
|
|
121
|
+
* (`provider-http`'s string-or-resolver), the composable one takes core's
|
|
122
|
+
* broader `CredentialInput`. A non-generic parameter union would widen
|
|
123
|
+
* `apiKey` to the union of both and fit neither target scheme.
|
|
124
|
+
*/
|
|
125
|
+
function authOf(options) {
|
|
126
|
+
return options.authHeader === "bearer" ? {
|
|
127
|
+
kind: "bearer",
|
|
128
|
+
token: options.apiKey,
|
|
129
|
+
label: "the `apiKey` option"
|
|
130
|
+
} : {
|
|
131
|
+
kind: "header",
|
|
132
|
+
name: "x-api-key",
|
|
133
|
+
value: options.apiKey,
|
|
134
|
+
label: "the `apiKey` option"
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
const ANTHROPIC_REASONING_FORMATS = /* @__PURE__ */ new Set(["output-config", "thinking-budget"]);
|
|
138
|
+
/**
|
|
139
|
+
* Build the dialect, rejecting a `reasoningFormat` that isn't one of this
|
|
140
|
+
* protocol's own two values. A JS caller (or one that fought past TypeScript
|
|
141
|
+
* with `as any`) mistyping a value from a DIFFERENT protocol — Chat
|
|
142
|
+
* Completions' `'deepseek'`, for instance — would otherwise fall through the
|
|
143
|
+
* `reasoningFormat === 'thinking-budget'` checks in `serialize.ts` and
|
|
144
|
+
* silently behave as `'output-config'` instead of failing loudly.
|
|
145
|
+
*/
|
|
146
|
+
/**
|
|
147
|
+
* @param promptCachingOverride - Forces `promptCaching` regardless of what
|
|
148
|
+
* `options` asked for — how the fallback build (never marks
|
|
149
|
+
* `cache_control`) differs from the primary one when caching is on.
|
|
150
|
+
* Omitted, `options.promptCaching` decides as normal.
|
|
151
|
+
*/
|
|
152
|
+
function dialectOf(options, promptCachingOverride) {
|
|
153
|
+
if (options.reasoningFormat !== void 0 && !ANTHROPIC_REASONING_FORMATS.has(options.reasoningFormat)) throw new TypeError(`Anthropic reasoningFormat must be 'output-config' or 'thinking-budget', received ${JSON.stringify(options.reasoningFormat)}`);
|
|
154
|
+
const budgets = options.thinkingBudgets ?? DEFAULT_THINKING_BUDGETS;
|
|
155
|
+
const promptCaching = promptCachingOverride ?? options.promptCaching;
|
|
156
|
+
return {
|
|
157
|
+
budgets,
|
|
158
|
+
...options.reasoningFormat === void 0 ? {} : { reasoningFormat: options.reasoningFormat },
|
|
159
|
+
...options.thinking === void 0 ? {} : { thinking: options.thinking },
|
|
160
|
+
...options.version === void 0 ? {} : { version: options.version },
|
|
161
|
+
...options.beta === void 0 ? {} : { beta: options.beta },
|
|
162
|
+
...promptCaching === void 0 ? {} : { promptCaching },
|
|
163
|
+
...options.promptCachingTtl === void 0 ? {} : { promptCachingTtl: options.promptCachingTtl }
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Recognize a dispatch rejection caused specifically by `cache_control` —
|
|
168
|
+
* the one signal {@link FieldFallbackAdapter} is allowed to react to. Scoped
|
|
169
|
+
* narrowly (a 400 whose message names the field) rather than treating every
|
|
170
|
+
* 400 as a reason to give up on caching, which would mask a real, unrelated
|
|
171
|
+
* request error behind a silent feature downgrade.
|
|
172
|
+
*/
|
|
173
|
+
function isCacheControlRejection(error) {
|
|
174
|
+
return error instanceof ModelError && error.failure.status === 400 && error.message.toLowerCase().includes("cache_control");
|
|
175
|
+
}
|
|
150
176
|
function transportLimits(options) {
|
|
151
177
|
return {
|
|
152
178
|
...options.allowInsecureHttp === void 0 ? {} : { allowInsecureHttp: options.allowInsecureHttp },
|
|
153
179
|
headers: endpointHeaders(options.headers),
|
|
180
|
+
...options.path === void 0 ? {} : { path: options.path },
|
|
181
|
+
...options.query === void 0 ? {} : { query: options.query },
|
|
182
|
+
...options.body === void 0 ? {} : { body: options.body },
|
|
183
|
+
...options.transformRequest === void 0 ? {} : { transformRequest: options.transformRequest },
|
|
154
184
|
...options.requestTimeoutMs === void 0 ? {} : { requestTimeoutMs: options.requestTimeoutMs },
|
|
155
185
|
...options.maxRequestBytes === void 0 ? {} : { maxRequestBytes: options.maxRequestBytes },
|
|
156
186
|
...options.maxResponseBytes === void 0 ? {} : { maxResponseBytes: options.maxResponseBytes },
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["anthropicMessagesProtocol"],"sources":["../src/context-policy.ts","../src/adapter.ts"],"sourcesContent":["import { createModelContextPolicy } from '@alvin0/ai-agent-sdk-provider-http'\nimport type { ModelContextPolicyOptions } from '@alvin0/ai-agent-sdk-provider-http'\n\n// Verified 2026-09-13: https://platform.claude.com/docs/en/build-with-claude/context-windows\nconst STANDARD_1M = Object.fromEntries([\n 'claude-opus-4-6', 'claude-opus-4-7', 'claude-opus-4-8', 'claude-opus-5',\n 'claude-sonnet-4-6', 'claude-sonnet-5', 'claude-fable-5', 'claude-fable-5-1',\n 'claude-mythos-5', 'claude-mythos-5-1', 'claude-mythos-preview',\n].map(id => [id, { defaultContextWindow: 1_000_000, maxContextWindow: 1_000_000 }]))\n\nexport function anthropicContextPolicy(options: ModelContextPolicyOptions) {\n return createModelContextPolicy(\n options.baseUrl === undefined || options.baseUrl.replace(/\\/$/, '') === 'https://api.anthropic.com'\n ? STANDARD_1M : {}, options.models, options.defaultContextWindow)\n}\n","/**\n * The Anthropic provider: the Messages API on `api.anthropic.com`.\n *\n * Configuration over {@link createHttpProvider}, like every other endpoint here.\n * The one thing it needs beyond the defaults is `describeModel`, to advertise its\n * thinking budgets as selectable reasoning efforts.\n *\n * @module ai-agent-sdk/providers/anthropic/adapter\n */\n\nimport type { ModelReasoningInfo } from '@alvin0/ai-agent-sdk-core'\nimport type { ModelProviderPlugin, ModelProviderRegistrar, RetryPolicyConfig } from '@alvin0/ai-agent-sdk-core'\nimport { anthropicContextPolicy } from './context-policy.ts'\nimport { ReasoningEffortId } from '@alvin0/ai-agent-sdk-core'\nimport {\n defineModelProviderPlugin,\n type ComposableModelProviderPlugin,\n type CredentialInput,\n type ModelTarget,\n} from '@alvin0/ai-agent-sdk-core/provider'\nimport type {\n HttpModelAdapter,\n ProviderCatalogModel,\n ProviderRequestLogger,\n} from '@alvin0/ai-agent-sdk-provider-http'\nimport {\n createHttpProvider,\n endpointHeaders,\n createRuntimeHttpProvider,\n type CredentialSource,\n} from '@alvin0/ai-agent-sdk-provider-http'\nimport {\n ANTHROPIC_VERSION,\n DEFAULT_THINKING_BUDGETS,\n anthropicMessagesProtocol,\n type AnthropicDialect,\n type ThinkingBudgets,\n} from '@alvin0/ai-agent-sdk-protocol-anthropic-messages'\n\n/** The Anthropic API base. */\nexport const ANTHROPIC_BASE_URL = 'https://api.anthropic.com'\n\n// Re-exported so callers can reach the protocol's constants from the provider\n// they are already importing.\nexport { ANTHROPIC_VERSION, DEFAULT_THINKING_BUDGETS }\n\n/** How the API key is obtained. */\nexport type AnthropicCredential = CredentialSource\n\n/** Turn the configured budgets into selectable reasoning efforts. */\nfunction reasoningInfo(budgets: ThinkingBudgets): ModelReasoningInfo {\n return {\n efforts: Object.keys(budgets).map(id => ({\n id: ReasoningEffortId(id),\n name: id.charAt(0).toUpperCase() + id.slice(1),\n description: budgets[id] === 0\n ? 'No extended thinking.'\n : `Up to ${budgets[id]?.toLocaleString() ?? '?'} thinking tokens.`,\n })),\n }\n}\n\n/** Options for {@link anthropicAdapter}. */\nexport interface AnthropicAdapterOptions {\n /** Injected API key or resolver. Universal packages never read environment variables. */\n apiKey: AnthropicCredential\n /** Endpoint base; defaults to {@link ANTHROPIC_BASE_URL}. */\n baseUrl?: string\n /** Extra endpoint headers, captured once per operation. Reserved names and collisions fail. */\n headers?: Readonly<Record<string, string>> | (() => Readonly<Record<string, string>>)\n /** Permit cleartext HTTP explicitly for trusted local gateways. */\n allowInsecureHttp?: boolean\n /** API version header; defaults to {@link ANTHROPIC_VERSION}. */\n version?: string\n /** Opt-in beta features, sent as `anthropic-beta`. */\n beta?: readonly string[]\n /**\n * Advisory model catalog.\n *\n * Empty by default: this package cannot know which model ids are current, and a\n * stale built-in list would name retired models.\n */\n models?: readonly ProviderCatalogModel[]\n /** Effort id to thinking-token budget; defaults to {@link DEFAULT_THINKING_BUDGETS}. */\n thinkingBudgets?: ThinkingBudgets\n /**\n * Output cap when neither caller nor catalog names one.\n *\n * This API REQUIRES `max_tokens`, so a default always has to exist.\n */\n defaultMaxTokens?: number\n /** Context capacity assumed for an uncatalogued model. */\n defaultContextWindow?: number\n /** Idle bound while a stream read is outstanding. */\n streamIdleTimeoutMs?: number\n requestTimeoutMs?: number\n maxRequestBytes?: number\n maxResponseBytes?: number\n maxResponseChunks?: number\n maxSseEvents?: number\n maxSseEventChars?: number\n maxErrorBodyBytes?: number\n requestLoggerTimeoutMs?: number\n /** Retry policy this route owns. */\n retryPolicy?: RetryPolicyConfig\n /** Optional exact wire-request logger; credentials are redacted. */\n requestLogger?: ProviderRequestLogger\n fetch?: typeof globalThis.fetch\n}\n\n/**\n * Create an Anthropic adapter.\n * @param options - credential, endpoint, and thinking-budget overrides.\n * @returns the adapter, ready to register.\n */\nexport function anthropicAdapter(options: AnthropicAdapterOptions): HttpModelAdapter {\n const contextPolicy = anthropicContextPolicy(options)\n const budgets = options.thinkingBudgets ?? DEFAULT_THINKING_BUDGETS\n const dialect: Partial<AnthropicDialect> = {\n budgets,\n ...options.version === undefined ? {} : { version: options.version },\n ...options.beta === undefined ? {} : { beta: options.beta },\n }\n\n return createHttpProvider({\n displayName: 'Anthropic',\n protocol: anthropicMessagesProtocol,\n baseUrl: options.baseUrl ?? ANTHROPIC_BASE_URL,\n // This API uses its own header rather than `authorization: Bearer`.\n auth: {\n kind: 'header',\n name: 'x-api-key',\n value: options.apiKey,\n label: 'the `apiKey` option',\n },\n dialect,\n describeModel: (info, effective) => ({\n ...contextPolicy(info),\n reasoning: info.reasoning ?? reasoningInfo(effective.budgets),\n }),\n ...options.models === undefined ? {} : { models: options.models },\n defaultMaxTokens: options.defaultMaxTokens ?? 8_192,\n defaultContextWindow: options.defaultContextWindow ?? 200_000,\n ...options.streamIdleTimeoutMs === undefined\n ? {}\n : { streamIdleTimeoutMs: options.streamIdleTimeoutMs },\n ...transportLimits(options),\n ...options.retryPolicy === undefined ? {} : { retryPolicy: options.retryPolicy },\n ...options.requestLogger === undefined ? {} : { requestLogger: options.requestLogger },\n })\n}\n\nexport interface AnthropicPluginOptions extends AnthropicAdapterOptions {\n /** Registry routes installed by the plugin. Defaults to `['anthropic']`. */\n readonly routes?: readonly string[]\n}\n\nexport interface AnthropicProviderOptions extends Omit<AnthropicAdapterOptions, 'apiKey'> {\n readonly defaultModel?: string | ModelTarget\n readonly apiKey: CredentialInput\n readonly id?: string\n readonly routes?: readonly string[]\n}\n\n/** Preferred transactional plugin for installing the Anthropic provider. */\nexport function anthropicPlugin(\n options: AnthropicProviderOptions,\n): ComposableModelProviderPlugin & { readonly family: 'anthropic' }\nexport function anthropicPlugin(options: AnthropicPluginOptions): ModelProviderPlugin\nexport function anthropicPlugin(\n options: AnthropicProviderOptions | AnthropicPluginOptions,\n): ModelProviderPlugin | (ComposableModelProviderPlugin & { readonly family: 'anthropic' }) {\n if (!usesRuntimeComposition(options)) return legacyAnthropicPlugin(options)\n const id = options.id ?? 'anthropic'\n const routes = Object.freeze([...(options.routes ?? [id])])\n return defineModelProviderPlugin({\n id,\n family: 'anthropic',\n displayName: 'Anthropic',\n routes,\n ...runtimeDefaultModel(options.defaultModel, routes),\n setup(registrar) {\n const adapter = createRuntimeAnthropicAdapter(options)\n const remove = registrar.registerAdapter(adapter)\n return () => { remove(); return undefined }\n },\n }) as ComposableModelProviderPlugin & { readonly family: 'anthropic' }\n}\n\nfunction legacyAnthropicPlugin(options: AnthropicPluginOptions): ModelProviderPlugin {\n const routes = Object.freeze([...(options.routes ?? ['anthropic'])])\n const adapter = anthropicAdapter(options)\n return Object.freeze({\n id: 'anthropic',\n displayName: 'Anthropic',\n setup(registrar: ModelProviderRegistrar) {\n registrar.registerAdapter(routes, adapter)\n },\n })\n}\n\nfunction createRuntimeAnthropicAdapter(options: AnthropicProviderOptions): HttpModelAdapter {\n const contextPolicy = anthropicContextPolicy(options)\n const budgets = options.thinkingBudgets ?? DEFAULT_THINKING_BUDGETS\n const dialect: Partial<AnthropicDialect> = {\n budgets,\n ...(options.version === undefined ? {} : { version: options.version }),\n ...(options.beta === undefined ? {} : { beta: options.beta }),\n }\n return createRuntimeHttpProvider({\n displayName: 'Anthropic',\n protocol: anthropicMessagesProtocol,\n baseUrl: options.baseUrl ?? ANTHROPIC_BASE_URL,\n auth: {\n kind: 'header',\n name: 'x-api-key',\n value: options.apiKey,\n label: 'the `apiKey` option',\n },\n dialect,\n describeModel: (info, effective) => ({\n ...contextPolicy(info),\n reasoning: info.reasoning ?? reasoningInfo(effective.budgets),\n }),\n ...(options.models === undefined ? {} : { models: options.models }),\n defaultMaxTokens: options.defaultMaxTokens ?? 8_192,\n defaultContextWindow: options.defaultContextWindow ?? 200_000,\n ...(options.streamIdleTimeoutMs === undefined ? {} : { streamIdleTimeoutMs: options.streamIdleTimeoutMs }),\n ...transportLimits(options),\n ...(options.retryPolicy === undefined ? {} : { retryPolicy: options.retryPolicy }),\n ...(options.requestLogger === undefined ? {} : { requestLogger: options.requestLogger }),\n })\n}\n\nfunction usesRuntimeComposition(\n options: AnthropicProviderOptions | AnthropicPluginOptions,\n): options is AnthropicProviderOptions {\n if ('id' in options || 'defaultModel' in options) return true\n if (typeof options.apiKey === 'object' && options.apiKey !== null) return true\n return typeof options.apiKey !== 'function'\n}\n\nfunction runtimeDefaultModel(\n value: string | ModelTarget | undefined,\n routes: readonly string[],\n): { readonly defaultModel?: ModelTarget } {\n if (value === undefined) return {}\n if (typeof value !== 'string') return { defaultModel: value }\n if (routes.length !== 1) {\n throw new TypeError('A string defaultModel requires exactly one Anthropic route')\n }\n return { defaultModel: Object.freeze({ provider: routes[0]!, id: value }) }\n}\n\nfunction transportLimits(options: AnthropicAdapterOptions | AnthropicProviderOptions) {\n return {\n ...(options.allowInsecureHttp === undefined ? {} : { allowInsecureHttp: options.allowInsecureHttp }),\n headers: endpointHeaders(options.headers),\n ...options.requestTimeoutMs === undefined ? {} : { requestTimeoutMs: options.requestTimeoutMs },\n ...options.maxRequestBytes === undefined ? {} : { maxRequestBytes: options.maxRequestBytes },\n ...options.maxResponseBytes === undefined ? {} : { maxResponseBytes: options.maxResponseBytes },\n ...options.maxResponseChunks === undefined ? {} : { maxResponseChunks: options.maxResponseChunks },\n ...options.maxSseEvents === undefined ? {} : { maxSseEvents: options.maxSseEvents },\n ...options.maxSseEventChars === undefined ? {} : { maxSseEventChars: options.maxSseEventChars },\n ...options.maxErrorBodyBytes === undefined ? {} : { maxErrorBodyBytes: options.maxErrorBodyBytes },\n ...options.requestLoggerTimeoutMs === undefined ? {} : { requestLoggerTimeoutMs: options.requestLoggerTimeoutMs },\n ...options.fetch === undefined ? {} : { fetch: options.fetch },\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["anthropicMessagesProtocol"],"sources":["../src/adapter.ts"],"sourcesContent":["/**\n * The Anthropic provider: the Messages API on `api.anthropic.com`.\n *\n * Configuration over {@link createHttpProvider}, like every other endpoint here.\n * The one thing it needs beyond the defaults is `describeModel`, to advertise its\n * thinking budgets as selectable reasoning efforts.\n *\n * @module ai-agent-sdk/providers/anthropic/adapter\n */\n\nimport type { ModelReasoningInfo } from '@alvin0/ai-agent-sdk-core'\nimport type { ModelProviderPlugin, ModelProviderRegistrar, RetryPolicyConfig } from '@alvin0/ai-agent-sdk-core'\nimport { ModelAdapter, ModelError, ReasoningEffortId } from '@alvin0/ai-agent-sdk-core'\nimport {\n defineModelProviderPlugin,\n type ComposableModelProviderPlugin,\n type CredentialInput,\n type ModelTarget,\n} from '@alvin0/ai-agent-sdk-core/provider'\nimport type {\n HeaderContext,\n HttpModelAdapter,\n ProviderCatalogModel,\n ProviderRequestLogger,\n ProviderResponseLogger,\n RequestContext,\n} from '@alvin0/ai-agent-sdk-provider-http'\nimport {\n createHttpProvider,\n endpointHeaders,\n createRuntimeHttpProvider,\n FieldFallbackAdapter,\n type CredentialSource,\n} from '@alvin0/ai-agent-sdk-provider-http'\nimport {\n ANTHROPIC_VERSION,\n DEFAULT_THINKING_BUDGETS,\n anthropicMessagesProtocol,\n type AnthropicDialect,\n type AnthropicReasoningFormat,\n type ThinkingBudgets,\n} from '@alvin0/ai-agent-sdk-protocol-anthropic-messages'\n\n/** The Anthropic API base. */\nexport const ANTHROPIC_BASE_URL = 'https://api.anthropic.com'\n\n// Re-exported so callers can reach the protocol's constants from the provider\n// they are already importing.\nexport { ANTHROPIC_VERSION, DEFAULT_THINKING_BUDGETS }\n\n/** How the API key is obtained. */\nexport type AnthropicCredential = CredentialSource\n\n/** Turn the configured budgets into selectable reasoning efforts. */\nfunction reasoningInfo(budgets: ThinkingBudgets): ModelReasoningInfo {\n return {\n efforts: Object.keys(budgets).map(id => ({\n id: ReasoningEffortId(id),\n name: id.charAt(0).toUpperCase() + id.slice(1),\n description: budgets[id] === 0\n ? 'No extended thinking.'\n : `Up to ${budgets[id]?.toLocaleString() ?? '?'} thinking tokens.`,\n })),\n }\n}\n\n/** Options for {@link anthropicAdapter}. */\nexport interface AnthropicAdapterOptions {\n /** Injected API key or resolver. Universal packages never read environment variables. */\n apiKey: AnthropicCredential\n /** Endpoint base; defaults to {@link ANTHROPIC_BASE_URL}. */\n baseUrl?: string\n /**\n * Name this endpoint uses in diagnostics and error messages. Defaults to\n * `'Anthropic'`; set it to the real vendor name (e.g. `'Kimi'`) when pointing\n * this provider at a compatible gateway, so a rejection names who rejected it.\n */\n displayName?: string\n /** Extra endpoint headers, captured once per operation. Reserved names and collisions fail. */\n headers?: Readonly<Record<string, string>> | ((ctx: HeaderContext) => Readonly<Record<string, string>>)\n /** Permit cleartext HTTP explicitly for trusted local gateways. */\n allowInsecureHttp?: boolean\n /** Override the request path this protocol would otherwise pick (e.g. a gateway deployment path). */\n path?: string\n /** Extra query-string parameters, or a resolver for them. Never for secrets. */\n query?: Readonly<Record<string, string>> | (() => Readonly<Record<string, string>>)\n /**\n * Fields to deep-merge into the serialized body. The caller's value always\n * wins, even over a field the SDK set. A `null` value deletes the field.\n */\n body?: Readonly<Record<string, unknown>>\n /** Last-resort hook with full authority over the body, run after `body` is merged in. */\n transformRequest?: (body: unknown, ctx: RequestContext) => unknown\n /** API version header; defaults to {@link ANTHROPIC_VERSION}. */\n version?: string\n /** Opt-in beta features, sent as `anthropic-beta`. */\n beta?: readonly string[]\n /**\n * Advisory model catalog.\n *\n * Empty by default: this package cannot know which model ids are current, and a\n * stale built-in list would name retired models.\n */\n models?: readonly ProviderCatalogModel[]\n /**\n * Which field carries reasoning effort. Defaults to `'output-config'`\n * (current GA models): the caller's effort string reaches\n * `output_config.effort` verbatim — pure pass-through, no SDK conversion.\n * Set `'thinking-budget'` for an older model or a gateway that only\n * understands a token budget; then effort is converted via `thinkingBudgets`\n * instead of being sent raw.\n */\n reasoningFormat?: AnthropicReasoningFormat\n /** Effort id to thinking-token budget; only consulted under `reasoningFormat: 'thinking-budget'`. */\n thinkingBudgets?: ThinkingBudgets\n /**\n * Extended-thinking mode, sent only when set. Independent of effort under\n * `'output-config'` — omission leaves the model's own default thinking\n * behavior alone rather than the SDK guessing one from the effort.\n */\n thinking?: 'adaptive' | 'disabled'\n /**\n * Mark the stable prefix of every request (system prompt, tool\n * definitions, every message but the newest) as a `cache_control`\n * breakpoint, so a long conversation reads its own unchanged history back\n * at a steep discount instead of paying to reprocess it on every turn.\n *\n * Off by default: this is an Anthropic-specific extension, and a gateway\n * behind this same adapter that speaks the Messages API but does not\n * understand `cache_control` should not be asked to guess. If a live\n * dispatch is ever rejected specifically for it, this adapter turns\n * caching off for itself, permanently, and retries once without it — it\n * never fails a call over an optimization the caller opted into.\n */\n promptCaching?: boolean\n /** Cache breakpoint lifetime. Defaults to this API's own default (5 minutes). */\n promptCachingTtl?: '5m' | '1h'\n /** How the API key travels. Defaults to `'x-api-key'`, this API's own header. */\n authHeader?: 'x-api-key' | 'bearer'\n /**\n * Output cap when neither caller nor catalog names one.\n *\n * This API REQUIRES `max_tokens`, so a default always has to exist.\n */\n defaultMaxTokens?: number\n /** Context capacity assumed for an uncatalogued model. */\n defaultContextWindow?: number\n /** Idle bound while a stream read is outstanding. */\n streamIdleTimeoutMs?: number\n requestTimeoutMs?: number\n maxRequestBytes?: number\n maxResponseBytes?: number\n maxResponseChunks?: number\n maxSseEvents?: number\n maxSseEventChars?: number\n maxErrorBodyBytes?: number\n requestLoggerTimeoutMs?: number\n /** Retry policy this route owns. */\n retryPolicy?: RetryPolicyConfig\n /** Optional exact wire-request logger; credentials are redacted. */\n requestLogger?: ProviderRequestLogger\n /** Optional exact wire-response logger, fired once a stream ends. */\n responseLogger?: ProviderResponseLogger\n fetch?: typeof globalThis.fetch\n}\n\n/**\n * Create an Anthropic adapter.\n * @param options - credential, endpoint, and thinking-budget overrides.\n * @returns the adapter, ready to register.\n */\nexport function anthropicAdapter(options: AnthropicAdapterOptions): ModelAdapter {\n const build = (promptCachingOverride?: boolean): HttpModelAdapter => createHttpProvider({\n displayName: options.displayName ?? 'Anthropic',\n protocol: anthropicMessagesProtocol,\n baseUrl: options.baseUrl ?? ANTHROPIC_BASE_URL,\n auth: authOf(options),\n dialect: dialectOf(options, promptCachingOverride),\n describeModel: (info, effective) => ({\n ...info,\n reasoning: info.reasoning ?? reasoningInfo(effective.budgets),\n }),\n ...options.models === undefined ? {} : { models: options.models },\n ...options.defaultMaxTokens === undefined ? {} : { defaultMaxTokens: options.defaultMaxTokens },\n ...options.defaultContextWindow === undefined ? {} : { defaultContextWindow: options.defaultContextWindow },\n ...options.streamIdleTimeoutMs === undefined\n ? {}\n : { streamIdleTimeoutMs: options.streamIdleTimeoutMs },\n ...transportLimits(options),\n ...options.retryPolicy === undefined ? {} : { retryPolicy: options.retryPolicy },\n ...options.requestLogger === undefined ? {} : { requestLogger: options.requestLogger },\n ...options.responseLogger === undefined ? {} : { responseLogger: options.responseLogger },\n })\n const primary = build()\n // Only wrapped when caching is actually requested: an adapter nobody asked\n // to cache anything with pays nothing extra.\n if (options.promptCaching !== true) return primary\n return new FieldFallbackAdapter(primary, build(false), { isFieldRejection: isCacheControlRejection })\n}\n\nexport interface AnthropicPluginOptions extends AnthropicAdapterOptions {\n /** Registry routes installed by the plugin. Defaults to `['anthropic']`. */\n readonly routes?: readonly string[]\n}\n\nexport interface AnthropicProviderOptions extends Omit<AnthropicAdapterOptions, 'apiKey'> {\n readonly defaultModel?: string | ModelTarget\n readonly apiKey: CredentialInput\n readonly id?: string\n readonly routes?: readonly string[]\n}\n\n/** Preferred transactional plugin for installing the Anthropic provider. */\nexport function anthropicPlugin(\n options: AnthropicProviderOptions,\n): ComposableModelProviderPlugin & { readonly family: 'anthropic' }\nexport function anthropicPlugin(options: AnthropicPluginOptions): ModelProviderPlugin\nexport function anthropicPlugin(\n options: AnthropicProviderOptions | AnthropicPluginOptions,\n): ModelProviderPlugin | (ComposableModelProviderPlugin & { readonly family: 'anthropic' }) {\n if (!usesRuntimeComposition(options)) return legacyAnthropicPlugin(options)\n const id = options.id ?? 'anthropic'\n const routes = Object.freeze([...(options.routes ?? [id])])\n return defineModelProviderPlugin({\n id,\n family: 'anthropic',\n displayName: options.displayName ?? 'Anthropic',\n routes,\n ...runtimeDefaultModel(options.defaultModel, routes),\n setup(registrar) {\n const adapter = createRuntimeAnthropicAdapter(options)\n const remove = registrar.registerAdapter(adapter)\n return () => { remove(); return undefined }\n },\n }) as ComposableModelProviderPlugin & { readonly family: 'anthropic' }\n}\n\nfunction legacyAnthropicPlugin(options: AnthropicPluginOptions): ModelProviderPlugin {\n const routes = Object.freeze([...(options.routes ?? ['anthropic'])])\n const adapter = anthropicAdapter(options)\n return Object.freeze({\n id: 'anthropic',\n displayName: options.displayName ?? 'Anthropic',\n setup(registrar: ModelProviderRegistrar) {\n registrar.registerAdapter(routes, adapter)\n },\n })\n}\n\nfunction createRuntimeAnthropicAdapter(options: AnthropicProviderOptions): ModelAdapter {\n const build = (promptCachingOverride?: boolean): HttpModelAdapter => createRuntimeHttpProvider({\n displayName: options.displayName ?? 'Anthropic',\n protocol: anthropicMessagesProtocol,\n baseUrl: options.baseUrl ?? ANTHROPIC_BASE_URL,\n auth: authOf(options),\n dialect: dialectOf(options, promptCachingOverride),\n describeModel: (info, effective) => ({\n ...info,\n reasoning: info.reasoning ?? reasoningInfo(effective.budgets),\n }),\n ...(options.models === undefined ? {} : { models: options.models }),\n ...(options.defaultMaxTokens === undefined ? {} : { defaultMaxTokens: options.defaultMaxTokens }),\n ...(options.defaultContextWindow === undefined ? {} : { defaultContextWindow: options.defaultContextWindow }),\n ...(options.streamIdleTimeoutMs === undefined ? {} : { streamIdleTimeoutMs: options.streamIdleTimeoutMs }),\n ...transportLimits(options),\n ...(options.retryPolicy === undefined ? {} : { retryPolicy: options.retryPolicy }),\n ...(options.requestLogger === undefined ? {} : { requestLogger: options.requestLogger }),\n ...(options.responseLogger === undefined ? {} : { responseLogger: options.responseLogger }),\n })\n const primary = build()\n if (options.promptCaching !== true) return primary\n return new FieldFallbackAdapter(primary, build(false), { isFieldRejection: isCacheControlRejection })\n}\n\nfunction usesRuntimeComposition(\n options: AnthropicProviderOptions | AnthropicPluginOptions,\n): options is AnthropicProviderOptions {\n if ('id' in options || 'defaultModel' in options) return true\n if (typeof options.apiKey === 'object' && options.apiKey !== null) return true\n return typeof options.apiKey !== 'function'\n}\n\nfunction runtimeDefaultModel(\n value: string | ModelTarget | undefined,\n routes: readonly string[],\n): { readonly defaultModel?: ModelTarget } {\n if (value === undefined) return {}\n if (typeof value !== 'string') return { defaultModel: value }\n if (routes.length !== 1) {\n throw new TypeError('A string defaultModel requires exactly one Anthropic route')\n }\n return { defaultModel: Object.freeze({ provider: routes[0]!, id: value }) }\n}\n\n/**\n * This API's own header is `x-api-key`, unlike most others' `authorization:\n * Bearer` — but a gateway sitting in front of it may expect Bearer instead.\n */\n/**\n * Generic over the credential type on purpose: the two call sites accept\n * DIFFERENT ones — the legacy adapter takes {@link AnthropicCredential}\n * (`provider-http`'s string-or-resolver), the composable one takes core's\n * broader `CredentialInput`. A non-generic parameter union would widen\n * `apiKey` to the union of both and fit neither target scheme.\n */\nfunction authOf<Credential>(options: {\n readonly authHeader?: 'x-api-key' | 'bearer'\n readonly apiKey: Credential\n}) {\n return options.authHeader === 'bearer'\n ? { kind: 'bearer' as const, token: options.apiKey, label: 'the `apiKey` option' }\n : { kind: 'header' as const, name: 'x-api-key', value: options.apiKey, label: 'the `apiKey` option' }\n}\n\nconst ANTHROPIC_REASONING_FORMATS = new Set(['output-config', 'thinking-budget'])\n\n/**\n * Build the dialect, rejecting a `reasoningFormat` that isn't one of this\n * protocol's own two values. A JS caller (or one that fought past TypeScript\n * with `as any`) mistyping a value from a DIFFERENT protocol — Chat\n * Completions' `'deepseek'`, for instance — would otherwise fall through the\n * `reasoningFormat === 'thinking-budget'` checks in `serialize.ts` and\n * silently behave as `'output-config'` instead of failing loudly.\n */\n/**\n * @param promptCachingOverride - Forces `promptCaching` regardless of what\n * `options` asked for — how the fallback build (never marks\n * `cache_control`) differs from the primary one when caching is on.\n * Omitted, `options.promptCaching` decides as normal.\n */\nfunction dialectOf(\n options: AnthropicAdapterOptions | AnthropicProviderOptions,\n promptCachingOverride?: boolean,\n): Partial<AnthropicDialect> {\n if (options.reasoningFormat !== undefined && !ANTHROPIC_REASONING_FORMATS.has(options.reasoningFormat)) {\n throw new TypeError(\n `Anthropic reasoningFormat must be 'output-config' or 'thinking-budget', received ${JSON.stringify(options.reasoningFormat)}`,\n )\n }\n const budgets = options.thinkingBudgets ?? DEFAULT_THINKING_BUDGETS\n const promptCaching = promptCachingOverride ?? options.promptCaching\n return {\n budgets,\n ...(options.reasoningFormat === undefined ? {} : { reasoningFormat: options.reasoningFormat }),\n ...(options.thinking === undefined ? {} : { thinking: options.thinking }),\n ...(options.version === undefined ? {} : { version: options.version }),\n ...(options.beta === undefined ? {} : { beta: options.beta }),\n ...(promptCaching === undefined ? {} : { promptCaching }),\n ...(options.promptCachingTtl === undefined ? {} : { promptCachingTtl: options.promptCachingTtl }),\n }\n}\n\n/**\n * Recognize a dispatch rejection caused specifically by `cache_control` —\n * the one signal {@link FieldFallbackAdapter} is allowed to react to. Scoped\n * narrowly (a 400 whose message names the field) rather than treating every\n * 400 as a reason to give up on caching, which would mask a real, unrelated\n * request error behind a silent feature downgrade.\n */\nfunction isCacheControlRejection(error: unknown): boolean {\n return error instanceof ModelError\n && error.failure.status === 400\n && error.message.toLowerCase().includes('cache_control')\n}\n\nfunction transportLimits(options: AnthropicAdapterOptions | AnthropicProviderOptions) {\n return {\n ...(options.allowInsecureHttp === undefined ? {} : { allowInsecureHttp: options.allowInsecureHttp }),\n headers: endpointHeaders(options.headers),\n ...options.path === undefined ? {} : { path: options.path },\n ...options.query === undefined ? {} : { query: options.query },\n ...options.body === undefined ? {} : { body: options.body },\n ...options.transformRequest === undefined ? {} : { transformRequest: options.transformRequest },\n ...options.requestTimeoutMs === undefined ? {} : { requestTimeoutMs: options.requestTimeoutMs },\n ...options.maxRequestBytes === undefined ? {} : { maxRequestBytes: options.maxRequestBytes },\n ...options.maxResponseBytes === undefined ? {} : { maxResponseBytes: options.maxResponseBytes },\n ...options.maxResponseChunks === undefined ? {} : { maxResponseChunks: options.maxResponseChunks },\n ...options.maxSseEvents === undefined ? {} : { maxSseEvents: options.maxSseEvents },\n ...options.maxSseEventChars === undefined ? {} : { maxSseEventChars: options.maxSseEventChars },\n ...options.maxErrorBodyBytes === undefined ? {} : { maxErrorBodyBytes: options.maxErrorBodyBytes },\n ...options.requestLoggerTimeoutMs === undefined ? {} : { requestLoggerTimeoutMs: options.requestLoggerTimeoutMs },\n ...options.fetch === undefined ? {} : { fetch: options.fetch },\n }\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"name": "alvin0 - chaulamdinhai",
|
|
5
5
|
"email": "chaulamdinhai@gmail.com"
|
|
6
6
|
},
|
|
7
|
-
"version": "0.1.
|
|
7
|
+
"version": "0.1.4",
|
|
8
8
|
"description": "Universal Anthropic adapter and provider plugin for ai-agent-sdk",
|
|
9
9
|
"license": "MIT",
|
|
10
10
|
"repository": {
|
|
@@ -38,15 +38,15 @@
|
|
|
38
38
|
"provenance": true
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@alvin0/ai-agent-sdk-provider-http": "^0.1.
|
|
42
|
-
"@alvin0/ai-agent-sdk-protocol-anthropic-messages": "^0.1.
|
|
41
|
+
"@alvin0/ai-agent-sdk-provider-http": "^0.1.4",
|
|
42
|
+
"@alvin0/ai-agent-sdk-protocol-anthropic-messages": "^0.1.4"
|
|
43
43
|
},
|
|
44
44
|
"peerDependencies": {
|
|
45
|
-
"@alvin0/ai-agent-sdk-core": "^0.1.
|
|
45
|
+
"@alvin0/ai-agent-sdk-core": "^0.1.4"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
|
-
"@alvin0/ai-agent-sdk-core": "^0.1.
|
|
49
|
-
"@alvin0/ai-agent-sdk-testkit": "^0.1.
|
|
48
|
+
"@alvin0/ai-agent-sdk-core": "^0.1.4",
|
|
49
|
+
"@alvin0/ai-agent-sdk-testkit": "^0.1.4",
|
|
50
50
|
"@arethetypeswrong/cli": "0.18.5",
|
|
51
51
|
"playwright": "1.62.1",
|
|
52
52
|
"publint": "0.3.24",
|