@rulvar/anthropic 1.14.0 → 1.16.0

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,3 +1,4 @@
1
+ import Anthropic, { ClientOptions } from "@anthropic-ai/sdk";
1
2
  import { CanonicalId, ChatEvent, ChatRequest, FinishInfo, ModelCaps, PriceTable, ProviderAdapter, Usage, WireError } from "@rulvar/core";
2
3
 
3
4
  //#region src/caps.d.ts
@@ -59,16 +60,44 @@ interface AnthropicClientLike {
59
60
  }>;
60
61
  };
61
62
  }
63
+ /**
64
+ * Official SDK construction options forwarded verbatim to
65
+ * `new Anthropic(...)`, minus `maxRetries`: Rulvar owns retries and
66
+ * wall-clock, so SDK autoretries stay disabled no matter what is passed
67
+ * here. This is the production surface for every credential mode the
68
+ * SDK supports beyond a plain API key: bearer `authToken`, an
69
+ * `AccessTokenProvider` via `credentials`, an `AnthropicConfig` via
70
+ * `config` (OIDC/workload-identity federation included), a named
71
+ * `profile`, plus `fetch`, `timeout`, and `defaultHeaders`.
72
+ */
73
+ type AnthropicSdkOptions = Omit<ClientOptions, "maxRetries">;
62
74
  interface AnthropicAdapterOptions {
75
+ /** Shorthand for `sdkOptions.apiKey`; setting both is a ConfigError. */
63
76
  apiKey?: string;
77
+ /** Shorthand for `sdkOptions.baseURL`; setting both is a ConfigError. */
64
78
  baseURL?: string;
65
- /** Test seam: a preconstructed client; production uses @anthropic-ai/sdk. */
66
- client?: AnthropicClientLike;
79
+ /** Official SDK construction options; see `AnthropicSdkOptions`. */
80
+ sdkOptions?: AnthropicSdkOptions;
81
+ /**
82
+ * A preconstructed client instead of the construction options above
83
+ * (combining them is a ConfigError): the official `Anthropic` instance
84
+ * (production; it must be constructed with `maxRetries: 0`) or a
85
+ * structural `AnthropicClientLike` mock (tests).
86
+ */
87
+ client?: Anthropic | AnthropicClientLike;
67
88
  }
68
89
  /**
69
90
  * Creates the first-class Anthropic adapter (id 'anthropic'). SDK
70
91
  * autoretries are disabled (max_retries 0): the core owns retries and
71
- * wall-clock.
92
+ * wall-clock. With no auth option at all, the underlying SDK resolves
93
+ * credentials itself: `ANTHROPIC_API_KEY`, then bearer
94
+ * `ANTHROPIC_AUTH_TOKEN`, then its config-file credential chain. When
95
+ * `sdkOptions` carries structured auth (`credentials`, `config`, or
96
+ * `profile`) and no `apiKey`/`authToken` is set anywhere, ambient
97
+ * environment credentials are suppressed (explicit `apiKey: null,
98
+ * authToken: null` are passed to the SDK), so the configured provider
99
+ * is the one that authenticates; the SDK itself would otherwise let an
100
+ * environment `ANTHROPIC_API_KEY` win over the provider.
72
101
  */
73
102
  declare function anthropic(options?: AnthropicAdapterOptions): ProviderAdapter;
74
103
  //#endregion
