@macpaw/ai-sdk 1.0.0 → 1.1.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/CHANGELOG.md CHANGED
@@ -1,91 +1,17 @@
1
- # 1.0.0 (2026-04-01)
1
+ # [1.1.0](https://github.com/MacPaw/ai-sdk-typescript/compare/v1.0.0...v1.1.0) (2026-04-02)
2
2
 
3
3
 
4
4
  ### Bug Fixes
5
5
 
6
- * add missing @esbuild/win32-x64 lockfile snapshot after merge ([d10abb6](https://github.com/MacPaw/ai-sdk-typescript/commit/d10abb6b9ba0be79dfcd2c725310724ed5feb313))
7
- * adjust test coverage command based on Node version ([10817d3](https://github.com/MacPaw/ai-sdk-typescript/commit/10817d3554fc0555a55fb65a835744ae9f4d0010))
8
- * enhance CI workflow to output package metrics in a structured format for better readability ([9fb5be2](https://github.com/MacPaw/ai-sdk-typescript/commit/9fb5be279815fce2987703265a89ee0a94e2704a))
9
- * enhance error handling for OpenAI API responses by adding status code checks for authentication and rate limit errors ([18f42f2](https://github.com/MacPaw/ai-sdk-typescript/commit/18f42f27f593d1d8453451849088880ed0686ebe))
10
- * ensure newline at end of file in core index export ([0be9278](https://github.com/MacPaw/ai-sdk-typescript/commit/0be9278b90e5b3fb8abfc7307833a7b4da868b61))
11
- * improve CI workflow to parse and display package metrics in a structured table format ([54c916f](https://github.com/MacPaw/ai-sdk-typescript/commit/54c916f06141d9fd075fe8522d024ea3a423f57a))
12
- * remove NPM_TOKEN and NODE_AUTH_TOKEN from release workflow ([d5d7607](https://github.com/MacPaw/ai-sdk-typescript/commit/d5d76079aa5f530816f94e2001afbac2b57c690d))
13
- * update chat completion stream test to avoid unused variable warning and refine content type validation in fetch implementation ([ccf272c](https://github.com/MacPaw/ai-sdk-typescript/commit/ccf272c1b05e30acc7dd5ba45d563a9617318976))
14
- * update copyright holder in LICENSE file from MacPaw Inc. to MacPaw Way Ltd. ([e7d4535](https://github.com/MacPaw/ai-sdk-typescript/commit/e7d453559ca88b82750b2a4cedffabd50e0f0b63))
15
- * update ESLint configuration to include 'scripts/' directory in ignores list ([b5923ce](https://github.com/MacPaw/ai-sdk-typescript/commit/b5923cedcb2643bc4a41275ec983e20fa8ca7f8d))
16
- * update import path for AIGatewayModule in README to reflect correct package structure ([9e35931](https://github.com/MacPaw/ai-sdk-typescript/commit/9e35931b0c37c7344a2e64220a045f91749b510c))
17
- * update repository URLs to use correct casing and remove GitHub release configuration ([647ca08](https://github.com/MacPaw/ai-sdk-typescript/commit/647ca08e93fa4f2bf0a8fba394655c30d05a731c))
18
- * update tsconfig.json to exclude test files from compilation ([c025e98](https://github.com/MacPaw/ai-sdk-typescript/commit/c025e98c2f6643fb18e6a3a236c5a80fcdcbf765))
6
+ * always strip placeholder Authorization header in createGatewayFetch to prevent leakage in gateway requests ([269da88](https://github.com/MacPaw/ai-sdk-typescript/commit/269da8859f49844029e470ad35a78d99078b5f45))
7
+ * bump version to 1.1.0 in package.json and enhance authorization handling in gateway-fetch and gateway-request ([b70b7fa](https://github.com/MacPaw/ai-sdk-typescript/commit/b70b7faa907535f6b2878646b06c87b5aae110f9))
8
+ * update import statement in gateway-request to use gateway-fetch for API key and token normalization ([7fa2c9e](https://github.com/MacPaw/ai-sdk-typescript/commit/7fa2c9e6e89036e3c345ef9cd3367a352c5c4381))
9
+ * update import statements in tests to use gateway-fetch for API key and token normalization ([b5dcfeb](https://github.com/MacPaw/ai-sdk-typescript/commit/b5dcfeba8845c69881a14dd75d15d2ec003b82a2))
19
10
 
20
11
 
21
12
  ### Features
22
13
 
23
- * add .gitignore file to exclude build artifacts, logs, and IDE configurations ([5946374](https://github.com/MacPaw/ai-sdk-typescript/commit/59463747dc875aae6f10eb70feef51ea1cb1c46a))
24
- * add .nvmrc and CONTRIBUTING.md files for project setup and contribution guidelines ([9ceb9d6](https://github.com/MacPaw/ai-sdk-typescript/commit/9ceb9d69037c84e571feee48d4402cc22eb49cd5))
25
- * add @vitest/coverage-v8 dependency to package.json and update pnpm-lock.yaml ([ef36590](https://github.com/MacPaw/ai-sdk-typescript/commit/ef3659022e03f0b14ccbbdc7295e3b52d829b303))
26
- * add AIGatewayExceptionFilter for structured error handling in NestJS ([9652fb4](https://github.com/MacPaw/ai-sdk-typescript/commit/9652fb46786a53dccf3eaa219ec45109846c0f91))
27
- * add Audio API facade for transcriptions and translations with request validation ([06f818c](https://github.com/MacPaw/ai-sdk-typescript/commit/06f818c12e34a0505b2605a88d75e00ea3d994cc))
28
- * add client-side request validation with specific validation functions for various request types ([8616e43](https://github.com/MacPaw/ai-sdk-typescript/commit/8616e4316292146fd2b5eec78e4a87061dd4dff5))
29
- * add compatibility check document for SDK and AI Gateway BFF ([a231005](https://github.com/MacPaw/ai-sdk-typescript/commit/a231005e06c050d0e18ffcf259ce4945125623ac))
30
- * add comprehensive mock testing utilities for AIGatewayClient, including mock functions, data, streams, and transport handling ([941fb68](https://github.com/MacPaw/ai-sdk-typescript/commit/941fb6819653455bd21f4df5c8a785770716f9fc))
31
- * add comprehensive test coverage for core functionalities including configuration resolution, error handling, request processing, and streaming results ([6a4300b](https://github.com/MacPaw/ai-sdk-typescript/commit/6a4300b45a1e8308c96a003da7a2fed020d59f2c))
32
- * add comprehensive test suite for AI Gateway SDK, covering client, audio, chat, embeddings, images, models, responses, and error handling ([4b5a464](https://github.com/MacPaw/ai-sdk-typescript/commit/4b5a46419f776be6e8498a5fcbc772f85b8b4b21))
33
- * add configurable fetch transport for browser and Node 18 plus with request signal management ([335712d](https://github.com/MacPaw/ai-sdk-typescript/commit/335712d81f5d6a48bc1c8ca7729898a7b0fafa5a))
34
- * add configuration types and default settings for AI Gateway SDK client ([00ece89](https://github.com/MacPaw/ai-sdk-typescript/commit/00ece89cbc9d091961394715a9e16aef79a16e00))
35
- * add core types for AI Gateway SDK including error codes, request/response structures, and chat completion interfaces ([3a0234e](https://github.com/MacPaw/ai-sdk-typescript/commit/3a0234eb6ec5acc89683ff34b59f0d82dd03b0bc))
36
- * add createAIGatewayFetch function for custom fetch handling with Bearer auth ([d4339ff](https://github.com/MacPaw/ai-sdk-typescript/commit/d4339ffd3664f4c236faeb286de7ffe5d6b3f10a))
37
- * add empty module files for core, nestjs, and provider directories ([757ac03](https://github.com/MacPaw/ai-sdk-typescript/commit/757ac03cf7898328b2101a45ac57c00022e67ff5))
38
- * add ESLint configuration for TypeScript support ([9d62474](https://github.com/MacPaw/ai-sdk-typescript/commit/9d624748c658ce5a5ad9c06722ea5125fd53eecd))
39
- * add helper functions and stream result objects for chat and response processing ([cddb5ee](https://github.com/MacPaw/ai-sdk-typescript/commit/cddb5eee83212117d5df389e4c396fefedd187eb))
40
- * add Images API facade for image generation and editing with request validation ([5f07d3d](https://github.com/MacPaw/ai-sdk-typescript/commit/5f07d3d988c7bc707add261a29face721ef1a9ec))
41
- * add initial project configuration files including .npmignore, .prettierrc, .releaserc.json, and build configurations for TypeScript and Vitest ([67c1b9d](https://github.com/MacPaw/ai-sdk-typescript/commit/67c1b9dfe57a5b5145b40453b8e835fae5ab558a))
42
- * add InjectAIGateway decorator for dependency injection of AIGatewayClient ([f8e6dee](https://github.com/MacPaw/ai-sdk-typescript/commit/f8e6dee5e66d3c47ebdf4859376b0faa570bdad8))
43
- * add integration instructions for AI Gateway SDK, including detailed setup for Cursor, Claude Code, and OpenAI Codex ([c943e21](https://github.com/MacPaw/ai-sdk-typescript/commit/c943e21a22f5b91719d69da893a52bfce52a2f21))
44
- * add issue templates for bug reports and feature requests to improve issue tracking ([07a60cb](https://github.com/MacPaw/ai-sdk-typescript/commit/07a60cb2781445230dca1c1397630141cb8aa87f))
45
- * add Model Info API facade for retrieving model information with optional parameters ([e890be8](https://github.com/MacPaw/ai-sdk-typescript/commit/e890be8ff67f28a141199c55950758f9defe2019))
46
- * add package.json ([7fe1503](https://github.com/MacPaw/ai-sdk-typescript/commit/7fe15030df15e6648bc90a52476c8b7f3ae909a2))
47
- * add pnpm lockfile for dependency management ([2da29ae](https://github.com/MacPaw/ai-sdk-typescript/commit/2da29aea8e5c589fad1b76d25639f9a8be67fd64))
48
- * add Responses API facade with support for synchronous and streaming response creation ([ee287c3](https://github.com/MacPaw/ai-sdk-typescript/commit/ee287c31b91060ae3182a6dd83538c270e0210e1))
49
- * add runtime module and enhance provider flexibility with new source resolution for AI Gateway SDK ([894d63d](https://github.com/MacPaw/ai-sdk-typescript/commit/894d63dd47b271480d137aa6501c0a4e21069df3))
50
- * add SECURITY.md file to outline security policy and vulnerability reporting process ([01236c3](https://github.com/MacPaw/ai-sdk-typescript/commit/01236c34fbc4881e04550bc5f7367305789586f7))
51
- * add setup script for Cursor skill and update README with usage instructions ([61acf79](https://github.com/MacPaw/ai-sdk-typescript/commit/61acf7943b7440d229177d6198fb9ecb873d2828))
52
- * add src/index.ts as the main entry point for the application ([226f28a](https://github.com/MacPaw/ai-sdk-typescript/commit/226f28a08835637ae581e5fb3946eec556a725d3))
53
- * add support for testing module in package.json and tsup configuration ([5a7245e](https://github.com/MacPaw/ai-sdk-typescript/commit/5a7245ebce61d2f6a742052ed3cd3f6a41340177))
54
- * add tests for X-Request-ID handling and Retry-After header parsing, enhance retry logic with abort signal support ([7d432e4](https://github.com/MacPaw/ai-sdk-typescript/commit/7d432e487faf733230102c85f95a255b8235db30))
55
- * add TypeScript configuration file ([ed292e4](https://github.com/MacPaw/ai-sdk-typescript/commit/ed292e48936669d0de129ff100d91b3211ef20fb))
56
- * centralize API path constants for audio, chat, embeddings, images, models, and responses ([0502abc](https://github.com/MacPaw/ai-sdk-typescript/commit/0502abce67a1920901f5a70bad0713e7089b9850))
57
- * consolidate exports in core index file for improved module accessibility ([d3ecdef](https://github.com/MacPaw/ai-sdk-typescript/commit/d3ecdef5a4eed7424c370c09a3deda0d3149242d))
58
- * consolidate setup scripts for AI Gateway integration, replacing setup-cursor with a unified setup script for Cursor, Claude Code, and OpenAI Codex; update README and add new templates for documentation ([5951d9d](https://github.com/MacPaw/ai-sdk-typescript/commit/5951d9d7f27edbac5af2ad9835155c15d81cdc0f))
59
- * enable code splitting in build configuration and enhance token fetching logic to handle forced refreshes correctly ([943a4a8](https://github.com/MacPaw/ai-sdk-typescript/commit/943a4a8c9fdf351f4294a456a46cbc7e37ed3f68))
60
- * enable passWithNoTests option in Vitest configuration ([13b4cf4](https://github.com/MacPaw/ai-sdk-typescript/commit/13b4cf4fe9b24628f28f76b802378192543d705a))
61
- * enhance AI Gateway integration documentation with automatic workflow steps and migration guidance ([cdb1a97](https://github.com/MacPaw/ai-sdk-typescript/commit/cdb1a9745b7fc458891304640637a51703ba5e4c))
62
- * enhance AIGatewayExceptionFilter and AIGatewayModule with additional metadata handling and global configuration option ([bad042e](https://github.com/MacPaw/ai-sdk-typescript/commit/bad042e5b0facd3993344ff986d3f8c4805ada55))
63
- * enhance AIGatewayFetch and request handling with new URL joining and gateway URL validation functions, improve token caching logic, and add sensitive header redaction for improved security ([aa3d185](https://github.com/MacPaw/ai-sdk-typescript/commit/aa3d185d1ffbd94d1c628de84e35cd3cb86af21a))
64
- * enhance provider flexibility by allowing lazy factory options for AIGateway and OpenAI providers, improving source resolution and caching mechanisms ([c0adf05](https://github.com/MacPaw/ai-sdk-typescript/commit/c0adf0537d001ee5e250e5f7d80f5a9f0844906a))
65
- * enhance SSE error handling and improve chat completion request structure ([044d17f](https://github.com/MacPaw/ai-sdk-typescript/commit/044d17f3314cfac2bbcfaed94ffa69880f2158e9))
66
- * enhance validation for response requests and improve fetch implementation to prevent token leakage ([0b94aa4](https://github.com/MacPaw/ai-sdk-typescript/commit/0b94aa4fe2e97184fbafcc751a3bcebda9c47cf0))
67
- * export AIGateway components and types for improved module integration ([c69b00a](https://github.com/MacPaw/ai-sdk-typescript/commit/c69b00a86d7817e171f24d928607ee9058645eab))
68
- * export anySignal function from abort module for signal handling ([91e710a](https://github.com/MacPaw/ai-sdk-typescript/commit/91e710a1d949112bdc87cafc6ec3ca942555850f))
69
- * implement AI Gateway client with API facades for chat ([110e24a](https://github.com/MacPaw/ai-sdk-typescript/commit/110e24a0485b65440d1bad19ba5b781b537350cc))
70
- * implement AIGatewayModule with static and async configuration options for AI Gateway client ([831b352](https://github.com/MacPaw/ai-sdk-typescript/commit/831b352696bd5bea355c2d4986df15102ccae101))
71
- * implement Chat Completions API facade with synchronous and streaming request handling ([746a8cc](https://github.com/MacPaw/ai-sdk-typescript/commit/746a8cc27a42153bae25d8a3a51fb0e71875ae0c))
72
- * implement error normalization layer for AI Gateway SDK with specific error subclasses ([3d02644](https://github.com/MacPaw/ai-sdk-typescript/commit/3d02644a2af552bce766c187844d6b95c1a016f4))
73
- * implement mock testing utilities for AIGatewayClient, including mock functions, data, and transport ([faaa77c](https://github.com/MacPaw/ai-sdk-typescript/commit/faaa77cfeb387ede552d08c1460cb523c7bae75a))
74
- * implement SSE parser for streaming responses with error handling and JSON parsing ([4839879](https://github.com/MacPaw/ai-sdk-typescript/commit/4839879dcf5acc155d35fb3d2be2dfbfd16599fe))
75
- * improve error handling for SSE streams and enhance content type validation in audio, chat, and response APIs ([89b3204](https://github.com/MacPaw/ai-sdk-typescript/commit/89b3204d5c9cebe5df293f2d84c3f4bbd762b22e))
76
- * integrate API path management into mock configurations across audio, chat, embeddings, images, models, responses, and core request tests ([a9ffde0](https://github.com/MacPaw/ai-sdk-typescript/commit/a9ffde09db0a761b17f437a79bec5eff26be1826))
77
- * introduce AI Gateway client with comprehensive API facades for chat, responses, embeddings, images, and audio, along with configuration and request handling improvements ([943305e](https://github.com/MacPaw/ai-sdk-typescript/commit/943305e6723ab02dc737802502d588d90cc1acc3))
78
- * introduce AIGatewayProvider for Vercel AI SDK integration with AI Gateway authentication and error handling ([604c127](https://github.com/MacPaw/ai-sdk-typescript/commit/604c127bcb0865b60c060f9a745de896ca139e95))
79
- * introduce API path constants and enhance request transport handling ([d9c5d1f](https://github.com/MacPaw/ai-sdk-typescript/commit/d9c5d1f8b7d9f340b3ea8bd5d872f0eb3ac473a3))
80
- * introduce API versioning and path management, refactor API calls to utilize dynamic paths ([d7202c6](https://github.com/MacPaw/ai-sdk-typescript/commit/d7202c6c0bcc4ed38cf0454def6ef7f24d6abf22))
81
- * introduce Embeddings API facade for creating embeddings with request validation ([d3eeddf](https://github.com/MacPaw/ai-sdk-typescript/commit/d3eeddfecea6b8f7d0ef766b3b9d93377a88448b))
82
- * refactor import statements to remove file extensions and add request handling with retry logic ([9f99aea](https://github.com/MacPaw/ai-sdk-typescript/commit/9f99aeae9cf6c28cab3bfbb88180df9c1eeef319))
83
- * refine AI Gateway integration documentation to clarify import practices for model providers ([7f70a7c](https://github.com/MacPaw/ai-sdk-typescript/commit/7f70a7cf63667b972d805545fc9c51d3f5b23651))
84
- * update AI Gateway integration documentation to clarify import guidelines for model providers and React hooks; emphasize usage of `@macpaw/ai/provider` and `ai/react` for improved setup and common mistakes ([8449ed2](https://github.com/MacPaw/ai-sdk-typescript/commit/8449ed2d7447fe2fcfff809873fe03c872b97a3b))
85
- * update dependencies and enhance AIGatewayProvider with built-in OpenAI support ([8a528bf](https://github.com/MacPaw/ai-sdk-typescript/commit/8a528bfa62403341d57374fa69e5d984a21a24f7))
86
- * update import paths ([934939f](https://github.com/MacPaw/ai-sdk-typescript/commit/934939f758fac83bb202e9f2be3f513cdab5aa62))
87
- * update Node.js version in release workflow and enhance tool version visibility ([a86be3a](https://github.com/MacPaw/ai-sdk-typescript/commit/a86be3a06107e92af665a1bcbb1303730f3a5f56))
88
- * update README to reflect new SDK name and comprehensive features for @macpaw/ai ([1913a75](https://github.com/MacPaw/ai-sdk-typescript/commit/1913a7586784e213c9edea8d025a71831869c17b))
14
+ * update migration and README to clarify upstream API usage and versioning; enhance examples for `createGatewayFetch` and `resolveGatewayBaseURL` ([11d910f](https://github.com/MacPaw/ai-sdk-typescript/commit/11d910ffad4b737b18fde6fe682cb9efa62c0834))
89
15
 
90
16
  # @macpaw/ai-sdk
91
17
 
package/MIGRATION.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  This package is a **small Vercel AI SDK extension** for MacPaw AI Gateway. Upstream **`ai`**, **`@ai-sdk/openai`**, **`@ai-sdk/react`** (or **`ai/react`**) stay the source for core APIs and hooks.
4
4
 
5
+ That also means upstream UI/hooks/version migrations stay upstream. If your installed `ai` / `@ai-sdk/react` version changes hook or schema APIs, follow the upstream versioned docs for those packages rather than expecting `@macpaw/ai-sdk` to redefine them.
6
+
5
7
  ## Entry points
6
8
 
7
9
  | Path | Role |
@@ -26,10 +28,14 @@ Replace `createAIGatewayClient` with:
26
28
 
27
29
  Types for request/response bodies can come from your app, from OpenAI SDK types, or from gateway OpenAPI — they are not re-exported from this package today.
28
30
 
31
+ If you want the default production Gateway URL in fetch-only flows, use the public `resolveGatewayBaseURL()` helper and pass the resolved value into `createGatewayFetch()`.
32
+
29
33
  ## If you used `@macpaw/ai-sdk/runtime`
30
34
 
31
35
  Internals (`executeRequestPipeline`, etc.) are not part of the public API. Prefer `createGatewayFetch` or provider options (`middleware`, `retry`, `timeout`, `fetch`).
32
36
 
37
+ The same applies to source-only error helpers: if a helper is not exported from `@macpaw/ai-sdk`, treat it as internal even if you see it in the repository source.
38
+
33
39
  ## Quick import cheatsheet
34
40
 
35
41
  ```ts
package/README.md CHANGED
@@ -30,6 +30,8 @@ npm install @macpaw/ai-sdk
30
30
 
31
31
  Also install upstream packages you call directly, for example `ai`, `@ai-sdk/openai`, `@ai-sdk/react`.
32
32
 
33
+ This package does not pin or wrap the upstream UI/hooks API from `ai` / `@ai-sdk/react`. Follow the versioned upstream docs for the exact major version you install there. If your chosen upstream version requires version-specific imports or patterns (for example schema helpers), use the upstream guidance for those APIs.
34
+
33
35
  ## Quick start (Vercel AI SDK)
34
36
 
35
37
  ```ts
@@ -88,9 +90,9 @@ Internal resolution: `resolveConfig()` in `gateway-config.ts`.
88
90
  Same auth, retry, middleware, and error normalization as the provider path. Use **relative** URLs under the gateway root (e.g. `'/api/v1/images/edits'`) or absolute URLs that stay under the same gateway origin.
89
91
 
90
92
  ```ts
91
- import { createGatewayFetch } from '@macpaw/ai-sdk';
93
+ import { createGatewayFetch, resolveGatewayBaseURL } from '@macpaw/ai-sdk';
92
94
 
93
- const baseURL = 'https://api.macpaw.com/ai'; // or resolve via env: 'production'
95
+ const baseURL = resolveGatewayBaseURL(undefined, 'production', 'gatewayFetch');
94
96
  const gatewayFetch = createGatewayFetch({
95
97
  baseURL,
96
98
  getAuthToken: async () => token,
@@ -106,6 +108,8 @@ const res = await gatewayFetch('/api/v1/images/edits', { method: 'POST', body: f
106
108
 
107
109
  Non-gateway absolute URLs are passed through without injecting Bearer auth (placeholder key is stripped). See `gateway-fetch.ts`.
108
110
 
111
+ `createGatewayFetch` requires a resolved `baseURL`. Use the exported `resolveGatewayBaseURL()` helper if you want the same `'production'` shortcut that provider factories support.
112
+
109
113
  ## `createGatewayProvider` — prefixed model IDs
110
114
 
111
115
  Bare model IDs get a default Gateway prefix per provider constant; IDs that already contain `/` are unchanged.
@@ -147,6 +151,8 @@ Extends `GatewayProviderSettings` plus OpenAI provider settings (without `apiKey
147
151
  - `normalizeErrors` — default `true`; non-OK Gateway responses throw typed errors
148
152
  - `createOpenAI` — optional override of `createOpenAI` from `@ai-sdk/openai` (tests/advanced)
149
153
 
154
+ Use `normalizeErrors: false` only when you intentionally want to inspect raw failed `Response` objects in provider-driven tests or adapters. Auth refresh and retry behavior still stay on; only typed non-OK error throwing is relaxed.
155
+
150
156
  ## Middleware
151
157
 
152
158
  ```ts
@@ -199,6 +205,8 @@ AIGatewayModule.forRoot({
199
205
  });
200
206
  ```
201
207
 
208
+ If your Nest app uses TypeScript subpath exports strictly, make sure its `tsconfig` uses a modern resolver such as `moduleResolution: "Node16"`, `"NodeNext"`, or `"bundler"` so `@macpaw/ai-sdk/nestjs` resolves correctly.
209
+
202
210
  Inject **`GatewayProviderSettings`** (not an HTTP client) and build providers in the service:
203
211
 
204
212
  ```ts
@@ -225,6 +233,8 @@ export class ChatService {
225
233
 
226
234
  `AIGatewayExceptionFilter` maps `AIGatewayError` to JSON HTTP responses. See `examples/nestjs/` for a copy-paste skeleton.
227
235
 
236
+ Only documented root exports are public API. Source-level helpers such as `parseErrorResponseFromResponse` and `parseStreamErrorPayload` may exist internally, but they are not supported import targets unless exported from `@macpaw/ai-sdk`.
237
+
228
238
  ## Examples
229
239
 
230
240
  From the repo root:
@@ -57,6 +57,9 @@ interface GatewayProviderSettings {
57
57
  */
58
58
  fetch?: typeof fetch;
59
59
  }
60
+ /** Default base URL for the production environment. */
61
+ declare const DEFAULT_BASE_URLS: Record<Environment, string>;
62
+ declare function resolveGatewayBaseURL(baseURL: string | undefined, env: Environment | undefined, consumerName: string): string;
60
63
 
61
64
  /**
62
65
  * Error types for the AI Gateway SDK.
@@ -178,4 +181,4 @@ declare function isAIGatewayError(value: unknown): value is AIGatewayError;
178
181
  */
179
182
  declare function parseErrorResponse(statusCode: number, body: unknown): never;
180
183
 
181
- export { AIGatewayError as A, CreditsError as C, ErrorCode as E, type GatewayProviderSettings as G, type Middleware as M, type NormalizedErrorMetadata as N, type OpenAIErrorResponse as O, RateLimitError as R, AuthError as a, GatewayApiCode as b, type GatewayApiErrorItem as c, type GatewayApiErrorResponse as d, GatewayValidationError as e, ModelNotAllowedError as f, type RetryConfig as g, isAIGatewayError as i, parseErrorResponse as p };
184
+ export { AIGatewayError as A, CreditsError as C, DEFAULT_BASE_URLS as D, type Environment as E, type GatewayProviderSettings as G, type Middleware as M, type NormalizedErrorMetadata as N, type OpenAIErrorResponse as O, RateLimitError as R, AuthError as a, ErrorCode as b, GatewayApiCode as c, type GatewayApiErrorItem as d, type GatewayApiErrorResponse as e, GatewayValidationError as f, ModelNotAllowedError as g, type RetryConfig as h, isAIGatewayError as i, parseErrorResponse as p, resolveGatewayBaseURL as r };
@@ -57,6 +57,9 @@ interface GatewayProviderSettings {
57
57
  */
58
58
  fetch?: typeof fetch;
59
59
  }
60
+ /** Default base URL for the production environment. */
61
+ declare const DEFAULT_BASE_URLS: Record<Environment, string>;
62
+ declare function resolveGatewayBaseURL(baseURL: string | undefined, env: Environment | undefined, consumerName: string): string;
60
63
 
61
64
  /**
62
65
  * Error types for the AI Gateway SDK.
@@ -178,4 +181,4 @@ declare function isAIGatewayError(value: unknown): value is AIGatewayError;
178
181
  */
179
182
  declare function parseErrorResponse(statusCode: number, body: unknown): never;
180
183
 
181
- export { AIGatewayError as A, CreditsError as C, ErrorCode as E, type GatewayProviderSettings as G, type Middleware as M, type NormalizedErrorMetadata as N, type OpenAIErrorResponse as O, RateLimitError as R, AuthError as a, GatewayApiCode as b, type GatewayApiErrorItem as c, type GatewayApiErrorResponse as d, GatewayValidationError as e, ModelNotAllowedError as f, type RetryConfig as g, isAIGatewayError as i, parseErrorResponse as p };
184
+ export { AIGatewayError as A, CreditsError as C, DEFAULT_BASE_URLS as D, type Environment as E, type GatewayProviderSettings as G, type Middleware as M, type NormalizedErrorMetadata as N, type OpenAIErrorResponse as O, RateLimitError as R, AuthError as a, ErrorCode as b, GatewayApiCode as c, type GatewayApiErrorItem as d, type GatewayApiErrorResponse as e, GatewayValidationError as f, ModelNotAllowedError as g, type RetryConfig as h, isAIGatewayError as i, parseErrorResponse as p, resolveGatewayBaseURL as r };
package/dist/index.cjs CHANGED
@@ -130,6 +130,11 @@ function hasHeaderCaseInsensitive(headers, name) {
130
130
  const lower = name.toLowerCase();
131
131
  return Object.keys(headers).some((k) => k.toLowerCase() === lower);
132
132
  }
133
+ function deleteAllAuthorizationHeaders(headers) {
134
+ for (const key of Object.keys(headers)) {
135
+ if (key.toLowerCase() === "authorization") delete headers[key];
136
+ }
137
+ }
133
138
  function shouldAutoSetJsonContentType(body, headers) {
134
139
  if (body == null || hasHeaderCaseInsensitive(headers, "content-type")) return false;
135
140
  const isFormData = typeof FormData !== "undefined" && body instanceof FormData;
@@ -244,13 +249,11 @@ async function executeRequest(config, request, behavior, forceRefreshToken) {
244
249
  }
245
250
  const finalHeaders = { ...currentRequest.headers };
246
251
  if (behavior.includeAuth) {
247
- const token = await config.getAuthToken(forceRefreshToken);
248
- if (token) {
252
+ deleteAllAuthorizationHeaders(finalHeaders);
253
+ const rawToken = await config.getAuthToken(forceRefreshToken);
254
+ const token = normalizeBearerToken(rawToken);
255
+ if (token && token !== GATEWAY_PLACEHOLDER_API_KEY) {
249
256
  finalHeaders.Authorization = `Bearer ${token}`;
250
- } else {
251
- for (const key of Object.keys(finalHeaders)) {
252
- if (key.toLowerCase() === "authorization") delete finalHeaders[key];
253
- }
254
257
  }
255
258
  }
256
259
  return executeFetch(config.fetchImpl, { ...currentRequest, headers: finalHeaders });
@@ -280,14 +283,29 @@ async function executeRequest(config, request, behavior, forceRefreshToken) {
280
283
  }
281
284
 
282
285
  // src/gateway-fetch.ts
286
+ var GATEWAY_PLACEHOLDER_API_KEY = "ai-gateway-auth-via-fetch";
283
287
  function resolveRequestUrl(input) {
284
288
  if (typeof input === "string") return input;
285
289
  if (input instanceof URL) return input.href;
286
290
  return input.url;
287
291
  }
292
+ function normalizeBearerToken(raw) {
293
+ if (raw == null) return null;
294
+ let s = String(raw).trim();
295
+ if (!s) return null;
296
+ if (s.startsWith('"') && s.endsWith('"') && s.length >= 2 || s.startsWith("'") && s.endsWith("'") && s.length >= 2) {
297
+ s = s.slice(1, -1).trim();
298
+ }
299
+ s = s.replace(/[,;]+\s*$/g, "").trim();
300
+ return s.length > 0 ? s : null;
301
+ }
288
302
  function stripPlaceholderAuthorization(headers, placeholder) {
289
303
  const auth = headers.get("authorization");
290
- if (auth === `Bearer ${placeholder}`) {
304
+ if (!auth) return;
305
+ const m = auth.match(/^Bearer\s+(\S+)/i);
306
+ if (!m) return;
307
+ const credential = normalizeBearerToken(m[1]);
308
+ if (credential === placeholder) {
291
309
  headers.delete("authorization");
292
310
  }
293
311
  }
@@ -306,7 +324,6 @@ function isGatewayUrl(url, gatewayBaseUrl) {
306
324
  const requestPath = url.pathname.replace(/\/$/, "");
307
325
  return url.origin === gatewayBaseUrl.origin && (requestPath === gatewayPath || requestPath.startsWith(`${gatewayPath}/`));
308
326
  }
309
- var GATEWAY_PLACEHOLDER_API_KEY = "ai-gateway-auth-via-fetch";
310
327
  function createGatewayFetch(options) {
311
328
  const { baseURL, normalizeErrors = true } = options;
312
329
  const base = baseURL.replace(/\/$/, "");
@@ -325,9 +342,7 @@ function createGatewayFetch(options) {
325
342
  headers.set(key, value);
326
343
  }
327
344
  }
328
- if (!isGatewayRequest) {
329
- stripPlaceholderAuthorization(headers, GATEWAY_PLACEHOLDER_API_KEY);
330
- }
345
+ stripPlaceholderAuthorization(headers, GATEWAY_PLACEHOLDER_API_KEY);
331
346
  return executeRequestPipeline(
332
347
  resolvedConfig,
333
348
  {
@@ -474,10 +489,12 @@ Object.defineProperty(exports, "parseErrorResponse", {
474
489
  enumerable: true,
475
490
  get: function () { return chunkN26BDEG5_cjs.parseErrorResponse; }
476
491
  });
492
+ exports.DEFAULT_BASE_URLS = DEFAULT_BASE_URLS;
477
493
  exports.GATEWAY_PLACEHOLDER_API_KEY = GATEWAY_PLACEHOLDER_API_KEY;
478
494
  exports.GATEWAY_PROVIDERS = GATEWAY_PROVIDERS;
479
495
  exports.createAIGatewayProvider = createAIGatewayProvider;
480
496
  exports.createGatewayFetch = createGatewayFetch;
481
497
  exports.createGatewayProvider = createGatewayProvider;
498
+ exports.resolveGatewayBaseURL = resolveGatewayBaseURL;
482
499
  //# sourceMappingURL=index.cjs.map
483
500
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/gateway-config.ts","../src/gateway-retry.ts","../src/gateway-request.ts","../src/gateway-fetch.ts","../src/gateway-provider.ts"],"names":["AuthError","parseErrorResponseFromResponse","builtinCreateOpenAI"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Configuration types and resolver for the AI Gateway SDK.\n *\n * GatewayProviderSettings is the public API — 8 fields.\n * ResolvedConfig is the internal resolved form used by the request pipeline.\n */\n\n/**\n * Supported gateway environments.\n * Only 'production' is exposed — non-production setups use a direct `baseURL`\n * instead, keeping env-specific URL management out of this library.\n */\nexport type Environment = 'production';\n\nexport interface RetryConfig {\n /** Max number of attempts (including first). Default 3. */\n maxAttempts?: number;\n /** Initial delay in ms. Default 1000. */\n initialDelayMs?: number;\n /** Max delay in ms. Default 30000. */\n maxDelayMs?: number;\n /** Retry only on these status codes (and network errors). Default: 429, 5xx. */\n retryableStatuses?: number[];\n}\n\nexport const DEFAULT_RETRY: Required<RetryConfig> = {\n maxAttempts: 3,\n initialDelayMs: 1000,\n maxDelayMs: 30000,\n retryableStatuses: [429, 500, 502, 503, 504],\n};\n\n/** Coerces invalid `maxAttempts` (0, negative, NaN) to the default. */\nexport function normalizeRetryConfig(merged: Required<RetryConfig>): Required<RetryConfig> {\n const n = Math.floor(Number(merged.maxAttempts));\n const maxAttempts = Number.isFinite(n) && n >= 1 ? n : DEFAULT_RETRY.maxAttempts;\n return { ...merged, maxAttempts };\n}\n\nexport interface RequestConfig {\n url: string;\n method: string;\n headers: Record<string, string>;\n body?: RequestInit['body'];\n signal?: AbortSignal | undefined;\n}\n\nexport type Middleware = (\n config: RequestConfig,\n next: (config: RequestConfig) => Promise<Response>,\n) => Promise<Response>;\n\n/**\n * Configuration for AI Gateway providers and NestJS module.\n *\n * Exactly 8 fields — covers auth, routing, request behaviour and middleware.\n */\nexport interface GatewayProviderSettings {\n /** Gateway base URL. Required if env is not set. */\n baseURL?: string;\n /** 'production' uses the default MacPaw Gateway URL. */\n env?: Environment;\n /**\n * Returns Bearer token for auth.\n * Called with `forceRefresh=true` after 401 — provide a fresh token.\n */\n getAuthToken: (forceRefresh?: boolean) => Promise<string | null>;\n /** Extra headers sent with every request. Do not set Authorization here. */\n headers?: Record<string, string>;\n /** Retry policy. Set to false to disable. */\n retry?: RetryConfig | false;\n /** Request timeout in ms. Default: 60000. */\n timeout?: number;\n /** Request interceptors. Run in order before each request. */\n middleware?: Middleware[];\n /**\n * Custom fetch implementation.\n * Use for testing or low-level request customization.\n */\n fetch?: typeof fetch;\n}\n\n/** Internal resolved form — used only by the request pipeline. */\nexport interface ResolvedConfig {\n baseURL: string;\n getAuthToken: (forceRefresh?: boolean) => Promise<string | null>;\n /** Already normalized — all fields present, maxAttempts ≥ 1. */\n retry: Required<RetryConfig> | false;\n middleware: Middleware[];\n headers?: Record<string, string>;\n timeout: number;\n fetchImpl?: typeof fetch;\n}\n\nexport function resolveConfig(config: GatewayProviderSettings & { baseURL: string }): ResolvedConfig {\n return {\n baseURL: config.baseURL,\n getAuthToken: config.getAuthToken,\n retry: config.retry === false ? false : normalizeRetryConfig({ ...DEFAULT_RETRY, ...config.retry }),\n middleware: [...(config.middleware ?? [])],\n headers: config.headers,\n timeout: config.timeout ?? 60_000,\n fetchImpl: config.fetch,\n };\n}\n\n/** Default base URL for the production environment. */\nexport const DEFAULT_BASE_URLS: Record<Environment, string> = {\n production: 'https://api.macpaw.com/ai',\n};\n\nexport function resolveGatewayBaseURL(\n baseURL: string | undefined,\n env: Environment | undefined,\n consumerName: string,\n): string {\n const resolved = baseURL ?? (env ? DEFAULT_BASE_URLS[env] : undefined);\n if (!resolved) {\n throw new Error(\n `${consumerName} requires baseURL or env (production). For non-production environments, pass baseURL directly.`,\n );\n }\n return resolved;\n}\n","/**\n * Retry with exponential backoff + jitter.\n * Only retries on 429, 5xx and network errors; never on 4xx (401, 402, etc.).\n *\n * Jitter prevents thundering herd when many clients retry simultaneously.\n * Respects Retry-After metadata from 429 responses.\n */\n\nimport type { RetryConfig } from './gateway-config';\nimport type { AIGatewayError } from './gateway-errors';\n\nfunction delay(ms: number, signal?: AbortSignal): Promise<void> {\n return new Promise((resolve, reject) => {\n if (signal?.aborted) {\n reject(signal.reason);\n return;\n }\n const timer = setTimeout(resolve, ms);\n signal?.addEventListener(\n 'abort',\n () => {\n clearTimeout(timer);\n reject(signal.reason);\n },\n { once: true },\n );\n });\n}\n\nfunction isRetryableStatus(status: number, retryableStatuses: number[]): boolean {\n return retryableStatuses.includes(status);\n}\n\n/** Add random jitter: 0-25% of the base delay to avoid thundering herd */\nfunction addJitter(delayMs: number): number {\n const jitter = delayMs * 0.25 * Math.random();\n return delayMs + jitter;\n}\n\nexport async function withRetry<T>(\n fn: () => Promise<T>,\n options: {\n /** Already-normalized config — all fields must be present. */\n retryConfig: Required<RetryConfig>;\n signal?: AbortSignal;\n isNetworkError?: (err: unknown) => boolean;\n },\n): Promise<T> {\n const { maxAttempts, initialDelayMs, maxDelayMs, retryableStatuses } = options.retryConfig;\n let lastError: unknown;\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n try {\n return await fn();\n } catch (err) {\n lastError = err;\n if (attempt === maxAttempts) break;\n const status = (err as { statusCode?: number })?.statusCode;\n const isRetryable =\n status != null ? isRetryableStatus(status, retryableStatuses) : (options.isNetworkError?.(err) ?? false);\n if (!isRetryable) throw err;\n\n const retryAfterSeconds = (err as AIGatewayError)?.retryAfter;\n let backoff: number;\n if (retryAfterSeconds != null && retryAfterSeconds > 0) {\n // Server-specified delay — use exactly, no jitter (contract compliance).\n backoff = retryAfterSeconds * 1000;\n } else {\n backoff = addJitter(Math.min(initialDelayMs * Math.pow(2, attempt - 1), maxDelayMs));\n }\n\n await delay(backoff, options.signal);\n }\n }\n throw lastError;\n}\n","/**\n * Shared request execution pipeline for the AI Gateway SDK.\n *\n * Handles: auth injection, Bearer token refresh on 401, middleware chain,\n * timeout, retry, and error normalization. Inlines abort, request-id,\n * and fetch transport as private helpers.\n */\n\nimport type { RequestConfig, ResolvedConfig } from './gateway-config';\nimport { AuthError, parseErrorResponseFromResponse } from './gateway-errors';\nimport { withRetry } from './gateway-retry';\n\n// ─── Private helpers ──────────────────────────────────────────────────────────\n\n/** Combine multiple AbortSignals — aborts when ANY fires. Uses native AbortSignal.any when available. */\nfunction anySignal(signals: AbortSignal[]): AbortSignal {\n const any = (AbortSignal as unknown as { any?: (signals: AbortSignal[]) => AbortSignal }).any;\n if (typeof any === 'function') {\n return any(signals);\n }\n const controller = new AbortController();\n const handlers: Array<[AbortSignal, () => void]> = [];\n function cleanup() {\n for (const [sig, handler] of handlers) sig.removeEventListener('abort', handler);\n handlers.length = 0;\n }\n for (const signal of signals) {\n if (signal.aborted) {\n controller.abort(signal.reason);\n return controller.signal;\n }\n const handler = () => {\n cleanup();\n controller.abort(signal.reason);\n };\n handlers.push([signal, handler]);\n signal.addEventListener('abort', handler, { once: true });\n }\n controller.signal.addEventListener('abort', cleanup, { once: true });\n return controller.signal;\n}\n\nlet _counter = 0;\n/** Generate a unique request ID for correlation. */\nfunction generateRequestId(prefix: string = 'sdk'): string {\n if (typeof globalThis.crypto?.randomUUID === 'function') {\n return `${prefix}-${globalThis.crypto.randomUUID()}`;\n }\n const timestamp = Date.now().toString(36);\n const count = (_counter++).toString(36);\n const random = Math.random().toString(36).slice(2, 8);\n return `${prefix}-${timestamp}-${count}-${random}`;\n}\n\n/** Case-insensitive header key lookup. */\nfunction hasHeaderCaseInsensitive(headers: Record<string, string>, name: string): boolean {\n const lower = name.toLowerCase();\n return Object.keys(headers).some((k) => k.toLowerCase() === lower);\n}\n\nfunction shouldAutoSetJsonContentType(body: RequestInit['body'], headers: Record<string, string>): boolean {\n if (body == null || hasHeaderCaseInsensitive(headers, 'content-type')) return false;\n const isFormData = typeof FormData !== 'undefined' && body instanceof FormData;\n const isBlob = typeof Blob !== 'undefined' && body instanceof Blob;\n return !isFormData && !isBlob;\n}\n\nfunction redactSensitiveHeaders(headers: Record<string, string>): Record<string, string> {\n const redacted: Record<string, string> = {};\n for (const [key, value] of Object.entries(headers)) {\n redacted[key] = key.toLowerCase() === 'authorization' ? '[REDACTED]' : value;\n }\n return redacted;\n}\n\nconst NODE_NETWORK_CODES = new Set([\n 'ECONNREFUSED',\n 'ECONNRESET',\n 'ENOTFOUND',\n 'EPIPE',\n 'ETIMEDOUT',\n 'ENETUNREACH',\n 'EAI_AGAIN',\n 'UND_ERR_CONNECT_TIMEOUT',\n]);\n\nconst FETCH_NETWORK_TYPEERROR_HINTS = [\n 'failed to fetch',\n 'fetch failed',\n 'load failed',\n 'networkerror',\n 'network error when attempting to fetch',\n];\n\nfunction hasRetryableNodeErrorCode(err: unknown): boolean {\n let cur: unknown = err;\n for (let depth = 0; depth < 5 && cur != null; depth++) {\n const code = (cur as { code?: string })?.code;\n if (typeof code === 'string' && NODE_NETWORK_CODES.has(code)) return true;\n cur = cur instanceof Error && cur.cause !== undefined ? cur.cause : undefined;\n }\n return false;\n}\n\nfunction isFetchFailureTypeError(err: unknown): boolean {\n if (!(err instanceof TypeError)) return false;\n const msg = String(err.message).toLowerCase();\n return FETCH_NETWORK_TYPEERROR_HINTS.some((hint) => msg.includes(hint));\n}\n\nfunction isNetworkError(err: unknown): boolean {\n return hasRetryableNodeErrorCode(err) || isFetchFailureTypeError(err);\n}\n\n/** Execute a single HTTP request using the configured fetch implementation. */\nasync function executeFetch(fetchImpl: typeof fetch | undefined, requestConfig: RequestConfig): Promise<Response> {\n const impl = fetchImpl ?? globalThis.fetch;\n if (typeof impl === 'undefined') {\n throw new Error(\n '@macpaw/ai-sdk requires a global `fetch` implementation. ' +\n 'Use Node.js 18+ or install a polyfill like `undici`.',\n );\n }\n return impl(requestConfig.url, {\n method: requestConfig.method,\n headers: requestConfig.headers,\n body: requestConfig.body,\n signal: requestConfig.signal,\n });\n}\n\n// ─── Public types ─────────────────────────────────────────────────────────────\n\nexport interface ExecuteRequestInput {\n url: string;\n method: string;\n body?: RequestInit['body'];\n headers?: Record<string, string>;\n signal?: AbortSignal;\n}\n\nexport interface ExecuteRequestBehavior {\n /** Merge config-level default headers before per-request headers. */\n includeConfigHeaders?: boolean;\n /** Resolve and inject Bearer auth via `getAuthToken()`. */\n includeAuth?: boolean;\n /** Auto-add `X-Request-ID` when missing. */\n includeRequestId?: boolean;\n /** Convert non-OK responses into normalized gateway errors. */\n normalizeErrors?: boolean;\n /** Retry once on auth failure by forcing a fresh token. */\n allowAuthRetry?: boolean;\n /** Request ID prefix for correlation, e.g. `sdk` or `provider`. */\n requestIdPrefix?: string;\n}\n\n// ─── Pipeline ─────────────────────────────────────────────────────────────────\n\nexport async function executeRequestPipeline(\n config: ResolvedConfig,\n request: ExecuteRequestInput,\n behavior?: ExecuteRequestBehavior,\n): Promise<Response> {\n const b: Required<ExecuteRequestBehavior> = {\n includeConfigHeaders: behavior?.includeConfigHeaders ?? true,\n includeAuth: behavior?.includeAuth ?? true,\n includeRequestId: behavior?.includeRequestId ?? true,\n normalizeErrors: behavior?.normalizeErrors ?? true,\n allowAuthRetry: behavior?.allowAuthRetry ?? true,\n requestIdPrefix: behavior?.requestIdPrefix ?? 'sdk',\n };\n return executeWithAuth(config, request, b, false);\n}\n\nasync function executeWithAuth(\n config: ResolvedConfig,\n request: ExecuteRequestInput,\n behavior: Required<ExecuteRequestBehavior>,\n isTokenRetry: boolean,\n): Promise<Response> {\n try {\n return await executeRequest(config, request, behavior, isTokenRetry);\n } catch (err) {\n if (behavior.allowAuthRetry && !isTokenRetry && err instanceof AuthError) {\n // ReadableStream bodies are single-consumer: once the first request reads\n // the stream it is consumed and cannot be replayed on the retry attempt.\n if (typeof ReadableStream !== 'undefined' && request.body instanceof ReadableStream) {\n throw err;\n }\n return executeWithAuth(config, request, behavior, true);\n }\n throw err;\n }\n}\n\nasync function executeRequest(\n config: ResolvedConfig,\n request: ExecuteRequestInput,\n behavior: Required<ExecuteRequestBehavior>,\n forceRefreshToken: boolean,\n): Promise<Response> {\n const headers: Record<string, string> = {\n ...(behavior.includeConfigHeaders ? config.headers : undefined),\n ...request.headers,\n };\n\n if (shouldAutoSetJsonContentType(request.body, headers)) {\n headers['Content-Type'] = 'application/json';\n }\n\n if (behavior.includeRequestId && !hasHeaderCaseInsensitive(headers, 'x-request-id')) {\n headers['X-Request-ID'] = generateRequestId(behavior.requestIdPrefix);\n }\n\n const timeoutMs = config.timeout;\n const userSignal = request.signal;\n\n async function doRequest(): Promise<Response> {\n const timeoutController = new AbortController();\n const timeoutId = setTimeout(\n () => timeoutController.abort(new Error(`Request timed out after ${timeoutMs}ms`)),\n timeoutMs,\n );\n\n const signal = userSignal ? anySignal([userSignal, timeoutController.signal]) : timeoutController.signal;\n\n const requestConfig: RequestConfig = {\n url: request.url,\n method: request.method,\n headers: { ...headers },\n body: request.body,\n signal,\n };\n\n const { middleware } = config;\n let index = 0;\n\n const next = async (currentRequest: RequestConfig): Promise<Response> => {\n if (index < middleware.length) {\n const middlewareItem = middleware[index++];\n return middlewareItem(currentRequest, next);\n }\n const finalHeaders = { ...currentRequest.headers };\n if (behavior.includeAuth) {\n const token = await config.getAuthToken(forceRefreshToken);\n if (token) {\n finalHeaders.Authorization = `Bearer ${token}`;\n } else {\n for (const key of Object.keys(finalHeaders)) {\n if (key.toLowerCase() === 'authorization') delete finalHeaders[key];\n }\n }\n }\n return executeFetch(config.fetchImpl, { ...currentRequest, headers: finalHeaders });\n };\n\n try {\n const response = await next(requestConfig);\n\n if (!response.ok) {\n const retryableStatuses = config.retry !== false ? config.retry.retryableStatuses : [];\n // Transport logic must fire regardless of normalizeErrors:\n // - 401 must throw AuthError so executeWithAuth can refresh the token\n // - retryable statuses must throw so withRetry can schedule retry attempts\n const isTransportCritical =\n (behavior.allowAuthRetry && response.status === 401) ||\n (config.retry !== false && retryableStatuses.includes(response.status));\n\n if (behavior.normalizeErrors || isTransportCritical) {\n await parseErrorResponseFromResponse(response);\n }\n }\n\n return response;\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n if (config.retry) {\n // doRequest() re-runs the full middleware chain on each retry attempt.\n // Middleware with side effects (metrics, audit logs) will fire per attempt.\n return withRetry(doRequest, {\n retryConfig: config.retry,\n signal: userSignal,\n isNetworkError,\n });\n }\n\n return doRequest();\n}\n\n/** Redact Authorization for safe logging/debugging. */\nexport { redactSensitiveHeaders };\n","/**\n * Custom fetch factory for use with Vercel AI SDK and other OpenAI-compatible clients.\n * Use this with createOpenAI({ baseURL, fetch: createGatewayFetch(...) }) or similar.\n *\n * AI Gateway HTTP paths are under /api/v1 (e.g. /api/v1/chat/completions).\n * So baseURL should be the gateway root, e.g. https://api.macpaw.com/ai\n *\n * Internally delegates to the shared request pipeline while guarding against\n * leaking gateway auth/headers to non-gateway hosts.\n */\n\nimport type { GatewayProviderSettings } from './gateway-config';\nimport { resolveConfig } from './gateway-config';\nimport { executeRequestPipeline } from './gateway-request';\n\n/**\n * Config for `createGatewayFetch`.\n * Extends GatewayProviderSettings with baseURL required (already resolved)\n * and normalizeErrors (provider-specific behavior).\n */\nexport interface GatewayFetchConfig extends GatewayProviderSettings {\n /** Resolved Gateway base URL (required — use resolveGatewayBaseURL first). */\n baseURL: string;\n /**\n * Normalize gateway error responses into `AIGatewayError`. Default: true.\n * When enabled, non-OK gateway responses throw instead of returning a failed Response.\n */\n normalizeErrors?: boolean;\n}\n\ntype FetchInput = string | URL | Request | { url: string };\n\nfunction resolveRequestUrl(input: FetchInput): string {\n if (typeof input === 'string') return input;\n if (input instanceof URL) return input.href;\n return input.url;\n}\n\nfunction stripPlaceholderAuthorization(headers: Headers, placeholder: string): void {\n const auth = headers.get('authorization');\n if (auth === `Bearer ${placeholder}`) {\n headers.delete('authorization');\n }\n}\n\nfunction headersToRecord(headers: Headers): Record<string, string> {\n const record: Record<string, string> = {};\n for (const [key, value] of headers.entries()) {\n record[key] = value;\n }\n return record;\n}\n\nfunction joinBaseUrl(baseURL: string, path: string): string {\n return `${baseURL}${path.startsWith('/') ? '' : '/'}${path}`;\n}\n\nfunction isGatewayUrl(url: URL, gatewayBaseUrl: URL): boolean {\n const gatewayPath = gatewayBaseUrl.pathname.replace(/\\/$/, '');\n const requestPath = url.pathname.replace(/\\/$/, '');\n return (\n url.origin === gatewayBaseUrl.origin && (requestPath === gatewayPath || requestPath.startsWith(`${gatewayPath}/`))\n );\n}\n\nexport const GATEWAY_PLACEHOLDER_API_KEY = 'ai-gateway-auth-via-fetch';\n\nexport function createGatewayFetch(\n options: GatewayFetchConfig,\n): (input: FetchInput, init?: RequestInit) => Promise<Response> {\n const { baseURL, normalizeErrors = true } = options;\n const base = baseURL.replace(/\\/$/, '');\n const gatewayBaseUrl = new URL(base);\n const resolvedConfig = resolveConfig({ ...options, baseURL: base });\n\n return async function gatewayFetch(input: FetchInput, init?: RequestInit): Promise<Response> {\n const rawUrl = resolveRequestUrl(input);\n const isAbsolute = rawUrl.startsWith('http://') || rawUrl.startsWith('https://');\n const resolvedUrl = new URL(isAbsolute ? rawUrl : joinBaseUrl(base, rawUrl));\n const isGatewayRequest = isGatewayUrl(resolvedUrl, gatewayBaseUrl);\n\n const request = typeof Request !== 'undefined' && input instanceof Request ? input : undefined;\n const requestClone = request?.clone();\n const headers = new Headers(requestClone?.headers);\n\n if (init?.headers) {\n for (const [key, value] of new Headers(init.headers).entries()) {\n headers.set(key, value);\n }\n }\n\n if (!isGatewayRequest) {\n stripPlaceholderAuthorization(headers, GATEWAY_PLACEHOLDER_API_KEY);\n }\n\n return executeRequestPipeline(\n resolvedConfig,\n {\n url: resolvedUrl.toString(),\n method: init?.method ?? requestClone?.method ?? 'GET',\n headers: headersToRecord(headers),\n body: init?.body ?? requestClone?.body,\n signal: init?.signal ?? requestClone?.signal,\n },\n {\n includeConfigHeaders: isGatewayRequest,\n includeAuth: isGatewayRequest,\n includeRequestId: isGatewayRequest,\n normalizeErrors: isGatewayRequest && normalizeErrors,\n allowAuthRetry: isGatewayRequest,\n requestIdPrefix: 'provider',\n },\n );\n };\n}\n","/**\n * AI Gateway provider factory.\n *\n * `createGatewayProvider()` routes bare model IDs through the gateway's\n * OpenAI-compatible endpoint with provider-specific prefixes.\n * `createAIGatewayProvider()` is the low-level escape hatch for direct\n * OpenAI-compatible provider construction.\n */\n\nimport { createOpenAI as builtinCreateOpenAI } from '@ai-sdk/openai';\nimport type { OpenAIProvider, OpenAIProviderSettings } from '@ai-sdk/openai';\nimport { createGatewayFetch, GATEWAY_PLACEHOLDER_API_KEY } from './gateway-fetch';\nimport type { Environment, GatewayProviderSettings } from './gateway-config';\nimport { resolveGatewayBaseURL } from './gateway-config';\n\n// ─── AIGatewayProvider (low-level) ────────────────────────────────────────────\n\nconst DEFAULT_API_VERSION = 'v1';\n\nexport interface AIGatewayProviderOptions\n extends Omit<OpenAIProviderSettings, 'apiKey' | 'baseURL' | 'fetch'>, GatewayProviderSettings {\n /**\n * Optional override for the OpenAI provider factory.\n * Uses `createOpenAI` from `@ai-sdk/openai` by default.\n */\n createOpenAI?: typeof builtinCreateOpenAI;\n /**\n * Normalize gateway error responses into `AIGatewayError`. Default: true.\n * When enabled, non-OK gateway responses throw instead of returning a failed Response.\n */\n normalizeErrors?: boolean;\n}\n\n/**\n * Creates a Vercel AI SDK-compatible provider backed by AI Gateway.\n *\n * The returned value is a fully typed `OpenAIProvider`, so existing apps can\n * keep using their `ai-sdk` helpers and model-selection patterns.\n */\nexport function createAIGatewayProvider(options: AIGatewayProviderOptions): OpenAIProvider {\n const baseURL = resolveGatewayBaseURL(options.baseURL, options.env as Environment, 'AIGatewayProvider');\n const customFetch = createGatewayFetch({ ...options, baseURL, normalizeErrors: options.normalizeErrors });\n\n const openAI = options.createOpenAI ?? builtinCreateOpenAI;\n\n return openAI({\n name: options.name,\n organization: options.organization,\n project: options.project,\n baseURL: `${baseURL.replace(/\\/$/, '')}/api/${DEFAULT_API_VERSION}`,\n fetch: customFetch,\n apiKey: GATEWAY_PLACEHOLDER_API_KEY,\n });\n}\n\n// ─── GatewayProvider (prefixed routing) ───────────────────────────────────────\n\nexport interface GatewayProviderBaseOptions extends AIGatewayProviderOptions {\n /**\n * Override the model ID prefix used for Gateway routing.\n * Default: the provider's canonical prefix (e.g. `'anthropic'`).\n *\n * Model IDs that already contain `/` are sent as-is.\n */\n modelPrefix?: string;\n}\n\nexport interface GatewayOpenAICompatibleOptions extends Omit<GatewayProviderBaseOptions, 'modelPrefix'> {\n /**\n * Required for openai-compatible backends because there is no single canonical\n * default prefix. Examples: `openai`, `fireworks_ai`, `openrouter`.\n */\n modelPrefix: string;\n}\n\nexport const GATEWAY_PROVIDERS = {\n ANTHROPIC: 'anthropic',\n GOOGLE: 'google',\n XAI: 'xai',\n GROQ: 'groq',\n MISTRAL: 'mistral',\n AMAZON_BEDROCK: 'amazon-bedrock',\n AZURE: 'azure',\n COHERE: 'cohere',\n PERPLEXITY: 'perplexity',\n DEEPSEEK: 'deepseek',\n TOGETHERAI: 'togetherai',\n OPENAI_COMPATIBLE: 'openai-compatible',\n} as const;\n\nexport type GatewayProvider = (typeof GATEWAY_PROVIDERS)[keyof typeof GATEWAY_PROVIDERS];\n\nexport type GatewayProviderWithDefaultPrefix = Exclude<GatewayProvider, typeof GATEWAY_PROVIDERS.OPENAI_COMPATIBLE>;\n\nexport interface GatewayProviderOptionsMap {\n [GATEWAY_PROVIDERS.OPENAI_COMPATIBLE]: GatewayOpenAICompatibleOptions;\n}\n\nexport type GatewayProviderOptions<P extends GatewayProvider> = P extends keyof GatewayProviderOptionsMap\n ? GatewayProviderOptionsMap[P]\n : GatewayProviderBaseOptions;\n\nconst GATEWAY_PROVIDER_DEFAULT_PREFIXES: Record<GatewayProviderWithDefaultPrefix, string> = {\n [GATEWAY_PROVIDERS.ANTHROPIC]: 'anthropic',\n [GATEWAY_PROVIDERS.GOOGLE]: 'google',\n [GATEWAY_PROVIDERS.XAI]: 'xai',\n [GATEWAY_PROVIDERS.GROQ]: 'groq',\n [GATEWAY_PROVIDERS.MISTRAL]: 'mistral',\n [GATEWAY_PROVIDERS.AMAZON_BEDROCK]: 'bedrock',\n [GATEWAY_PROVIDERS.AZURE]: 'azure',\n [GATEWAY_PROVIDERS.COHERE]: 'cohere',\n [GATEWAY_PROVIDERS.PERPLEXITY]: 'perplexity',\n [GATEWAY_PROVIDERS.DEEPSEEK]: 'deepseek',\n [GATEWAY_PROVIDERS.TOGETHERAI]: 'togetherai',\n};\n\nfunction prefixModelId(prefix: string, modelId: string): string {\n return modelId.includes('/') ? modelId : `${prefix}/${modelId}`;\n}\n\nfunction createPrefixedGatewayProvider(defaultPrefix: string, options: GatewayProviderBaseOptions): OpenAIProvider {\n const { modelPrefix, ...providerOptions } = options;\n const prefix = modelPrefix ?? defaultPrefix;\n const provider = createAIGatewayProvider(providerOptions);\n\n const wrapped = ((modelId: string) => provider(prefixModelId(prefix, modelId))) as OpenAIProvider;\n\n return new Proxy(wrapped, {\n apply(_target, _thisArg, args: [string, ...unknown[]]) {\n const [modelId, ...rest] = args;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return (provider as (...a: unknown[]) => any)(prefixModelId(prefix, modelId), ...rest);\n },\n get(_target, prop) {\n const value = Reflect.get(provider, prop, provider);\n if (typeof value === 'function') {\n return (...args: unknown[]) => {\n if (typeof args[0] === 'string') {\n args[0] = prefixModelId(prefix, args[0] as string);\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return (value as (...a: unknown[]) => any).apply(provider, args);\n };\n }\n return value;\n },\n has(_target, prop) {\n return prop in (provider as object);\n },\n });\n}\n\n/**\n * Creates an `OpenAIProvider` backed by AI Gateway for a supported provider.\n *\n * Bare model IDs are automatically prefixed with the provider's canonical\n * Gateway routing prefix. Model IDs that already contain `/` are passed as-is.\n */\nexport function createGatewayProvider(\n provider: GatewayProviderWithDefaultPrefix,\n options: GatewayProviderBaseOptions,\n): OpenAIProvider;\nexport function createGatewayProvider(\n provider: typeof GATEWAY_PROVIDERS.OPENAI_COMPATIBLE,\n options: GatewayOpenAICompatibleOptions,\n): OpenAIProvider;\nexport function createGatewayProvider(\n provider: GatewayProvider,\n options: GatewayProviderBaseOptions | GatewayOpenAICompatibleOptions,\n): OpenAIProvider {\n if (provider === GATEWAY_PROVIDERS.OPENAI_COMPATIBLE) {\n return createPrefixedGatewayProvider(\n (options as GatewayOpenAICompatibleOptions).modelPrefix,\n options as GatewayOpenAICompatibleOptions,\n );\n }\n\n return createPrefixedGatewayProvider(\n GATEWAY_PROVIDER_DEFAULT_PREFIXES[provider as GatewayProviderWithDefaultPrefix],\n options as GatewayProviderBaseOptions,\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/gateway-config.ts","../src/gateway-retry.ts","../src/gateway-request.ts","../src/gateway-fetch.ts","../src/gateway-provider.ts"],"names":["AuthError","parseErrorResponseFromResponse","builtinCreateOpenAI"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Configuration types and resolver for the AI Gateway SDK.\n *\n * GatewayProviderSettings is the public API — 8 fields.\n * ResolvedConfig is the internal resolved form used by the request pipeline.\n */\n\n/**\n * Supported gateway environments.\n * Only 'production' is exposed — non-production setups use a direct `baseURL`\n * instead, keeping env-specific URL management out of this library.\n */\nexport type Environment = 'production';\n\nexport interface RetryConfig {\n /** Max number of attempts (including first). Default 3. */\n maxAttempts?: number;\n /** Initial delay in ms. Default 1000. */\n initialDelayMs?: number;\n /** Max delay in ms. Default 30000. */\n maxDelayMs?: number;\n /** Retry only on these status codes (and network errors). Default: 429, 5xx. */\n retryableStatuses?: number[];\n}\n\nexport const DEFAULT_RETRY: Required<RetryConfig> = {\n maxAttempts: 3,\n initialDelayMs: 1000,\n maxDelayMs: 30000,\n retryableStatuses: [429, 500, 502, 503, 504],\n};\n\n/** Coerces invalid `maxAttempts` (0, negative, NaN) to the default. */\nexport function normalizeRetryConfig(merged: Required<RetryConfig>): Required<RetryConfig> {\n const n = Math.floor(Number(merged.maxAttempts));\n const maxAttempts = Number.isFinite(n) && n >= 1 ? n : DEFAULT_RETRY.maxAttempts;\n return { ...merged, maxAttempts };\n}\n\nexport interface RequestConfig {\n url: string;\n method: string;\n headers: Record<string, string>;\n body?: RequestInit['body'];\n signal?: AbortSignal | undefined;\n}\n\nexport type Middleware = (\n config: RequestConfig,\n next: (config: RequestConfig) => Promise<Response>,\n) => Promise<Response>;\n\n/**\n * Configuration for AI Gateway providers and NestJS module.\n *\n * Exactly 8 fields — covers auth, routing, request behaviour and middleware.\n */\nexport interface GatewayProviderSettings {\n /** Gateway base URL. Required if env is not set. */\n baseURL?: string;\n /** 'production' uses the default MacPaw Gateway URL. */\n env?: Environment;\n /**\n * Returns Bearer token for auth.\n * Called with `forceRefresh=true` after 401 — provide a fresh token.\n */\n getAuthToken: (forceRefresh?: boolean) => Promise<string | null>;\n /** Extra headers sent with every request. Do not set Authorization here. */\n headers?: Record<string, string>;\n /** Retry policy. Set to false to disable. */\n retry?: RetryConfig | false;\n /** Request timeout in ms. Default: 60000. */\n timeout?: number;\n /** Request interceptors. Run in order before each request. */\n middleware?: Middleware[];\n /**\n * Custom fetch implementation.\n * Use for testing or low-level request customization.\n */\n fetch?: typeof fetch;\n}\n\n/** Internal resolved form — used only by the request pipeline. */\nexport interface ResolvedConfig {\n baseURL: string;\n getAuthToken: (forceRefresh?: boolean) => Promise<string | null>;\n /** Already normalized — all fields present, maxAttempts ≥ 1. */\n retry: Required<RetryConfig> | false;\n middleware: Middleware[];\n headers?: Record<string, string>;\n timeout: number;\n fetchImpl?: typeof fetch;\n}\n\nexport function resolveConfig(config: GatewayProviderSettings & { baseURL: string }): ResolvedConfig {\n return {\n baseURL: config.baseURL,\n getAuthToken: config.getAuthToken,\n retry: config.retry === false ? false : normalizeRetryConfig({ ...DEFAULT_RETRY, ...config.retry }),\n middleware: [...(config.middleware ?? [])],\n headers: config.headers,\n timeout: config.timeout ?? 60_000,\n fetchImpl: config.fetch,\n };\n}\n\n/** Default base URL for the production environment. */\nexport const DEFAULT_BASE_URLS: Record<Environment, string> = {\n production: 'https://api.macpaw.com/ai',\n};\n\nexport function resolveGatewayBaseURL(\n baseURL: string | undefined,\n env: Environment | undefined,\n consumerName: string,\n): string {\n const resolved = baseURL ?? (env ? DEFAULT_BASE_URLS[env] : undefined);\n if (!resolved) {\n throw new Error(\n `${consumerName} requires baseURL or env (production). For non-production environments, pass baseURL directly.`,\n );\n }\n return resolved;\n}\n","/**\n * Retry with exponential backoff + jitter.\n * Only retries on 429, 5xx and network errors; never on 4xx (401, 402, etc.).\n *\n * Jitter prevents thundering herd when many clients retry simultaneously.\n * Respects Retry-After metadata from 429 responses.\n */\n\nimport type { RetryConfig } from './gateway-config';\nimport type { AIGatewayError } from './gateway-errors';\n\nfunction delay(ms: number, signal?: AbortSignal): Promise<void> {\n return new Promise((resolve, reject) => {\n if (signal?.aborted) {\n reject(signal.reason);\n return;\n }\n const timer = setTimeout(resolve, ms);\n signal?.addEventListener(\n 'abort',\n () => {\n clearTimeout(timer);\n reject(signal.reason);\n },\n { once: true },\n );\n });\n}\n\nfunction isRetryableStatus(status: number, retryableStatuses: number[]): boolean {\n return retryableStatuses.includes(status);\n}\n\n/** Add random jitter: 0-25% of the base delay to avoid thundering herd */\nfunction addJitter(delayMs: number): number {\n const jitter = delayMs * 0.25 * Math.random();\n return delayMs + jitter;\n}\n\nexport async function withRetry<T>(\n fn: () => Promise<T>,\n options: {\n /** Already-normalized config — all fields must be present. */\n retryConfig: Required<RetryConfig>;\n signal?: AbortSignal;\n isNetworkError?: (err: unknown) => boolean;\n },\n): Promise<T> {\n const { maxAttempts, initialDelayMs, maxDelayMs, retryableStatuses } = options.retryConfig;\n let lastError: unknown;\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n try {\n return await fn();\n } catch (err) {\n lastError = err;\n if (attempt === maxAttempts) break;\n const status = (err as { statusCode?: number })?.statusCode;\n const isRetryable =\n status != null ? isRetryableStatus(status, retryableStatuses) : (options.isNetworkError?.(err) ?? false);\n if (!isRetryable) throw err;\n\n const retryAfterSeconds = (err as AIGatewayError)?.retryAfter;\n let backoff: number;\n if (retryAfterSeconds != null && retryAfterSeconds > 0) {\n // Server-specified delay — use exactly, no jitter (contract compliance).\n backoff = retryAfterSeconds * 1000;\n } else {\n backoff = addJitter(Math.min(initialDelayMs * Math.pow(2, attempt - 1), maxDelayMs));\n }\n\n await delay(backoff, options.signal);\n }\n }\n throw lastError;\n}\n","/**\n * Shared request execution pipeline for the AI Gateway SDK.\n *\n * Handles: auth injection, Bearer token refresh on 401, middleware chain,\n * timeout, retry, and error normalization. Inlines abort, request-id,\n * and fetch transport as private helpers.\n */\n\nimport type { RequestConfig, ResolvedConfig } from './gateway-config';\nimport { AuthError, parseErrorResponseFromResponse } from './gateway-errors';\nimport { GATEWAY_PLACEHOLDER_API_KEY, normalizeBearerToken } from './gateway-fetch';\nimport { withRetry } from './gateway-retry';\n\n// ─── Private helpers ──────────────────────────────────────────────────────────\n\n/** Combine multiple AbortSignals — aborts when ANY fires. Uses native AbortSignal.any when available. */\nfunction anySignal(signals: AbortSignal[]): AbortSignal {\n const any = (AbortSignal as unknown as { any?: (signals: AbortSignal[]) => AbortSignal }).any;\n if (typeof any === 'function') {\n return any(signals);\n }\n const controller = new AbortController();\n const handlers: Array<[AbortSignal, () => void]> = [];\n function cleanup() {\n for (const [sig, handler] of handlers) sig.removeEventListener('abort', handler);\n handlers.length = 0;\n }\n for (const signal of signals) {\n if (signal.aborted) {\n controller.abort(signal.reason);\n return controller.signal;\n }\n const handler = () => {\n cleanup();\n controller.abort(signal.reason);\n };\n handlers.push([signal, handler]);\n signal.addEventListener('abort', handler, { once: true });\n }\n controller.signal.addEventListener('abort', cleanup, { once: true });\n return controller.signal;\n}\n\nlet _counter = 0;\n/** Generate a unique request ID for correlation. */\nfunction generateRequestId(prefix: string = 'sdk'): string {\n if (typeof globalThis.crypto?.randomUUID === 'function') {\n return `${prefix}-${globalThis.crypto.randomUUID()}`;\n }\n const timestamp = Date.now().toString(36);\n const count = (_counter++).toString(36);\n const random = Math.random().toString(36).slice(2, 8);\n return `${prefix}-${timestamp}-${count}-${random}`;\n}\n\n/** Case-insensitive header key lookup. */\nfunction hasHeaderCaseInsensitive(headers: Record<string, string>, name: string): boolean {\n const lower = name.toLowerCase();\n return Object.keys(headers).some((k) => k.toLowerCase() === lower);\n}\n\n/**\n * Drops every `Authorization` key regardless of casing.\n * Some runtimes would emit two header fields if both `authorization` and `Authorization`\n * exist on the same object; servers then merge them into one value with a comma.\n */\nfunction deleteAllAuthorizationHeaders(headers: Record<string, string>): void {\n for (const key of Object.keys(headers)) {\n if (key.toLowerCase() === 'authorization') delete headers[key];\n }\n}\n\nfunction shouldAutoSetJsonContentType(body: RequestInit['body'], headers: Record<string, string>): boolean {\n if (body == null || hasHeaderCaseInsensitive(headers, 'content-type')) return false;\n const isFormData = typeof FormData !== 'undefined' && body instanceof FormData;\n const isBlob = typeof Blob !== 'undefined' && body instanceof Blob;\n return !isFormData && !isBlob;\n}\n\nfunction redactSensitiveHeaders(headers: Record<string, string>): Record<string, string> {\n const redacted: Record<string, string> = {};\n for (const [key, value] of Object.entries(headers)) {\n redacted[key] = key.toLowerCase() === 'authorization' ? '[REDACTED]' : value;\n }\n return redacted;\n}\n\nconst NODE_NETWORK_CODES = new Set([\n 'ECONNREFUSED',\n 'ECONNRESET',\n 'ENOTFOUND',\n 'EPIPE',\n 'ETIMEDOUT',\n 'ENETUNREACH',\n 'EAI_AGAIN',\n 'UND_ERR_CONNECT_TIMEOUT',\n]);\n\nconst FETCH_NETWORK_TYPEERROR_HINTS = [\n 'failed to fetch',\n 'fetch failed',\n 'load failed',\n 'networkerror',\n 'network error when attempting to fetch',\n];\n\nfunction hasRetryableNodeErrorCode(err: unknown): boolean {\n let cur: unknown = err;\n for (let depth = 0; depth < 5 && cur != null; depth++) {\n const code = (cur as { code?: string })?.code;\n if (typeof code === 'string' && NODE_NETWORK_CODES.has(code)) return true;\n cur = cur instanceof Error && cur.cause !== undefined ? cur.cause : undefined;\n }\n return false;\n}\n\nfunction isFetchFailureTypeError(err: unknown): boolean {\n if (!(err instanceof TypeError)) return false;\n const msg = String(err.message).toLowerCase();\n return FETCH_NETWORK_TYPEERROR_HINTS.some((hint) => msg.includes(hint));\n}\n\nfunction isNetworkError(err: unknown): boolean {\n return hasRetryableNodeErrorCode(err) || isFetchFailureTypeError(err);\n}\n\n/** Execute a single HTTP request using the configured fetch implementation. */\nasync function executeFetch(fetchImpl: typeof fetch | undefined, requestConfig: RequestConfig): Promise<Response> {\n const impl = fetchImpl ?? globalThis.fetch;\n if (typeof impl === 'undefined') {\n throw new Error(\n '@macpaw/ai-sdk requires a global `fetch` implementation. ' +\n 'Use Node.js 18+ or install a polyfill like `undici`.',\n );\n }\n return impl(requestConfig.url, {\n method: requestConfig.method,\n headers: requestConfig.headers,\n body: requestConfig.body,\n signal: requestConfig.signal,\n });\n}\n\n// ─── Public types ─────────────────────────────────────────────────────────────\n\nexport interface ExecuteRequestInput {\n url: string;\n method: string;\n body?: RequestInit['body'];\n headers?: Record<string, string>;\n signal?: AbortSignal;\n}\n\nexport interface ExecuteRequestBehavior {\n /** Merge config-level default headers before per-request headers. */\n includeConfigHeaders?: boolean;\n /** Resolve and inject Bearer auth via `getAuthToken()`. */\n includeAuth?: boolean;\n /** Auto-add `X-Request-ID` when missing. */\n includeRequestId?: boolean;\n /** Convert non-OK responses into normalized gateway errors. */\n normalizeErrors?: boolean;\n /** Retry once on auth failure by forcing a fresh token. */\n allowAuthRetry?: boolean;\n /** Request ID prefix for correlation, e.g. `sdk` or `provider`. */\n requestIdPrefix?: string;\n}\n\n// ─── Pipeline ─────────────────────────────────────────────────────────────────\n\nexport async function executeRequestPipeline(\n config: ResolvedConfig,\n request: ExecuteRequestInput,\n behavior?: ExecuteRequestBehavior,\n): Promise<Response> {\n const b: Required<ExecuteRequestBehavior> = {\n includeConfigHeaders: behavior?.includeConfigHeaders ?? true,\n includeAuth: behavior?.includeAuth ?? true,\n includeRequestId: behavior?.includeRequestId ?? true,\n normalizeErrors: behavior?.normalizeErrors ?? true,\n allowAuthRetry: behavior?.allowAuthRetry ?? true,\n requestIdPrefix: behavior?.requestIdPrefix ?? 'sdk',\n };\n return executeWithAuth(config, request, b, false);\n}\n\nasync function executeWithAuth(\n config: ResolvedConfig,\n request: ExecuteRequestInput,\n behavior: Required<ExecuteRequestBehavior>,\n isTokenRetry: boolean,\n): Promise<Response> {\n try {\n return await executeRequest(config, request, behavior, isTokenRetry);\n } catch (err) {\n if (behavior.allowAuthRetry && !isTokenRetry && err instanceof AuthError) {\n // ReadableStream bodies are single-consumer: once the first request reads\n // the stream it is consumed and cannot be replayed on the retry attempt.\n if (typeof ReadableStream !== 'undefined' && request.body instanceof ReadableStream) {\n throw err;\n }\n return executeWithAuth(config, request, behavior, true);\n }\n throw err;\n }\n}\n\nasync function executeRequest(\n config: ResolvedConfig,\n request: ExecuteRequestInput,\n behavior: Required<ExecuteRequestBehavior>,\n forceRefreshToken: boolean,\n): Promise<Response> {\n const headers: Record<string, string> = {\n ...(behavior.includeConfigHeaders ? config.headers : undefined),\n ...request.headers,\n };\n\n if (shouldAutoSetJsonContentType(request.body, headers)) {\n headers['Content-Type'] = 'application/json';\n }\n\n if (behavior.includeRequestId && !hasHeaderCaseInsensitive(headers, 'x-request-id')) {\n headers['X-Request-ID'] = generateRequestId(behavior.requestIdPrefix);\n }\n\n const timeoutMs = config.timeout;\n const userSignal = request.signal;\n\n async function doRequest(): Promise<Response> {\n const timeoutController = new AbortController();\n const timeoutId = setTimeout(\n () => timeoutController.abort(new Error(`Request timed out after ${timeoutMs}ms`)),\n timeoutMs,\n );\n\n const signal = userSignal ? anySignal([userSignal, timeoutController.signal]) : timeoutController.signal;\n\n const requestConfig: RequestConfig = {\n url: request.url,\n method: request.method,\n headers: { ...headers },\n body: request.body,\n signal,\n };\n\n const { middleware } = config;\n let index = 0;\n\n const next = async (currentRequest: RequestConfig): Promise<Response> => {\n if (index < middleware.length) {\n const middlewareItem = middleware[index++];\n return middlewareItem(currentRequest, next);\n }\n const finalHeaders = { ...currentRequest.headers };\n if (behavior.includeAuth) {\n deleteAllAuthorizationHeaders(finalHeaders);\n const rawToken = await config.getAuthToken(forceRefreshToken);\n const token = normalizeBearerToken(rawToken);\n if (token && token !== GATEWAY_PLACEHOLDER_API_KEY) {\n finalHeaders.Authorization = `Bearer ${token}`;\n }\n }\n return executeFetch(config.fetchImpl, { ...currentRequest, headers: finalHeaders });\n };\n\n try {\n const response = await next(requestConfig);\n\n if (!response.ok) {\n const retryableStatuses = config.retry !== false ? config.retry.retryableStatuses : [];\n // Transport logic must fire regardless of normalizeErrors:\n // - 401 must throw AuthError so executeWithAuth can refresh the token\n // - retryable statuses must throw so withRetry can schedule retry attempts\n const isTransportCritical =\n (behavior.allowAuthRetry && response.status === 401) ||\n (config.retry !== false && retryableStatuses.includes(response.status));\n\n if (behavior.normalizeErrors || isTransportCritical) {\n await parseErrorResponseFromResponse(response);\n }\n }\n\n return response;\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n if (config.retry) {\n // doRequest() re-runs the full middleware chain on each retry attempt.\n // Middleware with side effects (metrics, audit logs) will fire per attempt.\n return withRetry(doRequest, {\n retryConfig: config.retry,\n signal: userSignal,\n isNetworkError,\n });\n }\n\n return doRequest();\n}\n\n/** Redact Authorization for safe logging/debugging. */\nexport { redactSensitiveHeaders };\n","/**\n * Custom fetch factory for use with Vercel AI SDK and other OpenAI-compatible clients.\n * Use this with createOpenAI({ baseURL, fetch: createGatewayFetch(...) }) or similar.\n *\n * AI Gateway HTTP paths are under /api/v1 (e.g. /api/v1/chat/completions).\n * So baseURL should be the gateway root, e.g. https://api.macpaw.com/ai\n *\n * Internally delegates to the shared request pipeline while guarding against\n * leaking gateway auth/headers to non-gateway hosts.\n */\n\nimport type { GatewayProviderSettings } from './gateway-config';\nimport { resolveConfig } from './gateway-config';\nimport { executeRequestPipeline } from './gateway-request';\n\nexport const GATEWAY_PLACEHOLDER_API_KEY = 'ai-gateway-auth-via-fetch';\n\n/**\n * Config for `createGatewayFetch`.\n * Extends GatewayProviderSettings with baseURL required (already resolved)\n * and normalizeErrors (provider-specific behavior).\n */\nexport interface GatewayFetchConfig extends GatewayProviderSettings {\n /** Resolved Gateway base URL (required — use resolveGatewayBaseURL first). */\n baseURL: string;\n /**\n * Normalize gateway error responses into `AIGatewayError`. Default: true.\n * When enabled, non-OK gateway responses throw instead of returning a failed Response.\n */\n normalizeErrors?: boolean;\n}\n\ntype FetchInput = string | URL | Request | { url: string };\n\nfunction resolveRequestUrl(input: FetchInput): string {\n if (typeof input === 'string') return input;\n if (input instanceof URL) return input.href;\n return input.url;\n}\n\n/**\n * Trims, strips a single layer of surrounding ASCII quotes, and removes\n * trailing comma/semicolon noise often introduced by .env or copy-paste.\n */\nexport function normalizeBearerToken(raw: string | null | undefined): string | null {\n if (raw == null) return null;\n let s = String(raw).trim();\n if (!s) return null;\n\n if (\n (s.startsWith('\"') && s.endsWith('\"') && s.length >= 2) ||\n (s.startsWith(\"'\") && s.endsWith(\"'\") && s.length >= 2)\n ) {\n s = s.slice(1, -1).trim();\n }\n\n s = s.replace(/[,;]+\\s*$/g, '').trim();\n return s.length > 0 ? s : null;\n}\n\n/**\n * Removes Authorization when it is only the OpenAI apiKey placeholder (optional trailing comma),\n * so a real Bearer from getAuthToken() is not merged with a junk value.\n */\nfunction stripPlaceholderAuthorization(headers: Headers, placeholder: string): void {\n const auth = headers.get('authorization');\n if (!auth) return;\n const m = auth.match(/^Bearer\\s+(\\S+)/i);\n if (!m) return;\n const credential = normalizeBearerToken(m[1]);\n if (credential === placeholder) {\n headers.delete('authorization');\n }\n}\n\nfunction headersToRecord(headers: Headers): Record<string, string> {\n const record: Record<string, string> = {};\n for (const [key, value] of headers.entries()) {\n record[key] = value;\n }\n return record;\n}\n\nfunction joinBaseUrl(baseURL: string, path: string): string {\n return `${baseURL}${path.startsWith('/') ? '' : '/'}${path}`;\n}\n\nfunction isGatewayUrl(url: URL, gatewayBaseUrl: URL): boolean {\n const gatewayPath = gatewayBaseUrl.pathname.replace(/\\/$/, '');\n const requestPath = url.pathname.replace(/\\/$/, '');\n return (\n url.origin === gatewayBaseUrl.origin && (requestPath === gatewayPath || requestPath.startsWith(`${gatewayPath}/`))\n );\n}\n\nexport function createGatewayFetch(\n options: GatewayFetchConfig,\n): (input: FetchInput, init?: RequestInit) => Promise<Response> {\n const { baseURL, normalizeErrors = true } = options;\n const base = baseURL.replace(/\\/$/, '');\n const gatewayBaseUrl = new URL(base);\n const resolvedConfig = resolveConfig({ ...options, baseURL: base });\n\n return async function gatewayFetch(input: FetchInput, init?: RequestInit): Promise<Response> {\n const rawUrl = resolveRequestUrl(input);\n const isAbsolute = rawUrl.startsWith('http://') || rawUrl.startsWith('https://');\n const resolvedUrl = new URL(isAbsolute ? rawUrl : joinBaseUrl(base, rawUrl));\n const isGatewayRequest = isGatewayUrl(resolvedUrl, gatewayBaseUrl);\n\n const request = typeof Request !== 'undefined' && input instanceof Request ? input : undefined;\n const requestClone = request?.clone();\n const headers = new Headers(requestClone?.headers);\n\n if (init?.headers) {\n for (const [key, value] of new Headers(init.headers).entries()) {\n headers.set(key, value);\n }\n }\n\n // Always strip the OpenAI placeholder before entering the shared pipeline.\n // For gateway requests the real Bearer is injected later via getAuthToken();\n // for non-gateway requests we also avoid leaking the sentinel downstream.\n stripPlaceholderAuthorization(headers, GATEWAY_PLACEHOLDER_API_KEY);\n\n return executeRequestPipeline(\n resolvedConfig,\n {\n url: resolvedUrl.toString(),\n method: init?.method ?? requestClone?.method ?? 'GET',\n headers: headersToRecord(headers),\n body: init?.body ?? requestClone?.body,\n signal: init?.signal ?? requestClone?.signal,\n },\n {\n includeConfigHeaders: isGatewayRequest,\n includeAuth: isGatewayRequest,\n includeRequestId: isGatewayRequest,\n normalizeErrors: isGatewayRequest && normalizeErrors,\n allowAuthRetry: isGatewayRequest,\n requestIdPrefix: 'provider',\n },\n );\n };\n}\n","/**\n * AI Gateway provider factory.\n *\n * `createGatewayProvider()` routes bare model IDs through the gateway's\n * OpenAI-compatible endpoint with provider-specific prefixes.\n * `createAIGatewayProvider()` is the low-level escape hatch for direct\n * OpenAI-compatible provider construction.\n */\n\nimport { createOpenAI as builtinCreateOpenAI } from '@ai-sdk/openai';\nimport type { OpenAIProvider, OpenAIProviderSettings } from '@ai-sdk/openai';\nimport { createGatewayFetch, GATEWAY_PLACEHOLDER_API_KEY } from './gateway-fetch';\nimport type { Environment, GatewayProviderSettings } from './gateway-config';\nimport { resolveGatewayBaseURL } from './gateway-config';\n\n// ─── AIGatewayProvider (low-level) ────────────────────────────────────────────\n\nconst DEFAULT_API_VERSION = 'v1';\n\nexport interface AIGatewayProviderOptions\n extends Omit<OpenAIProviderSettings, 'apiKey' | 'baseURL' | 'fetch'>, GatewayProviderSettings {\n /**\n * Optional override for the OpenAI provider factory.\n * Uses `createOpenAI` from `@ai-sdk/openai` by default.\n */\n createOpenAI?: typeof builtinCreateOpenAI;\n /**\n * Normalize gateway error responses into `AIGatewayError`. Default: true.\n * When enabled, non-OK gateway responses throw instead of returning a failed Response.\n */\n normalizeErrors?: boolean;\n}\n\n/**\n * Creates a Vercel AI SDK-compatible provider backed by AI Gateway.\n *\n * The returned value is a fully typed `OpenAIProvider`, so existing apps can\n * keep using their `ai-sdk` helpers and model-selection patterns.\n */\nexport function createAIGatewayProvider(options: AIGatewayProviderOptions): OpenAIProvider {\n const baseURL = resolveGatewayBaseURL(options.baseURL, options.env as Environment, 'AIGatewayProvider');\n const customFetch = createGatewayFetch({ ...options, baseURL, normalizeErrors: options.normalizeErrors });\n\n const openAI = options.createOpenAI ?? builtinCreateOpenAI;\n\n return openAI({\n name: options.name,\n organization: options.organization,\n project: options.project,\n baseURL: `${baseURL.replace(/\\/$/, '')}/api/${DEFAULT_API_VERSION}`,\n fetch: customFetch,\n apiKey: GATEWAY_PLACEHOLDER_API_KEY,\n });\n}\n\n// ─── GatewayProvider (prefixed routing) ───────────────────────────────────────\n\nexport interface GatewayProviderBaseOptions extends AIGatewayProviderOptions {\n /**\n * Override the model ID prefix used for Gateway routing.\n * Default: the provider's canonical prefix (e.g. `'anthropic'`).\n *\n * Model IDs that already contain `/` are sent as-is.\n */\n modelPrefix?: string;\n}\n\nexport interface GatewayOpenAICompatibleOptions extends Omit<GatewayProviderBaseOptions, 'modelPrefix'> {\n /**\n * Required for openai-compatible backends because there is no single canonical\n * default prefix. Examples: `openai`, `fireworks_ai`, `openrouter`.\n */\n modelPrefix: string;\n}\n\nexport const GATEWAY_PROVIDERS = {\n ANTHROPIC: 'anthropic',\n GOOGLE: 'google',\n XAI: 'xai',\n GROQ: 'groq',\n MISTRAL: 'mistral',\n AMAZON_BEDROCK: 'amazon-bedrock',\n AZURE: 'azure',\n COHERE: 'cohere',\n PERPLEXITY: 'perplexity',\n DEEPSEEK: 'deepseek',\n TOGETHERAI: 'togetherai',\n OPENAI_COMPATIBLE: 'openai-compatible',\n} as const;\n\nexport type GatewayProvider = (typeof GATEWAY_PROVIDERS)[keyof typeof GATEWAY_PROVIDERS];\n\nexport type GatewayProviderWithDefaultPrefix = Exclude<GatewayProvider, typeof GATEWAY_PROVIDERS.OPENAI_COMPATIBLE>;\n\nexport interface GatewayProviderOptionsMap {\n [GATEWAY_PROVIDERS.OPENAI_COMPATIBLE]: GatewayOpenAICompatibleOptions;\n}\n\nexport type GatewayProviderOptions<P extends GatewayProvider> = P extends keyof GatewayProviderOptionsMap\n ? GatewayProviderOptionsMap[P]\n : GatewayProviderBaseOptions;\n\nconst GATEWAY_PROVIDER_DEFAULT_PREFIXES: Record<GatewayProviderWithDefaultPrefix, string> = {\n [GATEWAY_PROVIDERS.ANTHROPIC]: 'anthropic',\n [GATEWAY_PROVIDERS.GOOGLE]: 'google',\n [GATEWAY_PROVIDERS.XAI]: 'xai',\n [GATEWAY_PROVIDERS.GROQ]: 'groq',\n [GATEWAY_PROVIDERS.MISTRAL]: 'mistral',\n [GATEWAY_PROVIDERS.AMAZON_BEDROCK]: 'bedrock',\n [GATEWAY_PROVIDERS.AZURE]: 'azure',\n [GATEWAY_PROVIDERS.COHERE]: 'cohere',\n [GATEWAY_PROVIDERS.PERPLEXITY]: 'perplexity',\n [GATEWAY_PROVIDERS.DEEPSEEK]: 'deepseek',\n [GATEWAY_PROVIDERS.TOGETHERAI]: 'togetherai',\n};\n\nfunction prefixModelId(prefix: string, modelId: string): string {\n return modelId.includes('/') ? modelId : `${prefix}/${modelId}`;\n}\n\nfunction createPrefixedGatewayProvider(defaultPrefix: string, options: GatewayProviderBaseOptions): OpenAIProvider {\n const { modelPrefix, ...providerOptions } = options;\n const prefix = modelPrefix ?? defaultPrefix;\n const provider = createAIGatewayProvider(providerOptions);\n\n const wrapped = ((modelId: string) => provider(prefixModelId(prefix, modelId))) as OpenAIProvider;\n\n return new Proxy(wrapped, {\n apply(_target, _thisArg, args: [string, ...unknown[]]) {\n const [modelId, ...rest] = args;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return (provider as (...a: unknown[]) => any)(prefixModelId(prefix, modelId), ...rest);\n },\n get(_target, prop) {\n const value = Reflect.get(provider, prop, provider);\n if (typeof value === 'function') {\n return (...args: unknown[]) => {\n if (typeof args[0] === 'string') {\n args[0] = prefixModelId(prefix, args[0] as string);\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return (value as (...a: unknown[]) => any).apply(provider, args);\n };\n }\n return value;\n },\n has(_target, prop) {\n return prop in (provider as object);\n },\n });\n}\n\n/**\n * Creates an `OpenAIProvider` backed by AI Gateway for a supported provider.\n *\n * Bare model IDs are automatically prefixed with the provider's canonical\n * Gateway routing prefix. Model IDs that already contain `/` are passed as-is.\n */\nexport function createGatewayProvider(\n provider: GatewayProviderWithDefaultPrefix,\n options: GatewayProviderBaseOptions,\n): OpenAIProvider;\nexport function createGatewayProvider(\n provider: typeof GATEWAY_PROVIDERS.OPENAI_COMPATIBLE,\n options: GatewayOpenAICompatibleOptions,\n): OpenAIProvider;\nexport function createGatewayProvider(\n provider: GatewayProvider,\n options: GatewayProviderBaseOptions | GatewayOpenAICompatibleOptions,\n): OpenAIProvider {\n if (provider === GATEWAY_PROVIDERS.OPENAI_COMPATIBLE) {\n return createPrefixedGatewayProvider(\n (options as GatewayOpenAICompatibleOptions).modelPrefix,\n options as GatewayOpenAICompatibleOptions,\n );\n }\n\n return createPrefixedGatewayProvider(\n GATEWAY_PROVIDER_DEFAULT_PREFIXES[provider as GatewayProviderWithDefaultPrefix],\n options as GatewayProviderBaseOptions,\n );\n}\n"]}
package/dist/index.d.cts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { OpenAIProviderSettings, createOpenAI, OpenAIProvider } from '@ai-sdk/openai';
2
- import { G as GatewayProviderSettings } from './gateway-errors-DdgDIyQw.cjs';
3
- export { A as AIGatewayError, a as AuthError, C as CreditsError, E as ErrorCode, b as GatewayApiCode, c as GatewayApiErrorItem, d as GatewayApiErrorResponse, e as GatewayValidationError, M as Middleware, f as ModelNotAllowedError, N as NormalizedErrorMetadata, O as OpenAIErrorResponse, R as RateLimitError, g as RetryConfig, i as isAIGatewayError, p as parseErrorResponse } from './gateway-errors-DdgDIyQw.cjs';
2
+ import { G as GatewayProviderSettings } from './gateway-errors-CPtIbrWq.cjs';
3
+ export { A as AIGatewayError, a as AuthError, C as CreditsError, D as DEFAULT_BASE_URLS, E as Environment, b as ErrorCode, c as GatewayApiCode, d as GatewayApiErrorItem, e as GatewayApiErrorResponse, f as GatewayValidationError, M as Middleware, g as ModelNotAllowedError, N as NormalizedErrorMetadata, O as OpenAIErrorResponse, R as RateLimitError, h as RetryConfig, i as isAIGatewayError, p as parseErrorResponse, r as resolveGatewayBaseURL } from './gateway-errors-CPtIbrWq.cjs';
4
4
 
5
5
  /**
6
6
  * AI Gateway provider factory.
@@ -86,6 +86,7 @@ declare function createGatewayProvider(provider: typeof GATEWAY_PROVIDERS.OPENAI
86
86
  * leaking gateway auth/headers to non-gateway hosts.
87
87
  */
88
88
 
89
+ declare const GATEWAY_PLACEHOLDER_API_KEY = "ai-gateway-auth-via-fetch";
89
90
  /**
90
91
  * Config for `createGatewayFetch`.
91
92
  * Extends GatewayProviderSettings with baseURL required (already resolved)
@@ -103,7 +104,6 @@ interface GatewayFetchConfig extends GatewayProviderSettings {
103
104
  type FetchInput = string | URL | Request | {
104
105
  url: string;
105
106
  };
106
- declare const GATEWAY_PLACEHOLDER_API_KEY = "ai-gateway-auth-via-fetch";
107
107
  declare function createGatewayFetch(options: GatewayFetchConfig): (input: FetchInput, init?: RequestInit) => Promise<Response>;
108
108
 
109
109
  export { type AIGatewayProviderOptions, GATEWAY_PLACEHOLDER_API_KEY, GATEWAY_PROVIDERS, type GatewayFetchConfig, type GatewayOpenAICompatibleOptions, type GatewayProvider, type GatewayProviderBaseOptions, type GatewayProviderOptions, type GatewayProviderOptionsMap, GatewayProviderSettings, type GatewayProviderWithDefaultPrefix, createAIGatewayProvider, createGatewayFetch, createGatewayProvider };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { OpenAIProviderSettings, createOpenAI, OpenAIProvider } from '@ai-sdk/openai';
2
- import { G as GatewayProviderSettings } from './gateway-errors-DdgDIyQw.js';
3
- export { A as AIGatewayError, a as AuthError, C as CreditsError, E as ErrorCode, b as GatewayApiCode, c as GatewayApiErrorItem, d as GatewayApiErrorResponse, e as GatewayValidationError, M as Middleware, f as ModelNotAllowedError, N as NormalizedErrorMetadata, O as OpenAIErrorResponse, R as RateLimitError, g as RetryConfig, i as isAIGatewayError, p as parseErrorResponse } from './gateway-errors-DdgDIyQw.js';
2
+ import { G as GatewayProviderSettings } from './gateway-errors-CPtIbrWq.js';
3
+ export { A as AIGatewayError, a as AuthError, C as CreditsError, D as DEFAULT_BASE_URLS, E as Environment, b as ErrorCode, c as GatewayApiCode, d as GatewayApiErrorItem, e as GatewayApiErrorResponse, f as GatewayValidationError, M as Middleware, g as ModelNotAllowedError, N as NormalizedErrorMetadata, O as OpenAIErrorResponse, R as RateLimitError, h as RetryConfig, i as isAIGatewayError, p as parseErrorResponse, r as resolveGatewayBaseURL } from './gateway-errors-CPtIbrWq.js';
4
4
 
5
5
  /**
6
6
  * AI Gateway provider factory.
@@ -86,6 +86,7 @@ declare function createGatewayProvider(provider: typeof GATEWAY_PROVIDERS.OPENAI
86
86
  * leaking gateway auth/headers to non-gateway hosts.
87
87
  */
88
88
 
89
+ declare const GATEWAY_PLACEHOLDER_API_KEY = "ai-gateway-auth-via-fetch";
89
90
  /**
90
91
  * Config for `createGatewayFetch`.
91
92
  * Extends GatewayProviderSettings with baseURL required (already resolved)
@@ -103,7 +104,6 @@ interface GatewayFetchConfig extends GatewayProviderSettings {
103
104
  type FetchInput = string | URL | Request | {
104
105
  url: string;
105
106
  };
106
- declare const GATEWAY_PLACEHOLDER_API_KEY = "ai-gateway-auth-via-fetch";
107
107
  declare function createGatewayFetch(options: GatewayFetchConfig): (input: FetchInput, init?: RequestInit) => Promise<Response>;
108
108
 
109
109
  export { type AIGatewayProviderOptions, GATEWAY_PLACEHOLDER_API_KEY, GATEWAY_PROVIDERS, type GatewayFetchConfig, type GatewayOpenAICompatibleOptions, type GatewayProvider, type GatewayProviderBaseOptions, type GatewayProviderOptions, type GatewayProviderOptionsMap, GatewayProviderSettings, type GatewayProviderWithDefaultPrefix, createAIGatewayProvider, createGatewayFetch, createGatewayProvider };
package/dist/index.js CHANGED
@@ -129,6 +129,11 @@ function hasHeaderCaseInsensitive(headers, name) {
129
129
  const lower = name.toLowerCase();
130
130
  return Object.keys(headers).some((k) => k.toLowerCase() === lower);
131
131
  }
132
+ function deleteAllAuthorizationHeaders(headers) {
133
+ for (const key of Object.keys(headers)) {
134
+ if (key.toLowerCase() === "authorization") delete headers[key];
135
+ }
136
+ }
132
137
  function shouldAutoSetJsonContentType(body, headers) {
133
138
  if (body == null || hasHeaderCaseInsensitive(headers, "content-type")) return false;
134
139
  const isFormData = typeof FormData !== "undefined" && body instanceof FormData;
@@ -243,13 +248,11 @@ async function executeRequest(config, request, behavior, forceRefreshToken) {
243
248
  }
244
249
  const finalHeaders = { ...currentRequest.headers };
245
250
  if (behavior.includeAuth) {
246
- const token = await config.getAuthToken(forceRefreshToken);
247
- if (token) {
251
+ deleteAllAuthorizationHeaders(finalHeaders);
252
+ const rawToken = await config.getAuthToken(forceRefreshToken);
253
+ const token = normalizeBearerToken(rawToken);
254
+ if (token && token !== GATEWAY_PLACEHOLDER_API_KEY) {
248
255
  finalHeaders.Authorization = `Bearer ${token}`;
249
- } else {
250
- for (const key of Object.keys(finalHeaders)) {
251
- if (key.toLowerCase() === "authorization") delete finalHeaders[key];
252
- }
253
256
  }
254
257
  }
255
258
  return executeFetch(config.fetchImpl, { ...currentRequest, headers: finalHeaders });
@@ -279,14 +282,29 @@ async function executeRequest(config, request, behavior, forceRefreshToken) {
279
282
  }
280
283
 
281
284
  // src/gateway-fetch.ts
285
+ var GATEWAY_PLACEHOLDER_API_KEY = "ai-gateway-auth-via-fetch";
282
286
  function resolveRequestUrl(input) {
283
287
  if (typeof input === "string") return input;
284
288
  if (input instanceof URL) return input.href;
285
289
  return input.url;
286
290
  }
291
+ function normalizeBearerToken(raw) {
292
+ if (raw == null) return null;
293
+ let s = String(raw).trim();
294
+ if (!s) return null;
295
+ if (s.startsWith('"') && s.endsWith('"') && s.length >= 2 || s.startsWith("'") && s.endsWith("'") && s.length >= 2) {
296
+ s = s.slice(1, -1).trim();
297
+ }
298
+ s = s.replace(/[,;]+\s*$/g, "").trim();
299
+ return s.length > 0 ? s : null;
300
+ }
287
301
  function stripPlaceholderAuthorization(headers, placeholder) {
288
302
  const auth = headers.get("authorization");
289
- if (auth === `Bearer ${placeholder}`) {
303
+ if (!auth) return;
304
+ const m = auth.match(/^Bearer\s+(\S+)/i);
305
+ if (!m) return;
306
+ const credential = normalizeBearerToken(m[1]);
307
+ if (credential === placeholder) {
290
308
  headers.delete("authorization");
291
309
  }
292
310
  }
@@ -305,7 +323,6 @@ function isGatewayUrl(url, gatewayBaseUrl) {
305
323
  const requestPath = url.pathname.replace(/\/$/, "");
306
324
  return url.origin === gatewayBaseUrl.origin && (requestPath === gatewayPath || requestPath.startsWith(`${gatewayPath}/`));
307
325
  }
308
- var GATEWAY_PLACEHOLDER_API_KEY = "ai-gateway-auth-via-fetch";
309
326
  function createGatewayFetch(options) {
310
327
  const { baseURL, normalizeErrors = true } = options;
311
328
  const base = baseURL.replace(/\/$/, "");
@@ -324,9 +341,7 @@ function createGatewayFetch(options) {
324
341
  headers.set(key, value);
325
342
  }
326
343
  }
327
- if (!isGatewayRequest) {
328
- stripPlaceholderAuthorization(headers, GATEWAY_PLACEHOLDER_API_KEY);
329
- }
344
+ stripPlaceholderAuthorization(headers, GATEWAY_PLACEHOLDER_API_KEY);
330
345
  return executeRequestPipeline(
331
346
  resolvedConfig,
332
347
  {
@@ -433,6 +448,6 @@ function createGatewayProvider(provider, options) {
433
448
  );
434
449
  }
435
450
 
436
- export { GATEWAY_PLACEHOLDER_API_KEY, GATEWAY_PROVIDERS, createAIGatewayProvider, createGatewayFetch, createGatewayProvider };
451
+ export { DEFAULT_BASE_URLS, GATEWAY_PLACEHOLDER_API_KEY, GATEWAY_PROVIDERS, createAIGatewayProvider, createGatewayFetch, createGatewayProvider, resolveGatewayBaseURL };
437
452
  //# sourceMappingURL=index.js.map
438
453
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/gateway-config.ts","../src/gateway-retry.ts","../src/gateway-request.ts","../src/gateway-fetch.ts","../src/gateway-provider.ts"],"names":["builtinCreateOpenAI"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Configuration types and resolver for the AI Gateway SDK.\n *\n * GatewayProviderSettings is the public API — 8 fields.\n * ResolvedConfig is the internal resolved form used by the request pipeline.\n */\n\n/**\n * Supported gateway environments.\n * Only 'production' is exposed — non-production setups use a direct `baseURL`\n * instead, keeping env-specific URL management out of this library.\n */\nexport type Environment = 'production';\n\nexport interface RetryConfig {\n /** Max number of attempts (including first). Default 3. */\n maxAttempts?: number;\n /** Initial delay in ms. Default 1000. */\n initialDelayMs?: number;\n /** Max delay in ms. Default 30000. */\n maxDelayMs?: number;\n /** Retry only on these status codes (and network errors). Default: 429, 5xx. */\n retryableStatuses?: number[];\n}\n\nexport const DEFAULT_RETRY: Required<RetryConfig> = {\n maxAttempts: 3,\n initialDelayMs: 1000,\n maxDelayMs: 30000,\n retryableStatuses: [429, 500, 502, 503, 504],\n};\n\n/** Coerces invalid `maxAttempts` (0, negative, NaN) to the default. */\nexport function normalizeRetryConfig(merged: Required<RetryConfig>): Required<RetryConfig> {\n const n = Math.floor(Number(merged.maxAttempts));\n const maxAttempts = Number.isFinite(n) && n >= 1 ? n : DEFAULT_RETRY.maxAttempts;\n return { ...merged, maxAttempts };\n}\n\nexport interface RequestConfig {\n url: string;\n method: string;\n headers: Record<string, string>;\n body?: RequestInit['body'];\n signal?: AbortSignal | undefined;\n}\n\nexport type Middleware = (\n config: RequestConfig,\n next: (config: RequestConfig) => Promise<Response>,\n) => Promise<Response>;\n\n/**\n * Configuration for AI Gateway providers and NestJS module.\n *\n * Exactly 8 fields — covers auth, routing, request behaviour and middleware.\n */\nexport interface GatewayProviderSettings {\n /** Gateway base URL. Required if env is not set. */\n baseURL?: string;\n /** 'production' uses the default MacPaw Gateway URL. */\n env?: Environment;\n /**\n * Returns Bearer token for auth.\n * Called with `forceRefresh=true` after 401 — provide a fresh token.\n */\n getAuthToken: (forceRefresh?: boolean) => Promise<string | null>;\n /** Extra headers sent with every request. Do not set Authorization here. */\n headers?: Record<string, string>;\n /** Retry policy. Set to false to disable. */\n retry?: RetryConfig | false;\n /** Request timeout in ms. Default: 60000. */\n timeout?: number;\n /** Request interceptors. Run in order before each request. */\n middleware?: Middleware[];\n /**\n * Custom fetch implementation.\n * Use for testing or low-level request customization.\n */\n fetch?: typeof fetch;\n}\n\n/** Internal resolved form — used only by the request pipeline. */\nexport interface ResolvedConfig {\n baseURL: string;\n getAuthToken: (forceRefresh?: boolean) => Promise<string | null>;\n /** Already normalized — all fields present, maxAttempts ≥ 1. */\n retry: Required<RetryConfig> | false;\n middleware: Middleware[];\n headers?: Record<string, string>;\n timeout: number;\n fetchImpl?: typeof fetch;\n}\n\nexport function resolveConfig(config: GatewayProviderSettings & { baseURL: string }): ResolvedConfig {\n return {\n baseURL: config.baseURL,\n getAuthToken: config.getAuthToken,\n retry: config.retry === false ? false : normalizeRetryConfig({ ...DEFAULT_RETRY, ...config.retry }),\n middleware: [...(config.middleware ?? [])],\n headers: config.headers,\n timeout: config.timeout ?? 60_000,\n fetchImpl: config.fetch,\n };\n}\n\n/** Default base URL for the production environment. */\nexport const DEFAULT_BASE_URLS: Record<Environment, string> = {\n production: 'https://api.macpaw.com/ai',\n};\n\nexport function resolveGatewayBaseURL(\n baseURL: string | undefined,\n env: Environment | undefined,\n consumerName: string,\n): string {\n const resolved = baseURL ?? (env ? DEFAULT_BASE_URLS[env] : undefined);\n if (!resolved) {\n throw new Error(\n `${consumerName} requires baseURL or env (production). For non-production environments, pass baseURL directly.`,\n );\n }\n return resolved;\n}\n","/**\n * Retry with exponential backoff + jitter.\n * Only retries on 429, 5xx and network errors; never on 4xx (401, 402, etc.).\n *\n * Jitter prevents thundering herd when many clients retry simultaneously.\n * Respects Retry-After metadata from 429 responses.\n */\n\nimport type { RetryConfig } from './gateway-config';\nimport type { AIGatewayError } from './gateway-errors';\n\nfunction delay(ms: number, signal?: AbortSignal): Promise<void> {\n return new Promise((resolve, reject) => {\n if (signal?.aborted) {\n reject(signal.reason);\n return;\n }\n const timer = setTimeout(resolve, ms);\n signal?.addEventListener(\n 'abort',\n () => {\n clearTimeout(timer);\n reject(signal.reason);\n },\n { once: true },\n );\n });\n}\n\nfunction isRetryableStatus(status: number, retryableStatuses: number[]): boolean {\n return retryableStatuses.includes(status);\n}\n\n/** Add random jitter: 0-25% of the base delay to avoid thundering herd */\nfunction addJitter(delayMs: number): number {\n const jitter = delayMs * 0.25 * Math.random();\n return delayMs + jitter;\n}\n\nexport async function withRetry<T>(\n fn: () => Promise<T>,\n options: {\n /** Already-normalized config — all fields must be present. */\n retryConfig: Required<RetryConfig>;\n signal?: AbortSignal;\n isNetworkError?: (err: unknown) => boolean;\n },\n): Promise<T> {\n const { maxAttempts, initialDelayMs, maxDelayMs, retryableStatuses } = options.retryConfig;\n let lastError: unknown;\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n try {\n return await fn();\n } catch (err) {\n lastError = err;\n if (attempt === maxAttempts) break;\n const status = (err as { statusCode?: number })?.statusCode;\n const isRetryable =\n status != null ? isRetryableStatus(status, retryableStatuses) : (options.isNetworkError?.(err) ?? false);\n if (!isRetryable) throw err;\n\n const retryAfterSeconds = (err as AIGatewayError)?.retryAfter;\n let backoff: number;\n if (retryAfterSeconds != null && retryAfterSeconds > 0) {\n // Server-specified delay — use exactly, no jitter (contract compliance).\n backoff = retryAfterSeconds * 1000;\n } else {\n backoff = addJitter(Math.min(initialDelayMs * Math.pow(2, attempt - 1), maxDelayMs));\n }\n\n await delay(backoff, options.signal);\n }\n }\n throw lastError;\n}\n","/**\n * Shared request execution pipeline for the AI Gateway SDK.\n *\n * Handles: auth injection, Bearer token refresh on 401, middleware chain,\n * timeout, retry, and error normalization. Inlines abort, request-id,\n * and fetch transport as private helpers.\n */\n\nimport type { RequestConfig, ResolvedConfig } from './gateway-config';\nimport { AuthError, parseErrorResponseFromResponse } from './gateway-errors';\nimport { withRetry } from './gateway-retry';\n\n// ─── Private helpers ──────────────────────────────────────────────────────────\n\n/** Combine multiple AbortSignals — aborts when ANY fires. Uses native AbortSignal.any when available. */\nfunction anySignal(signals: AbortSignal[]): AbortSignal {\n const any = (AbortSignal as unknown as { any?: (signals: AbortSignal[]) => AbortSignal }).any;\n if (typeof any === 'function') {\n return any(signals);\n }\n const controller = new AbortController();\n const handlers: Array<[AbortSignal, () => void]> = [];\n function cleanup() {\n for (const [sig, handler] of handlers) sig.removeEventListener('abort', handler);\n handlers.length = 0;\n }\n for (const signal of signals) {\n if (signal.aborted) {\n controller.abort(signal.reason);\n return controller.signal;\n }\n const handler = () => {\n cleanup();\n controller.abort(signal.reason);\n };\n handlers.push([signal, handler]);\n signal.addEventListener('abort', handler, { once: true });\n }\n controller.signal.addEventListener('abort', cleanup, { once: true });\n return controller.signal;\n}\n\nlet _counter = 0;\n/** Generate a unique request ID for correlation. */\nfunction generateRequestId(prefix: string = 'sdk'): string {\n if (typeof globalThis.crypto?.randomUUID === 'function') {\n return `${prefix}-${globalThis.crypto.randomUUID()}`;\n }\n const timestamp = Date.now().toString(36);\n const count = (_counter++).toString(36);\n const random = Math.random().toString(36).slice(2, 8);\n return `${prefix}-${timestamp}-${count}-${random}`;\n}\n\n/** Case-insensitive header key lookup. */\nfunction hasHeaderCaseInsensitive(headers: Record<string, string>, name: string): boolean {\n const lower = name.toLowerCase();\n return Object.keys(headers).some((k) => k.toLowerCase() === lower);\n}\n\nfunction shouldAutoSetJsonContentType(body: RequestInit['body'], headers: Record<string, string>): boolean {\n if (body == null || hasHeaderCaseInsensitive(headers, 'content-type')) return false;\n const isFormData = typeof FormData !== 'undefined' && body instanceof FormData;\n const isBlob = typeof Blob !== 'undefined' && body instanceof Blob;\n return !isFormData && !isBlob;\n}\n\nfunction redactSensitiveHeaders(headers: Record<string, string>): Record<string, string> {\n const redacted: Record<string, string> = {};\n for (const [key, value] of Object.entries(headers)) {\n redacted[key] = key.toLowerCase() === 'authorization' ? '[REDACTED]' : value;\n }\n return redacted;\n}\n\nconst NODE_NETWORK_CODES = new Set([\n 'ECONNREFUSED',\n 'ECONNRESET',\n 'ENOTFOUND',\n 'EPIPE',\n 'ETIMEDOUT',\n 'ENETUNREACH',\n 'EAI_AGAIN',\n 'UND_ERR_CONNECT_TIMEOUT',\n]);\n\nconst FETCH_NETWORK_TYPEERROR_HINTS = [\n 'failed to fetch',\n 'fetch failed',\n 'load failed',\n 'networkerror',\n 'network error when attempting to fetch',\n];\n\nfunction hasRetryableNodeErrorCode(err: unknown): boolean {\n let cur: unknown = err;\n for (let depth = 0; depth < 5 && cur != null; depth++) {\n const code = (cur as { code?: string })?.code;\n if (typeof code === 'string' && NODE_NETWORK_CODES.has(code)) return true;\n cur = cur instanceof Error && cur.cause !== undefined ? cur.cause : undefined;\n }\n return false;\n}\n\nfunction isFetchFailureTypeError(err: unknown): boolean {\n if (!(err instanceof TypeError)) return false;\n const msg = String(err.message).toLowerCase();\n return FETCH_NETWORK_TYPEERROR_HINTS.some((hint) => msg.includes(hint));\n}\n\nfunction isNetworkError(err: unknown): boolean {\n return hasRetryableNodeErrorCode(err) || isFetchFailureTypeError(err);\n}\n\n/** Execute a single HTTP request using the configured fetch implementation. */\nasync function executeFetch(fetchImpl: typeof fetch | undefined, requestConfig: RequestConfig): Promise<Response> {\n const impl = fetchImpl ?? globalThis.fetch;\n if (typeof impl === 'undefined') {\n throw new Error(\n '@macpaw/ai-sdk requires a global `fetch` implementation. ' +\n 'Use Node.js 18+ or install a polyfill like `undici`.',\n );\n }\n return impl(requestConfig.url, {\n method: requestConfig.method,\n headers: requestConfig.headers,\n body: requestConfig.body,\n signal: requestConfig.signal,\n });\n}\n\n// ─── Public types ─────────────────────────────────────────────────────────────\n\nexport interface ExecuteRequestInput {\n url: string;\n method: string;\n body?: RequestInit['body'];\n headers?: Record<string, string>;\n signal?: AbortSignal;\n}\n\nexport interface ExecuteRequestBehavior {\n /** Merge config-level default headers before per-request headers. */\n includeConfigHeaders?: boolean;\n /** Resolve and inject Bearer auth via `getAuthToken()`. */\n includeAuth?: boolean;\n /** Auto-add `X-Request-ID` when missing. */\n includeRequestId?: boolean;\n /** Convert non-OK responses into normalized gateway errors. */\n normalizeErrors?: boolean;\n /** Retry once on auth failure by forcing a fresh token. */\n allowAuthRetry?: boolean;\n /** Request ID prefix for correlation, e.g. `sdk` or `provider`. */\n requestIdPrefix?: string;\n}\n\n// ─── Pipeline ─────────────────────────────────────────────────────────────────\n\nexport async function executeRequestPipeline(\n config: ResolvedConfig,\n request: ExecuteRequestInput,\n behavior?: ExecuteRequestBehavior,\n): Promise<Response> {\n const b: Required<ExecuteRequestBehavior> = {\n includeConfigHeaders: behavior?.includeConfigHeaders ?? true,\n includeAuth: behavior?.includeAuth ?? true,\n includeRequestId: behavior?.includeRequestId ?? true,\n normalizeErrors: behavior?.normalizeErrors ?? true,\n allowAuthRetry: behavior?.allowAuthRetry ?? true,\n requestIdPrefix: behavior?.requestIdPrefix ?? 'sdk',\n };\n return executeWithAuth(config, request, b, false);\n}\n\nasync function executeWithAuth(\n config: ResolvedConfig,\n request: ExecuteRequestInput,\n behavior: Required<ExecuteRequestBehavior>,\n isTokenRetry: boolean,\n): Promise<Response> {\n try {\n return await executeRequest(config, request, behavior, isTokenRetry);\n } catch (err) {\n if (behavior.allowAuthRetry && !isTokenRetry && err instanceof AuthError) {\n // ReadableStream bodies are single-consumer: once the first request reads\n // the stream it is consumed and cannot be replayed on the retry attempt.\n if (typeof ReadableStream !== 'undefined' && request.body instanceof ReadableStream) {\n throw err;\n }\n return executeWithAuth(config, request, behavior, true);\n }\n throw err;\n }\n}\n\nasync function executeRequest(\n config: ResolvedConfig,\n request: ExecuteRequestInput,\n behavior: Required<ExecuteRequestBehavior>,\n forceRefreshToken: boolean,\n): Promise<Response> {\n const headers: Record<string, string> = {\n ...(behavior.includeConfigHeaders ? config.headers : undefined),\n ...request.headers,\n };\n\n if (shouldAutoSetJsonContentType(request.body, headers)) {\n headers['Content-Type'] = 'application/json';\n }\n\n if (behavior.includeRequestId && !hasHeaderCaseInsensitive(headers, 'x-request-id')) {\n headers['X-Request-ID'] = generateRequestId(behavior.requestIdPrefix);\n }\n\n const timeoutMs = config.timeout;\n const userSignal = request.signal;\n\n async function doRequest(): Promise<Response> {\n const timeoutController = new AbortController();\n const timeoutId = setTimeout(\n () => timeoutController.abort(new Error(`Request timed out after ${timeoutMs}ms`)),\n timeoutMs,\n );\n\n const signal = userSignal ? anySignal([userSignal, timeoutController.signal]) : timeoutController.signal;\n\n const requestConfig: RequestConfig = {\n url: request.url,\n method: request.method,\n headers: { ...headers },\n body: request.body,\n signal,\n };\n\n const { middleware } = config;\n let index = 0;\n\n const next = async (currentRequest: RequestConfig): Promise<Response> => {\n if (index < middleware.length) {\n const middlewareItem = middleware[index++];\n return middlewareItem(currentRequest, next);\n }\n const finalHeaders = { ...currentRequest.headers };\n if (behavior.includeAuth) {\n const token = await config.getAuthToken(forceRefreshToken);\n if (token) {\n finalHeaders.Authorization = `Bearer ${token}`;\n } else {\n for (const key of Object.keys(finalHeaders)) {\n if (key.toLowerCase() === 'authorization') delete finalHeaders[key];\n }\n }\n }\n return executeFetch(config.fetchImpl, { ...currentRequest, headers: finalHeaders });\n };\n\n try {\n const response = await next(requestConfig);\n\n if (!response.ok) {\n const retryableStatuses = config.retry !== false ? config.retry.retryableStatuses : [];\n // Transport logic must fire regardless of normalizeErrors:\n // - 401 must throw AuthError so executeWithAuth can refresh the token\n // - retryable statuses must throw so withRetry can schedule retry attempts\n const isTransportCritical =\n (behavior.allowAuthRetry && response.status === 401) ||\n (config.retry !== false && retryableStatuses.includes(response.status));\n\n if (behavior.normalizeErrors || isTransportCritical) {\n await parseErrorResponseFromResponse(response);\n }\n }\n\n return response;\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n if (config.retry) {\n // doRequest() re-runs the full middleware chain on each retry attempt.\n // Middleware with side effects (metrics, audit logs) will fire per attempt.\n return withRetry(doRequest, {\n retryConfig: config.retry,\n signal: userSignal,\n isNetworkError,\n });\n }\n\n return doRequest();\n}\n\n/** Redact Authorization for safe logging/debugging. */\nexport { redactSensitiveHeaders };\n","/**\n * Custom fetch factory for use with Vercel AI SDK and other OpenAI-compatible clients.\n * Use this with createOpenAI({ baseURL, fetch: createGatewayFetch(...) }) or similar.\n *\n * AI Gateway HTTP paths are under /api/v1 (e.g. /api/v1/chat/completions).\n * So baseURL should be the gateway root, e.g. https://api.macpaw.com/ai\n *\n * Internally delegates to the shared request pipeline while guarding against\n * leaking gateway auth/headers to non-gateway hosts.\n */\n\nimport type { GatewayProviderSettings } from './gateway-config';\nimport { resolveConfig } from './gateway-config';\nimport { executeRequestPipeline } from './gateway-request';\n\n/**\n * Config for `createGatewayFetch`.\n * Extends GatewayProviderSettings with baseURL required (already resolved)\n * and normalizeErrors (provider-specific behavior).\n */\nexport interface GatewayFetchConfig extends GatewayProviderSettings {\n /** Resolved Gateway base URL (required — use resolveGatewayBaseURL first). */\n baseURL: string;\n /**\n * Normalize gateway error responses into `AIGatewayError`. Default: true.\n * When enabled, non-OK gateway responses throw instead of returning a failed Response.\n */\n normalizeErrors?: boolean;\n}\n\ntype FetchInput = string | URL | Request | { url: string };\n\nfunction resolveRequestUrl(input: FetchInput): string {\n if (typeof input === 'string') return input;\n if (input instanceof URL) return input.href;\n return input.url;\n}\n\nfunction stripPlaceholderAuthorization(headers: Headers, placeholder: string): void {\n const auth = headers.get('authorization');\n if (auth === `Bearer ${placeholder}`) {\n headers.delete('authorization');\n }\n}\n\nfunction headersToRecord(headers: Headers): Record<string, string> {\n const record: Record<string, string> = {};\n for (const [key, value] of headers.entries()) {\n record[key] = value;\n }\n return record;\n}\n\nfunction joinBaseUrl(baseURL: string, path: string): string {\n return `${baseURL}${path.startsWith('/') ? '' : '/'}${path}`;\n}\n\nfunction isGatewayUrl(url: URL, gatewayBaseUrl: URL): boolean {\n const gatewayPath = gatewayBaseUrl.pathname.replace(/\\/$/, '');\n const requestPath = url.pathname.replace(/\\/$/, '');\n return (\n url.origin === gatewayBaseUrl.origin && (requestPath === gatewayPath || requestPath.startsWith(`${gatewayPath}/`))\n );\n}\n\nexport const GATEWAY_PLACEHOLDER_API_KEY = 'ai-gateway-auth-via-fetch';\n\nexport function createGatewayFetch(\n options: GatewayFetchConfig,\n): (input: FetchInput, init?: RequestInit) => Promise<Response> {\n const { baseURL, normalizeErrors = true } = options;\n const base = baseURL.replace(/\\/$/, '');\n const gatewayBaseUrl = new URL(base);\n const resolvedConfig = resolveConfig({ ...options, baseURL: base });\n\n return async function gatewayFetch(input: FetchInput, init?: RequestInit): Promise<Response> {\n const rawUrl = resolveRequestUrl(input);\n const isAbsolute = rawUrl.startsWith('http://') || rawUrl.startsWith('https://');\n const resolvedUrl = new URL(isAbsolute ? rawUrl : joinBaseUrl(base, rawUrl));\n const isGatewayRequest = isGatewayUrl(resolvedUrl, gatewayBaseUrl);\n\n const request = typeof Request !== 'undefined' && input instanceof Request ? input : undefined;\n const requestClone = request?.clone();\n const headers = new Headers(requestClone?.headers);\n\n if (init?.headers) {\n for (const [key, value] of new Headers(init.headers).entries()) {\n headers.set(key, value);\n }\n }\n\n if (!isGatewayRequest) {\n stripPlaceholderAuthorization(headers, GATEWAY_PLACEHOLDER_API_KEY);\n }\n\n return executeRequestPipeline(\n resolvedConfig,\n {\n url: resolvedUrl.toString(),\n method: init?.method ?? requestClone?.method ?? 'GET',\n headers: headersToRecord(headers),\n body: init?.body ?? requestClone?.body,\n signal: init?.signal ?? requestClone?.signal,\n },\n {\n includeConfigHeaders: isGatewayRequest,\n includeAuth: isGatewayRequest,\n includeRequestId: isGatewayRequest,\n normalizeErrors: isGatewayRequest && normalizeErrors,\n allowAuthRetry: isGatewayRequest,\n requestIdPrefix: 'provider',\n },\n );\n };\n}\n","/**\n * AI Gateway provider factory.\n *\n * `createGatewayProvider()` routes bare model IDs through the gateway's\n * OpenAI-compatible endpoint with provider-specific prefixes.\n * `createAIGatewayProvider()` is the low-level escape hatch for direct\n * OpenAI-compatible provider construction.\n */\n\nimport { createOpenAI as builtinCreateOpenAI } from '@ai-sdk/openai';\nimport type { OpenAIProvider, OpenAIProviderSettings } from '@ai-sdk/openai';\nimport { createGatewayFetch, GATEWAY_PLACEHOLDER_API_KEY } from './gateway-fetch';\nimport type { Environment, GatewayProviderSettings } from './gateway-config';\nimport { resolveGatewayBaseURL } from './gateway-config';\n\n// ─── AIGatewayProvider (low-level) ────────────────────────────────────────────\n\nconst DEFAULT_API_VERSION = 'v1';\n\nexport interface AIGatewayProviderOptions\n extends Omit<OpenAIProviderSettings, 'apiKey' | 'baseURL' | 'fetch'>, GatewayProviderSettings {\n /**\n * Optional override for the OpenAI provider factory.\n * Uses `createOpenAI` from `@ai-sdk/openai` by default.\n */\n createOpenAI?: typeof builtinCreateOpenAI;\n /**\n * Normalize gateway error responses into `AIGatewayError`. Default: true.\n * When enabled, non-OK gateway responses throw instead of returning a failed Response.\n */\n normalizeErrors?: boolean;\n}\n\n/**\n * Creates a Vercel AI SDK-compatible provider backed by AI Gateway.\n *\n * The returned value is a fully typed `OpenAIProvider`, so existing apps can\n * keep using their `ai-sdk` helpers and model-selection patterns.\n */\nexport function createAIGatewayProvider(options: AIGatewayProviderOptions): OpenAIProvider {\n const baseURL = resolveGatewayBaseURL(options.baseURL, options.env as Environment, 'AIGatewayProvider');\n const customFetch = createGatewayFetch({ ...options, baseURL, normalizeErrors: options.normalizeErrors });\n\n const openAI = options.createOpenAI ?? builtinCreateOpenAI;\n\n return openAI({\n name: options.name,\n organization: options.organization,\n project: options.project,\n baseURL: `${baseURL.replace(/\\/$/, '')}/api/${DEFAULT_API_VERSION}`,\n fetch: customFetch,\n apiKey: GATEWAY_PLACEHOLDER_API_KEY,\n });\n}\n\n// ─── GatewayProvider (prefixed routing) ───────────────────────────────────────\n\nexport interface GatewayProviderBaseOptions extends AIGatewayProviderOptions {\n /**\n * Override the model ID prefix used for Gateway routing.\n * Default: the provider's canonical prefix (e.g. `'anthropic'`).\n *\n * Model IDs that already contain `/` are sent as-is.\n */\n modelPrefix?: string;\n}\n\nexport interface GatewayOpenAICompatibleOptions extends Omit<GatewayProviderBaseOptions, 'modelPrefix'> {\n /**\n * Required for openai-compatible backends because there is no single canonical\n * default prefix. Examples: `openai`, `fireworks_ai`, `openrouter`.\n */\n modelPrefix: string;\n}\n\nexport const GATEWAY_PROVIDERS = {\n ANTHROPIC: 'anthropic',\n GOOGLE: 'google',\n XAI: 'xai',\n GROQ: 'groq',\n MISTRAL: 'mistral',\n AMAZON_BEDROCK: 'amazon-bedrock',\n AZURE: 'azure',\n COHERE: 'cohere',\n PERPLEXITY: 'perplexity',\n DEEPSEEK: 'deepseek',\n TOGETHERAI: 'togetherai',\n OPENAI_COMPATIBLE: 'openai-compatible',\n} as const;\n\nexport type GatewayProvider = (typeof GATEWAY_PROVIDERS)[keyof typeof GATEWAY_PROVIDERS];\n\nexport type GatewayProviderWithDefaultPrefix = Exclude<GatewayProvider, typeof GATEWAY_PROVIDERS.OPENAI_COMPATIBLE>;\n\nexport interface GatewayProviderOptionsMap {\n [GATEWAY_PROVIDERS.OPENAI_COMPATIBLE]: GatewayOpenAICompatibleOptions;\n}\n\nexport type GatewayProviderOptions<P extends GatewayProvider> = P extends keyof GatewayProviderOptionsMap\n ? GatewayProviderOptionsMap[P]\n : GatewayProviderBaseOptions;\n\nconst GATEWAY_PROVIDER_DEFAULT_PREFIXES: Record<GatewayProviderWithDefaultPrefix, string> = {\n [GATEWAY_PROVIDERS.ANTHROPIC]: 'anthropic',\n [GATEWAY_PROVIDERS.GOOGLE]: 'google',\n [GATEWAY_PROVIDERS.XAI]: 'xai',\n [GATEWAY_PROVIDERS.GROQ]: 'groq',\n [GATEWAY_PROVIDERS.MISTRAL]: 'mistral',\n [GATEWAY_PROVIDERS.AMAZON_BEDROCK]: 'bedrock',\n [GATEWAY_PROVIDERS.AZURE]: 'azure',\n [GATEWAY_PROVIDERS.COHERE]: 'cohere',\n [GATEWAY_PROVIDERS.PERPLEXITY]: 'perplexity',\n [GATEWAY_PROVIDERS.DEEPSEEK]: 'deepseek',\n [GATEWAY_PROVIDERS.TOGETHERAI]: 'togetherai',\n};\n\nfunction prefixModelId(prefix: string, modelId: string): string {\n return modelId.includes('/') ? modelId : `${prefix}/${modelId}`;\n}\n\nfunction createPrefixedGatewayProvider(defaultPrefix: string, options: GatewayProviderBaseOptions): OpenAIProvider {\n const { modelPrefix, ...providerOptions } = options;\n const prefix = modelPrefix ?? defaultPrefix;\n const provider = createAIGatewayProvider(providerOptions);\n\n const wrapped = ((modelId: string) => provider(prefixModelId(prefix, modelId))) as OpenAIProvider;\n\n return new Proxy(wrapped, {\n apply(_target, _thisArg, args: [string, ...unknown[]]) {\n const [modelId, ...rest] = args;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return (provider as (...a: unknown[]) => any)(prefixModelId(prefix, modelId), ...rest);\n },\n get(_target, prop) {\n const value = Reflect.get(provider, prop, provider);\n if (typeof value === 'function') {\n return (...args: unknown[]) => {\n if (typeof args[0] === 'string') {\n args[0] = prefixModelId(prefix, args[0] as string);\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return (value as (...a: unknown[]) => any).apply(provider, args);\n };\n }\n return value;\n },\n has(_target, prop) {\n return prop in (provider as object);\n },\n });\n}\n\n/**\n * Creates an `OpenAIProvider` backed by AI Gateway for a supported provider.\n *\n * Bare model IDs are automatically prefixed with the provider's canonical\n * Gateway routing prefix. Model IDs that already contain `/` are passed as-is.\n */\nexport function createGatewayProvider(\n provider: GatewayProviderWithDefaultPrefix,\n options: GatewayProviderBaseOptions,\n): OpenAIProvider;\nexport function createGatewayProvider(\n provider: typeof GATEWAY_PROVIDERS.OPENAI_COMPATIBLE,\n options: GatewayOpenAICompatibleOptions,\n): OpenAIProvider;\nexport function createGatewayProvider(\n provider: GatewayProvider,\n options: GatewayProviderBaseOptions | GatewayOpenAICompatibleOptions,\n): OpenAIProvider {\n if (provider === GATEWAY_PROVIDERS.OPENAI_COMPATIBLE) {\n return createPrefixedGatewayProvider(\n (options as GatewayOpenAICompatibleOptions).modelPrefix,\n options as GatewayOpenAICompatibleOptions,\n );\n }\n\n return createPrefixedGatewayProvider(\n GATEWAY_PROVIDER_DEFAULT_PREFIXES[provider as GatewayProviderWithDefaultPrefix],\n options as GatewayProviderBaseOptions,\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/gateway-config.ts","../src/gateway-retry.ts","../src/gateway-request.ts","../src/gateway-fetch.ts","../src/gateway-provider.ts"],"names":["builtinCreateOpenAI"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Configuration types and resolver for the AI Gateway SDK.\n *\n * GatewayProviderSettings is the public API — 8 fields.\n * ResolvedConfig is the internal resolved form used by the request pipeline.\n */\n\n/**\n * Supported gateway environments.\n * Only 'production' is exposed — non-production setups use a direct `baseURL`\n * instead, keeping env-specific URL management out of this library.\n */\nexport type Environment = 'production';\n\nexport interface RetryConfig {\n /** Max number of attempts (including first). Default 3. */\n maxAttempts?: number;\n /** Initial delay in ms. Default 1000. */\n initialDelayMs?: number;\n /** Max delay in ms. Default 30000. */\n maxDelayMs?: number;\n /** Retry only on these status codes (and network errors). Default: 429, 5xx. */\n retryableStatuses?: number[];\n}\n\nexport const DEFAULT_RETRY: Required<RetryConfig> = {\n maxAttempts: 3,\n initialDelayMs: 1000,\n maxDelayMs: 30000,\n retryableStatuses: [429, 500, 502, 503, 504],\n};\n\n/** Coerces invalid `maxAttempts` (0, negative, NaN) to the default. */\nexport function normalizeRetryConfig(merged: Required<RetryConfig>): Required<RetryConfig> {\n const n = Math.floor(Number(merged.maxAttempts));\n const maxAttempts = Number.isFinite(n) && n >= 1 ? n : DEFAULT_RETRY.maxAttempts;\n return { ...merged, maxAttempts };\n}\n\nexport interface RequestConfig {\n url: string;\n method: string;\n headers: Record<string, string>;\n body?: RequestInit['body'];\n signal?: AbortSignal | undefined;\n}\n\nexport type Middleware = (\n config: RequestConfig,\n next: (config: RequestConfig) => Promise<Response>,\n) => Promise<Response>;\n\n/**\n * Configuration for AI Gateway providers and NestJS module.\n *\n * Exactly 8 fields — covers auth, routing, request behaviour and middleware.\n */\nexport interface GatewayProviderSettings {\n /** Gateway base URL. Required if env is not set. */\n baseURL?: string;\n /** 'production' uses the default MacPaw Gateway URL. */\n env?: Environment;\n /**\n * Returns Bearer token for auth.\n * Called with `forceRefresh=true` after 401 — provide a fresh token.\n */\n getAuthToken: (forceRefresh?: boolean) => Promise<string | null>;\n /** Extra headers sent with every request. Do not set Authorization here. */\n headers?: Record<string, string>;\n /** Retry policy. Set to false to disable. */\n retry?: RetryConfig | false;\n /** Request timeout in ms. Default: 60000. */\n timeout?: number;\n /** Request interceptors. Run in order before each request. */\n middleware?: Middleware[];\n /**\n * Custom fetch implementation.\n * Use for testing or low-level request customization.\n */\n fetch?: typeof fetch;\n}\n\n/** Internal resolved form — used only by the request pipeline. */\nexport interface ResolvedConfig {\n baseURL: string;\n getAuthToken: (forceRefresh?: boolean) => Promise<string | null>;\n /** Already normalized — all fields present, maxAttempts ≥ 1. */\n retry: Required<RetryConfig> | false;\n middleware: Middleware[];\n headers?: Record<string, string>;\n timeout: number;\n fetchImpl?: typeof fetch;\n}\n\nexport function resolveConfig(config: GatewayProviderSettings & { baseURL: string }): ResolvedConfig {\n return {\n baseURL: config.baseURL,\n getAuthToken: config.getAuthToken,\n retry: config.retry === false ? false : normalizeRetryConfig({ ...DEFAULT_RETRY, ...config.retry }),\n middleware: [...(config.middleware ?? [])],\n headers: config.headers,\n timeout: config.timeout ?? 60_000,\n fetchImpl: config.fetch,\n };\n}\n\n/** Default base URL for the production environment. */\nexport const DEFAULT_BASE_URLS: Record<Environment, string> = {\n production: 'https://api.macpaw.com/ai',\n};\n\nexport function resolveGatewayBaseURL(\n baseURL: string | undefined,\n env: Environment | undefined,\n consumerName: string,\n): string {\n const resolved = baseURL ?? (env ? DEFAULT_BASE_URLS[env] : undefined);\n if (!resolved) {\n throw new Error(\n `${consumerName} requires baseURL or env (production). For non-production environments, pass baseURL directly.`,\n );\n }\n return resolved;\n}\n","/**\n * Retry with exponential backoff + jitter.\n * Only retries on 429, 5xx and network errors; never on 4xx (401, 402, etc.).\n *\n * Jitter prevents thundering herd when many clients retry simultaneously.\n * Respects Retry-After metadata from 429 responses.\n */\n\nimport type { RetryConfig } from './gateway-config';\nimport type { AIGatewayError } from './gateway-errors';\n\nfunction delay(ms: number, signal?: AbortSignal): Promise<void> {\n return new Promise((resolve, reject) => {\n if (signal?.aborted) {\n reject(signal.reason);\n return;\n }\n const timer = setTimeout(resolve, ms);\n signal?.addEventListener(\n 'abort',\n () => {\n clearTimeout(timer);\n reject(signal.reason);\n },\n { once: true },\n );\n });\n}\n\nfunction isRetryableStatus(status: number, retryableStatuses: number[]): boolean {\n return retryableStatuses.includes(status);\n}\n\n/** Add random jitter: 0-25% of the base delay to avoid thundering herd */\nfunction addJitter(delayMs: number): number {\n const jitter = delayMs * 0.25 * Math.random();\n return delayMs + jitter;\n}\n\nexport async function withRetry<T>(\n fn: () => Promise<T>,\n options: {\n /** Already-normalized config — all fields must be present. */\n retryConfig: Required<RetryConfig>;\n signal?: AbortSignal;\n isNetworkError?: (err: unknown) => boolean;\n },\n): Promise<T> {\n const { maxAttempts, initialDelayMs, maxDelayMs, retryableStatuses } = options.retryConfig;\n let lastError: unknown;\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n try {\n return await fn();\n } catch (err) {\n lastError = err;\n if (attempt === maxAttempts) break;\n const status = (err as { statusCode?: number })?.statusCode;\n const isRetryable =\n status != null ? isRetryableStatus(status, retryableStatuses) : (options.isNetworkError?.(err) ?? false);\n if (!isRetryable) throw err;\n\n const retryAfterSeconds = (err as AIGatewayError)?.retryAfter;\n let backoff: number;\n if (retryAfterSeconds != null && retryAfterSeconds > 0) {\n // Server-specified delay — use exactly, no jitter (contract compliance).\n backoff = retryAfterSeconds * 1000;\n } else {\n backoff = addJitter(Math.min(initialDelayMs * Math.pow(2, attempt - 1), maxDelayMs));\n }\n\n await delay(backoff, options.signal);\n }\n }\n throw lastError;\n}\n","/**\n * Shared request execution pipeline for the AI Gateway SDK.\n *\n * Handles: auth injection, Bearer token refresh on 401, middleware chain,\n * timeout, retry, and error normalization. Inlines abort, request-id,\n * and fetch transport as private helpers.\n */\n\nimport type { RequestConfig, ResolvedConfig } from './gateway-config';\nimport { AuthError, parseErrorResponseFromResponse } from './gateway-errors';\nimport { GATEWAY_PLACEHOLDER_API_KEY, normalizeBearerToken } from './gateway-fetch';\nimport { withRetry } from './gateway-retry';\n\n// ─── Private helpers ──────────────────────────────────────────────────────────\n\n/** Combine multiple AbortSignals — aborts when ANY fires. Uses native AbortSignal.any when available. */\nfunction anySignal(signals: AbortSignal[]): AbortSignal {\n const any = (AbortSignal as unknown as { any?: (signals: AbortSignal[]) => AbortSignal }).any;\n if (typeof any === 'function') {\n return any(signals);\n }\n const controller = new AbortController();\n const handlers: Array<[AbortSignal, () => void]> = [];\n function cleanup() {\n for (const [sig, handler] of handlers) sig.removeEventListener('abort', handler);\n handlers.length = 0;\n }\n for (const signal of signals) {\n if (signal.aborted) {\n controller.abort(signal.reason);\n return controller.signal;\n }\n const handler = () => {\n cleanup();\n controller.abort(signal.reason);\n };\n handlers.push([signal, handler]);\n signal.addEventListener('abort', handler, { once: true });\n }\n controller.signal.addEventListener('abort', cleanup, { once: true });\n return controller.signal;\n}\n\nlet _counter = 0;\n/** Generate a unique request ID for correlation. */\nfunction generateRequestId(prefix: string = 'sdk'): string {\n if (typeof globalThis.crypto?.randomUUID === 'function') {\n return `${prefix}-${globalThis.crypto.randomUUID()}`;\n }\n const timestamp = Date.now().toString(36);\n const count = (_counter++).toString(36);\n const random = Math.random().toString(36).slice(2, 8);\n return `${prefix}-${timestamp}-${count}-${random}`;\n}\n\n/** Case-insensitive header key lookup. */\nfunction hasHeaderCaseInsensitive(headers: Record<string, string>, name: string): boolean {\n const lower = name.toLowerCase();\n return Object.keys(headers).some((k) => k.toLowerCase() === lower);\n}\n\n/**\n * Drops every `Authorization` key regardless of casing.\n * Some runtimes would emit two header fields if both `authorization` and `Authorization`\n * exist on the same object; servers then merge them into one value with a comma.\n */\nfunction deleteAllAuthorizationHeaders(headers: Record<string, string>): void {\n for (const key of Object.keys(headers)) {\n if (key.toLowerCase() === 'authorization') delete headers[key];\n }\n}\n\nfunction shouldAutoSetJsonContentType(body: RequestInit['body'], headers: Record<string, string>): boolean {\n if (body == null || hasHeaderCaseInsensitive(headers, 'content-type')) return false;\n const isFormData = typeof FormData !== 'undefined' && body instanceof FormData;\n const isBlob = typeof Blob !== 'undefined' && body instanceof Blob;\n return !isFormData && !isBlob;\n}\n\nfunction redactSensitiveHeaders(headers: Record<string, string>): Record<string, string> {\n const redacted: Record<string, string> = {};\n for (const [key, value] of Object.entries(headers)) {\n redacted[key] = key.toLowerCase() === 'authorization' ? '[REDACTED]' : value;\n }\n return redacted;\n}\n\nconst NODE_NETWORK_CODES = new Set([\n 'ECONNREFUSED',\n 'ECONNRESET',\n 'ENOTFOUND',\n 'EPIPE',\n 'ETIMEDOUT',\n 'ENETUNREACH',\n 'EAI_AGAIN',\n 'UND_ERR_CONNECT_TIMEOUT',\n]);\n\nconst FETCH_NETWORK_TYPEERROR_HINTS = [\n 'failed to fetch',\n 'fetch failed',\n 'load failed',\n 'networkerror',\n 'network error when attempting to fetch',\n];\n\nfunction hasRetryableNodeErrorCode(err: unknown): boolean {\n let cur: unknown = err;\n for (let depth = 0; depth < 5 && cur != null; depth++) {\n const code = (cur as { code?: string })?.code;\n if (typeof code === 'string' && NODE_NETWORK_CODES.has(code)) return true;\n cur = cur instanceof Error && cur.cause !== undefined ? cur.cause : undefined;\n }\n return false;\n}\n\nfunction isFetchFailureTypeError(err: unknown): boolean {\n if (!(err instanceof TypeError)) return false;\n const msg = String(err.message).toLowerCase();\n return FETCH_NETWORK_TYPEERROR_HINTS.some((hint) => msg.includes(hint));\n}\n\nfunction isNetworkError(err: unknown): boolean {\n return hasRetryableNodeErrorCode(err) || isFetchFailureTypeError(err);\n}\n\n/** Execute a single HTTP request using the configured fetch implementation. */\nasync function executeFetch(fetchImpl: typeof fetch | undefined, requestConfig: RequestConfig): Promise<Response> {\n const impl = fetchImpl ?? globalThis.fetch;\n if (typeof impl === 'undefined') {\n throw new Error(\n '@macpaw/ai-sdk requires a global `fetch` implementation. ' +\n 'Use Node.js 18+ or install a polyfill like `undici`.',\n );\n }\n return impl(requestConfig.url, {\n method: requestConfig.method,\n headers: requestConfig.headers,\n body: requestConfig.body,\n signal: requestConfig.signal,\n });\n}\n\n// ─── Public types ─────────────────────────────────────────────────────────────\n\nexport interface ExecuteRequestInput {\n url: string;\n method: string;\n body?: RequestInit['body'];\n headers?: Record<string, string>;\n signal?: AbortSignal;\n}\n\nexport interface ExecuteRequestBehavior {\n /** Merge config-level default headers before per-request headers. */\n includeConfigHeaders?: boolean;\n /** Resolve and inject Bearer auth via `getAuthToken()`. */\n includeAuth?: boolean;\n /** Auto-add `X-Request-ID` when missing. */\n includeRequestId?: boolean;\n /** Convert non-OK responses into normalized gateway errors. */\n normalizeErrors?: boolean;\n /** Retry once on auth failure by forcing a fresh token. */\n allowAuthRetry?: boolean;\n /** Request ID prefix for correlation, e.g. `sdk` or `provider`. */\n requestIdPrefix?: string;\n}\n\n// ─── Pipeline ─────────────────────────────────────────────────────────────────\n\nexport async function executeRequestPipeline(\n config: ResolvedConfig,\n request: ExecuteRequestInput,\n behavior?: ExecuteRequestBehavior,\n): Promise<Response> {\n const b: Required<ExecuteRequestBehavior> = {\n includeConfigHeaders: behavior?.includeConfigHeaders ?? true,\n includeAuth: behavior?.includeAuth ?? true,\n includeRequestId: behavior?.includeRequestId ?? true,\n normalizeErrors: behavior?.normalizeErrors ?? true,\n allowAuthRetry: behavior?.allowAuthRetry ?? true,\n requestIdPrefix: behavior?.requestIdPrefix ?? 'sdk',\n };\n return executeWithAuth(config, request, b, false);\n}\n\nasync function executeWithAuth(\n config: ResolvedConfig,\n request: ExecuteRequestInput,\n behavior: Required<ExecuteRequestBehavior>,\n isTokenRetry: boolean,\n): Promise<Response> {\n try {\n return await executeRequest(config, request, behavior, isTokenRetry);\n } catch (err) {\n if (behavior.allowAuthRetry && !isTokenRetry && err instanceof AuthError) {\n // ReadableStream bodies are single-consumer: once the first request reads\n // the stream it is consumed and cannot be replayed on the retry attempt.\n if (typeof ReadableStream !== 'undefined' && request.body instanceof ReadableStream) {\n throw err;\n }\n return executeWithAuth(config, request, behavior, true);\n }\n throw err;\n }\n}\n\nasync function executeRequest(\n config: ResolvedConfig,\n request: ExecuteRequestInput,\n behavior: Required<ExecuteRequestBehavior>,\n forceRefreshToken: boolean,\n): Promise<Response> {\n const headers: Record<string, string> = {\n ...(behavior.includeConfigHeaders ? config.headers : undefined),\n ...request.headers,\n };\n\n if (shouldAutoSetJsonContentType(request.body, headers)) {\n headers['Content-Type'] = 'application/json';\n }\n\n if (behavior.includeRequestId && !hasHeaderCaseInsensitive(headers, 'x-request-id')) {\n headers['X-Request-ID'] = generateRequestId(behavior.requestIdPrefix);\n }\n\n const timeoutMs = config.timeout;\n const userSignal = request.signal;\n\n async function doRequest(): Promise<Response> {\n const timeoutController = new AbortController();\n const timeoutId = setTimeout(\n () => timeoutController.abort(new Error(`Request timed out after ${timeoutMs}ms`)),\n timeoutMs,\n );\n\n const signal = userSignal ? anySignal([userSignal, timeoutController.signal]) : timeoutController.signal;\n\n const requestConfig: RequestConfig = {\n url: request.url,\n method: request.method,\n headers: { ...headers },\n body: request.body,\n signal,\n };\n\n const { middleware } = config;\n let index = 0;\n\n const next = async (currentRequest: RequestConfig): Promise<Response> => {\n if (index < middleware.length) {\n const middlewareItem = middleware[index++];\n return middlewareItem(currentRequest, next);\n }\n const finalHeaders = { ...currentRequest.headers };\n if (behavior.includeAuth) {\n deleteAllAuthorizationHeaders(finalHeaders);\n const rawToken = await config.getAuthToken(forceRefreshToken);\n const token = normalizeBearerToken(rawToken);\n if (token && token !== GATEWAY_PLACEHOLDER_API_KEY) {\n finalHeaders.Authorization = `Bearer ${token}`;\n }\n }\n return executeFetch(config.fetchImpl, { ...currentRequest, headers: finalHeaders });\n };\n\n try {\n const response = await next(requestConfig);\n\n if (!response.ok) {\n const retryableStatuses = config.retry !== false ? config.retry.retryableStatuses : [];\n // Transport logic must fire regardless of normalizeErrors:\n // - 401 must throw AuthError so executeWithAuth can refresh the token\n // - retryable statuses must throw so withRetry can schedule retry attempts\n const isTransportCritical =\n (behavior.allowAuthRetry && response.status === 401) ||\n (config.retry !== false && retryableStatuses.includes(response.status));\n\n if (behavior.normalizeErrors || isTransportCritical) {\n await parseErrorResponseFromResponse(response);\n }\n }\n\n return response;\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n if (config.retry) {\n // doRequest() re-runs the full middleware chain on each retry attempt.\n // Middleware with side effects (metrics, audit logs) will fire per attempt.\n return withRetry(doRequest, {\n retryConfig: config.retry,\n signal: userSignal,\n isNetworkError,\n });\n }\n\n return doRequest();\n}\n\n/** Redact Authorization for safe logging/debugging. */\nexport { redactSensitiveHeaders };\n","/**\n * Custom fetch factory for use with Vercel AI SDK and other OpenAI-compatible clients.\n * Use this with createOpenAI({ baseURL, fetch: createGatewayFetch(...) }) or similar.\n *\n * AI Gateway HTTP paths are under /api/v1 (e.g. /api/v1/chat/completions).\n * So baseURL should be the gateway root, e.g. https://api.macpaw.com/ai\n *\n * Internally delegates to the shared request pipeline while guarding against\n * leaking gateway auth/headers to non-gateway hosts.\n */\n\nimport type { GatewayProviderSettings } from './gateway-config';\nimport { resolveConfig } from './gateway-config';\nimport { executeRequestPipeline } from './gateway-request';\n\nexport const GATEWAY_PLACEHOLDER_API_KEY = 'ai-gateway-auth-via-fetch';\n\n/**\n * Config for `createGatewayFetch`.\n * Extends GatewayProviderSettings with baseURL required (already resolved)\n * and normalizeErrors (provider-specific behavior).\n */\nexport interface GatewayFetchConfig extends GatewayProviderSettings {\n /** Resolved Gateway base URL (required — use resolveGatewayBaseURL first). */\n baseURL: string;\n /**\n * Normalize gateway error responses into `AIGatewayError`. Default: true.\n * When enabled, non-OK gateway responses throw instead of returning a failed Response.\n */\n normalizeErrors?: boolean;\n}\n\ntype FetchInput = string | URL | Request | { url: string };\n\nfunction resolveRequestUrl(input: FetchInput): string {\n if (typeof input === 'string') return input;\n if (input instanceof URL) return input.href;\n return input.url;\n}\n\n/**\n * Trims, strips a single layer of surrounding ASCII quotes, and removes\n * trailing comma/semicolon noise often introduced by .env or copy-paste.\n */\nexport function normalizeBearerToken(raw: string | null | undefined): string | null {\n if (raw == null) return null;\n let s = String(raw).trim();\n if (!s) return null;\n\n if (\n (s.startsWith('\"') && s.endsWith('\"') && s.length >= 2) ||\n (s.startsWith(\"'\") && s.endsWith(\"'\") && s.length >= 2)\n ) {\n s = s.slice(1, -1).trim();\n }\n\n s = s.replace(/[,;]+\\s*$/g, '').trim();\n return s.length > 0 ? s : null;\n}\n\n/**\n * Removes Authorization when it is only the OpenAI apiKey placeholder (optional trailing comma),\n * so a real Bearer from getAuthToken() is not merged with a junk value.\n */\nfunction stripPlaceholderAuthorization(headers: Headers, placeholder: string): void {\n const auth = headers.get('authorization');\n if (!auth) return;\n const m = auth.match(/^Bearer\\s+(\\S+)/i);\n if (!m) return;\n const credential = normalizeBearerToken(m[1]);\n if (credential === placeholder) {\n headers.delete('authorization');\n }\n}\n\nfunction headersToRecord(headers: Headers): Record<string, string> {\n const record: Record<string, string> = {};\n for (const [key, value] of headers.entries()) {\n record[key] = value;\n }\n return record;\n}\n\nfunction joinBaseUrl(baseURL: string, path: string): string {\n return `${baseURL}${path.startsWith('/') ? '' : '/'}${path}`;\n}\n\nfunction isGatewayUrl(url: URL, gatewayBaseUrl: URL): boolean {\n const gatewayPath = gatewayBaseUrl.pathname.replace(/\\/$/, '');\n const requestPath = url.pathname.replace(/\\/$/, '');\n return (\n url.origin === gatewayBaseUrl.origin && (requestPath === gatewayPath || requestPath.startsWith(`${gatewayPath}/`))\n );\n}\n\nexport function createGatewayFetch(\n options: GatewayFetchConfig,\n): (input: FetchInput, init?: RequestInit) => Promise<Response> {\n const { baseURL, normalizeErrors = true } = options;\n const base = baseURL.replace(/\\/$/, '');\n const gatewayBaseUrl = new URL(base);\n const resolvedConfig = resolveConfig({ ...options, baseURL: base });\n\n return async function gatewayFetch(input: FetchInput, init?: RequestInit): Promise<Response> {\n const rawUrl = resolveRequestUrl(input);\n const isAbsolute = rawUrl.startsWith('http://') || rawUrl.startsWith('https://');\n const resolvedUrl = new URL(isAbsolute ? rawUrl : joinBaseUrl(base, rawUrl));\n const isGatewayRequest = isGatewayUrl(resolvedUrl, gatewayBaseUrl);\n\n const request = typeof Request !== 'undefined' && input instanceof Request ? input : undefined;\n const requestClone = request?.clone();\n const headers = new Headers(requestClone?.headers);\n\n if (init?.headers) {\n for (const [key, value] of new Headers(init.headers).entries()) {\n headers.set(key, value);\n }\n }\n\n // Always strip the OpenAI placeholder before entering the shared pipeline.\n // For gateway requests the real Bearer is injected later via getAuthToken();\n // for non-gateway requests we also avoid leaking the sentinel downstream.\n stripPlaceholderAuthorization(headers, GATEWAY_PLACEHOLDER_API_KEY);\n\n return executeRequestPipeline(\n resolvedConfig,\n {\n url: resolvedUrl.toString(),\n method: init?.method ?? requestClone?.method ?? 'GET',\n headers: headersToRecord(headers),\n body: init?.body ?? requestClone?.body,\n signal: init?.signal ?? requestClone?.signal,\n },\n {\n includeConfigHeaders: isGatewayRequest,\n includeAuth: isGatewayRequest,\n includeRequestId: isGatewayRequest,\n normalizeErrors: isGatewayRequest && normalizeErrors,\n allowAuthRetry: isGatewayRequest,\n requestIdPrefix: 'provider',\n },\n );\n };\n}\n","/**\n * AI Gateway provider factory.\n *\n * `createGatewayProvider()` routes bare model IDs through the gateway's\n * OpenAI-compatible endpoint with provider-specific prefixes.\n * `createAIGatewayProvider()` is the low-level escape hatch for direct\n * OpenAI-compatible provider construction.\n */\n\nimport { createOpenAI as builtinCreateOpenAI } from '@ai-sdk/openai';\nimport type { OpenAIProvider, OpenAIProviderSettings } from '@ai-sdk/openai';\nimport { createGatewayFetch, GATEWAY_PLACEHOLDER_API_KEY } from './gateway-fetch';\nimport type { Environment, GatewayProviderSettings } from './gateway-config';\nimport { resolveGatewayBaseURL } from './gateway-config';\n\n// ─── AIGatewayProvider (low-level) ────────────────────────────────────────────\n\nconst DEFAULT_API_VERSION = 'v1';\n\nexport interface AIGatewayProviderOptions\n extends Omit<OpenAIProviderSettings, 'apiKey' | 'baseURL' | 'fetch'>, GatewayProviderSettings {\n /**\n * Optional override for the OpenAI provider factory.\n * Uses `createOpenAI` from `@ai-sdk/openai` by default.\n */\n createOpenAI?: typeof builtinCreateOpenAI;\n /**\n * Normalize gateway error responses into `AIGatewayError`. Default: true.\n * When enabled, non-OK gateway responses throw instead of returning a failed Response.\n */\n normalizeErrors?: boolean;\n}\n\n/**\n * Creates a Vercel AI SDK-compatible provider backed by AI Gateway.\n *\n * The returned value is a fully typed `OpenAIProvider`, so existing apps can\n * keep using their `ai-sdk` helpers and model-selection patterns.\n */\nexport function createAIGatewayProvider(options: AIGatewayProviderOptions): OpenAIProvider {\n const baseURL = resolveGatewayBaseURL(options.baseURL, options.env as Environment, 'AIGatewayProvider');\n const customFetch = createGatewayFetch({ ...options, baseURL, normalizeErrors: options.normalizeErrors });\n\n const openAI = options.createOpenAI ?? builtinCreateOpenAI;\n\n return openAI({\n name: options.name,\n organization: options.organization,\n project: options.project,\n baseURL: `${baseURL.replace(/\\/$/, '')}/api/${DEFAULT_API_VERSION}`,\n fetch: customFetch,\n apiKey: GATEWAY_PLACEHOLDER_API_KEY,\n });\n}\n\n// ─── GatewayProvider (prefixed routing) ───────────────────────────────────────\n\nexport interface GatewayProviderBaseOptions extends AIGatewayProviderOptions {\n /**\n * Override the model ID prefix used for Gateway routing.\n * Default: the provider's canonical prefix (e.g. `'anthropic'`).\n *\n * Model IDs that already contain `/` are sent as-is.\n */\n modelPrefix?: string;\n}\n\nexport interface GatewayOpenAICompatibleOptions extends Omit<GatewayProviderBaseOptions, 'modelPrefix'> {\n /**\n * Required for openai-compatible backends because there is no single canonical\n * default prefix. Examples: `openai`, `fireworks_ai`, `openrouter`.\n */\n modelPrefix: string;\n}\n\nexport const GATEWAY_PROVIDERS = {\n ANTHROPIC: 'anthropic',\n GOOGLE: 'google',\n XAI: 'xai',\n GROQ: 'groq',\n MISTRAL: 'mistral',\n AMAZON_BEDROCK: 'amazon-bedrock',\n AZURE: 'azure',\n COHERE: 'cohere',\n PERPLEXITY: 'perplexity',\n DEEPSEEK: 'deepseek',\n TOGETHERAI: 'togetherai',\n OPENAI_COMPATIBLE: 'openai-compatible',\n} as const;\n\nexport type GatewayProvider = (typeof GATEWAY_PROVIDERS)[keyof typeof GATEWAY_PROVIDERS];\n\nexport type GatewayProviderWithDefaultPrefix = Exclude<GatewayProvider, typeof GATEWAY_PROVIDERS.OPENAI_COMPATIBLE>;\n\nexport interface GatewayProviderOptionsMap {\n [GATEWAY_PROVIDERS.OPENAI_COMPATIBLE]: GatewayOpenAICompatibleOptions;\n}\n\nexport type GatewayProviderOptions<P extends GatewayProvider> = P extends keyof GatewayProviderOptionsMap\n ? GatewayProviderOptionsMap[P]\n : GatewayProviderBaseOptions;\n\nconst GATEWAY_PROVIDER_DEFAULT_PREFIXES: Record<GatewayProviderWithDefaultPrefix, string> = {\n [GATEWAY_PROVIDERS.ANTHROPIC]: 'anthropic',\n [GATEWAY_PROVIDERS.GOOGLE]: 'google',\n [GATEWAY_PROVIDERS.XAI]: 'xai',\n [GATEWAY_PROVIDERS.GROQ]: 'groq',\n [GATEWAY_PROVIDERS.MISTRAL]: 'mistral',\n [GATEWAY_PROVIDERS.AMAZON_BEDROCK]: 'bedrock',\n [GATEWAY_PROVIDERS.AZURE]: 'azure',\n [GATEWAY_PROVIDERS.COHERE]: 'cohere',\n [GATEWAY_PROVIDERS.PERPLEXITY]: 'perplexity',\n [GATEWAY_PROVIDERS.DEEPSEEK]: 'deepseek',\n [GATEWAY_PROVIDERS.TOGETHERAI]: 'togetherai',\n};\n\nfunction prefixModelId(prefix: string, modelId: string): string {\n return modelId.includes('/') ? modelId : `${prefix}/${modelId}`;\n}\n\nfunction createPrefixedGatewayProvider(defaultPrefix: string, options: GatewayProviderBaseOptions): OpenAIProvider {\n const { modelPrefix, ...providerOptions } = options;\n const prefix = modelPrefix ?? defaultPrefix;\n const provider = createAIGatewayProvider(providerOptions);\n\n const wrapped = ((modelId: string) => provider(prefixModelId(prefix, modelId))) as OpenAIProvider;\n\n return new Proxy(wrapped, {\n apply(_target, _thisArg, args: [string, ...unknown[]]) {\n const [modelId, ...rest] = args;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return (provider as (...a: unknown[]) => any)(prefixModelId(prefix, modelId), ...rest);\n },\n get(_target, prop) {\n const value = Reflect.get(provider, prop, provider);\n if (typeof value === 'function') {\n return (...args: unknown[]) => {\n if (typeof args[0] === 'string') {\n args[0] = prefixModelId(prefix, args[0] as string);\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return (value as (...a: unknown[]) => any).apply(provider, args);\n };\n }\n return value;\n },\n has(_target, prop) {\n return prop in (provider as object);\n },\n });\n}\n\n/**\n * Creates an `OpenAIProvider` backed by AI Gateway for a supported provider.\n *\n * Bare model IDs are automatically prefixed with the provider's canonical\n * Gateway routing prefix. Model IDs that already contain `/` are passed as-is.\n */\nexport function createGatewayProvider(\n provider: GatewayProviderWithDefaultPrefix,\n options: GatewayProviderBaseOptions,\n): OpenAIProvider;\nexport function createGatewayProvider(\n provider: typeof GATEWAY_PROVIDERS.OPENAI_COMPATIBLE,\n options: GatewayOpenAICompatibleOptions,\n): OpenAIProvider;\nexport function createGatewayProvider(\n provider: GatewayProvider,\n options: GatewayProviderBaseOptions | GatewayOpenAICompatibleOptions,\n): OpenAIProvider {\n if (provider === GATEWAY_PROVIDERS.OPENAI_COMPATIBLE) {\n return createPrefixedGatewayProvider(\n (options as GatewayOpenAICompatibleOptions).modelPrefix,\n options as GatewayOpenAICompatibleOptions,\n );\n }\n\n return createPrefixedGatewayProvider(\n GATEWAY_PROVIDER_DEFAULT_PREFIXES[provider as GatewayProviderWithDefaultPrefix],\n options as GatewayProviderBaseOptions,\n );\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  import { ModuleMetadata, Type, InjectionToken, OptionalFactoryDependency, DynamicModule, ExceptionFilter, ArgumentsHost } from '@nestjs/common';
2
- import { G as GatewayProviderSettings, A as AIGatewayError } from '../gateway-errors-DdgDIyQw.cjs';
2
+ import { G as GatewayProviderSettings, A as AIGatewayError } from '../gateway-errors-CPtIbrWq.cjs';
3
3
 
4
4
  /**
5
5
  * Synchronous module configuration.
@@ -1,5 +1,5 @@
1
1
  import { ModuleMetadata, Type, InjectionToken, OptionalFactoryDependency, DynamicModule, ExceptionFilter, ArgumentsHost } from '@nestjs/common';
2
- import { G as GatewayProviderSettings, A as AIGatewayError } from '../gateway-errors-DdgDIyQw.js';
2
+ import { G as GatewayProviderSettings, A as AIGatewayError } from '../gateway-errors-CPtIbrWq.js';
3
3
 
4
4
  /**
5
5
  * Synchronous module configuration.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@macpaw/ai-sdk",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "Vercel AI SDK extension layer for AI Gateway with MacPaw and Setapp auth flows",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -56,7 +56,7 @@
56
56
  },
57
57
  "packageManager": "pnpm@10.15.1",
58
58
  "publishConfig": {
59
- "access": "restricted"
59
+ "access": "public"
60
60
  },
61
61
  "scripts": {
62
62
  "build": "tsup",
@@ -9,6 +9,7 @@ Apply these rules when integrating MacPaw AI Gateway.
9
9
  - `@macpaw/ai-sdk/nestjs`: NestJS module and decorators.
10
10
  - Install `@ai-sdk/openai` when using `createAIGatewayProvider` or `createGatewayProvider`.
11
11
  - Never use `createAIGatewayClient`, `@macpaw/ai-sdk/client`, `runtime`, `types`, or `testing`.
12
+ - For UI hooks or schema helpers, follow the versioned upstream docs for the installed `ai` / `@ai-sdk/react` major version; this package does not redefine those APIs.
12
13
 
13
14
  ## Choose one integration path
14
15
 
@@ -22,7 +23,7 @@ Apply these rules when integrating MacPaw AI Gateway.
22
23
  - Do not invent a token source. Ask once if unclear.
23
24
  - Do not place gateway tokens in browser-only code.
24
25
  - `env` supports only `'production'`; use `baseURL` for staging/custom hosts.
25
- - `createGatewayFetch` requires `baseURL`.
26
+ - `createGatewayFetch` requires a resolved `baseURL`; prefer `resolveGatewayBaseURL()` when you want the default production host.
26
27
  - Remove legacy imports and dependencies only after confirming all usages are migrated.
27
28
 
28
29
  ## Canonical snippets
@@ -9,13 +9,14 @@ Use this guidance when integrating MacPaw AI Gateway into this project.
9
9
  - Keep generation primitives on upstream `ai` / `@ai-sdk/*`.
10
10
  - Install `@ai-sdk/openai` when using `createAIGatewayProvider` or `createGatewayProvider`; those paths depend on the OpenAI-compatible provider package.
11
11
  - Do not use `createAIGatewayClient`, `@macpaw/ai-sdk/client`, `runtime`, `types`, or `testing`; those surfaces do not exist.
12
+ - For UI hooks or schema helpers, follow the versioned upstream docs for the installed `ai` / `@ai-sdk/react` major version; this package does not redefine those APIs.
12
13
 
13
14
  ## Guardrails
14
15
 
15
16
  - Do not invent a token source. If server-side token retrieval is unclear, ask one concise question.
16
17
  - Do not put real gateway tokens in browser-only code.
17
18
  - Use `env: 'production'` only for the default MacPaw host. Use `baseURL` for staging or custom hosts.
18
- - `createGatewayFetch` requires a resolved `baseURL`; do not pass only `env`.
19
+ - `createGatewayFetch` requires a resolved `baseURL`; do not pass only `env`. Prefer `resolveGatewayBaseURL()` when you want the default production host.
19
20
  - Remove old provider dependencies only after verifying there are no remaining usages.
20
21
 
21
22
  ## Preferred paths
@@ -15,6 +15,7 @@ Detect the app shape, choose one integration path, apply the smallest correct pa
15
15
  - Use `@macpaw/ai-sdk/provider` only as a compatibility alias.
16
16
  - Use `@macpaw/ai-sdk/nestjs` for `AIGatewayModule`, `@InjectAIGateway()`, and `AIGatewayExceptionFilter`.
17
17
  - Do not use `createAIGatewayClient`, `@macpaw/ai-sdk/client`, `runtime`, `types`, or `testing`; they do not exist.
18
+ - For UI hooks or schema helpers, follow the versioned upstream docs for the installed `ai` / `@ai-sdk/react` major version; this package does not redefine those APIs.
18
19
 
19
20
  ## Guardrails
20
21
 
@@ -22,7 +23,7 @@ Detect the app shape, choose one integration path, apply the smallest correct pa
22
23
  - Do not place real tokens in browser-only code. Frontend-only apps need a backend/BFF token source.
23
24
  - Do not remove direct OpenAI/Anthropic paths unless all usages are migrated or the user asked for it.
24
25
  - Use `baseURL` for staging/custom hosts. `env` supports only `'production'`.
25
- - `createGatewayFetch` requires a resolved `baseURL`; do not pass only `env`.
26
+ - `createGatewayFetch` requires a resolved `baseURL`; do not pass only `env`. Prefer `resolveGatewayBaseURL()` when you want the default production host.
26
27
 
27
28
  ## Choose one path
28
29