@runappsai/sdk 0.0.0-stage → 0.3.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/LICENSE +21 -0
- package/README.md +274 -2
- package/dist/activity-tracker.d.ts +113 -0
- package/dist/activity-tracker.d.ts.map +1 -0
- package/dist/activity-tracker.js +176 -0
- package/dist/activity-tracker.js.map +1 -0
- package/dist/audio.d.ts +129 -0
- package/dist/audio.d.ts.map +1 -0
- package/dist/audio.js +267 -0
- package/dist/audio.js.map +1 -0
- package/dist/browser-auth.d.ts +179 -0
- package/dist/browser-auth.d.ts.map +1 -0
- package/dist/browser-auth.js +1361 -0
- package/dist/browser-auth.js.map +1 -0
- package/dist/chat.d.ts +221 -0
- package/dist/chat.d.ts.map +1 -0
- package/dist/chat.js +155 -0
- package/dist/chat.js.map +1 -0
- package/dist/client.d.ts +155 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +157 -0
- package/dist/client.js.map +1 -0
- package/dist/computer.d.ts +57 -0
- package/dist/computer.d.ts.map +1 -0
- package/dist/computer.js +21 -0
- package/dist/computer.js.map +1 -0
- package/dist/embeddings.d.ts +64 -0
- package/dist/embeddings.d.ts.map +1 -0
- package/dist/embeddings.js +30 -0
- package/dist/embeddings.js.map +1 -0
- package/dist/errors.d.ts +24 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +29 -0
- package/dist/errors.js.map +1 -0
- package/dist/event-wrap.d.ts +59 -0
- package/dist/event-wrap.d.ts.map +1 -0
- package/dist/event-wrap.js +142 -0
- package/dist/event-wrap.js.map +1 -0
- package/dist/events.d.ts +119 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +87 -0
- package/dist/events.js.map +1 -0
- package/dist/files.d.ts +218 -0
- package/dist/files.d.ts.map +1 -0
- package/dist/files.js +212 -0
- package/dist/files.js.map +1 -0
- package/dist/image.d.ts +185 -0
- package/dist/image.d.ts.map +1 -0
- package/dist/image.js +148 -0
- package/dist/image.js.map +1 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +26 -0
- package/dist/index.js.map +1 -0
- package/dist/media.d.ts +56 -0
- package/dist/media.d.ts.map +1 -0
- package/dist/media.js +133 -0
- package/dist/media.js.map +1 -0
- package/dist/model_options.d.ts +165 -0
- package/dist/model_options.d.ts.map +1 -0
- package/dist/model_options.js +59 -0
- package/dist/model_options.js.map +1 -0
- package/dist/models.d.ts +88 -0
- package/dist/models.d.ts.map +1 -0
- package/dist/models.js +55 -0
- package/dist/models.js.map +1 -0
- package/dist/sdk.umd.js +4 -0
- package/dist/sdk.umd.js.map +1 -0
- package/dist/transport.d.ts +120 -0
- package/dist/transport.d.ts.map +1 -0
- package/dist/transport.js +214 -0
- package/dist/transport.js.map +1 -0
- package/dist/types.d.ts +31 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/validate.d.ts +16 -0
- package/dist/validate.d.ts.map +1 -0
- package/dist/validate.js +329 -0
- package/dist/validate.js.map +1 -0
- package/dist/video.d.ts +134 -0
- package/dist/video.d.ts.map +1 -0
- package/dist/video.js +60 -0
- package/dist/video.js.map +1 -0
- package/package.json +54 -4
- package/src/activity-tracker.ts +251 -0
- package/src/audio.ts +440 -0
- package/src/browser-auth.ts +1529 -0
- package/src/chat.ts +368 -0
- package/src/client.ts +250 -0
- package/src/computer.ts +80 -0
- package/src/embeddings.ts +97 -0
- package/src/errors.ts +29 -0
- package/src/event-wrap.ts +168 -0
- package/src/events.ts +172 -0
- package/src/files.ts +347 -0
- package/src/image.ts +339 -0
- package/src/index.ts +151 -0
- package/src/media.ts +147 -0
- package/src/model_options.ts +220 -0
- package/src/models.ts +121 -0
- package/src/transport.ts +292 -0
- package/src/types.ts +31 -0
- package/src/validate.ts +364 -0
- package/src/video.ts +215 -0
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internal — shared HTTP transport used by every service. Not part of the
|
|
3
|
+
* public API; do not import from outside `src/`.
|
|
4
|
+
*
|
|
5
|
+
* Uses the global `fetch` (Node 18+ / browsers / Deno / Bun all ship it).
|
|
6
|
+
* Errors from the gateway (status >= 400) are parsed and surfaced as
|
|
7
|
+
* `APIError`. Network errors propagate as the underlying fetch reject.
|
|
8
|
+
*/
|
|
9
|
+
export interface TransportOptions {
|
|
10
|
+
baseURL: string;
|
|
11
|
+
/** Static bearer token. Required unless `apiKeyResolver` is supplied. */
|
|
12
|
+
apiKey?: string;
|
|
13
|
+
/** Dynamic resolver — called immediately before each request. Use this
|
|
14
|
+
* when the token is short-lived and refreshed externally (e.g. running
|
|
15
|
+
* inside a runjobs resource bundle that exposes
|
|
16
|
+
* `window.runjobs.getToken()`). The result is awaited per request, so
|
|
17
|
+
* the caller can return a Promise that hits a token endpoint. Wins
|
|
18
|
+
* over `apiKey` when both are supplied. */
|
|
19
|
+
apiKeyResolver?: () => string | Promise<string>;
|
|
20
|
+
/**
|
|
21
|
+
* Hook invoked on 401 responses, *before* the request is automatically
|
|
22
|
+
* retried once. Use this to invalidate any cached token so the next
|
|
23
|
+
* `apiKeyResolver` call fetches a fresh one. Throwing here cancels
|
|
24
|
+
* the retry — the original 401 propagates.
|
|
25
|
+
*
|
|
26
|
+
* Typical wiring (browser-auth):
|
|
27
|
+
* onUnauthorized: () => auth.invalidate()
|
|
28
|
+
* which clears the in-memory + persisted token without flipping the
|
|
29
|
+
* sticky "signed out" flag. The retry's resolveToken() then triggers
|
|
30
|
+
* the standard signIn() redirect-grant flow.
|
|
31
|
+
*/
|
|
32
|
+
onUnauthorized?: () => void | Promise<void>;
|
|
33
|
+
/** Optional fetch override (e.g. node-fetch with custom agent). */
|
|
34
|
+
fetchImpl?: typeof fetch;
|
|
35
|
+
}
|
|
36
|
+
export declare class Transport {
|
|
37
|
+
readonly baseURL: string;
|
|
38
|
+
private readonly apiKey;
|
|
39
|
+
private readonly apiKeyResolver;
|
|
40
|
+
private readonly onUnauthorized;
|
|
41
|
+
private readonly fetchImpl;
|
|
42
|
+
constructor(opts: TransportOptions);
|
|
43
|
+
/** Resolve the bearer token for the next request. */
|
|
44
|
+
private resolveToken;
|
|
45
|
+
/**
|
|
46
|
+
* Wrap a fetch call with single-attempt 401 retry. `build` produces a
|
|
47
|
+
* fresh RequestInit each call (so headers can re-resolve a fresh token,
|
|
48
|
+
* and bodies can be re-streamed for retry). On 401, invokes
|
|
49
|
+
* `onUnauthorized()` (giving the caller a chance to invalidate cached
|
|
50
|
+
* auth state) then retries once with a fresh init. No retry if
|
|
51
|
+
* `onUnauthorized` is absent or already retried.
|
|
52
|
+
*/
|
|
53
|
+
private fetchWithAuthRetry;
|
|
54
|
+
/**
|
|
55
|
+
* Every request goes out uncacheable.
|
|
56
|
+
*
|
|
57
|
+
* Our identity lives in the Authorization header, never in the URL — so
|
|
58
|
+
* two different apps calling e.g. `/v1/files/projects/index.json` hit the
|
|
59
|
+
* *same* URL with different tokens. The browser's HTTP cache doesn't key
|
|
60
|
+
* on request headers, and it is partitioned by the top-level registrable
|
|
61
|
+
* domain, which every `*.runapps.dev` bundle shares. One cacheable
|
|
62
|
+
* response was therefore enough for app A to read app B's file and then
|
|
63
|
+
* save it back as its own. The server no longer marks these cacheable;
|
|
64
|
+
* this is the client-side half of that fix, and it also protects bundles
|
|
65
|
+
* pinned to an older backend.
|
|
66
|
+
*/
|
|
67
|
+
private buildInit;
|
|
68
|
+
/** POST JSON body; parse JSON response. */
|
|
69
|
+
postJSON<T>(path: string, body: unknown, init?: {
|
|
70
|
+
signal?: AbortSignal;
|
|
71
|
+
}): Promise<T>;
|
|
72
|
+
/** GET path; parse JSON response. */
|
|
73
|
+
getJSON<T>(path: string, init?: {
|
|
74
|
+
signal?: AbortSignal;
|
|
75
|
+
}): Promise<T>;
|
|
76
|
+
/** GET path; return raw bytes + content-type (for video/audio downloads)
|
|
77
|
+
* and the ETag of those bytes, when the server sends one. */
|
|
78
|
+
getRaw(path: string, init?: {
|
|
79
|
+
signal?: AbortSignal;
|
|
80
|
+
}): Promise<{
|
|
81
|
+
data: Uint8Array;
|
|
82
|
+
contentType: string;
|
|
83
|
+
etag?: string;
|
|
84
|
+
}>;
|
|
85
|
+
/** POST a multipart/form-data body. Used by audio.transcribe and image.edit. */
|
|
86
|
+
postMultipart<T>(path: string, form: FormData, init?: {
|
|
87
|
+
signal?: AbortSignal;
|
|
88
|
+
}): Promise<T>;
|
|
89
|
+
/**
|
|
90
|
+
* POST JSON body; return the raw streaming Response. Used by chat
|
|
91
|
+
* streaming. Caller is responsible for consuming the SSE body.
|
|
92
|
+
*/
|
|
93
|
+
postJSONStream(path: string, body: unknown, init?: {
|
|
94
|
+
signal?: AbortSignal;
|
|
95
|
+
}): Promise<Response>;
|
|
96
|
+
/** PUT raw bytes with caller-supplied content type and headers. */
|
|
97
|
+
putBytes<T>(path: string, body: BodyInit, opts?: {
|
|
98
|
+
contentType?: string;
|
|
99
|
+
headers?: Record<string, string>;
|
|
100
|
+
signal?: AbortSignal;
|
|
101
|
+
parse?: "json" | "none";
|
|
102
|
+
}): Promise<T>;
|
|
103
|
+
/** DELETE path; parse JSON response (or no body). */
|
|
104
|
+
deletePath<T>(path: string, init?: {
|
|
105
|
+
signal?: AbortSignal;
|
|
106
|
+
parse?: "json" | "none";
|
|
107
|
+
}): Promise<T>;
|
|
108
|
+
/** HEAD path; surface status + selected response headers. Used by
|
|
109
|
+
* exists / stat where the body would just be an opaque blob. */
|
|
110
|
+
head(path: string, init?: {
|
|
111
|
+
signal?: AbortSignal;
|
|
112
|
+
}): Promise<{
|
|
113
|
+
status: number;
|
|
114
|
+
headers: Headers;
|
|
115
|
+
}>;
|
|
116
|
+
private jsonHeaders;
|
|
117
|
+
private authHeaders;
|
|
118
|
+
private parseError;
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=transport.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import { APIError } from "./errors.js";
|
|
2
|
+
export class Transport {
|
|
3
|
+
baseURL;
|
|
4
|
+
apiKey;
|
|
5
|
+
apiKeyResolver;
|
|
6
|
+
onUnauthorized;
|
|
7
|
+
fetchImpl;
|
|
8
|
+
constructor(opts) {
|
|
9
|
+
if (!opts.apiKey && !opts.apiKeyResolver) {
|
|
10
|
+
throw new Error("RunApps: pass either `apiKey` or `apiKeyResolver` when constructing the client");
|
|
11
|
+
}
|
|
12
|
+
this.baseURL = opts.baseURL.replace(/\/+$/, "");
|
|
13
|
+
this.apiKey = opts.apiKey;
|
|
14
|
+
this.apiKeyResolver = opts.apiKeyResolver;
|
|
15
|
+
this.onUnauthorized = opts.onUnauthorized;
|
|
16
|
+
// Bind to globalThis when using the platform's native fetch.
|
|
17
|
+
// Without binding, `this.fetchImpl(...)` invokes with `this`
|
|
18
|
+
// pointing at the Transport instance, and the browser's
|
|
19
|
+
// `Window.fetch` rejects that with "Illegal invocation".
|
|
20
|
+
// Caller-supplied `fetchImpl` is used as-is — they're responsible
|
|
21
|
+
// for any binding their wrapper needs.
|
|
22
|
+
this.fetchImpl = opts.fetchImpl ?? fetch.bind(globalThis);
|
|
23
|
+
}
|
|
24
|
+
/** Resolve the bearer token for the next request. */
|
|
25
|
+
async resolveToken() {
|
|
26
|
+
if (this.apiKeyResolver)
|
|
27
|
+
return await this.apiKeyResolver();
|
|
28
|
+
return this.apiKey ?? "";
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Wrap a fetch call with single-attempt 401 retry. `build` produces a
|
|
32
|
+
* fresh RequestInit each call (so headers can re-resolve a fresh token,
|
|
33
|
+
* and bodies can be re-streamed for retry). On 401, invokes
|
|
34
|
+
* `onUnauthorized()` (giving the caller a chance to invalidate cached
|
|
35
|
+
* auth state) then retries once with a fresh init. No retry if
|
|
36
|
+
* `onUnauthorized` is absent or already retried.
|
|
37
|
+
*/
|
|
38
|
+
async fetchWithAuthRetry(path, build) {
|
|
39
|
+
const url = this.baseURL + path;
|
|
40
|
+
let resp = await this.fetchImpl(url, await this.buildInit(build));
|
|
41
|
+
if (resp.status !== 401 || !this.onUnauthorized)
|
|
42
|
+
return resp;
|
|
43
|
+
try {
|
|
44
|
+
await this.onUnauthorized();
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
// Hook bailed out — surface the original 401.
|
|
48
|
+
return resp;
|
|
49
|
+
}
|
|
50
|
+
resp = await this.fetchImpl(url, await this.buildInit(build));
|
|
51
|
+
return resp;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Every request goes out uncacheable.
|
|
55
|
+
*
|
|
56
|
+
* Our identity lives in the Authorization header, never in the URL — so
|
|
57
|
+
* two different apps calling e.g. `/v1/files/projects/index.json` hit the
|
|
58
|
+
* *same* URL with different tokens. The browser's HTTP cache doesn't key
|
|
59
|
+
* on request headers, and it is partitioned by the top-level registrable
|
|
60
|
+
* domain, which every `*.runapps.dev` bundle shares. One cacheable
|
|
61
|
+
* response was therefore enough for app A to read app B's file and then
|
|
62
|
+
* save it back as its own. The server no longer marks these cacheable;
|
|
63
|
+
* this is the client-side half of that fix, and it also protects bundles
|
|
64
|
+
* pinned to an older backend.
|
|
65
|
+
*/
|
|
66
|
+
async buildInit(build) {
|
|
67
|
+
const init = await build();
|
|
68
|
+
return init.cache ? init : { ...init, cache: "no-store" };
|
|
69
|
+
}
|
|
70
|
+
/** POST JSON body; parse JSON response. */
|
|
71
|
+
async postJSON(path, body, init) {
|
|
72
|
+
const resp = await this.fetchWithAuthRetry(path, async () => ({
|
|
73
|
+
method: "POST",
|
|
74
|
+
headers: await this.jsonHeaders(),
|
|
75
|
+
body: JSON.stringify(body),
|
|
76
|
+
signal: init?.signal,
|
|
77
|
+
}));
|
|
78
|
+
if (!resp.ok) {
|
|
79
|
+
throw await this.parseError(resp);
|
|
80
|
+
}
|
|
81
|
+
return (await resp.json());
|
|
82
|
+
}
|
|
83
|
+
/** GET path; parse JSON response. */
|
|
84
|
+
async getJSON(path, init) {
|
|
85
|
+
const resp = await this.fetchWithAuthRetry(path, async () => ({
|
|
86
|
+
method: "GET",
|
|
87
|
+
headers: await this.authHeaders(),
|
|
88
|
+
signal: init?.signal,
|
|
89
|
+
}));
|
|
90
|
+
if (!resp.ok) {
|
|
91
|
+
throw await this.parseError(resp);
|
|
92
|
+
}
|
|
93
|
+
return (await resp.json());
|
|
94
|
+
}
|
|
95
|
+
/** GET path; return raw bytes + content-type (for video/audio downloads)
|
|
96
|
+
* and the ETag of those bytes, when the server sends one. */
|
|
97
|
+
async getRaw(path, init) {
|
|
98
|
+
const resp = await this.fetchWithAuthRetry(path, async () => ({
|
|
99
|
+
method: "GET",
|
|
100
|
+
headers: await this.authHeaders(),
|
|
101
|
+
signal: init?.signal,
|
|
102
|
+
}));
|
|
103
|
+
if (!resp.ok) {
|
|
104
|
+
throw await this.parseError(resp);
|
|
105
|
+
}
|
|
106
|
+
const buf = new Uint8Array(await resp.arrayBuffer());
|
|
107
|
+
const contentType = resp.headers.get("content-type") ?? "";
|
|
108
|
+
const etag = (resp.headers.get("etag") ?? "").replace(/"/g, "") || undefined;
|
|
109
|
+
return { data: buf, contentType, etag };
|
|
110
|
+
}
|
|
111
|
+
/** POST a multipart/form-data body. Used by audio.transcribe and image.edit. */
|
|
112
|
+
async postMultipart(path, form, init) {
|
|
113
|
+
const resp = await this.fetchWithAuthRetry(path, async () => ({
|
|
114
|
+
method: "POST",
|
|
115
|
+
headers: await this.authHeaders(), // do NOT set Content-Type — fetch sets it with boundary
|
|
116
|
+
body: form,
|
|
117
|
+
signal: init?.signal,
|
|
118
|
+
}));
|
|
119
|
+
if (!resp.ok) {
|
|
120
|
+
throw await this.parseError(resp);
|
|
121
|
+
}
|
|
122
|
+
return (await resp.json());
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* POST JSON body; return the raw streaming Response. Used by chat
|
|
126
|
+
* streaming. Caller is responsible for consuming the SSE body.
|
|
127
|
+
*/
|
|
128
|
+
async postJSONStream(path, body, init) {
|
|
129
|
+
const resp = await this.fetchWithAuthRetry(path, async () => ({
|
|
130
|
+
method: "POST",
|
|
131
|
+
headers: {
|
|
132
|
+
...(await this.jsonHeaders()),
|
|
133
|
+
"Accept-Encoding": "identity", // SSE lines arrive immediately, no gzip
|
|
134
|
+
},
|
|
135
|
+
body: JSON.stringify(body),
|
|
136
|
+
signal: init?.signal,
|
|
137
|
+
}));
|
|
138
|
+
if (!resp.ok) {
|
|
139
|
+
throw await this.parseError(resp);
|
|
140
|
+
}
|
|
141
|
+
return resp;
|
|
142
|
+
}
|
|
143
|
+
/** PUT raw bytes with caller-supplied content type and headers. */
|
|
144
|
+
async putBytes(path, body, opts) {
|
|
145
|
+
const resp = await this.fetchWithAuthRetry(path, async () => {
|
|
146
|
+
const headers = {
|
|
147
|
+
...(await this.authHeaders()),
|
|
148
|
+
"Content-Type": opts?.contentType ?? "application/octet-stream",
|
|
149
|
+
};
|
|
150
|
+
if (opts?.headers)
|
|
151
|
+
Object.assign(headers, opts.headers);
|
|
152
|
+
return {
|
|
153
|
+
method: "PUT",
|
|
154
|
+
headers,
|
|
155
|
+
body,
|
|
156
|
+
signal: opts?.signal,
|
|
157
|
+
};
|
|
158
|
+
});
|
|
159
|
+
if (!resp.ok)
|
|
160
|
+
throw await this.parseError(resp);
|
|
161
|
+
if (opts?.parse === "none")
|
|
162
|
+
return undefined;
|
|
163
|
+
return (await resp.json());
|
|
164
|
+
}
|
|
165
|
+
/** DELETE path; parse JSON response (or no body). */
|
|
166
|
+
async deletePath(path, init) {
|
|
167
|
+
const resp = await this.fetchWithAuthRetry(path, async () => ({
|
|
168
|
+
method: "DELETE",
|
|
169
|
+
headers: await this.authHeaders(),
|
|
170
|
+
signal: init?.signal,
|
|
171
|
+
}));
|
|
172
|
+
if (!resp.ok)
|
|
173
|
+
throw await this.parseError(resp);
|
|
174
|
+
if (init?.parse === "none")
|
|
175
|
+
return undefined;
|
|
176
|
+
return (await resp.json());
|
|
177
|
+
}
|
|
178
|
+
/** HEAD path; surface status + selected response headers. Used by
|
|
179
|
+
* exists / stat where the body would just be an opaque blob. */
|
|
180
|
+
async head(path, init) {
|
|
181
|
+
const resp = await this.fetchWithAuthRetry(path, async () => ({
|
|
182
|
+
method: "HEAD",
|
|
183
|
+
headers: await this.authHeaders(),
|
|
184
|
+
signal: init?.signal,
|
|
185
|
+
}));
|
|
186
|
+
return { status: resp.status, headers: resp.headers };
|
|
187
|
+
}
|
|
188
|
+
async jsonHeaders() {
|
|
189
|
+
return {
|
|
190
|
+
"Content-Type": "application/json",
|
|
191
|
+
Authorization: `Bearer ${await this.resolveToken()}`,
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
async authHeaders() {
|
|
195
|
+
return { Authorization: `Bearer ${await this.resolveToken()}` };
|
|
196
|
+
}
|
|
197
|
+
async parseError(resp) {
|
|
198
|
+
const text = await resp.text();
|
|
199
|
+
let type = "error";
|
|
200
|
+
let message = text || resp.statusText;
|
|
201
|
+
try {
|
|
202
|
+
const parsed = JSON.parse(text);
|
|
203
|
+
if (parsed.type)
|
|
204
|
+
type = parsed.type;
|
|
205
|
+
if (parsed.message)
|
|
206
|
+
message = parsed.message;
|
|
207
|
+
}
|
|
208
|
+
catch {
|
|
209
|
+
// Body wasn't JSON — fall back to raw text.
|
|
210
|
+
}
|
|
211
|
+
return new APIError(resp.status, type, message);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
//# sourceMappingURL=transport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transport.js","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Usage carries token consumption and cost information returned with every
|
|
3
|
+
* gateway response. `total_cost` is the gateway's billing total in USD —
|
|
4
|
+
* always present, while token counts are only populated when the upstream
|
|
5
|
+
* provider surfaces them.
|
|
6
|
+
*
|
|
7
|
+
* For chat completions that invoked server-executed tools (via the
|
|
8
|
+
* `server_tools` field), `total_cost` includes BOTH the model's raw
|
|
9
|
+
* upstream cost (summed across iterations) AND the post-markup USD price
|
|
10
|
+
* of every tool invocation. The per-tool breakdown lives in `tool_costs`
|
|
11
|
+
* so callers can attribute charges without having to re-run the loop.
|
|
12
|
+
*/
|
|
13
|
+
export interface Usage {
|
|
14
|
+
prompt_tokens?: number;
|
|
15
|
+
completion_tokens?: number;
|
|
16
|
+
total_tokens?: number;
|
|
17
|
+
total_cost: number;
|
|
18
|
+
tool_costs?: ToolCost[];
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Per-tool spend for a single chat completion that used server-executed
|
|
22
|
+
* tools. `cost` is in USD and already post-markup — it matches the
|
|
23
|
+
* amount actually deducted from the user's balance for that tool's
|
|
24
|
+
* invocations during the request.
|
|
25
|
+
*/
|
|
26
|
+
export interface ToolCost {
|
|
27
|
+
name: string;
|
|
28
|
+
count: number;
|
|
29
|
+
cost: number;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,KAAK;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,QAAQ,EAAE,CAAC;CACzB;AAED;;;;;GAKG;AACH,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Schema } from "./model_options.js";
|
|
2
|
+
export interface ValidationError {
|
|
3
|
+
field: string;
|
|
4
|
+
reason: string;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Three-pass validator: per-field type/enum/bounds → per-field
|
|
8
|
+
* presence → cross-field constraints. Unknown fields in `req`
|
|
9
|
+
* (vendor passthroughs) are silently ignored — the gateway still
|
|
10
|
+
* validates them server-side if it cares.
|
|
11
|
+
*
|
|
12
|
+
* Returns an empty array on success, or a flat list of all
|
|
13
|
+
* validation failures so the UI can surface them at once.
|
|
14
|
+
*/
|
|
15
|
+
export declare function validateRequest(schema: Schema | null | undefined, req?: Record<string, unknown>): ValidationError[];
|
|
16
|
+
//# sourceMappingURL=validate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,MAAM,EAAkC,MAAM,oBAAoB,CAAC;AAEjF,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACjC,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAChC,eAAe,EAAE,CA8BnB"}
|