@@ -147,4 +176,4 @@ declare function mapAnthropicStream(stream: AsyncIterable<AnthropicStreamEvent>,
147
176
  */
148
177
  declare function anthropicErrorToWire(error: unknown): WireError;
149
178
  //#endregion
150
- export { ANTHROPIC_MODELS, ANTHROPIC_PRICING, type AnthropicAdapterOptions, type AnthropicClientLike, type AnthropicModelInfo, type AnthropicStreamEvent, DEFAULT_PAUSE_TURN_MAX_CONTINUATIONS, IdMap, type TurnMapping, anthropic, anthropicErrorToWire, anthropicModelInfo, buildAnthropicParams, mapAnthropicStream, mapStopReason, normalizeAnthropicUsage };
179
+ export { ANTHROPIC_MODELS, ANTHROPIC_PRICING, type AnthropicAdapterOptions, type AnthropicClientLike, type AnthropicModelInfo, type AnthropicSdkOptions, type AnthropicStreamEvent, DEFAULT_PAUSE_TURN_MAX_CONTINUATIONS, IdMap, type TurnMapping, anthropic, anthropicErrorToWire, anthropicModelInfo, buildAnthropicParams, mapAnthropicStream, mapStopReason, normalizeAnthropicUsage };
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import Anthropic from "@anthropic-ai/sdk";
2
- import { createCanonicalIdMinter, isStrictCompatibleSchema } from "@rulvar/core";
2
+ import { ConfigError, createCanonicalIdMinter, isStrictCompatibleSchema } from "@rulvar/core";
3
3
  //#region src/caps.ts
4
4
  const ALL_EFFORTS = [
5
5
  "low",
@@ -665,17 +665,43 @@ function anthropicErrorToWire(error) {
665
665
  */
666
666
  /** pause_turn continuation cap. */
667
667
  const DEFAULT_PAUSE_TURN_MAX_CONTINUATIONS = 5;
668
+ function resolveAnthropicClient(options) {
669
+ if (options.client !== void 0) {
670
+ if (options.apiKey !== void 0 || options.baseURL !== void 0 || options.sdkOptions !== void 0) throw new ConfigError("anthropic(): 'client' is mutually exclusive with 'apiKey', 'baseURL', and 'sdkOptions'; configure the preconstructed client directly");
671
+ const maxRetries = options.client.maxRetries;
672
+ if (typeof maxRetries === "number" && maxRetries !== 0) throw new ConfigError(`anthropic(): the injected client has SDK autoretries enabled (maxRetries ${String(maxRetries)}); construct it with maxRetries: 0, Rulvar owns retries and wall-clock`);
673
+ return options.client;
674
+ }
675
+ const sdkOptions = options.sdkOptions ?? {};
676
+ if (options.apiKey !== void 0 && sdkOptions.apiKey !== void 0) throw new ConfigError("anthropic(): 'apiKey' and 'sdkOptions.apiKey' are both set; pick one place");
677
+ if (options.baseURL !== void 0 && sdkOptions.baseURL !== void 0) throw new ConfigError("anthropic(): 'baseURL' and 'sdkOptions.baseURL' are both set; pick one place");
678
+ const suppressAmbientEnv = (sdkOptions.credentials != null || sdkOptions.config != null || sdkOptions.profile != null) && options.apiKey === void 0 && sdkOptions.apiKey === void 0 && sdkOptions.authToken === void 0;
679
+ return new Anthropic({
680
+ ...sdkOptions,
681
+ ...suppressAmbientEnv ? {
682
+ apiKey: null,
683
+ authToken: null
684
+ } : {},
685
+ ...options.apiKey === void 0 ? {} : { apiKey: options.apiKey },
686
+ ...options.baseURL === void 0 ? {} : { baseURL: options.baseURL },
687
+ maxRetries: 0
688
+ });
689
+ }
668
690
  /**
669
691
  * Creates the first-class Anthropic adapter (id 'anthropic'). SDK
670
692
  * autoretries are disabled (max_retries 0): the core owns retries and
671
- * wall-clock.
693
+ * wall-clock. With no auth option at all, the underlying SDK resolves
694
+ * credentials itself: `ANTHROPIC_API_KEY`, then bearer
695
+ * `ANTHROPIC_AUTH_TOKEN`, then its config-file credential chain. When
696
+ * `sdkOptions` carries structured auth (`credentials`, `config`, or
697
+ * `profile`) and no `apiKey`/`authToken` is set anywhere, ambient
698
+ * environment credentials are suppressed (explicit `apiKey: null,
699
+ * authToken: null` are passed to the SDK), so the configured provider
700
+ * is the one that authenticates; the SDK itself would otherwise let an
701
+ * environment `ANTHROPIC_API_KEY` win over the provider.
672
702
  */
673
703
  function anthropic(options = {}) {
674
- const client = options.client ?? new Anthropic({
675
- ...options.apiKey === void 0 ? {} : { apiKey: options.apiKey },
676
- ...options.baseURL === void 0 ? {} : { baseURL: options.baseURL },
677
- maxRetries: 0
678
- });
704
+ const client = resolveAnthropicClient(options);
679
705
  const ids = new IdMap(createCanonicalIdMinter());
680
706
  const refreshed = /* @__PURE__ */ new Map();
681
707
  function infoFor(model) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rulvar/anthropic",
3
- "version": "1.14.0",
3
+ "version": "1.16.0",
4
4
  "description": "Rulvar first-class provider adapter over @anthropic-ai/sdk.",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -23,13 +23,13 @@
23
23
  },
24
24
  "dependencies": {
25
25
  "@anthropic-ai/sdk": "^0.110.0",
26
- "@rulvar/core": "1.14.0"
26
+ "@rulvar/core": "1.16.0"
27
27
  },
28
28
  "devDependencies": {
29
29
  "@types/node": "^22.20.0",
30
30
  "tsdown": "^0.22.3",
31
31
  "typescript": "~6.0.3",
32
- "@rulvar/testing": "1.14.0"
32
+ "@rulvar/testing": "1.16.0"
33
33
  },
34
34
  "repository": {
35
35
  "type": "git",