@openkeyai/sdk 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +52 -4
- package/dist/index.cjs +371 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +528 -10
- package/dist/index.d.ts +528 -10
- package/dist/index.js +366 -2
- package/dist/index.js.map +1 -1
- package/package.json +11 -10
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# `@openkeyai/sdk`
|
|
2
2
|
|
|
3
|
-
The SDK every [OpenKey AI](https://openkeyai.com) tool installs.
|
|
3
|
+
The SDK every [OpenKey AI](https://openkeyai.com) tool installs. JWT verification, the zero-trust API proxy, typed convenience methods for OpenAI / Anthropic / Replicate, and typed errors mirroring the hub's frozen error contract.
|
|
4
4
|
|
|
5
5
|
```bash
|
|
6
6
|
pnpm add @openkeyai/sdk
|
|
@@ -9,18 +9,66 @@ pnpm add @openkeyai/sdk
|
|
|
9
9
|
|
|
10
10
|
## Status
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
Surface defined in [`hub/docs/TOOL_SDK.md`](https://github.com/OpenKeyAI/hub/blob/main/docs/TOOL_SDK.md). Status by module in 0.2.0:
|
|
13
13
|
|
|
14
|
-
| Module | 0.
|
|
14
|
+
| Module | 0.2.0 | Notes |
|
|
15
15
|
|---|---|---|
|
|
16
16
|
| `session.verify` | ✅ | Uses the hub's JWKS endpoint |
|
|
17
|
-
| `
|
|
17
|
+
| `proxy.call / .callRaw / .callStream` | ✅ | Phase 19 zero-trust proxy — plaintext key never enters your Worker |
|
|
18
|
+
| `openai.{images,chat,embeddings,audio}` | ✅ | Typed convenience over the proxy |
|
|
19
|
+
| `anthropic.messages` | ✅ | Typed convenience over the proxy |
|
|
20
|
+
| `replicate.predictions` | ✅ | Typed convenience over the proxy |
|
|
21
|
+
| `keys.get` → `SecureKey` | ✅ | Kept for endpoints the proxy doesn't typeset yet |
|
|
18
22
|
| `user.profile` | ⏳ deferred | Needs hub to ship `/api/me` |
|
|
19
23
|
| `billing.status` | ⏳ deferred | Needs hub to ship `/api/billing/status` |
|
|
20
24
|
| `webhooks.handler` | ⏳ deferred | Lands with hub Phase 16 |
|
|
21
25
|
|
|
22
26
|
Deferred modules are simply absent from exports — your tool gets a TypeScript error if it tries to use them, not a runtime surprise.
|
|
23
27
|
|
|
28
|
+
## Which pattern should I use?
|
|
29
|
+
|
|
30
|
+
| You want to… | Use |
|
|
31
|
+
|---|---|
|
|
32
|
+
| Call a canonical model endpoint (OpenAI images, chat, Anthropic messages, Replicate predictions) | **Typed convenience** — `openai.images.generate(token, params)` etc. |
|
|
33
|
+
| Call any registered provider on any path / method we haven't typed yet | **Generic proxy** — `proxy.call(token, { provider, method, path, body })` |
|
|
34
|
+
| Get a binary response (TTS audio, image bytes) | `proxy.callRaw(...)` or `openai.audio.speech.create(...)` |
|
|
35
|
+
| Stream a response (chat SSE, chunked downloads) | `proxy.callStream(...)` or `openai.chat.completions.stream(...)` |
|
|
36
|
+
| Call a provider the hub doesn't route through yet, or run fine-tuning / batch / custom auth | `keys.get(token, provider)` + `SecureKey.use()` (legacy) |
|
|
37
|
+
|
|
38
|
+
**Default to the proxy.** The plaintext key never enters your tool process — every other consideration is downstream of that.
|
|
39
|
+
|
|
40
|
+
## Quick start — proxy pattern (recommended, Phase 19+)
|
|
41
|
+
|
|
42
|
+
```ts
|
|
43
|
+
import { session, openai, ProviderError, RateLimitedError, SubscriptionInactiveError } from "@openkeyai/sdk";
|
|
44
|
+
|
|
45
|
+
export async function handleRequest(req: Request) {
|
|
46
|
+
const jwt = req.headers.get("authorization")?.replace(/^Bearer\s+/i, "") ?? "";
|
|
47
|
+
|
|
48
|
+
const claims = await session.verify(jwt, {
|
|
49
|
+
hubUrl: "https://openkeyai.com",
|
|
50
|
+
expectedAudience: "tool-youtube-thumbnail-generator",
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
try {
|
|
54
|
+
const result = await openai.images.generate(jwt, {
|
|
55
|
+
model: "gpt-image-1",
|
|
56
|
+
prompt: "Vibrant YouTube thumbnail for a tech tutorial",
|
|
57
|
+
n: 4,
|
|
58
|
+
size: "1792x1024",
|
|
59
|
+
});
|
|
60
|
+
return Response.json({ images: result.data });
|
|
61
|
+
} catch (err) {
|
|
62
|
+
if (err instanceof SubscriptionInactiveError) return new Response("Paywall", { status: 402 });
|
|
63
|
+
if (err instanceof RateLimitedError) return new Response("Slow down", { status: 429, headers: { "retry-after": String(err.retryAfter) } });
|
|
64
|
+
if (err instanceof ProviderError) return Response.json({ openai_error: err.body }, { status: err.upstreamStatus });
|
|
65
|
+
throw err;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
The plaintext OpenAI key is fetched + injected + scrubbed entirely inside the hub's Worker. Your tool process never sees `sk-proj-…`.
|
|
71
|
+
|
|
24
72
|
## Quick start
|
|
25
73
|
|
|
26
74
|
A typical tool's request handler:
|
package/dist/index.cjs
CHANGED
|
@@ -119,6 +119,41 @@ var SecureKeyConsumedError = class extends HubSdkError {
|
|
|
119
119
|
this.name = "SecureKeyConsumedError";
|
|
120
120
|
}
|
|
121
121
|
};
|
|
122
|
+
var ProviderNotConfiguredError = class extends HubSdkError {
|
|
123
|
+
constructor(provider) {
|
|
124
|
+
super(
|
|
125
|
+
"provider_not_configured",
|
|
126
|
+
`Provider "${provider}" is not registered with the hub proxy. Available providers are listed at /api/proxy (coming) or in the hub's src/lib/proxy/providers.ts.`,
|
|
127
|
+
404
|
|
128
|
+
);
|
|
129
|
+
this.name = "ProviderNotConfiguredError";
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
var ProviderError = class extends HubSdkError {
|
|
133
|
+
/** The provider slug we tried to call. */
|
|
134
|
+
provider;
|
|
135
|
+
/** The path on the provider that returned non-2xx. */
|
|
136
|
+
path;
|
|
137
|
+
/**
|
|
138
|
+
* The upstream response body. Parsed as JSON when the upstream's
|
|
139
|
+
* content-type was JSON; raw text otherwise.
|
|
140
|
+
*/
|
|
141
|
+
body;
|
|
142
|
+
/** The upstream response status code (relayed unchanged). */
|
|
143
|
+
upstreamStatus;
|
|
144
|
+
constructor(provider, path, upstreamStatus, body) {
|
|
145
|
+
super(
|
|
146
|
+
"provider_error",
|
|
147
|
+
`${provider} ${path} returned ${upstreamStatus}.`,
|
|
148
|
+
upstreamStatus
|
|
149
|
+
);
|
|
150
|
+
this.name = "ProviderError";
|
|
151
|
+
this.provider = provider;
|
|
152
|
+
this.path = path;
|
|
153
|
+
this.upstreamStatus = upstreamStatus;
|
|
154
|
+
this.body = body;
|
|
155
|
+
}
|
|
156
|
+
};
|
|
122
157
|
function errorFromResponse(status, body, context) {
|
|
123
158
|
const code = body?.error ?? "internal";
|
|
124
159
|
switch (code) {
|
|
@@ -136,6 +171,8 @@ function errorFromResponse(status, body, context) {
|
|
|
136
171
|
return new NotSubscribedError();
|
|
137
172
|
case "provider_not_granted":
|
|
138
173
|
return new ProviderNotGrantedError(context.provider ?? "unknown");
|
|
174
|
+
case "provider_not_configured":
|
|
175
|
+
return new ProviderNotConfiguredError(context.provider ?? "unknown");
|
|
139
176
|
case "rate_limited":
|
|
140
177
|
return new RateLimitedError(context.retryAfter ?? 60);
|
|
141
178
|
case "key_not_found":
|
|
@@ -145,6 +182,25 @@ function errorFromResponse(status, body, context) {
|
|
|
145
182
|
return new InternalError(status);
|
|
146
183
|
}
|
|
147
184
|
}
|
|
185
|
+
function isHubErrorBody(body) {
|
|
186
|
+
if (typeof body !== "object" || body === null) return false;
|
|
187
|
+
const errorField = body.error;
|
|
188
|
+
if (typeof errorField !== "string") return false;
|
|
189
|
+
const knownCodes = [
|
|
190
|
+
"missing_token",
|
|
191
|
+
"bad_token",
|
|
192
|
+
"missing_scope",
|
|
193
|
+
"subscription_inactive",
|
|
194
|
+
"tool_not_found",
|
|
195
|
+
"not_subscribed",
|
|
196
|
+
"provider_not_granted",
|
|
197
|
+
"rate_limited",
|
|
198
|
+
"key_not_found",
|
|
199
|
+
"internal",
|
|
200
|
+
"provider_not_configured"
|
|
201
|
+
];
|
|
202
|
+
return knownCodes.includes(errorField);
|
|
203
|
+
}
|
|
148
204
|
var resolvers = /* @__PURE__ */ new Map();
|
|
149
205
|
function getJwksResolver(hubUrl) {
|
|
150
206
|
const cached = resolvers.get(hubUrl);
|
|
@@ -199,6 +255,7 @@ async function verify(jwt, opts = {}) {
|
|
|
199
255
|
const jti = payload.jti;
|
|
200
256
|
const iat = payload.iat;
|
|
201
257
|
const exp = payload.exp;
|
|
258
|
+
const rawMode = payload.mode;
|
|
202
259
|
if (typeof sub !== "string" || sub.length === 0) {
|
|
203
260
|
throw new BadTokenError("sub claim missing or invalid.");
|
|
204
261
|
}
|
|
@@ -217,12 +274,22 @@ async function verify(jwt, opts = {}) {
|
|
|
217
274
|
if (typeof iat !== "number" || typeof exp !== "number") {
|
|
218
275
|
throw new BadTokenError("iat / exp claims missing or invalid.");
|
|
219
276
|
}
|
|
277
|
+
const mode = typeof rawMode === "string" && (rawMode === "production" || rawMode === "owner_test") ? rawMode : rawMode === void 0 ? "production" : null;
|
|
278
|
+
if (mode === null) {
|
|
279
|
+
throw new BadTokenError(
|
|
280
|
+
`mode claim must be 'production' or 'owner_test' (got ${JSON.stringify(rawMode)}).`
|
|
281
|
+
);
|
|
282
|
+
}
|
|
283
|
+
const rawName = payload.name;
|
|
284
|
+
const name = typeof rawName === "string" && rawName.length > 0 ? rawName : void 0;
|
|
220
285
|
return {
|
|
221
286
|
iss: "https://openkeyai.com",
|
|
222
287
|
sub,
|
|
223
288
|
aud,
|
|
224
289
|
scopes,
|
|
225
290
|
subscription_active: subscriptionActive,
|
|
291
|
+
mode,
|
|
292
|
+
...name ? { name } : {},
|
|
226
293
|
iat,
|
|
227
294
|
exp,
|
|
228
295
|
jti
|
|
@@ -357,6 +424,298 @@ async function get(jwt, provider, opts = {}) {
|
|
|
357
424
|
});
|
|
358
425
|
}
|
|
359
426
|
|
|
427
|
+
// src/proxy.ts
|
|
428
|
+
var PROXY_PATH = "/api/proxy";
|
|
429
|
+
function ensureBearer(token) {
|
|
430
|
+
if (!token || typeof token !== "string") {
|
|
431
|
+
throw new BadTokenError("No JWT provided.");
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
function buildUrl(opts) {
|
|
435
|
+
if (!opts.provider) {
|
|
436
|
+
throw new BadTokenError("ProxyCallOptions.provider is required.");
|
|
437
|
+
}
|
|
438
|
+
if (!opts.path || !opts.path.startsWith("/")) {
|
|
439
|
+
throw new BadTokenError(
|
|
440
|
+
"ProxyCallOptions.path must start with '/' (e.g. '/v1/chat/completions')."
|
|
441
|
+
);
|
|
442
|
+
}
|
|
443
|
+
const hubUrl = opts.hubUrl ?? "https://openkeyai.com";
|
|
444
|
+
return new URL(
|
|
445
|
+
`${PROXY_PATH}/${encodeURIComponent(opts.provider)}${opts.path}`,
|
|
446
|
+
hubUrl
|
|
447
|
+
);
|
|
448
|
+
}
|
|
449
|
+
function buildRequestInit(token, opts) {
|
|
450
|
+
const headers = new Headers();
|
|
451
|
+
if (opts.headers) {
|
|
452
|
+
for (const [k, v] of Object.entries(opts.headers)) {
|
|
453
|
+
headers.set(k, v);
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
headers.set("authorization", `Bearer ${token}`);
|
|
457
|
+
let body;
|
|
458
|
+
if (opts.method === "GET" || opts.method === "DELETE" || opts.body == null) {
|
|
459
|
+
body = void 0;
|
|
460
|
+
} else if (typeof opts.body === "string" || opts.body instanceof Blob || opts.body instanceof FormData || opts.body instanceof ArrayBuffer || opts.body instanceof ReadableStream) {
|
|
461
|
+
body = opts.body;
|
|
462
|
+
} else {
|
|
463
|
+
body = JSON.stringify(opts.body);
|
|
464
|
+
if (!headers.has("content-type")) {
|
|
465
|
+
headers.set("content-type", "application/json");
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
if (!headers.has("accept")) {
|
|
469
|
+
headers.set("accept", "application/json");
|
|
470
|
+
}
|
|
471
|
+
return {
|
|
472
|
+
method: opts.method,
|
|
473
|
+
headers,
|
|
474
|
+
body,
|
|
475
|
+
signal: opts.signal,
|
|
476
|
+
// @ts-expect-error duplex is part of fetch's RequestInit on Workers + recent Node
|
|
477
|
+
duplex: body instanceof ReadableStream ? "half" : void 0
|
|
478
|
+
};
|
|
479
|
+
}
|
|
480
|
+
async function rawFetch(token, opts) {
|
|
481
|
+
ensureBearer(token);
|
|
482
|
+
const url = buildUrl(opts);
|
|
483
|
+
try {
|
|
484
|
+
return await fetch(url.toString(), buildRequestInit(token, opts));
|
|
485
|
+
} catch (err) {
|
|
486
|
+
if (err instanceof DOMException && err.name === "AbortError") {
|
|
487
|
+
throw err;
|
|
488
|
+
}
|
|
489
|
+
throw new NetworkError(err);
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
async function parseBodyByContentType(response) {
|
|
493
|
+
const ct = response.headers.get("content-type") ?? "";
|
|
494
|
+
if (ct.includes("application/json")) {
|
|
495
|
+
try {
|
|
496
|
+
return await response.json();
|
|
497
|
+
} catch {
|
|
498
|
+
return null;
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
try {
|
|
502
|
+
return await response.text();
|
|
503
|
+
} catch {
|
|
504
|
+
return null;
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
async function handleResponse(response, opts, expectJson) {
|
|
508
|
+
if (response.ok) {
|
|
509
|
+
if (!expectJson) return response;
|
|
510
|
+
return await response.json();
|
|
511
|
+
}
|
|
512
|
+
const body = await parseBodyByContentType(response);
|
|
513
|
+
if (isHubErrorBody(body)) {
|
|
514
|
+
const retryAfter = parseInt(response.headers.get("retry-after") ?? "60", 10);
|
|
515
|
+
throw errorFromResponse(
|
|
516
|
+
response.status,
|
|
517
|
+
{ error: body.error },
|
|
518
|
+
{
|
|
519
|
+
provider: opts.provider,
|
|
520
|
+
scopeNeeded: "keys.read",
|
|
521
|
+
retryAfter: Number.isFinite(retryAfter) ? retryAfter : 60
|
|
522
|
+
}
|
|
523
|
+
);
|
|
524
|
+
}
|
|
525
|
+
throw new ProviderError(opts.provider, opts.path, response.status, body);
|
|
526
|
+
}
|
|
527
|
+
async function call(token, opts) {
|
|
528
|
+
const response = await rawFetch(token, opts);
|
|
529
|
+
return handleResponse(response, opts, true);
|
|
530
|
+
}
|
|
531
|
+
async function callRaw(token, opts) {
|
|
532
|
+
const response = await rawFetch(token, opts);
|
|
533
|
+
return handleResponse(response, opts, false);
|
|
534
|
+
}
|
|
535
|
+
async function callStream(token, opts) {
|
|
536
|
+
const response = await rawFetch(token, opts);
|
|
537
|
+
if (!response.ok) {
|
|
538
|
+
const body = await parseBodyByContentType(response);
|
|
539
|
+
if (isHubErrorBody(body)) {
|
|
540
|
+
const retryAfter = parseInt(
|
|
541
|
+
response.headers.get("retry-after") ?? "60",
|
|
542
|
+
10
|
|
543
|
+
);
|
|
544
|
+
throw errorFromResponse(
|
|
545
|
+
response.status,
|
|
546
|
+
{ error: body.error },
|
|
547
|
+
{
|
|
548
|
+
provider: opts.provider,
|
|
549
|
+
scopeNeeded: "keys.read",
|
|
550
|
+
retryAfter: Number.isFinite(retryAfter) ? retryAfter : 60
|
|
551
|
+
}
|
|
552
|
+
);
|
|
553
|
+
}
|
|
554
|
+
throw new ProviderError(opts.provider, opts.path, response.status, body);
|
|
555
|
+
}
|
|
556
|
+
if (response.body == null) {
|
|
557
|
+
throw new BadTokenError("Upstream returned 2xx with no body to stream.");
|
|
558
|
+
}
|
|
559
|
+
return response.body;
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
// src/providers/openai.ts
|
|
563
|
+
var openai = {
|
|
564
|
+
images: {
|
|
565
|
+
generate(token, params, opts = {}) {
|
|
566
|
+
return call(token, {
|
|
567
|
+
...opts,
|
|
568
|
+
provider: "openai",
|
|
569
|
+
method: "POST",
|
|
570
|
+
path: "/v1/images/generations",
|
|
571
|
+
body: params
|
|
572
|
+
});
|
|
573
|
+
}
|
|
574
|
+
},
|
|
575
|
+
chat: {
|
|
576
|
+
completions: {
|
|
577
|
+
create(token, params, opts = {}) {
|
|
578
|
+
return call(token, {
|
|
579
|
+
...opts,
|
|
580
|
+
provider: "openai",
|
|
581
|
+
method: "POST",
|
|
582
|
+
path: "/v1/chat/completions",
|
|
583
|
+
body: params
|
|
584
|
+
});
|
|
585
|
+
},
|
|
586
|
+
stream(token, params, opts = {}) {
|
|
587
|
+
return callStream(token, {
|
|
588
|
+
...opts,
|
|
589
|
+
provider: "openai",
|
|
590
|
+
method: "POST",
|
|
591
|
+
path: "/v1/chat/completions",
|
|
592
|
+
body: { ...params, stream: true }
|
|
593
|
+
});
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
},
|
|
597
|
+
embeddings: {
|
|
598
|
+
create(token, params, opts = {}) {
|
|
599
|
+
return call(token, {
|
|
600
|
+
...opts,
|
|
601
|
+
provider: "openai",
|
|
602
|
+
method: "POST",
|
|
603
|
+
path: "/v1/embeddings",
|
|
604
|
+
body: params
|
|
605
|
+
});
|
|
606
|
+
}
|
|
607
|
+
},
|
|
608
|
+
audio: {
|
|
609
|
+
transcriptions: {
|
|
610
|
+
create(token, params, opts = {}) {
|
|
611
|
+
const fd = new FormData();
|
|
612
|
+
fd.append("file", params.file, params.filename ?? "audio.webm");
|
|
613
|
+
fd.append("model", params.model);
|
|
614
|
+
if (params.language) fd.append("language", params.language);
|
|
615
|
+
if (params.prompt) fd.append("prompt", params.prompt);
|
|
616
|
+
if (params.response_format)
|
|
617
|
+
fd.append("response_format", params.response_format);
|
|
618
|
+
if (params.temperature !== void 0)
|
|
619
|
+
fd.append("temperature", String(params.temperature));
|
|
620
|
+
return call(token, {
|
|
621
|
+
...opts,
|
|
622
|
+
provider: "openai",
|
|
623
|
+
method: "POST",
|
|
624
|
+
path: "/v1/audio/transcriptions",
|
|
625
|
+
body: fd
|
|
626
|
+
});
|
|
627
|
+
}
|
|
628
|
+
},
|
|
629
|
+
speech: {
|
|
630
|
+
create(token, params, opts = {}) {
|
|
631
|
+
return callRaw(token, {
|
|
632
|
+
...opts,
|
|
633
|
+
provider: "openai",
|
|
634
|
+
method: "POST",
|
|
635
|
+
path: "/v1/audio/speech",
|
|
636
|
+
body: params
|
|
637
|
+
});
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
};
|
|
642
|
+
|
|
643
|
+
// src/providers/anthropic.ts
|
|
644
|
+
var anthropic = {
|
|
645
|
+
messages: {
|
|
646
|
+
create(token, params, opts = {}) {
|
|
647
|
+
return call(token, {
|
|
648
|
+
...opts,
|
|
649
|
+
provider: "anthropic",
|
|
650
|
+
method: "POST",
|
|
651
|
+
path: "/v1/messages",
|
|
652
|
+
body: params
|
|
653
|
+
});
|
|
654
|
+
},
|
|
655
|
+
stream(token, params, opts = {}) {
|
|
656
|
+
return callStream(token, {
|
|
657
|
+
...opts,
|
|
658
|
+
provider: "anthropic",
|
|
659
|
+
method: "POST",
|
|
660
|
+
path: "/v1/messages",
|
|
661
|
+
body: { ...params, stream: true }
|
|
662
|
+
});
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
};
|
|
666
|
+
|
|
667
|
+
// src/providers/replicate.ts
|
|
668
|
+
var replicate = {
|
|
669
|
+
predictions: {
|
|
670
|
+
create(token, params, opts = {}) {
|
|
671
|
+
return call(token, {
|
|
672
|
+
...opts,
|
|
673
|
+
provider: "replicate",
|
|
674
|
+
method: "POST",
|
|
675
|
+
path: "/v1/predictions",
|
|
676
|
+
body: params
|
|
677
|
+
});
|
|
678
|
+
},
|
|
679
|
+
get(token, predictionId, opts = {}) {
|
|
680
|
+
return call(token, {
|
|
681
|
+
...opts,
|
|
682
|
+
provider: "replicate",
|
|
683
|
+
method: "GET",
|
|
684
|
+
path: `/v1/predictions/${encodeURIComponent(predictionId)}`
|
|
685
|
+
});
|
|
686
|
+
},
|
|
687
|
+
cancel(token, predictionId, opts = {}) {
|
|
688
|
+
return call(token, {
|
|
689
|
+
...opts,
|
|
690
|
+
provider: "replicate",
|
|
691
|
+
method: "POST",
|
|
692
|
+
path: `/v1/predictions/${encodeURIComponent(predictionId)}/cancel`
|
|
693
|
+
});
|
|
694
|
+
},
|
|
695
|
+
/**
|
|
696
|
+
* Convenience: create + poll until the prediction reaches a terminal
|
|
697
|
+
* status. Polls every `pollIntervalMs` (default 1000ms) with the
|
|
698
|
+
* provided AbortSignal honoured.
|
|
699
|
+
*
|
|
700
|
+
* For long-running predictions consider using webhooks via
|
|
701
|
+
* `create({ webhook, webhook_events_filter })` instead so you're not
|
|
702
|
+
* holding open a long fetch.
|
|
703
|
+
*/
|
|
704
|
+
async run(token, params, opts = {}) {
|
|
705
|
+
const interval = opts.pollIntervalMs ?? 1e3;
|
|
706
|
+
let prediction = await this.create(token, params, opts);
|
|
707
|
+
while (prediction.status === "starting" || prediction.status === "processing") {
|
|
708
|
+
if (opts.signal?.aborted) {
|
|
709
|
+
throw opts.signal.reason ?? new DOMException("Aborted", "AbortError");
|
|
710
|
+
}
|
|
711
|
+
await new Promise((resolve) => setTimeout(resolve, interval));
|
|
712
|
+
prediction = await this.get(token, prediction.id, opts);
|
|
713
|
+
}
|
|
714
|
+
return prediction;
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
};
|
|
718
|
+
|
|
360
719
|
// src/index.ts
|
|
361
720
|
var session = {
|
|
362
721
|
verify
|
|
@@ -364,7 +723,12 @@ var session = {
|
|
|
364
723
|
var keys = {
|
|
365
724
|
get
|
|
366
725
|
};
|
|
367
|
-
var
|
|
726
|
+
var proxy = {
|
|
727
|
+
call,
|
|
728
|
+
callRaw,
|
|
729
|
+
callStream
|
|
730
|
+
};
|
|
731
|
+
var SDK_VERSION = "0.2.0";
|
|
368
732
|
|
|
369
733
|
exports.BadTokenError = BadTokenError;
|
|
370
734
|
exports.HubSdkError = HubSdkError;
|
|
@@ -374,6 +738,8 @@ exports.MissingScopeError = MissingScopeError;
|
|
|
374
738
|
exports.MissingTokenError = MissingTokenError;
|
|
375
739
|
exports.NetworkError = NetworkError;
|
|
376
740
|
exports.NotSubscribedError = NotSubscribedError;
|
|
741
|
+
exports.ProviderError = ProviderError;
|
|
742
|
+
exports.ProviderNotConfiguredError = ProviderNotConfiguredError;
|
|
377
743
|
exports.ProviderNotGrantedError = ProviderNotGrantedError;
|
|
378
744
|
exports.RateLimitedError = RateLimitedError;
|
|
379
745
|
exports.SDK_VERSION = SDK_VERSION;
|
|
@@ -381,7 +747,11 @@ exports.SecureKey = SecureKey;
|
|
|
381
747
|
exports.SecureKeyConsumedError = SecureKeyConsumedError;
|
|
382
748
|
exports.SubscriptionInactiveError = SubscriptionInactiveError;
|
|
383
749
|
exports.ToolNotFoundError = ToolNotFoundError;
|
|
750
|
+
exports.anthropic = anthropic;
|
|
384
751
|
exports.keys = keys;
|
|
752
|
+
exports.openai = openai;
|
|
753
|
+
exports.proxy = proxy;
|
|
754
|
+
exports.replicate = replicate;
|
|
385
755
|
exports.session = session;
|
|
386
756
|
//# sourceMappingURL=index.cjs.map
|
|
387
757
|
//# sourceMappingURL=index.cjs.map
|