@rulvar/openai 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 OpenAI, { ClientOptions } from "openai";
1
2
  import { CanonicalId, ChatEvent, ChatRequest, Effort, ModelCaps, PriceTable, ProviderAdapter, Usage, WireError } from "@rulvar/core";
2
3
 
3
4
  //#region src/caps.d.ts
@@ -47,11 +48,31 @@ interface OpenAiClientLike {
47
48
  };
48
49
  };
49
50
  }
51
+ /**
52
+ * Official SDK construction options forwarded verbatim to
53
+ * `new OpenAI(...)`, minus `maxRetries`: Rulvar owns retries and
54
+ * wall-clock, so SDK autoretries stay disabled no matter what is passed
55
+ * here. This is the production surface for auth beyond a plain API key,
56
+ * `workloadIdentity` federation included, plus `fetch`, `timeout`, and
57
+ * `defaultHeaders`. The SDK's own rules still apply inside it, e.g.
58
+ * `sdkOptions.apiKey` and `sdkOptions.workloadIdentity` are mutually
59
+ * exclusive and rejected typed at construction.
60
+ */
61
+ type OpenAiSdkOptions = Omit<ClientOptions, "maxRetries">;
50
62
  interface OpenAiAdapterOptions {
63
+ /** Shorthand for `sdkOptions.apiKey`; setting both is a ConfigError. */
51
64
  apiKey?: string;
65
+ /** Shorthand for `sdkOptions.baseURL`; setting both is a ConfigError. */
52
66
  baseURL?: string;
53
- /** Test seam: a preconstructed client; production uses the openai SDK. */
54
- client?: OpenAiClientLike;
67
+ /** Official SDK construction options; see `OpenAiSdkOptions`. */
68
+ sdkOptions?: OpenAiSdkOptions;
69
+ /**
70
+ * A preconstructed client instead of the construction options above
71
+ * (combining them is a ConfigError): the official `OpenAI` instance
72
+ * (production; it must be constructed with `maxRetries: 0`) or a
73
+ * structural `OpenAiClientLike` mock (tests).
74
+ */
75
+ client?: OpenAI | OpenAiClientLike;
55
76
  }
56
77
  /** Creates the first-class OpenAI adapter (id 'openai'); maxRetries 0. */
57
78
  declare function openai(options?: OpenAiAdapterOptions): ProviderAdapter;
@@ -145,4 +166,4 @@ declare function buildChatCompletionsParams(req: ChatRequest, ids: OpenAiIdMap):
145
166
  */
146
167
  declare function mapChatCompletionsStream(stream: AsyncIterable<Record<string, unknown>>, ids: OpenAiIdMap): AsyncGenerator<ChatEvent, void>;
147
168
  //#endregion
148
- export { CONSERVATIVE_COMPATIBLE_CAPS, OPENAI_MODELS, OPENAI_PRICING, type OpenAiAdapterOptions, type OpenAiClientLike, type OpenAiCompatibleConfig, OpenAiIdMap, type OpenAiModelInfo, type ResponsesStreamEvent, buildChatCompletionsParams, buildResponsesParams, mapChatCompletionsStream, mapOpenAiEffort, mapResponsesStream, normalizeOpenAiUsage, openAiErrorToWire, openAiModelInfo, openai, openaiCompatible };
169
+ export { CONSERVATIVE_COMPATIBLE_CAPS, OPENAI_MODELS, OPENAI_PRICING, type OpenAiAdapterOptions, type OpenAiClientLike, type OpenAiCompatibleConfig, OpenAiIdMap, type OpenAiModelInfo, type OpenAiSdkOptions, type ResponsesStreamEvent, buildChatCompletionsParams, buildResponsesParams, mapChatCompletionsStream, mapOpenAiEffort, mapResponsesStream, normalizeOpenAiUsage, openAiErrorToWire, openAiModelInfo, openai, openaiCompatible };
package/dist/index.js CHANGED
@@ -623,13 +623,27 @@ async function* mapChatCompletionsStream(stream, ids) {
623
623
  * Docs: https://docs.rulvar.com/guide/providers
624
624
  * The openaiCompatible factory ships in M3.
625
625
  */
626
- /** Creates the first-class OpenAI adapter (id 'openai'); maxRetries 0. */
627
- function openai(options = {}) {
628
- const client = options.client ?? new OpenAI({
626
+ function resolveOpenAiClient(options) {
627
+ if (options.client !== void 0) {
628
+ if (options.apiKey !== void 0 || options.baseURL !== void 0 || options.sdkOptions !== void 0) throw new ConfigError("openai(): 'client' is mutually exclusive with 'apiKey', 'baseURL', and 'sdkOptions'; configure the preconstructed client directly");
629
+ const maxRetries = options.client.maxRetries;
630
+ if (typeof maxRetries === "number" && maxRetries !== 0) throw new ConfigError(`openai(): the injected client has SDK autoretries enabled (maxRetries ${String(maxRetries)}); construct it with maxRetries: 0, Rulvar owns retries and wall-clock`);
631
+ return options.client;
632
+ }
633
+ const sdkOptions = options.sdkOptions ?? {};
634
+ if (options.apiKey !== void 0 && sdkOptions.apiKey !== void 0) throw new ConfigError("openai(): 'apiKey' and 'sdkOptions.apiKey' are both set; pick one place");
635
+ if (options.apiKey !== void 0 && sdkOptions.workloadIdentity !== void 0) throw new ConfigError("openai(): 'apiKey' and 'sdkOptions.workloadIdentity' are mutually exclusive auth modes");
636
+ if (options.baseURL !== void 0 && sdkOptions.baseURL !== void 0) throw new ConfigError("openai(): 'baseURL' and 'sdkOptions.baseURL' are both set; pick one place");
637
+ return new OpenAI({
638
+ ...sdkOptions,
629
639
  ...options.apiKey === void 0 ? {} : { apiKey: options.apiKey },
630
640
  ...options.baseURL === void 0 ? {} : { baseURL: options.baseURL },
631
641
  maxRetries: 0
632
642
  });
643
+ }
644
+ /** Creates the first-class OpenAI adapter (id 'openai'); maxRetries 0. */
645
+ function openai(options = {}) {
646
+ const client = resolveOpenAiClient(options);
633
647
  const ids = new OpenAiIdMap(createCanonicalIdMinter());
634
648
  return {
635
649
  id: "openai",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rulvar/openai",
3
- "version": "1.14.0",
3
+ "version": "1.16.0",
4
4
  "description": "Rulvar first-class provider adapter for the OpenAI Responses API, plus the openaiCompatible factory.",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -23,13 +23,13 @@
23
23
  },
24
24
  "dependencies": {
25
25
  "openai": "^6.45.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",