@zorveus/sdk 0.1.8 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +88 -11
- package/dist/adapters/openai.d.mts +33 -0
- package/dist/adapters/openai.d.ts +33 -0
- package/dist/adapters/openai.js +384 -0
- package/dist/adapters/openai.js.map +1 -0
- package/dist/adapters/openai.mjs +95 -0
- package/dist/adapters/openai.mjs.map +1 -0
- package/dist/adapters/vercel.d.mts +24 -0
- package/dist/adapters/vercel.d.ts +24 -0
- package/dist/adapters/vercel.js +336 -0
- package/dist/adapters/vercel.js.map +1 -0
- package/dist/adapters/vercel.mjs +57 -0
- package/dist/adapters/vercel.mjs.map +1 -0
- package/dist/chunk-6SPZ5W5D.mjs +285 -0
- package/dist/chunk-6SPZ5W5D.mjs.map +1 -0
- package/dist/index.d.mts +101 -285
- package/dist/index.d.ts +101 -285
- package/dist/index.js +212 -25
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +115 -178
- package/dist/index.mjs.map +1 -1
- package/dist/zorveus-error-DbltWNhC.d.mts +347 -0
- package/dist/zorveus-error-DbltWNhC.d.ts +347 -0
- package/package.json +57 -1
package/README.md
CHANGED
|
@@ -8,6 +8,7 @@ Official TypeScript and JavaScript client library for the [Zorveus](https://zorv
|
|
|
8
8
|
- **Product User management and credit grants**: Track spend limits, query live balances, and grant promotional credits using `externalUserId`.
|
|
9
9
|
- **Model discovery**: Query available models for an inference key with `client.models.list({ routeStatus: "available" })`.
|
|
10
10
|
- **Spend tracking**: Real-time spending and remaining balance queries with `client.getUsage()`.
|
|
11
|
+
- **Finance reporting**: Cursor-paginated usage events with wallet, BYOK, cache, and settlement fields.
|
|
11
12
|
- **OAuth 2.0 PKCE utilities**: PKCE parameters generation, authorization URL construction, and token exchange helpers.
|
|
12
13
|
- **Provider credentials management**: Store and route provider keys.
|
|
13
14
|
|
|
@@ -58,8 +59,46 @@ for await (const chunk of stream) {
|
|
|
58
59
|
|
|
59
60
|
// Query current usage and spend cap
|
|
60
61
|
const usage = await client.getUsage();
|
|
61
|
-
console.log(`
|
|
62
|
-
|
|
62
|
+
console.log(`Period spend: $${usage.spent_this_period}, remaining balance: $${usage.remaining_balance}`);
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Adapters for OpenAI SDK and Vercel AI SDK
|
|
66
|
+
|
|
67
|
+
### OpenAI SDK integration (`ZorveusOpenAI`)
|
|
68
|
+
|
|
69
|
+
If your codebase uses the official `openai` npm package, import `ZorveusOpenAI` from `@zorveus/sdk/openai`. It wraps `OpenAI` and automatically injects `metadata.external_user_id` into request payloads:
|
|
70
|
+
|
|
71
|
+
```typescript
|
|
72
|
+
import { ZorveusOpenAI } from "@zorveus/sdk/openai";
|
|
73
|
+
|
|
74
|
+
const openai = new ZorveusOpenAI({
|
|
75
|
+
apiKey: process.env.ZORVEUS_INFERENCE_KEY,
|
|
76
|
+
externalUserId: "usr_sara_101"
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
const completion = await openai.chat.completions.create({
|
|
80
|
+
model: "openai/gpt-4.1-mini",
|
|
81
|
+
messages: [{ role: "user", content: "Hello from Zorveus!" }]
|
|
82
|
+
});
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Vercel AI SDK integration (`createZorveus`)
|
|
86
|
+
|
|
87
|
+
If your project uses Vercel AI SDK (`ai` and `@ai-sdk/openai`), import `createZorveus` from `@zorveus/sdk/vercel`:
|
|
88
|
+
|
|
89
|
+
```typescript
|
|
90
|
+
import { createZorveus } from "@zorveus/sdk/vercel";
|
|
91
|
+
import { streamText } from "ai";
|
|
92
|
+
|
|
93
|
+
const zorveus = createZorveus({
|
|
94
|
+
apiKey: process.env.ZORVEUS_INFERENCE_KEY,
|
|
95
|
+
externalUserId: "usr_sara_101"
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
const { textStream } = streamText({
|
|
99
|
+
model: zorveus("openai/gpt-4.1-mini"),
|
|
100
|
+
prompt: "Generate 3 headline ideas."
|
|
101
|
+
});
|
|
63
102
|
```
|
|
64
103
|
|
|
65
104
|
## Quickstart for product users and credit grants (`ZorveusServiceClient`)
|
|
@@ -99,7 +138,7 @@ const grantRes = await zorveus.productUsers.grantCreditByExternalId({
|
|
|
99
138
|
});
|
|
100
139
|
|
|
101
140
|
console.log("Issued Grant ID:", grantRes.credit_grant.credit_grant_id);
|
|
102
|
-
console.log("New
|
|
141
|
+
console.log("New Available Credits:", grantRes.credit_summary.available_credits);
|
|
103
142
|
|
|
104
143
|
// Query user credit grants ledger
|
|
105
144
|
const ledger = await zorveus.productUsers.listCreditGrantsByExternalId({
|
|
@@ -152,6 +191,9 @@ console.log("User access token:", tokenData.access_token);
|
|
|
152
191
|
console.log("App connection ID:", tokenData.app_connection_id);
|
|
153
192
|
```
|
|
154
193
|
|
|
194
|
+
> [!NOTE]
|
|
195
|
+
> OAuth authorization requests require at least one model scope such as `models:*` alongside `inference:write`. Omitting model scopes triggers a `zorveus_model_scope_required` authorization error.
|
|
196
|
+
|
|
155
197
|
## API reference
|
|
156
198
|
|
|
157
199
|
### `Zorveus` (Inference client)
|
|
@@ -174,6 +216,27 @@ console.log("App connection ID:", tokenData.app_connection_id);
|
|
|
174
216
|
| `list(params)` | List organization product users (`GET /product-users`) |
|
|
175
217
|
| `revokeCredit(userIdentifier, grantId)` | Revoke active grant (`POST /product-users/{id}/credit-grants/{grantId}/revoke`) |
|
|
176
218
|
|
|
219
|
+
### `ZorveusServiceClient.usageEvents` (finance reporting)
|
|
220
|
+
|
|
221
|
+
```typescript
|
|
222
|
+
import { normalInputTokens, ZorveusServiceClient } from "@zorveus/sdk";
|
|
223
|
+
|
|
224
|
+
const service = new ZorveusServiceClient({ apiKey: process.env.ZORVEUS_SERVICE_KEY });
|
|
225
|
+
const page = await service.usageEvents.list({ orgId: "org_123", limit: 50 });
|
|
226
|
+
|
|
227
|
+
for (const event of page.events) {
|
|
228
|
+
console.log({
|
|
229
|
+
virtualSpend: event.virtual_spend,
|
|
230
|
+
walletCharge: event.sell_cost,
|
|
231
|
+
providerCost: event.provider_cost,
|
|
232
|
+
cacheSavings: event.cache_savings,
|
|
233
|
+
normalInputTokens: normalInputTokens(event)
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
All monetary fields are decimal strings. Keep them as strings or use a decimal-number library. Do not use `parseFloat()` for financial calculations. `normalInputTokens()` returns `null` unless the provider reported a valid cache breakdown.
|
|
239
|
+
|
|
177
240
|
### `ZorveusServiceClient.providerCredentials` (BYOK management)
|
|
178
241
|
|
|
179
242
|
| Method | Description |
|
|
@@ -195,26 +258,40 @@ console.log("App connection ID:", tokenData.app_connection_id);
|
|
|
195
258
|
|
|
196
259
|
## Error handling
|
|
197
260
|
|
|
198
|
-
The SDK exposes error classes
|
|
261
|
+
The SDK exposes typed error classes matching the Zorveus finance and gateway contract:
|
|
199
262
|
|
|
200
263
|
```typescript
|
|
201
|
-
import {
|
|
264
|
+
import {
|
|
265
|
+
ZorveusError,
|
|
266
|
+
ProductUserAllowanceInsufficientError,
|
|
267
|
+
CapExceededError,
|
|
268
|
+
InsufficientFundsError,
|
|
269
|
+
RateLimitError
|
|
270
|
+
} from "@zorveus/sdk";
|
|
202
271
|
|
|
203
272
|
try {
|
|
204
|
-
await
|
|
273
|
+
await client.chat.completions.create({ ... });
|
|
205
274
|
} catch (error) {
|
|
206
|
-
if (error instanceof
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
console.error("
|
|
275
|
+
if (error instanceof ProductUserAllowanceInsufficientError) {
|
|
276
|
+
// HTTP 403: Base allowance and promotional credits exhausted
|
|
277
|
+
console.error("Allowance shortfall:", error.params?.shortfall);
|
|
278
|
+
console.error("Remaining base:", error.params?.remaining_base_allowance);
|
|
279
|
+
console.error("Promotional credits:", error.params?.promotional_credit_balance);
|
|
280
|
+
} else if (error instanceof CapExceededError) {
|
|
281
|
+
// HTTP 403: Key or member cap reached
|
|
282
|
+
console.error("Key cap reached:", error.message);
|
|
283
|
+
} else if (error instanceof InsufficientFundsError) {
|
|
284
|
+
// HTTP 402: Organization wallet lacks funds for wallet charge or BYOK fee
|
|
285
|
+
console.error("Organization wallet empty, top-up required:", error.message);
|
|
210
286
|
} else if (error instanceof RateLimitError) {
|
|
211
|
-
console.error("Rate limit exceeded");
|
|
287
|
+
console.error("Rate limit exceeded:", error.message);
|
|
212
288
|
} else if (error instanceof ZorveusError) {
|
|
213
289
|
console.error(`Zorveus Error (${error.status}):`, error.message);
|
|
214
290
|
}
|
|
215
291
|
}
|
|
216
292
|
```
|
|
217
293
|
|
|
294
|
+
|
|
218
295
|
## License
|
|
219
296
|
|
|
220
297
|
MIT © [Zorveus Inc.](https://zorveus.com)
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import OpenAI from 'openai';
|
|
2
|
+
export { p as parseZorveusGatewayError } from '../zorveus-error-DbltWNhC.mjs';
|
|
3
|
+
|
|
4
|
+
interface ZorveusOpenAIOptions {
|
|
5
|
+
apiKey?: string;
|
|
6
|
+
baseURL?: string;
|
|
7
|
+
externalUserId?: string;
|
|
8
|
+
productEndUserId?: string;
|
|
9
|
+
displayName?: string;
|
|
10
|
+
userEmail?: string;
|
|
11
|
+
email?: string;
|
|
12
|
+
userMetadata?: Record<string, unknown>;
|
|
13
|
+
appId?: string;
|
|
14
|
+
metadata?: Record<string, unknown>;
|
|
15
|
+
defaultHeaders?: Record<string, string>;
|
|
16
|
+
[key: string]: unknown;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* ZorveusOpenAI wraps the official OpenAI SDK client, automatically injecting
|
|
20
|
+
* metadata (external_user_id, product_end_user_id, and product_user attribution) into request payloads.
|
|
21
|
+
*/
|
|
22
|
+
declare class ZorveusOpenAI extends OpenAI {
|
|
23
|
+
private readonly defaultExternalUserId?;
|
|
24
|
+
private readonly defaultProductEndUserId?;
|
|
25
|
+
private readonly defaultDisplayName?;
|
|
26
|
+
private readonly defaultUserEmail?;
|
|
27
|
+
private readonly defaultUserMetadata?;
|
|
28
|
+
private readonly defaultAppId?;
|
|
29
|
+
private readonly defaultMetadata?;
|
|
30
|
+
constructor(options?: ZorveusOpenAIOptions);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export { ZorveusOpenAI, type ZorveusOpenAIOptions };
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import OpenAI from 'openai';
|
|
2
|
+
export { p as parseZorveusGatewayError } from '../zorveus-error-DbltWNhC.js';
|
|
3
|
+
|
|
4
|
+
interface ZorveusOpenAIOptions {
|
|
5
|
+
apiKey?: string;
|
|
6
|
+
baseURL?: string;
|
|
7
|
+
externalUserId?: string;
|
|
8
|
+
productEndUserId?: string;
|
|
9
|
+
displayName?: string;
|
|
10
|
+
userEmail?: string;
|
|
11
|
+
email?: string;
|
|
12
|
+
userMetadata?: Record<string, unknown>;
|
|
13
|
+
appId?: string;
|
|
14
|
+
metadata?: Record<string, unknown>;
|
|
15
|
+
defaultHeaders?: Record<string, string>;
|
|
16
|
+
[key: string]: unknown;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* ZorveusOpenAI wraps the official OpenAI SDK client, automatically injecting
|
|
20
|
+
* metadata (external_user_id, product_end_user_id, and product_user attribution) into request payloads.
|
|
21
|
+
*/
|
|
22
|
+
declare class ZorveusOpenAI extends OpenAI {
|
|
23
|
+
private readonly defaultExternalUserId?;
|
|
24
|
+
private readonly defaultProductEndUserId?;
|
|
25
|
+
private readonly defaultDisplayName?;
|
|
26
|
+
private readonly defaultUserEmail?;
|
|
27
|
+
private readonly defaultUserMetadata?;
|
|
28
|
+
private readonly defaultAppId?;
|
|
29
|
+
private readonly defaultMetadata?;
|
|
30
|
+
constructor(options?: ZorveusOpenAIOptions);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export { ZorveusOpenAI, type ZorveusOpenAIOptions };
|
|
@@ -0,0 +1,384 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/adapters/openai.ts
|
|
31
|
+
var openai_exports = {};
|
|
32
|
+
__export(openai_exports, {
|
|
33
|
+
ZorveusOpenAI: () => ZorveusOpenAI,
|
|
34
|
+
parseZorveusGatewayError: () => parseZorveusGatewayError
|
|
35
|
+
});
|
|
36
|
+
module.exports = __toCommonJS(openai_exports);
|
|
37
|
+
var import_openai = __toESM(require("openai"));
|
|
38
|
+
|
|
39
|
+
// src/errors/zorveus-error.ts
|
|
40
|
+
var ZorveusError = class extends Error {
|
|
41
|
+
status;
|
|
42
|
+
code;
|
|
43
|
+
param;
|
|
44
|
+
type;
|
|
45
|
+
params;
|
|
46
|
+
headers;
|
|
47
|
+
rawBody;
|
|
48
|
+
constructor(message, options = {}) {
|
|
49
|
+
super(message);
|
|
50
|
+
this.name = "ZorveusError";
|
|
51
|
+
this.status = options.status;
|
|
52
|
+
this.code = options.code;
|
|
53
|
+
this.param = options.param;
|
|
54
|
+
this.type = options.type;
|
|
55
|
+
this.params = options.params;
|
|
56
|
+
this.headers = options.headers;
|
|
57
|
+
this.rawBody = options.rawBody;
|
|
58
|
+
if (options.cause) {
|
|
59
|
+
this.cause = options.cause;
|
|
60
|
+
}
|
|
61
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
var APIStatusError = class extends ZorveusError {
|
|
65
|
+
constructor(message, options) {
|
|
66
|
+
super(message, options);
|
|
67
|
+
this.name = "APIStatusError";
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
var AuthenticationError = class extends APIStatusError {
|
|
71
|
+
constructor(message = "Invalid or expired Zorveus credentials", options = {}) {
|
|
72
|
+
super(message, { ...options, status: options.status ?? 401 });
|
|
73
|
+
this.name = "AuthenticationError";
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
var PermissionDeniedError = class extends APIStatusError {
|
|
77
|
+
constructor(message = "Permission denied for this operation or model", options = {}) {
|
|
78
|
+
super(message, { ...options, status: options.status ?? 403 });
|
|
79
|
+
this.name = "PermissionDeniedError";
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
var NotFoundError = class extends APIStatusError {
|
|
83
|
+
constructor(message = "Resource not found", options = {}) {
|
|
84
|
+
super(message, { ...options, status: options.status ?? 404 });
|
|
85
|
+
this.name = "NotFoundError";
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
var UnprocessableEntityError = class extends APIStatusError {
|
|
89
|
+
constructor(message = "Request validation failed", options = {}) {
|
|
90
|
+
super(message, { ...options, status: options.status ?? 422 });
|
|
91
|
+
this.name = "UnprocessableEntityError";
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
var RateLimitError = class extends APIStatusError {
|
|
95
|
+
constructor(message = "Rate limit exceeded. Please retry after some time.", options = {}) {
|
|
96
|
+
super(message, { ...options, status: options.status ?? 429 });
|
|
97
|
+
this.name = "RateLimitError";
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
var InternalServerError = class extends APIStatusError {
|
|
101
|
+
constructor(message = "Zorveus internal server error", options = {}) {
|
|
102
|
+
super(message, { ...options, status: options.status ?? 500 });
|
|
103
|
+
this.name = "InternalServerError";
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
var ZorveusBusinessError = class extends APIStatusError {
|
|
107
|
+
constructor(message, options) {
|
|
108
|
+
super(message, options);
|
|
109
|
+
this.name = "ZorveusBusinessError";
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
var InsufficientFundsError = class extends ZorveusBusinessError {
|
|
113
|
+
constructor(message = "Wallet balance exhausted. Top up required.", options = {}) {
|
|
114
|
+
super(message, {
|
|
115
|
+
...options,
|
|
116
|
+
status: options.status ?? 402,
|
|
117
|
+
code: options.code ?? "zorveus_reservation_insufficient_balance"
|
|
118
|
+
});
|
|
119
|
+
this.name = "InsufficientFundsError";
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
var CapExceededError = class extends ZorveusBusinessError {
|
|
123
|
+
constructor(message = "Spending cap limit reached", options = {}) {
|
|
124
|
+
super(message, {
|
|
125
|
+
...options,
|
|
126
|
+
status: options.status ?? 403,
|
|
127
|
+
code: options.code ?? "zorveus_cap_exceeded"
|
|
128
|
+
});
|
|
129
|
+
this.name = "CapExceededError";
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
var ProductUserAllowanceInsufficientError = class extends ZorveusBusinessError {
|
|
133
|
+
constructor(message = "Product user AI allowance is insufficient for this request.", options = {}) {
|
|
134
|
+
super(message, {
|
|
135
|
+
...options,
|
|
136
|
+
status: options.status ?? 403,
|
|
137
|
+
code: options.code ?? "zorveus_product_user_allowance_insufficient",
|
|
138
|
+
params: options.params
|
|
139
|
+
});
|
|
140
|
+
this.name = "ProductUserAllowanceInsufficientError";
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
var CreditGrantExpiredError = class extends ZorveusBusinessError {
|
|
144
|
+
constructor(message = "Product user credit grant has expired", options = {}) {
|
|
145
|
+
super(message, {
|
|
146
|
+
...options,
|
|
147
|
+
status: options.status ?? 403,
|
|
148
|
+
code: options.code ?? "credit_grant_expired"
|
|
149
|
+
});
|
|
150
|
+
this.name = "CreditGrantExpiredError";
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
var AppConnectionNotFoundError = class extends ZorveusBusinessError {
|
|
154
|
+
constructor(message = "Inference key or app connection not found or revoked", options = {}) {
|
|
155
|
+
super(message, {
|
|
156
|
+
...options,
|
|
157
|
+
status: options.status ?? 403,
|
|
158
|
+
code: options.code ?? "zorveus_app_connection_not_found"
|
|
159
|
+
});
|
|
160
|
+
this.name = "AppConnectionNotFoundError";
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
var ReservationConflictError = class extends ZorveusBusinessError {
|
|
164
|
+
constructor(message = "Idempotency key reused with conflicting request parameters", options = {}) {
|
|
165
|
+
super(message, {
|
|
166
|
+
...options,
|
|
167
|
+
status: options.status ?? 409,
|
|
168
|
+
code: options.code ?? "zorveus_reservation_conflict"
|
|
169
|
+
});
|
|
170
|
+
this.name = "ReservationConflictError";
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
function createAPIError(status, body, headers) {
|
|
174
|
+
let message = `Request failed with status ${status}`;
|
|
175
|
+
let code;
|
|
176
|
+
let param;
|
|
177
|
+
let type;
|
|
178
|
+
let params;
|
|
179
|
+
let parsedBody = body;
|
|
180
|
+
if (typeof body === "string") {
|
|
181
|
+
try {
|
|
182
|
+
parsedBody = JSON.parse(body);
|
|
183
|
+
} catch {
|
|
184
|
+
try {
|
|
185
|
+
parsedBody = JSON.parse(body.replace(/'/g, '"'));
|
|
186
|
+
} catch {
|
|
187
|
+
const codeMatch = body.match(/['"]code['"]\s*:\s*['"]([^'"]+)['"]/);
|
|
188
|
+
const msgMatch = body.match(/['"]message['"]\s*:\s*['"]([^'"]+)['"]/);
|
|
189
|
+
if (msgMatch?.[1]) message = msgMatch[1];
|
|
190
|
+
if (codeMatch?.[1]) code = codeMatch[1];
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
if (parsedBody && typeof parsedBody === "object") {
|
|
195
|
+
const obj = parsedBody;
|
|
196
|
+
const providerFields = obj.provider_specific_fields ?? obj.error?.provider_specific_fields;
|
|
197
|
+
const nestedGatewayError = providerFields?.error ?? providerFields;
|
|
198
|
+
if (nestedGatewayError && typeof nestedGatewayError === "object") {
|
|
199
|
+
if (typeof nestedGatewayError.message === "string") message = nestedGatewayError.message;
|
|
200
|
+
if (typeof nestedGatewayError.code === "string") code = nestedGatewayError.code;
|
|
201
|
+
if (typeof nestedGatewayError.param === "string") param = nestedGatewayError.param;
|
|
202
|
+
if (typeof nestedGatewayError.type === "string") type = nestedGatewayError.type;
|
|
203
|
+
if (nestedGatewayError.params && typeof nestedGatewayError.params === "object") {
|
|
204
|
+
params = nestedGatewayError.params;
|
|
205
|
+
}
|
|
206
|
+
} else if (obj.error && typeof obj.error === "object") {
|
|
207
|
+
const err = obj.error;
|
|
208
|
+
if (typeof err.message === "string") message = err.message;
|
|
209
|
+
if (typeof err.code === "string") code = err.code;
|
|
210
|
+
if (typeof err.param === "string") param = err.param;
|
|
211
|
+
if (typeof err.type === "string") type = err.type;
|
|
212
|
+
if (err.params && typeof err.params === "object") {
|
|
213
|
+
params = err.params;
|
|
214
|
+
}
|
|
215
|
+
} else {
|
|
216
|
+
if (typeof obj.message === "string") message = obj.message;
|
|
217
|
+
if (typeof obj.code === "string") code = obj.code;
|
|
218
|
+
if (typeof obj.param === "string") param = obj.param;
|
|
219
|
+
if (typeof obj.type === "string") type = obj.type;
|
|
220
|
+
if (obj.params && typeof obj.params === "object") {
|
|
221
|
+
params = obj.params;
|
|
222
|
+
}
|
|
223
|
+
if (typeof obj.detail === "string") {
|
|
224
|
+
message = obj.detail;
|
|
225
|
+
} else if (Array.isArray(obj.detail) && obj.detail.length > 0) {
|
|
226
|
+
const first = obj.detail[0];
|
|
227
|
+
if (first && typeof first.msg === "string") {
|
|
228
|
+
message = first.msg;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
const options = { status, code, param, type, params, headers, rawBody: body };
|
|
234
|
+
const normalizedCode = (code || "").toLowerCase();
|
|
235
|
+
if (normalizedCode === "zorveus_product_user_allowance_insufficient" || normalizedCode === "zorveus_product_user_credits_insufficient" || normalizedCode.includes("allowance_insufficient") || normalizedCode.includes("credits_insufficient") || message.toLowerCase().includes("allowance remaining")) {
|
|
236
|
+
return new ProductUserAllowanceInsufficientError(message, {
|
|
237
|
+
...options,
|
|
238
|
+
status: status === 200 ? 403 : status,
|
|
239
|
+
params
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
if (normalizedCode === "zorveus_cap_exceeded" || normalizedCode.includes("cap_exceed") || normalizedCode.includes("spend_cap") || message.toLowerCase().includes("spending cap")) {
|
|
243
|
+
return new CapExceededError(message, options);
|
|
244
|
+
}
|
|
245
|
+
if (normalizedCode === "zorveus_app_connection_not_found" || normalizedCode.includes("app_connection_not_found")) {
|
|
246
|
+
return new AppConnectionNotFoundError(message, options);
|
|
247
|
+
}
|
|
248
|
+
if (status === 409 || normalizedCode === "zorveus_reservation_conflict" || normalizedCode.includes("reservation_conflict")) {
|
|
249
|
+
return new ReservationConflictError(message, options);
|
|
250
|
+
}
|
|
251
|
+
if (status === 402 || normalizedCode === "zorveus_reservation_insufficient_balance" || normalizedCode.includes("insufficient_funds") || normalizedCode.includes("balance_exhausted") || normalizedCode.includes("insufficient_balance") || normalizedCode.includes("wallet_empty") || message.toLowerCase().includes("insufficient funds") || message.toLowerCase().includes("balance exhausted") || message.toLowerCase().includes("wallet is empty")) {
|
|
252
|
+
return new InsufficientFundsError(message, options);
|
|
253
|
+
}
|
|
254
|
+
if (normalizedCode.includes("grant_expired")) {
|
|
255
|
+
return new CreditGrantExpiredError(message, options);
|
|
256
|
+
}
|
|
257
|
+
if (status === 401) {
|
|
258
|
+
return new AuthenticationError(message, options);
|
|
259
|
+
}
|
|
260
|
+
if (status === 403) {
|
|
261
|
+
return new PermissionDeniedError(message, options);
|
|
262
|
+
}
|
|
263
|
+
if (status === 404) {
|
|
264
|
+
return new NotFoundError(message, options);
|
|
265
|
+
}
|
|
266
|
+
if (status === 422) {
|
|
267
|
+
return new UnprocessableEntityError(message, options);
|
|
268
|
+
}
|
|
269
|
+
if (status === 429) {
|
|
270
|
+
return new RateLimitError(message, options);
|
|
271
|
+
}
|
|
272
|
+
if (status >= 500) {
|
|
273
|
+
return new InternalServerError(message, options);
|
|
274
|
+
}
|
|
275
|
+
return new APIStatusError(message, options);
|
|
276
|
+
}
|
|
277
|
+
function parseZorveusGatewayError(error) {
|
|
278
|
+
if (error instanceof ZorveusError) {
|
|
279
|
+
return error;
|
|
280
|
+
}
|
|
281
|
+
if (!error || typeof error !== "object") {
|
|
282
|
+
return error;
|
|
283
|
+
}
|
|
284
|
+
const errObj = error;
|
|
285
|
+
const status = typeof errObj.status === "number" ? errObj.status : typeof errObj.statusCode === "number" ? errObj.statusCode : void 0;
|
|
286
|
+
const rawBody = errObj.error ?? errObj.body ?? errObj.rawBody;
|
|
287
|
+
if (status !== void 0 && rawBody !== void 0) {
|
|
288
|
+
const headers = errObj.headers && typeof errObj.headers === "object" ? errObj.headers : void 0;
|
|
289
|
+
return createAPIError(status, rawBody, headers);
|
|
290
|
+
}
|
|
291
|
+
return error;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
// src/adapters/openai.ts
|
|
295
|
+
var ZorveusOpenAI = class extends import_openai.default {
|
|
296
|
+
defaultExternalUserId;
|
|
297
|
+
defaultProductEndUserId;
|
|
298
|
+
defaultDisplayName;
|
|
299
|
+
defaultUserEmail;
|
|
300
|
+
defaultUserMetadata;
|
|
301
|
+
defaultAppId;
|
|
302
|
+
defaultMetadata;
|
|
303
|
+
constructor(options = {}) {
|
|
304
|
+
const apiKey = options.apiKey ?? process.env.ZORVEUS_INFERENCE_KEY;
|
|
305
|
+
if (!apiKey) {
|
|
306
|
+
throw new Error("Zorveus API key is required. Set ZORVEUS_INFERENCE_KEY or pass apiKey.");
|
|
307
|
+
}
|
|
308
|
+
const {
|
|
309
|
+
externalUserId,
|
|
310
|
+
productEndUserId,
|
|
311
|
+
displayName,
|
|
312
|
+
userEmail,
|
|
313
|
+
email,
|
|
314
|
+
userMetadata,
|
|
315
|
+
appId,
|
|
316
|
+
metadata,
|
|
317
|
+
baseURL,
|
|
318
|
+
defaultHeaders,
|
|
319
|
+
...restOptions
|
|
320
|
+
} = options;
|
|
321
|
+
super({
|
|
322
|
+
apiKey,
|
|
323
|
+
baseURL: baseURL ?? process.env.ZORVEUS_GATEWAY_URL ?? "https://api.zorveus.com/v1",
|
|
324
|
+
defaultHeaders,
|
|
325
|
+
...restOptions
|
|
326
|
+
});
|
|
327
|
+
this.defaultExternalUserId = externalUserId;
|
|
328
|
+
this.defaultProductEndUserId = productEndUserId;
|
|
329
|
+
this.defaultDisplayName = displayName;
|
|
330
|
+
this.defaultUserEmail = userEmail || email;
|
|
331
|
+
this.defaultUserMetadata = userMetadata;
|
|
332
|
+
this.defaultAppId = appId;
|
|
333
|
+
this.defaultMetadata = metadata;
|
|
334
|
+
const buildMetadata = (body) => {
|
|
335
|
+
const extId = body?.user ?? body?.external_user_id ?? this.defaultExternalUserId;
|
|
336
|
+
const prodUserId = body?.product_end_user_id ?? body?.metadata?.product_end_user_id ?? this.defaultProductEndUserId;
|
|
337
|
+
const dName = body?.display_name ?? this.defaultDisplayName;
|
|
338
|
+
const uEmail = body?.user_email ?? body?.email ?? this.defaultUserEmail;
|
|
339
|
+
const uMeta = body?.user_metadata ?? this.defaultUserMetadata;
|
|
340
|
+
const aId = body?.app_id ?? this.defaultAppId;
|
|
341
|
+
const productUser = {
|
|
342
|
+
...dName ? { display_name: dName } : {},
|
|
343
|
+
...uEmail ? { email: uEmail } : {},
|
|
344
|
+
...uMeta ? { metadata: uMeta } : {},
|
|
345
|
+
...body?.metadata?.product_user
|
|
346
|
+
};
|
|
347
|
+
const merged = {
|
|
348
|
+
...extId ? { external_user_id: extId } : {},
|
|
349
|
+
...prodUserId ? { product_end_user_id: prodUserId } : {},
|
|
350
|
+
...aId ? { app_id: aId } : {},
|
|
351
|
+
...Object.keys(productUser).length > 0 ? { product_user: productUser } : {},
|
|
352
|
+
...this.defaultMetadata,
|
|
353
|
+
...body?.metadata
|
|
354
|
+
};
|
|
355
|
+
return Object.keys(merged).length > 0 ? merged : void 0;
|
|
356
|
+
};
|
|
357
|
+
const originalCreate = this.chat.completions.create.bind(this.chat.completions);
|
|
358
|
+
this.chat.completions.create = ((body, requestOptions) => {
|
|
359
|
+
const mergedMetadata = buildMetadata(body);
|
|
360
|
+
const updatedBody = {
|
|
361
|
+
...body,
|
|
362
|
+
...mergedMetadata ? { metadata: mergedMetadata } : {}
|
|
363
|
+
};
|
|
364
|
+
return originalCreate(updatedBody, requestOptions);
|
|
365
|
+
});
|
|
366
|
+
if (this.responses && typeof this.responses.create === "function") {
|
|
367
|
+
const originalResponsesCreate = this.responses.create.bind(this.responses);
|
|
368
|
+
this.responses.create = ((body, requestOptions) => {
|
|
369
|
+
const mergedMetadata = buildMetadata(body);
|
|
370
|
+
const updatedBody = {
|
|
371
|
+
...body,
|
|
372
|
+
...mergedMetadata ? { metadata: mergedMetadata } : {}
|
|
373
|
+
};
|
|
374
|
+
return originalResponsesCreate(updatedBody, requestOptions);
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
};
|
|
379
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
380
|
+
0 && (module.exports = {
|
|
381
|
+
ZorveusOpenAI,
|
|
382
|
+
parseZorveusGatewayError
|
|
383
|
+
});
|
|
384
|
+
//# sourceMappingURL=openai.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/adapters/openai.ts","../../src/errors/zorveus-error.ts"],"sourcesContent":["import OpenAI from \"openai\";\nexport { parseZorveusGatewayError } from \"../errors/zorveus-error\";\n\nexport interface ZorveusOpenAIOptions {\n apiKey?: string;\n baseURL?: string;\n externalUserId?: string;\n productEndUserId?: string;\n displayName?: string;\n userEmail?: string;\n email?: string;\n userMetadata?: Record<string, unknown>;\n appId?: string;\n metadata?: Record<string, unknown>;\n defaultHeaders?: Record<string, string>;\n [key: string]: unknown;\n}\n\n/**\n * ZorveusOpenAI wraps the official OpenAI SDK client, automatically injecting\n * metadata (external_user_id, product_end_user_id, and product_user attribution) into request payloads.\n */\nexport class ZorveusOpenAI extends OpenAI {\n private readonly defaultExternalUserId?: string;\n private readonly defaultProductEndUserId?: string;\n private readonly defaultDisplayName?: string;\n private readonly defaultUserEmail?: string;\n private readonly defaultUserMetadata?: Record<string, unknown>;\n private readonly defaultAppId?: string;\n private readonly defaultMetadata?: Record<string, unknown>;\n\n constructor(options: ZorveusOpenAIOptions = {}) {\n const apiKey = options.apiKey ?? process.env.ZORVEUS_INFERENCE_KEY;\n if (!apiKey) {\n throw new Error(\"Zorveus API key is required. Set ZORVEUS_INFERENCE_KEY or pass apiKey.\");\n }\n\n const {\n externalUserId,\n productEndUserId,\n displayName,\n userEmail,\n email,\n userMetadata,\n appId,\n metadata,\n baseURL,\n defaultHeaders,\n ...restOptions\n } = options;\n\n super({\n apiKey,\n baseURL: baseURL ?? process.env.ZORVEUS_GATEWAY_URL ?? \"https://api.zorveus.com/v1\",\n defaultHeaders,\n ...restOptions\n });\n\n this.defaultExternalUserId = externalUserId;\n this.defaultProductEndUserId = productEndUserId;\n this.defaultDisplayName = displayName;\n this.defaultUserEmail = userEmail || email;\n this.defaultUserMetadata = userMetadata;\n this.defaultAppId = appId;\n this.defaultMetadata = metadata;\n\n const buildMetadata = (body: any) => {\n const extId = body?.user ?? body?.external_user_id ?? this.defaultExternalUserId;\n const prodUserId =\n body?.product_end_user_id ??\n body?.metadata?.product_end_user_id ??\n this.defaultProductEndUserId;\n const dName = body?.display_name ?? this.defaultDisplayName;\n const uEmail = body?.user_email ?? body?.email ?? this.defaultUserEmail;\n const uMeta = body?.user_metadata ?? this.defaultUserMetadata;\n const aId = body?.app_id ?? this.defaultAppId;\n\n const productUser = {\n ...(dName ? { display_name: dName } : {}),\n ...(uEmail ? { email: uEmail } : {}),\n ...(uMeta ? { metadata: uMeta } : {}),\n ...body?.metadata?.product_user\n };\n\n const merged = {\n ...(extId ? { external_user_id: extId } : {}),\n ...(prodUserId ? { product_end_user_id: prodUserId } : {}),\n ...(aId ? { app_id: aId } : {}),\n ...(Object.keys(productUser).length > 0 ? { product_user: productUser } : {}),\n ...this.defaultMetadata,\n ...body?.metadata\n };\n\n return Object.keys(merged).length > 0 ? merged : undefined;\n };\n\n const originalCreate = this.chat.completions.create.bind(this.chat.completions);\n\n this.chat.completions.create = ((body: any, requestOptions?: any) => {\n const mergedMetadata = buildMetadata(body);\n const updatedBody = {\n ...body,\n ...(mergedMetadata ? { metadata: mergedMetadata } : {})\n };\n\n return originalCreate(updatedBody, requestOptions);\n }) as any;\n\n if (this.responses && typeof (this.responses as any).create === \"function\") {\n const originalResponsesCreate = (this.responses as any).create.bind(this.responses);\n\n (this.responses as any).create = ((body: any, requestOptions?: any) => {\n const mergedMetadata = buildMetadata(body);\n const updatedBody = {\n ...body,\n ...(mergedMetadata ? { metadata: mergedMetadata } : {})\n };\n\n return originalResponsesCreate(updatedBody, requestOptions);\n }) as any;\n }\n }\n}\n","import type { ProductUserAllowanceInsufficientParams } from \"../types/product-users\";\n\n/**\n * Base class for all Zorveus SDK errors.\n */\nexport class ZorveusError extends Error {\n readonly status?: number;\n readonly code?: string;\n readonly param?: string;\n readonly type?: string;\n readonly params?: Record<string, unknown>;\n readonly headers?: Record<string, string>;\n readonly rawBody?: unknown;\n\n constructor(\n message: string,\n options: {\n status?: number;\n code?: string;\n param?: string;\n type?: string;\n params?: Record<string, unknown>;\n headers?: Record<string, string>;\n rawBody?: unknown;\n cause?: unknown;\n } = {}\n ) {\n super(message);\n this.name = \"ZorveusError\";\n this.status = options.status;\n this.code = options.code;\n this.param = options.param;\n this.type = options.type;\n this.params = options.params;\n this.headers = options.headers;\n this.rawBody = options.rawBody;\n if (options.cause) {\n this.cause = options.cause;\n }\n\n // Restore prototype chain\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/**\n * Thrown when an HTTP request fails before receiving a response (network drops, DNS failures, aborts/timeouts).\n */\nexport class APIConnectionError extends ZorveusError {\n constructor(message = \"Connection to Zorveus API failed\", options: { cause?: unknown } = {}) {\n super(message, options);\n this.name = \"APIConnectionError\";\n if (options.cause) {\n this.cause = options.cause;\n }\n }\n}\n\n/**\n * Base class for all HTTP 4xx and 5xx responses from the Zorveus API.\n */\nexport class APIStatusError extends ZorveusError {\n constructor(\n message: string,\n options: {\n status: number;\n code?: string;\n param?: string;\n type?: string;\n params?: Record<string, unknown>;\n headers?: Record<string, string>;\n rawBody?: unknown;\n }\n ) {\n super(message, options);\n this.name = \"APIStatusError\";\n }\n}\n\n/**\n * HTTP 401: Invalid or expired API key, Service key, or OAuth access token.\n */\nexport class AuthenticationError extends APIStatusError {\n constructor(message = \"Invalid or expired Zorveus credentials\", options: Omit<ConstructorParameters<typeof APIStatusError>[1], \"status\"> & { status?: number } = {}) {\n super(message, { ...options, status: options.status ?? 401 });\n this.name = \"AuthenticationError\";\n }\n}\n\n/**\n * HTTP 403: Forbidden access, insufficient scope, or model not permitted.\n */\nexport class PermissionDeniedError extends APIStatusError {\n constructor(message = \"Permission denied for this operation or model\", options: Omit<ConstructorParameters<typeof APIStatusError>[1], \"status\"> & { status?: number } = {}) {\n super(message, { ...options, status: options.status ?? 403 });\n this.name = \"PermissionDeniedError\";\n }\n}\n\n/**\n * HTTP 404: Requested resource (app, user, credential, model) was not found.\n */\nexport class NotFoundError extends APIStatusError {\n constructor(message = \"Resource not found\", options: Omit<ConstructorParameters<typeof APIStatusError>[1], \"status\"> & { status?: number } = {}) {\n super(message, { ...options, status: options.status ?? 404 });\n this.name = \"NotFoundError\";\n }\n}\n\n/**\n * HTTP 422: Request schema validation failure.\n */\nexport class UnprocessableEntityError extends APIStatusError {\n constructor(message = \"Request validation failed\", options: Omit<ConstructorParameters<typeof APIStatusError>[1], \"status\"> & { status?: number } = {}) {\n super(message, { ...options, status: options.status ?? 422 });\n this.name = \"UnprocessableEntityError\";\n }\n}\n\n/**\n * HTTP 429: Rate limit exceeded or quota exhausted.\n */\nexport class RateLimitError extends APIStatusError {\n constructor(message = \"Rate limit exceeded. Please retry after some time.\", options: Omit<ConstructorParameters<typeof APIStatusError>[1], \"status\"> & { status?: number } = {}) {\n super(message, { ...options, status: options.status ?? 429 });\n this.name = \"RateLimitError\";\n }\n}\n\n/**\n * HTTP 500, 502, 503, 504: Zorveus internal server or upstream gateway error.\n */\nexport class InternalServerError extends APIStatusError {\n constructor(message = \"Zorveus internal server error\", options: Omit<ConstructorParameters<typeof APIStatusError>[1], \"status\"> & { status?: number } = {}) {\n super(message, { ...options, status: options.status ?? 500 });\n this.name = \"InternalServerError\";\n }\n}\n\n/**\n * Base class for Zorveus financial and business constraint errors.\n */\nexport class ZorveusBusinessError extends APIStatusError {\n constructor(\n message: string,\n options: {\n status: number;\n code?: string;\n param?: string;\n type?: string;\n params?: Record<string, unknown>;\n headers?: Record<string, string>;\n rawBody?: unknown;\n }\n ) {\n super(message, options);\n this.name = \"ZorveusBusinessError\";\n }\n}\n\n/**\n * HTTP 402: Organization wallet balance is exhausted or insufficient for estimated charge/fee.\n */\nexport class InsufficientFundsError extends ZorveusBusinessError {\n constructor(\n message = \"Wallet balance exhausted. Top up required.\",\n options: Omit<ConstructorParameters<typeof ZorveusBusinessError>[1], \"status\"> & { status?: number } = {}\n ) {\n super(message, {\n ...options,\n status: options.status ?? 402,\n code: options.code ?? \"zorveus_reservation_insufficient_balance\"\n });\n this.name = \"InsufficientFundsError\";\n }\n}\n\n/**\n * HTTP 403: Spending cap limit reached for inference key or member.\n */\nexport class CapExceededError extends ZorveusBusinessError {\n constructor(\n message = \"Spending cap limit reached\",\n options: Omit<ConstructorParameters<typeof ZorveusBusinessError>[1], \"status\"> & { status?: number } = {}\n ) {\n super(message, {\n ...options,\n status: options.status ?? 403,\n code: options.code ?? \"zorveus_cap_exceeded\"\n });\n this.name = \"CapExceededError\";\n }\n}\n\n/**\n * HTTP 403: Enforced AI allowance exhausted for a product user on an inference key.\n * Contains shortfall and breakdown between base cap and promotional credits.\n */\nexport class ProductUserAllowanceInsufficientError extends ZorveusBusinessError {\n declare readonly params?: ProductUserAllowanceInsufficientParams;\n\n constructor(\n message = \"Product user AI allowance is insufficient for this request.\",\n options: Omit<ConstructorParameters<typeof ZorveusBusinessError>[1], \"status\"> & {\n status?: number;\n params?: ProductUserAllowanceInsufficientParams;\n } = {}\n ) {\n super(message, {\n ...options,\n status: options.status ?? 403,\n code: options.code ?? \"zorveus_product_user_allowance_insufficient\",\n params: options.params\n });\n this.name = \"ProductUserAllowanceInsufficientError\";\n }\n}\n\n/**\n * HTTP 403: Product user credit grant has expired.\n */\nexport class CreditGrantExpiredError extends ZorveusBusinessError {\n constructor(\n message = \"Product user credit grant has expired\",\n options: Omit<ConstructorParameters<typeof ZorveusBusinessError>[1], \"status\"> & { status?: number } = {}\n ) {\n super(message, {\n ...options,\n status: options.status ?? 403,\n code: options.code ?? \"credit_grant_expired\"\n });\n this.name = \"CreditGrantExpiredError\";\n }\n}\n\n/**\n * HTTP 403: Supplied inference key or connected app is invalid or revoked.\n */\nexport class AppConnectionNotFoundError extends ZorveusBusinessError {\n constructor(\n message = \"Inference key or app connection not found or revoked\",\n options: Omit<ConstructorParameters<typeof ZorveusBusinessError>[1], \"status\"> & { status?: number } = {}\n ) {\n super(message, {\n ...options,\n status: options.status ?? 403,\n code: options.code ?? \"zorveus_app_connection_not_found\"\n });\n this.name = \"AppConnectionNotFoundError\";\n }\n}\n\n/**\n * HTTP 409: Idempotency key reused with mismatched request parameters.\n */\nexport class ReservationConflictError extends ZorveusBusinessError {\n constructor(\n message = \"Idempotency key reused with conflicting request parameters\",\n options: Omit<ConstructorParameters<typeof ZorveusBusinessError>[1], \"status\"> & { status?: number } = {}\n ) {\n super(message, {\n ...options,\n status: options.status ?? 409,\n code: options.code ?? \"zorveus_reservation_conflict\"\n });\n this.name = \"ReservationConflictError\";\n }\n}\n\n/**\n * Factory that parses HTTP status code and response payload into the most specific ZorveusError subclass.\n */\nexport function createAPIError(\n status: number,\n body: unknown,\n headers?: Record<string, string>\n): APIStatusError {\n let message = `Request failed with status ${status}`;\n let code: string | undefined;\n let param: string | undefined;\n let type: string | undefined;\n let params: Record<string, unknown> | undefined;\n\n // Normalize string error bodies (including single-quoted Python dict strings)\n let parsedBody: unknown = body;\n if (typeof body === \"string\") {\n try {\n parsedBody = JSON.parse(body);\n } catch {\n try {\n parsedBody = JSON.parse(body.replace(/'/g, '\"'));\n } catch {\n const codeMatch = body.match(/['\"]code['\"]\\s*:\\s*['\"]([^'\"]+)['\"]/);\n const msgMatch = body.match(/['\"]message['\"]\\s*:\\s*['\"]([^'\"]+)['\"]/);\n if (msgMatch?.[1]) message = msgMatch[1];\n if (codeMatch?.[1]) code = codeMatch[1];\n }\n }\n }\n\n // Extract structured error details if available\n if (parsedBody && typeof parsedBody === \"object\") {\n const obj = parsedBody as Record<string, unknown>;\n\n // Check OpenAI-compatible gateway wrapper: provider_specific_fields.error or error.provider_specific_fields.error\n const providerFields = (\n obj.provider_specific_fields ??\n (obj.error as Record<string, unknown> | undefined)?.provider_specific_fields\n ) as Record<string, unknown> | undefined;\n const nestedGatewayError = (providerFields?.error ?? providerFields) as Record<string, unknown> | undefined;\n\n if (nestedGatewayError && typeof nestedGatewayError === \"object\") {\n if (typeof nestedGatewayError.message === \"string\") message = nestedGatewayError.message;\n if (typeof nestedGatewayError.code === \"string\") code = nestedGatewayError.code;\n if (typeof nestedGatewayError.param === \"string\") param = nestedGatewayError.param;\n if (typeof nestedGatewayError.type === \"string\") type = nestedGatewayError.type;\n if (nestedGatewayError.params && typeof nestedGatewayError.params === \"object\") {\n params = nestedGatewayError.params as Record<string, unknown>;\n }\n } else if (obj.error && typeof obj.error === \"object\") {\n const err = obj.error as Record<string, unknown>;\n if (typeof err.message === \"string\") message = err.message;\n if (typeof err.code === \"string\") code = err.code;\n if (typeof err.param === \"string\") param = err.param;\n if (typeof err.type === \"string\") type = err.type;\n if (err.params && typeof err.params === \"object\") {\n params = err.params as Record<string, unknown>;\n }\n } else {\n if (typeof obj.message === \"string\") message = obj.message;\n if (typeof obj.code === \"string\") code = obj.code;\n if (typeof obj.param === \"string\") param = obj.param;\n if (typeof obj.type === \"string\") type = obj.type;\n if (obj.params && typeof obj.params === \"object\") {\n params = obj.params as Record<string, unknown>;\n }\n if (typeof obj.detail === \"string\") {\n message = obj.detail;\n } else if (Array.isArray(obj.detail) && obj.detail.length > 0) {\n const first = obj.detail[0];\n if (first && typeof first.msg === \"string\") {\n message = first.msg;\n }\n }\n }\n }\n\n const options = { status, code, param, type, params, headers, rawBody: body };\n const normalizedCode = (code || \"\").toLowerCase();\n\n // 1. Enforced product-user allowance denial (HTTP 403)\n if (\n normalizedCode === \"zorveus_product_user_allowance_insufficient\" ||\n normalizedCode === \"zorveus_product_user_credits_insufficient\" ||\n normalizedCode.includes(\"allowance_insufficient\") ||\n normalizedCode.includes(\"credits_insufficient\") ||\n message.toLowerCase().includes(\"allowance remaining\")\n ) {\n return new ProductUserAllowanceInsufficientError(message, {\n ...options,\n status: status === 200 ? 403 : status,\n params: params as ProductUserAllowanceInsufficientParams | undefined\n });\n }\n\n // 2. Spending cap exceeded (HTTP 403)\n if (\n normalizedCode === \"zorveus_cap_exceeded\" ||\n normalizedCode.includes(\"cap_exceed\") ||\n normalizedCode.includes(\"spend_cap\") ||\n message.toLowerCase().includes(\"spending cap\")\n ) {\n return new CapExceededError(message, options);\n }\n\n // 3. App connection not found / revoked (HTTP 403)\n if (\n normalizedCode === \"zorveus_app_connection_not_found\" ||\n normalizedCode.includes(\"app_connection_not_found\")\n ) {\n return new AppConnectionNotFoundError(message, options);\n }\n\n // 4. Idempotency reservation conflict (HTTP 409)\n if (\n status === 409 ||\n normalizedCode === \"zorveus_reservation_conflict\" ||\n normalizedCode.includes(\"reservation_conflict\")\n ) {\n return new ReservationConflictError(message, options);\n }\n\n // 5. Wallet insufficient balance (HTTP 402)\n if (\n status === 402 ||\n normalizedCode === \"zorveus_reservation_insufficient_balance\" ||\n normalizedCode.includes(\"insufficient_funds\") ||\n normalizedCode.includes(\"balance_exhausted\") ||\n normalizedCode.includes(\"insufficient_balance\") ||\n normalizedCode.includes(\"wallet_empty\") ||\n message.toLowerCase().includes(\"insufficient funds\") ||\n message.toLowerCase().includes(\"balance exhausted\") ||\n message.toLowerCase().includes(\"wallet is empty\")\n ) {\n return new InsufficientFundsError(message, options);\n }\n\n // 6. Expired credit grant (HTTP 403)\n if (normalizedCode.includes(\"grant_expired\")) {\n return new CreditGrantExpiredError(message, options);\n }\n\n // Status code based fallback mapping\n if (status === 401) {\n return new AuthenticationError(message, options);\n }\n\n if (status === 403) {\n return new PermissionDeniedError(message, options);\n }\n\n if (status === 404) {\n return new NotFoundError(message, options);\n }\n\n if (status === 422) {\n return new UnprocessableEntityError(message, options);\n }\n\n if (status === 429) {\n return new RateLimitError(message, options);\n }\n\n if (status >= 500) {\n return new InternalServerError(message, options);\n }\n\n return new APIStatusError(message, options);\n}\n\n/**\n * Parses errors thrown by OpenAI SDK or Vercel AI SDK into typed Zorveus errors.\n */\nexport function parseZorveusGatewayError(error: unknown): ZorveusError | unknown {\n if (error instanceof ZorveusError) {\n return error;\n }\n\n if (!error || typeof error !== \"object\") {\n return error;\n }\n\n const errObj = error as Record<string, unknown>;\n const status =\n typeof errObj.status === \"number\"\n ? errObj.status\n : typeof errObj.statusCode === \"number\"\n ? errObj.statusCode\n : undefined;\n\n const rawBody = errObj.error ?? errObj.body ?? errObj.rawBody;\n if (status !== undefined && rawBody !== undefined) {\n const headers =\n errObj.headers && typeof errObj.headers === \"object\"\n ? (errObj.headers as Record<string, string>)\n : undefined;\n return createAPIError(status, rawBody, headers);\n }\n\n return error;\n}\n\n"],"mappings":"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","names":["OpenAI"]}
|