@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 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; collisions and reserved auth/transport headers
9
- are rejected. Supply credentials with `apiKey`; use `version` and `beta` for
10
- Anthropic protocol headers. Static records are copied.
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 { CredentialSource, HttpModelAdapter, ProviderCatalogModel, ProviderRequestLogger } from "@alvin0/ai-agent-sdk-provider-http";
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 { ANTHROPIC_VERSION, AnthropicDialect, AnthropicReasoningState, DEFAULT_THINKING_BUDGETS, ThinkingBudgets, ThinkingBudgets as ThinkingBudgets$1, anthropicMessagesProtocol } from "@alvin0/ai-agent-sdk-protocol-anthropic-messages";
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
- /** Effort id to thinking-token budget; defaults to {@link DEFAULT_THINKING_BUDGETS}. */
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): HttpModelAdapter;
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[];
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/adapter.ts"],"mappings":";;;;;;cAwCa;;KAOD,sBAAsB;;UAgBjB;;EAEf,QAAQ;;EAER;;EAEA,UAAU,SAAS,iCAAiC,SAAS;;EAE7D;;EAEA;;EAEA;;;;;;;EAOA,kBAAkB;;EAElB,kBAAkB;;;;;;EAMlB;;EAEA;;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;EAEA,cAAc;;EAEd,gBAAgB;EAChB,eAAe,WAAW;;;;;;;iBAQZ,iBAAiB,SAAS,0BAA0B;UAqCnD,+BAA+B;;WAErC;;UAGM,iCAAiC,KAAK;WAC5C,wBAAwB;WACxB,QAAQ;WACR;WACA;;;iBAIK,gBACd,SAAS,2BACR;WAA2C;;iBAC9B,gBAAgB,SAAS,yBAAyB"}
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 { createHttpProvider, createModelContextPolicy, createRuntimeHttpProvider, endpointHeaders } from "@alvin0/ai-agent-sdk-provider-http";
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 contextPolicy = anthropicContextPolicy(options);
46
- const dialect = {
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
- kind: "header",
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
- ...contextPolicy(info),
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 ?? 8192,
68
- defaultContextWindow: options.defaultContextWindow ?? 2e5,
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 contextPolicy = anthropicContextPolicy(options);
107
- const dialect = {
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
- kind: "header",
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
- ...contextPolicy(info),
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 ?? 8192,
129
- defaultContextWindow: options.defaultContextWindow ?? 2e5,
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.3",
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.3",
42
- "@alvin0/ai-agent-sdk-protocol-anthropic-messages": "^0.1.3"
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.3"
45
+ "@alvin0/ai-agent-sdk-core": "^0.1.4"
46
46
  },
47
47
  "devDependencies": {
48
- "@alvin0/ai-agent-sdk-core": "^0.1.3",
49
- "@alvin0/ai-agent-sdk-testkit": "^0.1.3",
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",