lightnode-sdk 0.4.8 → 0.5.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/dist/bridge.d.ts +233 -0
- package/dist/bridge.js +201 -0
- package/dist/chat.d.ts +70 -0
- package/dist/chat.js +88 -0
- package/dist/cli.js +202 -2
- package/dist/crypto.js +6 -1
- package/dist/dao.d.ts +439 -0
- package/dist/dao.js +234 -0
- package/dist/index.d.ts +31 -4
- package/dist/index.js +63 -4
- package/dist/inference.d.ts +34 -0
- package/dist/inference.js +107 -6
- package/dist/onchain-models.d.ts +380 -0
- package/dist/onchain-models.js +187 -0
- package/dist/subgraph.d.ts +2 -0
- package/dist/subgraph.js +6 -0
- package/dist/worker.d.ts +104 -0
- package/dist/worker.js +186 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import { NETWORKS, WORKER_REGISTRY, REGISTRY_TOPICS } from "./networks.js";
|
|
2
2
|
import { fromWei } from "./subgraph.js";
|
|
3
3
|
import { aggregateModelStats, aggregateWorkerStats, networkAnalytics, modelStatsCsv, workerStatsCsv, workerJobsCsv } from "./analytics.js";
|
|
4
|
-
import { modelId as computeModelId, estimateJobFee, JOB_REGISTRY_CONSUMER_ABI, consumerGatewayUrl, consumerGatewayHost, prepareSession, submitPrompt, decryptResponse, generateEcdhKeyPair, runInference, runInferenceWithKey } from "./inference.js";
|
|
4
|
+
import { modelId as computeModelId, estimateJobFee, JOB_REGISTRY_CONSUMER_ABI, consumerGatewayUrl, consumerGatewayHost, prepareSession, submitPrompt, decryptResponse, generateEcdhKeyPair, runInference, runInferenceWithKey, runInferenceStream } from "./inference.js";
|
|
5
|
+
import { Conversation, chat } from "./chat.js";
|
|
6
|
+
import { preflight as workerPreflight, watch as workerWatch } from "./worker.js";
|
|
7
|
+
import { Bridge, BRIDGE_ROUTE, HYPERLANE_ROUTER_ABI, ERC20_ABI, addressToBytes32, quoteBridgeFee, bridgeableBalance, bridgeAllowance, approveBridge, bridgeTransfer } from "./bridge.js";
|
|
8
|
+
import { DAO, DAO_ADDRESSES, ProposalState, PROPOSAL_STATE_LABEL, VoteSupport, GOVERNOR_ABI, VOTES_ABI } from "./dao.js";
|
|
9
|
+
import { OnchainModelRegistry, AIVM_MODEL_REGISTRY_ABI, BENCHMARK_REGISTRY_ABI, ModelStatus, MODEL_STATUS_LABEL } from "./onchain-models.js";
|
|
5
10
|
import { StalledWorkerError, OnChainRevertError, RelayTokenTimeoutError, GatewayAuthError, isStalledWorker } from "./errors.js";
|
|
6
11
|
import { GatewayClient, GatewayHttpError } from "./gateway.js";
|
|
7
12
|
import * as crypto from "./crypto.js";
|
|
@@ -45,6 +50,23 @@ export declare class LightNode {
|
|
|
45
50
|
isRegistered(address: string): Promise<boolean | null>;
|
|
46
51
|
/** Settled worker earnings in whole LCAI (from total_earned wei). */
|
|
47
52
|
getEarningsLcai(address: string): Promise<number>;
|
|
53
|
+
/**
|
|
54
|
+
* One job's current status, classified for builders deciding whether to
|
|
55
|
+
* retry / claim a refund / accept the answer. `category` is the
|
|
56
|
+
* builder-friendly label; `raw` is the indexer's literal state string.
|
|
57
|
+
* Null when the indexer has never seen the job (still pending propagation).
|
|
58
|
+
*/
|
|
59
|
+
getJobStatus(jobId: string | bigint): Promise<{
|
|
60
|
+
id: string;
|
|
61
|
+
raw: string;
|
|
62
|
+
category: "submitted" | "in-flight" | "completed" | "stalled" | "disputed" | "resolved" | "unknown";
|
|
63
|
+
worker: string | null;
|
|
64
|
+
model: string | null;
|
|
65
|
+
submittedAt: number | null;
|
|
66
|
+
completedAt: number | null;
|
|
67
|
+
workerShareLcai: number;
|
|
68
|
+
refundable: boolean;
|
|
69
|
+
} | null>;
|
|
48
70
|
/** keccak256 of a model tag (its on-chain + indexer id). */
|
|
49
71
|
modelId(tag: string): `0x${string}`;
|
|
50
72
|
/** On-chain inference fee for a model, in whole LCAI (what submitJob must be paid). */
|
|
@@ -66,8 +88,13 @@ export declare class LightNode {
|
|
|
66
88
|
* (especially in registry-proxy environments like StackBlitz where lockfiles
|
|
67
89
|
* may pin an older minor than the local install command suggests).
|
|
68
90
|
*/
|
|
69
|
-
export declare const SDK_VERSION = "0.
|
|
70
|
-
export { NETWORKS, WORKER_REGISTRY, REGISTRY_TOPICS, aggregateModelStats, aggregateWorkerStats, networkAnalytics, modelStatsCsv, workerStatsCsv, workerJobsCsv, fromWei, computeModelId as modelId, estimateJobFee, JOB_REGISTRY_CONSUMER_ABI, consumerGatewayUrl, consumerGatewayHost, GatewayClient, GatewayHttpError, prepareSession, submitPrompt, decryptResponse, generateEcdhKeyPair, crypto, runInference, runInferenceWithKey, StalledWorkerError, OnChainRevertError, RelayTokenTimeoutError, GatewayAuthError, isStalledWorker, };
|
|
91
|
+
export declare const SDK_VERSION = "0.5.0";
|
|
92
|
+
export { NETWORKS, WORKER_REGISTRY, REGISTRY_TOPICS, aggregateModelStats, aggregateWorkerStats, networkAnalytics, modelStatsCsv, workerStatsCsv, workerJobsCsv, fromWei, computeModelId as modelId, estimateJobFee, JOB_REGISTRY_CONSUMER_ABI, consumerGatewayUrl, consumerGatewayHost, GatewayClient, GatewayHttpError, prepareSession, submitPrompt, decryptResponse, generateEcdhKeyPair, crypto, runInference, runInferenceWithKey, runInferenceStream, Conversation, chat, workerPreflight, workerWatch, Bridge, BRIDGE_ROUTE, HYPERLANE_ROUTER_ABI, ERC20_ABI, addressToBytes32, quoteBridgeFee, bridgeableBalance, bridgeAllowance, approveBridge, bridgeTransfer, DAO, DAO_ADDRESSES, ProposalState, PROPOSAL_STATE_LABEL, VoteSupport, GOVERNOR_ABI, VOTES_ABI, OnchainModelRegistry, AIVM_MODEL_REGISTRY_ABI, BENCHMARK_REGISTRY_ABI, ModelStatus, MODEL_STATUS_LABEL, StalledWorkerError, OnChainRevertError, RelayTokenTimeoutError, GatewayAuthError, isStalledWorker, };
|
|
71
93
|
export type { BearerSource, GatewayClientOptions, SelectSessionResult, PrepareSessionResult, UploadBlobResult, SessionTokenResult } from "./gateway.js";
|
|
72
|
-
export type { SessionPreparation, RunInferenceArgs, RunInferenceResult, RunInferenceWithKeyArgs } from "./inference.js";
|
|
94
|
+
export type { SessionPreparation, RunInferenceArgs, RunInferenceResult, RunInferenceWithKeyArgs, RunInferenceStreamResult } from "./inference.js";
|
|
95
|
+
export type { ChatRole, ChatMessage, ConversationOptions, ConversationSendResult } from "./chat.js";
|
|
96
|
+
export type { WorkerPreflightArgs, WorkerPreflightResult, WorkerWatchOptions, WorkerEventKind, WorkerEvent, WorkerWatchHandle } from "./worker.js";
|
|
97
|
+
export type { BridgeChain, BridgeEndpoints, BridgeTransferArgs } from "./bridge.js";
|
|
98
|
+
export type { DaoChain, DaoAddresses, ProposalSummary, DaoConfig } from "./dao.js";
|
|
99
|
+
export type { BaseModel, ModelVariant, AccessTier, AccessPolicy, Benchmark, OnchainModelRegistryOptions } from "./onchain-models.js";
|
|
73
100
|
export type { NetworkId, NetworkConfig, Worker, Job, ModelInfo, NetworkStats, ModelStat, WorkerStat, NetworkAnalytics };
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
import { NETWORKS, WORKER_REGISTRY, REGISTRY_TOPICS } from "./networks.js";
|
|
2
|
-
import { fetchWorker, fetchWorkerJobs, fetchRecentJobs, fetchModels, fetchWorkers, summarize, fromWei, } from "./subgraph.js";
|
|
2
|
+
import { fetchWorker, fetchWorkerJobs, fetchRecentJobs, fetchJob, fetchModels, fetchWorkers, summarize, fromWei, } from "./subgraph.js";
|
|
3
3
|
import { isRegistered } from "./onchain.js";
|
|
4
4
|
import { aggregateModelStats, aggregateWorkerStats, networkAnalytics, modelStatsCsv, workerStatsCsv, workerJobsCsv, } from "./analytics.js";
|
|
5
|
-
import { modelId as computeModelId, estimateJobFee, JOB_REGISTRY_CONSUMER_ABI, consumerGatewayUrl, consumerGatewayHost, prepareSession, submitPrompt, decryptResponse, generateEcdhKeyPair, runInference, runInferenceWithKey, } from "./inference.js";
|
|
5
|
+
import { modelId as computeModelId, estimateJobFee, JOB_REGISTRY_CONSUMER_ABI, consumerGatewayUrl, consumerGatewayHost, prepareSession, submitPrompt, decryptResponse, generateEcdhKeyPair, runInference, runInferenceWithKey, runInferenceStream, } from "./inference.js";
|
|
6
|
+
import { Conversation, chat } from "./chat.js";
|
|
7
|
+
import { preflight as workerPreflight, watch as workerWatch } from "./worker.js";
|
|
8
|
+
import { Bridge, BRIDGE_ROUTE, HYPERLANE_ROUTER_ABI, ERC20_ABI, addressToBytes32, quoteBridgeFee, bridgeableBalance, bridgeAllowance, approveBridge, bridgeTransfer, } from "./bridge.js";
|
|
9
|
+
import { DAO, DAO_ADDRESSES, ProposalState, PROPOSAL_STATE_LABEL, VoteSupport, GOVERNOR_ABI, VOTES_ABI, } from "./dao.js";
|
|
10
|
+
import { OnchainModelRegistry, AIVM_MODEL_REGISTRY_ABI, BENCHMARK_REGISTRY_ABI, ModelStatus, MODEL_STATUS_LABEL, } from "./onchain-models.js";
|
|
6
11
|
import { StalledWorkerError, OnChainRevertError, RelayTokenTimeoutError, GatewayAuthError, isStalledWorker, } from "./errors.js";
|
|
7
12
|
import { GatewayClient, GatewayHttpError } from "./gateway.js";
|
|
8
13
|
import * as crypto from "./crypto.js";
|
|
@@ -72,6 +77,48 @@ export class LightNode {
|
|
|
72
77
|
const w = await fetchWorker(this.network, address);
|
|
73
78
|
return w ? fromWei(w.total_earned) : 0;
|
|
74
79
|
}
|
|
80
|
+
/**
|
|
81
|
+
* One job's current status, classified for builders deciding whether to
|
|
82
|
+
* retry / claim a refund / accept the answer. `category` is the
|
|
83
|
+
* builder-friendly label; `raw` is the indexer's literal state string.
|
|
84
|
+
* Null when the indexer has never seen the job (still pending propagation).
|
|
85
|
+
*/
|
|
86
|
+
async getJobStatus(jobId) {
|
|
87
|
+
const j = await fetchJob(this.network, jobId);
|
|
88
|
+
if (!j)
|
|
89
|
+
return null;
|
|
90
|
+
const state = (j.state ?? "").trim();
|
|
91
|
+
const stateLow = state.toLowerCase();
|
|
92
|
+
const category = /completed|released|paid/.test(stateLow)
|
|
93
|
+
? "completed"
|
|
94
|
+
: /timed.?out|stalled|expired/.test(stateLow)
|
|
95
|
+
? "stalled"
|
|
96
|
+
: /disputed/.test(stateLow)
|
|
97
|
+
? "disputed"
|
|
98
|
+
: /resolved/.test(stateLow)
|
|
99
|
+
? "resolved"
|
|
100
|
+
: /ack/.test(stateLow)
|
|
101
|
+
? "in-flight"
|
|
102
|
+
: /submitted/.test(stateLow)
|
|
103
|
+
? "submitted"
|
|
104
|
+
: "unknown";
|
|
105
|
+
// A refund is on the table when the worker accepted the job but never
|
|
106
|
+
// produced an answer within the protocol's dispute window. The protocol's
|
|
107
|
+
// own timeout/dispute pipeline reclaims the fee; this flag is the SDK's
|
|
108
|
+
// builder-facing hint that the on-chain refund call is the right path.
|
|
109
|
+
const refundable = category === "stalled" || category === "disputed";
|
|
110
|
+
return {
|
|
111
|
+
id: j.id,
|
|
112
|
+
raw: state,
|
|
113
|
+
category,
|
|
114
|
+
worker: j.worker ?? null,
|
|
115
|
+
model: j.model_id ?? null,
|
|
116
|
+
submittedAt: j.submitted_at ?? null,
|
|
117
|
+
completedAt: j.completed_at ?? null,
|
|
118
|
+
workerShareLcai: fromWei(j.worker_share),
|
|
119
|
+
refundable,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
75
122
|
/** keccak256 of a model tag (its on-chain + indexer id). */
|
|
76
123
|
modelId(tag) {
|
|
77
124
|
return computeModelId(tag);
|
|
@@ -96,11 +143,23 @@ export class LightNode {
|
|
|
96
143
|
* (especially in registry-proxy environments like StackBlitz where lockfiles
|
|
97
144
|
* may pin an older minor than the local install command suggests).
|
|
98
145
|
*/
|
|
99
|
-
export const SDK_VERSION = "0.
|
|
146
|
+
export const SDK_VERSION = "0.5.0";
|
|
100
147
|
export { NETWORKS, WORKER_REGISTRY, REGISTRY_TOPICS, aggregateModelStats, aggregateWorkerStats, networkAnalytics, modelStatsCsv, workerStatsCsv, workerJobsCsv, fromWei, computeModelId as modelId, estimateJobFee, JOB_REGISTRY_CONSUMER_ABI, consumerGatewayUrl, consumerGatewayHost,
|
|
101
148
|
// v0.3 inference-submit surface (BETA - see README "Submitting inference").
|
|
102
149
|
GatewayClient, GatewayHttpError, prepareSession, submitPrompt, decryptResponse, generateEcdhKeyPair, crypto,
|
|
103
150
|
// v0.4 high-level orchestrator: one call, full flow.
|
|
104
151
|
runInference,
|
|
105
152
|
// v0.4.3 key-in-answer-out shortcut: same flow, no viem/SIWE wiring.
|
|
106
|
-
runInferenceWithKey,
|
|
153
|
+
runInferenceWithKey,
|
|
154
|
+
// v0.4.9 AsyncIterable<string> wrapper around runInferenceWithKey.
|
|
155
|
+
runInferenceStream,
|
|
156
|
+
// v0.5.0 multi-turn conversation helper (history client-side; one inference per turn).
|
|
157
|
+
Conversation, chat,
|
|
158
|
+
// v0.5.0 worker preflight + watch (one real test inference + status polling).
|
|
159
|
+
workerPreflight, workerWatch,
|
|
160
|
+
// v0.5.0 Bridge SDK (Hyperlane Warp Route wrapper for LCAI <-> Ethereum).
|
|
161
|
+
Bridge, BRIDGE_ROUTE, HYPERLANE_ROUTER_ABI, ERC20_ABI, addressToBytes32, quoteBridgeFee, bridgeableBalance, bridgeAllowance, approveBridge, bridgeTransfer,
|
|
162
|
+
// v0.5.0 DAO SDK (LCAIGovernor wrapper on Ethereum mainnet).
|
|
163
|
+
DAO, DAO_ADDRESSES, ProposalState, PROPOSAL_STATE_LABEL, VoteSupport, GOVERNOR_ABI, VOTES_ABI,
|
|
164
|
+
// v0.5.0 On-chain model registry reader (AIVMModelRegistry + BenchmarkRegistry).
|
|
165
|
+
OnchainModelRegistry, AIVM_MODEL_REGISTRY_ABI, BENCHMARK_REGISTRY_ABI, ModelStatus, MODEL_STATUS_LABEL, StalledWorkerError, OnChainRevertError, RelayTokenTimeoutError, GatewayAuthError, isStalledWorker, };
|
package/dist/inference.d.ts
CHANGED
|
@@ -287,3 +287,37 @@ export interface RunInferenceWithKeyArgs {
|
|
|
287
287
|
* ```
|
|
288
288
|
*/
|
|
289
289
|
export declare function runInferenceWithKey(args: RunInferenceWithKeyArgs): Promise<RunInferenceResult>;
|
|
290
|
+
export interface RunInferenceStreamResult {
|
|
291
|
+
/** Streamed chunks (decrypted, in arrival order). */
|
|
292
|
+
[Symbol.asyncIterator](): AsyncIterator<string>;
|
|
293
|
+
/**
|
|
294
|
+
* Resolves with the same shape `runInference` returns once the iterator
|
|
295
|
+
* has finished (i.e. you've consumed all chunks). `answer` is the full
|
|
296
|
+
* assembled string. Awaiting this before consuming the iterator hangs;
|
|
297
|
+
* always iterate first or in parallel with another consumer.
|
|
298
|
+
*/
|
|
299
|
+
done: Promise<RunInferenceResult>;
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* Stream-shaped wrapper over `runInferenceWithKey`. Returns an async-iterable
|
|
303
|
+
* of decrypted chunks plus a `done` promise that resolves to the full result
|
|
304
|
+
* once the iteration completes.
|
|
305
|
+
*
|
|
306
|
+
* @example
|
|
307
|
+
* ```ts
|
|
308
|
+
* import { runInferenceStream } from "lightnode-sdk";
|
|
309
|
+
*
|
|
310
|
+
* const stream = runInferenceStream({
|
|
311
|
+
* network: "testnet",
|
|
312
|
+
* privateKey: process.env.PRIVATE_KEY!,
|
|
313
|
+
* prompt: "Write a haiku about decentralized AI.",
|
|
314
|
+
* });
|
|
315
|
+
*
|
|
316
|
+
* for await (const chunk of stream) {
|
|
317
|
+
* process.stdout.write(chunk);
|
|
318
|
+
* }
|
|
319
|
+
* const { txs } = await stream.done;
|
|
320
|
+
* console.log("\n", txs);
|
|
321
|
+
* ```
|
|
322
|
+
*/
|
|
323
|
+
export declare function runInferenceStream(args: RunInferenceWithKeyArgs): RunInferenceStreamResult;
|
package/dist/inference.js
CHANGED
|
@@ -535,16 +535,32 @@ export async function runInferenceWithKey(args) {
|
|
|
535
535
|
if (!verify.token)
|
|
536
536
|
throw new GatewayAuthError(verifyRes.status, "auth verify returned no token");
|
|
537
537
|
const gateway = new GatewayClientCtor({ network: networkId, bearer: verify.token, baseUrl: args.gatewayUrl ?? gwBase });
|
|
538
|
-
// Pick a WebSocket: the browser global
|
|
539
|
-
//
|
|
540
|
-
//
|
|
541
|
-
|
|
538
|
+
// Pick a WebSocket: caller-supplied wins, else the browser global, else try
|
|
539
|
+
// to lazy-import the `ws` package (Node). The webpackIgnore hint keeps
|
|
540
|
+
// bundlers from blowing up trying to resolve `ws` for browser bundles where
|
|
541
|
+
// we never reach this branch.
|
|
542
|
+
let wsCtor = args.WebSocket ??
|
|
542
543
|
(typeof globalThis !== "undefined" && globalThis.WebSocket
|
|
543
544
|
? globalThis.WebSocket
|
|
544
545
|
: undefined);
|
|
545
546
|
if (!wsCtor) {
|
|
546
|
-
|
|
547
|
-
|
|
547
|
+
try {
|
|
548
|
+
// Hide the module name from TS's static resolver via a Function-built
|
|
549
|
+
// dynamic import - otherwise TS errors trying to find @types/ws (we do
|
|
550
|
+
// not want that as a SDK devDep). The webpackIgnore-style comment also
|
|
551
|
+
// keeps browser bundlers from trying to resolve `ws`.
|
|
552
|
+
const dynamicImport = Function("n", "return import(/* webpackIgnore: true */ n)");
|
|
553
|
+
const mod = await dynamicImport("ws");
|
|
554
|
+
wsCtor = mod.default ?? mod.WebSocket;
|
|
555
|
+
}
|
|
556
|
+
catch {
|
|
557
|
+
// `ws` not installed - keep wsCtor undefined and fall into the error below.
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
if (!wsCtor) {
|
|
561
|
+
throw new Error("runInferenceWithKey: no WebSocket constructor available. In Node, install `ws` " +
|
|
562
|
+
"(`npm i ws`) - the SDK will pick it up automatically. Or pass one explicitly: " +
|
|
563
|
+
"`import WS from 'ws'; runInferenceWithKey({ WebSocket: WS, ... })`.");
|
|
548
564
|
}
|
|
549
565
|
return runInference({
|
|
550
566
|
prompt: args.prompt,
|
|
@@ -560,3 +576,88 @@ export async function runInferenceWithKey(args) {
|
|
|
560
576
|
relayUrl: args.relayUrl,
|
|
561
577
|
});
|
|
562
578
|
}
|
|
579
|
+
/**
|
|
580
|
+
* Stream-shaped wrapper over `runInferenceWithKey`. Returns an async-iterable
|
|
581
|
+
* of decrypted chunks plus a `done` promise that resolves to the full result
|
|
582
|
+
* once the iteration completes.
|
|
583
|
+
*
|
|
584
|
+
* @example
|
|
585
|
+
* ```ts
|
|
586
|
+
* import { runInferenceStream } from "lightnode-sdk";
|
|
587
|
+
*
|
|
588
|
+
* const stream = runInferenceStream({
|
|
589
|
+
* network: "testnet",
|
|
590
|
+
* privateKey: process.env.PRIVATE_KEY!,
|
|
591
|
+
* prompt: "Write a haiku about decentralized AI.",
|
|
592
|
+
* });
|
|
593
|
+
*
|
|
594
|
+
* for await (const chunk of stream) {
|
|
595
|
+
* process.stdout.write(chunk);
|
|
596
|
+
* }
|
|
597
|
+
* const { txs } = await stream.done;
|
|
598
|
+
* console.log("\n", txs);
|
|
599
|
+
* ```
|
|
600
|
+
*/
|
|
601
|
+
export function runInferenceStream(args) {
|
|
602
|
+
// Bounded queue of pending chunks; consumed in order by the iterator. We
|
|
603
|
+
// can't use an unbounded array because the inference may produce chunks
|
|
604
|
+
// faster than the consumer reads them - bounding at 1024 is enough to absorb
|
|
605
|
+
// model-output bursts without unbounded memory growth.
|
|
606
|
+
const queue = [];
|
|
607
|
+
const waiters = [];
|
|
608
|
+
let finished = false;
|
|
609
|
+
let error = null;
|
|
610
|
+
const push = (chunk) => {
|
|
611
|
+
if (waiters.length > 0) {
|
|
612
|
+
const resolve = waiters.shift();
|
|
613
|
+
if (resolve)
|
|
614
|
+
resolve({ value: chunk, done: false });
|
|
615
|
+
}
|
|
616
|
+
else {
|
|
617
|
+
queue.push(chunk);
|
|
618
|
+
}
|
|
619
|
+
};
|
|
620
|
+
const finish = (err = null) => {
|
|
621
|
+
finished = true;
|
|
622
|
+
error = err;
|
|
623
|
+
while (waiters.length > 0) {
|
|
624
|
+
const resolve = waiters.shift();
|
|
625
|
+
if (!resolve)
|
|
626
|
+
continue;
|
|
627
|
+
if (err)
|
|
628
|
+
resolve({ value: undefined, done: true });
|
|
629
|
+
else
|
|
630
|
+
resolve({ value: undefined, done: true });
|
|
631
|
+
}
|
|
632
|
+
};
|
|
633
|
+
const done = runInferenceWithKey({
|
|
634
|
+
...args,
|
|
635
|
+
onChunk: (chunk) => push(chunk),
|
|
636
|
+
})
|
|
637
|
+
.then((res) => {
|
|
638
|
+
finish(null);
|
|
639
|
+
return res;
|
|
640
|
+
})
|
|
641
|
+
.catch((e) => {
|
|
642
|
+
finish(e);
|
|
643
|
+
throw e;
|
|
644
|
+
});
|
|
645
|
+
return {
|
|
646
|
+
[Symbol.asyncIterator]() {
|
|
647
|
+
return {
|
|
648
|
+
async next() {
|
|
649
|
+
if (queue.length > 0) {
|
|
650
|
+
return { value: queue.shift(), done: false };
|
|
651
|
+
}
|
|
652
|
+
if (finished) {
|
|
653
|
+
if (error)
|
|
654
|
+
throw error;
|
|
655
|
+
return { value: undefined, done: true };
|
|
656
|
+
}
|
|
657
|
+
return new Promise((resolve) => waiters.push(resolve));
|
|
658
|
+
},
|
|
659
|
+
};
|
|
660
|
+
},
|
|
661
|
+
done,
|
|
662
|
+
};
|
|
663
|
+
}
|