@alvin0/ai-agent-sdk-provider-anthropic 0.1.0 → 0.1.1

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/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
+ import { CredentialSource, HttpModelAdapter, ProviderCatalogModel, ProviderRequestLogger } from "@alvin0/ai-agent-sdk-provider-http";
1
2
  import { ModelProviderPlugin, RetryPolicyConfig } from "@alvin0/ai-agent-sdk-core";
2
3
  import { ComposableModelProviderPlugin, CredentialInput, ModelTarget } from "@alvin0/ai-agent-sdk-core/provider";
3
- import { CredentialSource, HttpModelAdapter, ProviderCatalogModel, ProviderRequestLogger } from "@alvin0/ai-agent-sdk-provider-http";
4
4
  import { ANTHROPIC_VERSION, AnthropicDialect, 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. */
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/adapter.ts"],"mappings":";;;;;;cAsCa;;KAOD,sBAAsB;;UAgBjB;;EAEf,QAAQ;;EAER;;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;UAoCnD,+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":";;;;;;cAuCa;;KAOD,sBAAsB;;UAgBjB;;EAEf,QAAQ;;EAER;;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"}
package/dist/index.js CHANGED
@@ -1,8 +1,30 @@
1
+ import { createHttpProvider, createModelContextPolicy, createRuntimeHttpProvider } from "@alvin0/ai-agent-sdk-provider-http";
1
2
  import { ReasoningEffortId } from "@alvin0/ai-agent-sdk-core";
2
3
  import { defineModelProviderPlugin } from "@alvin0/ai-agent-sdk-core/provider";
3
- import { createHttpProvider, createRuntimeHttpProvider } 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
6
28
  //#region src/adapter.ts
7
29
  /** The Anthropic API base. */
8
30
  const ANTHROPIC_BASE_URL = "https://api.anthropic.com";
@@ -20,6 +42,7 @@ function reasoningInfo(budgets) {
20
42
  * @returns the adapter, ready to register.
21
43
  */
22
44
  function anthropicAdapter(options) {
45
+ const contextPolicy = anthropicContextPolicy(options);
23
46
  const dialect = {
24
47
  budgets: options.thinkingBudgets ?? DEFAULT_THINKING_BUDGETS,
25
48
  ...options.version === void 0 ? {} : { version: options.version },
@@ -37,7 +60,7 @@ function anthropicAdapter(options) {
37
60
  },
38
61
  dialect,
39
62
  describeModel: (info, effective) => ({
40
- ...info,
63
+ ...contextPolicy(info),
41
64
  reasoning: info.reasoning ?? reasoningInfo(effective.budgets)
42
65
  }),
43
66
  ...options.models === void 0 ? {} : { models: options.models },
@@ -80,6 +103,7 @@ function legacyAnthropicPlugin(options) {
80
103
  });
81
104
  }
82
105
  function createRuntimeAnthropicAdapter(options) {
106
+ const contextPolicy = anthropicContextPolicy(options);
83
107
  const dialect = {
84
108
  budgets: options.thinkingBudgets ?? DEFAULT_THINKING_BUDGETS,
85
109
  ...options.version === void 0 ? {} : { version: options.version },
@@ -97,7 +121,7 @@ function createRuntimeAnthropicAdapter(options) {
97
121
  },
98
122
  dialect,
99
123
  describeModel: (info, effective) => ({
100
- ...info,
124
+ ...contextPolicy(info),
101
125
  reasoning: info.reasoning ?? reasoningInfo(effective.budgets)
102
126
  }),
103
127
  ...options.models === void 0 ? {} : { models: options.models },
package/dist/index.js.map CHANGED
@@ -1 +1 @@
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 { 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 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 /** 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 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 ...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 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 ...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.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/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 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 /** 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.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.0",
7
+ "version": "0.1.1",
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.0",
42
- "@alvin0/ai-agent-sdk-protocol-anthropic-messages": "^0.1.0"
41
+ "@alvin0/ai-agent-sdk-provider-http": "^0.1.1",
42
+ "@alvin0/ai-agent-sdk-protocol-anthropic-messages": "^0.1.1"
43
43
  },
44
44
  "peerDependencies": {
45
- "@alvin0/ai-agent-sdk-core": "^0.1.0"
45
+ "@alvin0/ai-agent-sdk-core": "^0.1.1"
46
46
  },
47
47
  "devDependencies": {
48
- "@alvin0/ai-agent-sdk-core": "^0.1.0",
49
- "@alvin0/ai-agent-sdk-testkit": "^0.1.0",
48
+ "@alvin0/ai-agent-sdk-core": "^0.1.1",
49
+ "@alvin0/ai-agent-sdk-testkit": "^0.1.1",
50
50
  "@arethetypeswrong/cli": "0.18.5",
51
51
  "playwright": "1.62.1",
52
52
  "publint": "0.3.24",