@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.
Files changed (105) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +274 -2
  3. package/dist/activity-tracker.d.ts +113 -0
  4. package/dist/activity-tracker.d.ts.map +1 -0
  5. package/dist/activity-tracker.js +176 -0
  6. package/dist/activity-tracker.js.map +1 -0
  7. package/dist/audio.d.ts +129 -0
  8. package/dist/audio.d.ts.map +1 -0
  9. package/dist/audio.js +267 -0
  10. package/dist/audio.js.map +1 -0
  11. package/dist/browser-auth.d.ts +179 -0
  12. package/dist/browser-auth.d.ts.map +1 -0
  13. package/dist/browser-auth.js +1361 -0
  14. package/dist/browser-auth.js.map +1 -0
  15. package/dist/chat.d.ts +221 -0
  16. package/dist/chat.d.ts.map +1 -0
  17. package/dist/chat.js +155 -0
  18. package/dist/chat.js.map +1 -0
  19. package/dist/client.d.ts +155 -0
  20. package/dist/client.d.ts.map +1 -0
  21. package/dist/client.js +157 -0
  22. package/dist/client.js.map +1 -0
  23. package/dist/computer.d.ts +57 -0
  24. package/dist/computer.d.ts.map +1 -0
  25. package/dist/computer.js +21 -0
  26. package/dist/computer.js.map +1 -0
  27. package/dist/embeddings.d.ts +64 -0
  28. package/dist/embeddings.d.ts.map +1 -0
  29. package/dist/embeddings.js +30 -0
  30. package/dist/embeddings.js.map +1 -0
  31. package/dist/errors.d.ts +24 -0
  32. package/dist/errors.d.ts.map +1 -0
  33. package/dist/errors.js +29 -0
  34. package/dist/errors.js.map +1 -0
  35. package/dist/event-wrap.d.ts +59 -0
  36. package/dist/event-wrap.d.ts.map +1 -0
  37. package/dist/event-wrap.js +142 -0
  38. package/dist/event-wrap.js.map +1 -0
  39. package/dist/events.d.ts +119 -0
  40. package/dist/events.d.ts.map +1 -0
  41. package/dist/events.js +87 -0
  42. package/dist/events.js.map +1 -0
  43. package/dist/files.d.ts +218 -0
  44. package/dist/files.d.ts.map +1 -0
  45. package/dist/files.js +212 -0
  46. package/dist/files.js.map +1 -0
  47. package/dist/image.d.ts +185 -0
  48. package/dist/image.d.ts.map +1 -0
  49. package/dist/image.js +148 -0
  50. package/dist/image.js.map +1 -0
  51. package/dist/index.d.ts +30 -0
  52. package/dist/index.d.ts.map +1 -0
  53. package/dist/index.js +26 -0
  54. package/dist/index.js.map +1 -0
  55. package/dist/media.d.ts +56 -0
  56. package/dist/media.d.ts.map +1 -0
  57. package/dist/media.js +133 -0
  58. package/dist/media.js.map +1 -0
  59. package/dist/model_options.d.ts +165 -0
  60. package/dist/model_options.d.ts.map +1 -0
  61. package/dist/model_options.js +59 -0
  62. package/dist/model_options.js.map +1 -0
  63. package/dist/models.d.ts +88 -0
  64. package/dist/models.d.ts.map +1 -0
  65. package/dist/models.js +55 -0
  66. package/dist/models.js.map +1 -0
  67. package/dist/sdk.umd.js +4 -0
  68. package/dist/sdk.umd.js.map +1 -0
  69. package/dist/transport.d.ts +120 -0
  70. package/dist/transport.d.ts.map +1 -0
  71. package/dist/transport.js +214 -0
  72. package/dist/transport.js.map +1 -0
  73. package/dist/types.d.ts +31 -0
  74. package/dist/types.d.ts.map +1 -0
  75. package/dist/types.js +2 -0
  76. package/dist/types.js.map +1 -0
  77. package/dist/validate.d.ts +16 -0
  78. package/dist/validate.d.ts.map +1 -0
  79. package/dist/validate.js +329 -0
  80. package/dist/validate.js.map +1 -0
  81. package/dist/video.d.ts +134 -0
  82. package/dist/video.d.ts.map +1 -0
  83. package/dist/video.js +60 -0
  84. package/dist/video.js.map +1 -0
  85. package/package.json +54 -4
  86. package/src/activity-tracker.ts +251 -0
  87. package/src/audio.ts +440 -0
  88. package/src/browser-auth.ts +1529 -0
  89. package/src/chat.ts +368 -0
  90. package/src/client.ts +250 -0
  91. package/src/computer.ts +80 -0
  92. package/src/embeddings.ts +97 -0
  93. package/src/errors.ts +29 -0
  94. package/src/event-wrap.ts +168 -0
  95. package/src/events.ts +172 -0
  96. package/src/files.ts +347 -0
  97. package/src/image.ts +339 -0
  98. package/src/index.ts +151 -0
  99. package/src/media.ts +147 -0
  100. package/src/model_options.ts +220 -0
  101. package/src/models.ts +121 -0
  102. package/src/transport.ts +292 -0
  103. package/src/types.ts +31 -0
  104. package/src/validate.ts +364 -0
  105. 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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"}
@@ -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,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -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"}