@independo/inderun-web 0.3.0-dev.1 → 0.3.0-dev.3

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.
@@ -1,9 +1,20 @@
1
- import { type TaskRequest, type TaskResult } from "@independo/inderun-contracts";
1
+ import { type StreamEvent, type StreamRunHandle, type TaskRequest, type TaskResult } from "@independo/inderun-contracts";
2
2
  import type { HostServices } from "./host.js";
3
3
  import type { ProviderCapabilitySnapshot } from "./provider.js";
4
4
  import type { IndeRunApi } from "./generated/inderun-api.js";
5
5
  import { ProviderRegistry } from "./registry.js";
6
6
  import { type TelemetryService } from "./telemetry.js";
7
+ /**
8
+ * Handle returned by IndeRun.stream(). `events` is the canonical StreamEvent
9
+ * sequence for this run, terminating in exactly one terminal StreamEvent per the
10
+ * Event Gate's guarantee. `cancel()` is idempotent: repeated or concurrent calls
11
+ * produce exactly one `cancelled` terminal outcome.
12
+ */
13
+ export interface StreamHandleResult {
14
+ handle: StreamRunHandle;
15
+ events: AsyncIterable<StreamEvent>;
16
+ cancel(reason?: string): void;
17
+ }
7
18
  /**
8
19
  * Main orchestrator SDK entrypoint class.
9
20
  * Validates tasks, executes routing rules based on request constraints and connectivity,
@@ -40,6 +51,20 @@ export declare class IndeRun implements IndeRunApi {
40
51
  * @throws {IndeRunException} Standardized error indicating validation, connection, or provider failures.
41
52
  */
42
53
  run(request: TaskRequest): Promise<TaskResult>;
54
+ /**
55
+ * Orchestrates a Mode 2 streaming execution of a TaskRequest.
56
+ *
57
+ * Reuses the same route selection as run(), restricted to providers that declare
58
+ * `supports.streaming` and implement `stream()`. Fallback to the next provider is
59
+ * allowed only before the first content event has been admitted for the run; once
60
+ * one has been delivered, the run is committed to that provider and any later
61
+ * provider failure becomes a terminal error outcome rather than a silent provider
62
+ * swap. Cancellation always forecloses fallback, regardless of commit state, and
63
+ * is idempotent.
64
+ * @param request - The canonical task request containing prompts, tasks, and constraints.
65
+ * @throws {IndeRunException} If validation fails or no eligible streaming provider exists.
66
+ */
67
+ stream(request: TaskRequest): Promise<StreamHandleResult>;
43
68
  /**
44
69
  * Reports each registered provider's static descriptor and current dynamic capability check,
45
70
  * without executing a task. Useful for UI that shows live provider availability before a run.
@@ -1 +1 @@
1
- {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/core/engine.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,UAAU,EAChB,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,eAAe,CAAC;AAChE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAGjD,OAAO,EAAuB,KAAK,gBAAgB,EAAwB,MAAM,gBAAgB,CAAC;AAElG;;;;GAIG;AACH,qBAAa,OAAQ,YAAW,UAAU;IAWtC,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,YAAY;IAXtB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,gBAAgB,CAAmB;IAE3C;;;;;OAKG;gBAEO,QAAQ,EAAE,gBAAgB,EAC1B,YAAY,EAAE,YAAY,EAClC,gBAAgB,CAAC,EAAE,gBAAgB;IAOrC;;;OAGG;IACH,OAAO,CAAC,QAAQ;IAShB;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IAoBxB;;;;;;;OAOG;IACG,GAAG,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;IAuIpD;;;OAGG;IACG,iBAAiB,IAAI,OAAO,CAAC,0BAA0B,EAAE,CAAC;CASjE"}
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/core/engine.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,eAAe,EAEpB,KAAK,WAAW,EAChB,KAAK,UAAU,EAChB,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,KAAK,EAAmB,0BAA0B,EAAE,MAAM,eAAe,CAAC;AACjF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAQjD,OAAO,EAAuB,KAAK,gBAAgB,EAAwB,MAAM,gBAAgB,CAAC;AAGlG;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,eAAe,CAAC;IACxB,MAAM,EAAE,aAAa,CAAC,WAAW,CAAC,CAAC;IACnC,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAED;;;;GAIG;AACH,qBAAa,OAAQ,YAAW,UAAU;IAWtC,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,YAAY;IAXtB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,gBAAgB,CAAmB;IAE3C;;;;;OAKG;gBAEO,QAAQ,EAAE,gBAAgB,EAC1B,YAAY,EAAE,YAAY,EAClC,gBAAgB,CAAC,EAAE,gBAAgB;IAOrC;;;OAGG;IACH,OAAO,CAAC,QAAQ;IAShB;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IAoBxB;;;;;;;OAOG;IACG,GAAG,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;IAuIpD;;;;;;;;;;;;OAYG;IACG,MAAM,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAsQ/D;;;OAGG;IACG,iBAAiB,IAAI,OAAO,CAAC,0BAA0B,EAAE,CAAC;CASjE"}
@@ -1,8 +1,9 @@
1
1
  import { getTaskRequestValidationIssues } from "@independo/inderun-contracts";
2
2
  import { ProviderRegistry } from "./registry.js";
3
3
  import { Router } from "./router.js";
4
- import { createInternal, toIndeRunException } from "./errors.js";
4
+ import { createCapabilityMismatch, createInternal, createUnavailable, toIndeRunException } from "./errors.js";
5
5
  import { NoOpTelemetryService } from "./telemetry.js";
6
+ import { EventGate } from "./event-gate.js";
6
7
  /**
7
8
  * Main orchestrator SDK entrypoint class.
8
9
  * Validates tasks, executes routing rules based on request constraints and connectivity,
@@ -190,6 +191,261 @@ export class IndeRun {
190
191
  throw exception;
191
192
  }
192
193
  }
194
+ /**
195
+ * Orchestrates a Mode 2 streaming execution of a TaskRequest.
196
+ *
197
+ * Reuses the same route selection as run(), restricted to providers that declare
198
+ * `supports.streaming` and implement `stream()`. Fallback to the next provider is
199
+ * allowed only before the first content event has been admitted for the run; once
200
+ * one has been delivered, the run is committed to that provider and any later
201
+ * provider failure becomes a terminal error outcome rather than a silent provider
202
+ * swap. Cancellation always forecloses fallback, regardless of commit state, and
203
+ * is idempotent.
204
+ * @param request - The canonical task request containing prompts, tasks, and constraints.
205
+ * @throws {IndeRunException} If validation fails or no eligible streaming provider exists.
206
+ */
207
+ async stream(request) {
208
+ const startTime = this.hostServices.clock ? this.hostServices.clock.now() : Date.now();
209
+ const now = () => (this.hostServices.clock ? this.hostServices.clock.now() : Date.now());
210
+ const runId = request.requestId || `run_${Math.random().toString(36).substring(2, 11)}`;
211
+ const validationIssues = getTaskRequestValidationIssues(request);
212
+ if (validationIssues.length > 0) {
213
+ const message = `Validation failed for TaskRequest: ${validationIssues
214
+ .map((i) => `${i.path} - ${i.message}`)
215
+ .join("; ")}`;
216
+ throw createInternal(message, { runId, details: { validationIssues } });
217
+ }
218
+ const routeSelection = await this.router.selectRoute(request, this.hostServices);
219
+ const allProviders = [routeSelection.provider, ...routeSelection.fallbackProviders];
220
+ const providers = allProviders.filter((p) => p.describe().supports.streaming && typeof p.stream === "function");
221
+ this.safeEmit({
222
+ type: "route_decided",
223
+ runId,
224
+ timestamp: now(),
225
+ payload: {
226
+ selectedProviderId: routeSelection.routePlan.selectedProviderId,
227
+ fallbackProviderIds: routeSelection.routePlan.fallbackProviderIds,
228
+ rejectedProviders: routeSelection.routePlan.rejectedProviders,
229
+ fallbackAvailable: providers.length > 1,
230
+ taskKind: request.task.kind,
231
+ explanation: routeSelection.explanation,
232
+ constraints: request.constraints ?? null,
233
+ preferences: request.preferences ?? null,
234
+ plannerSource: routeSelection.plannerSource,
235
+ plannerUnavailableReason: routeSelection.plannerUnavailableReason ?? null
236
+ }
237
+ });
238
+ if (providers.length === 0) {
239
+ throw createCapabilityMismatch("No eligible provider supports streaming for this request.", {
240
+ runId,
241
+ details: { taskKind: request.task.kind }
242
+ });
243
+ }
244
+ const controller = new AbortController();
245
+ const gate = new EventGate(runId);
246
+ const hostServices = this.hostServices;
247
+ const safeEmit = this.safeEmit.bind(this);
248
+ const getStableMessage = this.getStableMessage.bind(this);
249
+ const handle = {
250
+ runId,
251
+ schemaVersion: "1.0",
252
+ startedAt: startTime,
253
+ providerId: providers[0].describe().id
254
+ };
255
+ async function* run() {
256
+ const attemptedProviderIds = [];
257
+ let committed = false;
258
+ const cancelledOutcome = (partialText) => {
259
+ const reason = typeof controller.signal.reason === "string" ? controller.signal.reason : undefined;
260
+ return {
261
+ outcome: "cancelled",
262
+ runId,
263
+ schemaVersion: "1.0",
264
+ partialText,
265
+ ...(reason !== undefined ? { reason } : {})
266
+ };
267
+ };
268
+ for (const [index, provider] of providers.entries()) {
269
+ if (controller.signal.aborted) {
270
+ break;
271
+ }
272
+ const providerId = provider.describe().id;
273
+ attemptedProviderIds.push(providerId);
274
+ safeEmit({
275
+ type: "stream_attempt_started",
276
+ runId,
277
+ timestamp: now(),
278
+ payload: { providerId, fallbackOccurred: index > 0 }
279
+ });
280
+ let partialText = "";
281
+ try {
282
+ const iterable = provider.stream(request, {
283
+ runId,
284
+ hostServices: hostServices,
285
+ signal: controller.signal
286
+ });
287
+ let terminatedInLoop = false;
288
+ for await (const ev of iterable) {
289
+ if (controller.signal.aborted) {
290
+ break;
291
+ }
292
+ if (ev.kind === "error") {
293
+ throw ev.error;
294
+ }
295
+ if (ev.kind === "delta" || ev.kind === "snapshot") {
296
+ partialText = ev.kind === "delta" ? partialText + ev.text : ev.text;
297
+ if (!committed) {
298
+ committed = true;
299
+ safeEmit({
300
+ type: "stream_attempt_succeeded",
301
+ runId,
302
+ timestamp: now(),
303
+ payload: { providerId, attemptedProviderIds }
304
+ });
305
+ }
306
+ const streamEvent = gate.admit({
307
+ timestamp: now(),
308
+ type: ev.kind === "delta" ? "content_delta" : "content_snapshot",
309
+ payload: { text: ev.text }
310
+ });
311
+ if (streamEvent)
312
+ yield streamEvent;
313
+ continue;
314
+ }
315
+ // ev.kind === "done"
316
+ const outcome = {
317
+ outcome: "completed",
318
+ runId,
319
+ schemaVersion: "1.0",
320
+ finalText: ev.finalText,
321
+ telemetry: { providerUsed: providerId, totalMs: now() - startTime },
322
+ ...(ev.usage !== undefined ? { usage: ev.usage } : {})
323
+ };
324
+ const terminal = gate.terminate(outcome, now());
325
+ safeEmit({
326
+ type: "stream_completed",
327
+ runId,
328
+ timestamp: now(),
329
+ payload: { providerId, durationMs: now() - startTime, attemptedProviderIds }
330
+ });
331
+ terminatedInLoop = true;
332
+ if (terminal)
333
+ yield terminal;
334
+ return;
335
+ }
336
+ if (terminatedInLoop) {
337
+ return;
338
+ }
339
+ if (controller.signal.aborted) {
340
+ const terminal = gate.terminate(cancelledOutcome(partialText), now());
341
+ safeEmit({
342
+ type: "stream_cancelled",
343
+ runId,
344
+ timestamp: now(),
345
+ payload: { providerId, attemptedProviderIds }
346
+ });
347
+ if (terminal)
348
+ yield terminal;
349
+ return;
350
+ }
351
+ // Provider's iterable ended without a terminal "done"/"error" event.
352
+ throw new Error(`Provider '${providerId}' stream ended without a terminal event.`);
353
+ }
354
+ catch (err) {
355
+ if (controller.signal.aborted) {
356
+ const terminal = gate.terminate(cancelledOutcome(partialText), now());
357
+ safeEmit({
358
+ type: "stream_cancelled",
359
+ runId,
360
+ timestamp: now(),
361
+ payload: { providerId, attemptedProviderIds }
362
+ });
363
+ if (terminal)
364
+ yield terminal;
365
+ return;
366
+ }
367
+ const exception = toIndeRunException(err, {
368
+ providerId,
369
+ runId,
370
+ details: { attemptedProviderIds }
371
+ });
372
+ if (!committed) {
373
+ safeEmit({
374
+ type: "stream_attempt_failed",
375
+ runId,
376
+ timestamp: now(),
377
+ payload: {
378
+ providerId,
379
+ errorClass: exception.errorClass,
380
+ message: getStableMessage(exception.errorClass)
381
+ }
382
+ });
383
+ continue;
384
+ }
385
+ const outcome = {
386
+ outcome: "error",
387
+ runId,
388
+ schemaVersion: "1.0",
389
+ error: exception.toContractError(),
390
+ partialText
391
+ };
392
+ const terminal = gate.terminate(outcome, now());
393
+ safeEmit({
394
+ type: "stream_failed",
395
+ runId,
396
+ timestamp: now(),
397
+ payload: {
398
+ providerId,
399
+ errorClass: exception.errorClass,
400
+ message: getStableMessage(exception.errorClass),
401
+ attemptedProviderIds
402
+ }
403
+ });
404
+ if (terminal)
405
+ yield terminal;
406
+ return;
407
+ }
408
+ }
409
+ // Every provider failed pre-commit, or cancellation landed before any attempt started.
410
+ if (controller.signal.aborted) {
411
+ const terminal = gate.terminate(cancelledOutcome(""), now());
412
+ safeEmit({
413
+ type: "stream_cancelled",
414
+ runId,
415
+ timestamp: now(),
416
+ payload: { attemptedProviderIds }
417
+ });
418
+ if (terminal)
419
+ yield terminal;
420
+ return;
421
+ }
422
+ const exception = createUnavailable("All eligible streaming providers failed.", {
423
+ runId,
424
+ details: { attemptedProviderIds }
425
+ });
426
+ const outcome = {
427
+ outcome: "error",
428
+ runId,
429
+ schemaVersion: "1.0",
430
+ error: exception.toContractError(),
431
+ partialText: ""
432
+ };
433
+ const terminal = gate.terminate(outcome, now());
434
+ safeEmit({
435
+ type: "stream_failed",
436
+ runId,
437
+ timestamp: now(),
438
+ payload: {
439
+ errorClass: exception.errorClass,
440
+ message: getStableMessage(exception.errorClass),
441
+ attemptedProviderIds
442
+ }
443
+ });
444
+ if (terminal)
445
+ yield terminal;
446
+ }
447
+ return { handle, events: run(), cancel: (reason) => controller.abort(reason) };
448
+ }
193
449
  /**
194
450
  * Reports each registered provider's static descriptor and current dynamic capability check,
195
451
  * without executing a task. Useful for UI that shows live provider availability before a run.
@@ -0,0 +1,37 @@
1
+ import type { StreamEvent, StreamTerminalOutcome } from "@independo/inderun-contracts";
2
+ /**
3
+ * Per-run gatekeeper for Mode 2 streaming. Enforces the two structural guarantees
4
+ * required by the streaming orchestrator: exactly one terminal outcome is ever
5
+ * produced for a run, and no event is admitted after that terminal outcome fires.
6
+ *
7
+ * Correctness relies on `admit`/`terminate` performing their check-and-set
8
+ * synchronously with no `await` in between — safe under JS's single-threaded,
9
+ * run-to-completion semantics even with interleaved `await` resumption elsewhere
10
+ * (e.g. a provider's async iterator and a caller's `cancel()` racing).
11
+ */
12
+ export declare class EventGate {
13
+ private readonly runId;
14
+ private sequence;
15
+ private terminated;
16
+ private terminalOutcome;
17
+ constructor(runId: string);
18
+ /**
19
+ * Admits a non-terminal StreamEvent, assigning it the next monotonic sequence
20
+ * number. Returns null (suppressing the event) if the run has already terminated.
21
+ */
22
+ admit(event: {
23
+ timestamp: number;
24
+ type: string;
25
+ payload?: StreamEvent["payload"];
26
+ }): StreamEvent | null;
27
+ /**
28
+ * Terminates the run with the given outcome. First writer wins: only the first
29
+ * call produces a terminal StreamEvent and stores the outcome; every subsequent
30
+ * call (duplicate provider "done", late error after cancel, concurrent cancel()
31
+ * calls) is a silent no-op that returns null, making repeated cancellation safe.
32
+ */
33
+ terminate(outcome: StreamTerminalOutcome, timestamp: number): StreamEvent | null;
34
+ isTerminated(): boolean;
35
+ getOutcome(): StreamTerminalOutcome | undefined;
36
+ }
37
+ //# sourceMappingURL=event-gate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-gate.d.ts","sourceRoot":"","sources":["../../src/core/event-gate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAEvF;;;;;;;;;GASG;AACH,qBAAa,SAAS;IAKR,OAAO,CAAC,QAAQ,CAAC,KAAK;IAJlC,OAAO,CAAC,QAAQ,CAAK;IACrB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,eAAe,CAAoC;gBAE9B,KAAK,EAAE,MAAM;IAE1C;;;OAGG;IACH,KAAK,CAAC,KAAK,EAAE;QACX,SAAS,EAAE,MAAM,CAAC;QAClB,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,CAAC,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC;KAClC,GAAG,WAAW,GAAG,IAAI;IActB;;;;;OAKG;IACH,SAAS,CAAC,OAAO,EAAE,qBAAqB,EAAE,SAAS,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI;IAgBhF,YAAY,IAAI,OAAO;IAIvB,UAAU,IAAI,qBAAqB,GAAG,SAAS;CAGhD"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Per-run gatekeeper for Mode 2 streaming. Enforces the two structural guarantees
3
+ * required by the streaming orchestrator: exactly one terminal outcome is ever
4
+ * produced for a run, and no event is admitted after that terminal outcome fires.
5
+ *
6
+ * Correctness relies on `admit`/`terminate` performing their check-and-set
7
+ * synchronously with no `await` in between — safe under JS's single-threaded,
8
+ * run-to-completion semantics even with interleaved `await` resumption elsewhere
9
+ * (e.g. a provider's async iterator and a caller's `cancel()` racing).
10
+ */
11
+ export class EventGate {
12
+ runId;
13
+ sequence = 0;
14
+ terminated = false;
15
+ terminalOutcome;
16
+ constructor(runId) {
17
+ this.runId = runId;
18
+ }
19
+ /**
20
+ * Admits a non-terminal StreamEvent, assigning it the next monotonic sequence
21
+ * number. Returns null (suppressing the event) if the run has already terminated.
22
+ */
23
+ admit(event) {
24
+ if (this.terminated) {
25
+ return null;
26
+ }
27
+ return {
28
+ runId: this.runId,
29
+ schemaVersion: "1.0",
30
+ sequence: this.sequence++,
31
+ timestamp: event.timestamp,
32
+ type: event.type,
33
+ ...(event.payload !== undefined ? { payload: event.payload } : {})
34
+ };
35
+ }
36
+ /**
37
+ * Terminates the run with the given outcome. First writer wins: only the first
38
+ * call produces a terminal StreamEvent and stores the outcome; every subsequent
39
+ * call (duplicate provider "done", late error after cancel, concurrent cancel()
40
+ * calls) is a silent no-op that returns null, making repeated cancellation safe.
41
+ */
42
+ terminate(outcome, timestamp) {
43
+ if (this.terminated) {
44
+ return null;
45
+ }
46
+ this.terminated = true;
47
+ this.terminalOutcome = outcome;
48
+ return {
49
+ runId: this.runId,
50
+ schemaVersion: "1.0",
51
+ sequence: this.sequence++,
52
+ timestamp,
53
+ type: "terminal",
54
+ payload: outcome
55
+ };
56
+ }
57
+ isTerminated() {
58
+ return this.terminated;
59
+ }
60
+ getOutcome() {
61
+ return this.terminalOutcome;
62
+ }
63
+ }
@@ -118,6 +118,42 @@ export interface RunContext {
118
118
  */
119
119
  hostServices: HostServices;
120
120
  }
121
+ /**
122
+ * Execution context passed to provider stream commands. Extends RunContext with the
123
+ * caller-driven cancellation signal; the Engine core owns the AbortController and
124
+ * threads its signal here, so providers never need to construct their own.
125
+ */
126
+ export interface ProviderStreamContext extends RunContext {
127
+ /**
128
+ * Signals caller-driven cancellation of this stream. Providers with `cancel: "hard"`
129
+ * should tear down their connection immediately on abort; `cancel: "soft"` providers
130
+ * may stop relaying events without interrupting underlying local work; `cancel:
131
+ * "none"` providers may ignore it entirely; the engine enforces the caller-visible
132
+ * cancellation guarantee at the consumer loop regardless of what the provider does.
133
+ */
134
+ signal: AbortSignal;
135
+ }
136
+ /**
137
+ * A raw, provider-shaped streaming event yielded by ProviderAdapter.stream(). This is
138
+ * intentionally distinct from the canonical StreamEvent contract: providers emit
139
+ * provider-shaped deltas here, and the Engine core's Event Gate normalizes these into
140
+ * StreamEvent/StreamTerminalOutcome, keeping provider-specific mechanics from leaking
141
+ * through the public API.
142
+ */
143
+ export type ProviderStreamEvent = {
144
+ kind: "delta";
145
+ text: string;
146
+ } | {
147
+ kind: "snapshot";
148
+ text: string;
149
+ } | {
150
+ kind: "done";
151
+ finalText: string;
152
+ usage?: TaskResult["usage"];
153
+ } | {
154
+ kind: "error";
155
+ error: unknown;
156
+ };
121
157
  /**
122
158
  * Pluggable execution adapter contract that wraps a specific model runtime
123
159
  * (system frameworks, local runtimes, or cloud APIs) and exposes normalized APIs.
@@ -135,5 +171,10 @@ export interface ProviderAdapter {
135
171
  * Executes a task request in Mode 1 (request/response).
136
172
  */
137
173
  run(req: TaskRequest, ctx: RunContext): Promise<TaskResult>;
174
+ /**
175
+ * Executes a task request in Mode 2 (streaming). Optional: only providers declaring
176
+ * `describe().supports.streaming === true` are expected to implement this.
177
+ */
178
+ stream?(req: TaskRequest, ctx: ProviderStreamContext): AsyncIterable<ProviderStreamEvent>;
138
179
  }
139
180
  //# sourceMappingURL=provider.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../src/core/provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC5E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAE9C;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC;;OAEG;IACH,EAAE,EAAE,MAAM,CAAC;IACX;;OAEG;IACH,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC;IACjC;;OAEG;IACH,SAAS,EAAE,YAAY,GAAG,gBAAgB,GAAG,MAAM,GAAG,KAAK,GAAG,UAAU,CAAC;IACzE;;OAEG;IACH,cAAc,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,WAAW,CAAC;IAEnD;;OAEG;IACH,QAAQ,EAAE;QACR,mEAAmE;QACnE,GAAG,EAAE,OAAO,CAAC;QACb,mDAAmD;QACnD,SAAS,EAAE,OAAO,CAAC;QACnB,6DAA6D;QAC7D,QAAQ,EAAE,OAAO,CAAC;QAClB,6DAA6D;QAC7D,KAAK,EAAE,OAAO,CAAC;QACf,wEAAwE;QACxE,eAAe,EAAE,OAAO,CAAC;QACzB,kFAAkF;QAClF,gBAAgB,EAAE,OAAO,CAAC;QAC1B,6EAA6E;QAC7E,UAAU,EAAE,OAAO,CAAC;KACrB,CAAC;IAEF;;;;;OAKG;IACH,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;IAEjC;;OAEG;IACH,KAAK,EAAE,MAAM,EAAE,CAAC;IAEhB;;OAEG;IACH,MAAM,CAAC,EAAE;QACP,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,CAAC;IAEF;;OAEG;IACH,OAAO,CAAC,EAAE;QACR,6DAA6D;QAC7D,gBAAgB,EAAE,OAAO,CAAC;QAC1B,2DAA2D;QAC3D,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;KACpB,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,2BAA2B;IAC1C;;OAEG;IACH,SAAS,EAAE,OAAO,CAAC;IACnB;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;GAGG;AACH,MAAM,WAAW,0BAA0B;IACzC;;;OAGG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,UAAU,EAAE,kBAAkB,CAAC;IAC/B;;;OAGG;IACH,YAAY,EAAE,2BAA2B,CAAC;CAC3C;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,YAAY,EAAE,YAAY,CAAC;CAC5B;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B;;OAEG;IACH,QAAQ,IAAI,kBAAkB,CAAC;IAC/B;;OAEG;IACH,YAAY,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,2BAA2B,CAAC,CAAC;IACvE;;OAEG;IACH,GAAG,CAAC,GAAG,EAAE,WAAW,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;CAC7D"}
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../src/core/provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC5E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAE9C;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC;;OAEG;IACH,EAAE,EAAE,MAAM,CAAC;IACX;;OAEG;IACH,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC;IACjC;;OAEG;IACH,SAAS,EAAE,YAAY,GAAG,gBAAgB,GAAG,MAAM,GAAG,KAAK,GAAG,UAAU,CAAC;IACzE;;OAEG;IACH,cAAc,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,WAAW,CAAC;IAEnD;;OAEG;IACH,QAAQ,EAAE;QACR,mEAAmE;QACnE,GAAG,EAAE,OAAO,CAAC;QACb,mDAAmD;QACnD,SAAS,EAAE,OAAO,CAAC;QACnB,6DAA6D;QAC7D,QAAQ,EAAE,OAAO,CAAC;QAClB,6DAA6D;QAC7D,KAAK,EAAE,OAAO,CAAC;QACf,wEAAwE;QACxE,eAAe,EAAE,OAAO,CAAC;QACzB,kFAAkF;QAClF,gBAAgB,EAAE,OAAO,CAAC;QAC1B,6EAA6E;QAC7E,UAAU,EAAE,OAAO,CAAC;KACrB,CAAC;IAEF;;;;;OAKG;IACH,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;IAEjC;;OAEG;IACH,KAAK,EAAE,MAAM,EAAE,CAAC;IAEhB;;OAEG;IACH,MAAM,CAAC,EAAE;QACP,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,CAAC;IAEF;;OAEG;IACH,OAAO,CAAC,EAAE;QACR,6DAA6D;QAC7D,gBAAgB,EAAE,OAAO,CAAC;QAC1B,2DAA2D;QAC3D,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;KACpB,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,2BAA2B;IAC1C;;OAEG;IACH,SAAS,EAAE,OAAO,CAAC;IACnB;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;GAGG;AACH,MAAM,WAAW,0BAA0B;IACzC;;;OAGG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,UAAU,EAAE,kBAAkB,CAAC;IAC/B;;;OAGG;IACH,YAAY,EAAE,2BAA2B,CAAC;CAC3C;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,YAAY,EAAE,YAAY,CAAC;CAC5B;AAED;;;;GAIG;AACH,MAAM,WAAW,qBAAsB,SAAQ,UAAU;IACvD;;;;;;OAMG;IACH,MAAM,EAAE,WAAW,CAAC;CACrB;AAED;;;;;;GAMG;AACH,MAAM,MAAM,mBAAmB,GAC3B;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC/B;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,CAAA;CAAE,GAChE;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAAC;AAEtC;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B;;OAEG;IACH,QAAQ,IAAI,kBAAkB,CAAC;IAC/B;;OAEG;IACH,YAAY,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,2BAA2B,CAAC,CAAC;IACvE;;OAEG;IACH,GAAG,CAAC,GAAG,EAAE,WAAW,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAC5D;;;OAGG;IACH,MAAM,CAAC,CAAC,GAAG,EAAE,WAAW,EAAE,GAAG,EAAE,qBAAqB,GAAG,aAAa,CAAC,mBAAmB,CAAC,CAAC;CAC3F"}
package/dist/index.d.ts CHANGED
@@ -1,10 +1,11 @@
1
1
  export { type ConnectivityService, type DeviceConstraintsService, type SecureStorageService, type ClockService, type HttpClientService, type HttpRequest, type HttpResponse, type HostServices, type ThermalState } from "./core/host.js";
2
- export { type ProviderDescriptor, type ProviderDynamicCapabilities, type ProviderCapabilitySnapshot, type RunContext, type ProviderAdapter } from "./core/provider.js";
2
+ export { type ProviderDescriptor, type ProviderDynamicCapabilities, type ProviderCapabilitySnapshot, type RunContext, type ProviderAdapter, type ProviderStreamContext, type ProviderStreamEvent } from "./core/provider.js";
3
+ export { EventGate } from "./core/event-gate.js";
3
4
  export { ProviderRegistry } from "./core/registry.js";
4
5
  export { type RouteSelection, Router } from "./core/router.js";
5
6
  export { type RoutePlanner, type PlannerOutcome, type WasmUnavailableReason, type SharedPlannerInput, type SharedPlannerRoutePlan, WasmRoutePlanner } from "./core/route-planner.js";
6
7
  export { type IndeRunExceptionParams, IndeRunException, createCapabilityMismatch, createOffline, createAuthError, createRateLimited, createTimeout, createUnavailable, createInternal, toIndeRunException } from "./core/errors.js";
7
- export { IndeRun } from "./core/engine.js";
8
+ export { IndeRun, type StreamHandleResult } from "./core/engine.js";
8
9
  export type { IndeRunApi } from "./core/generated/inderun-api.js";
9
10
  export { type TelemetryEventType, type TelemetryEvent, type TelemetryService, NoOpTelemetryService } from "./core/telemetry.js";
10
11
  export { BrowserConnectivityService, FetchHttpClient, SystemClockService, createBrowserHostServices, type CreateBrowserHostServicesOptions, type FetchHttpClientOptions } from "./core/browser-host.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,wBAAwB,EAC7B,KAAK,oBAAoB,EACzB,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACtB,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,YAAY,EAClB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,2BAA2B,EAChC,KAAK,0BAA0B,EAC/B,KAAK,UAAU,EACf,KAAK,eAAe,EACrB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC/D,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,qBAAqB,EAC1B,KAAK,kBAAkB,EACvB,KAAK,sBAAsB,EAC3B,gBAAgB,EACjB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACL,KAAK,sBAAsB,EAC3B,gBAAgB,EAChB,wBAAwB,EACxB,aAAa,EACb,eAAe,EACf,iBAAiB,EACjB,aAAa,EACb,iBAAiB,EACjB,cAAc,EACd,kBAAkB,EACnB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,YAAY,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAElE,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,oBAAoB,EACrB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,0BAA0B,EAC1B,eAAe,EACf,kBAAkB,EAClB,yBAAyB,EACzB,KAAK,gCAAgC,EACrC,KAAK,sBAAsB,EAC5B,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,gBAAgB,EAAE,KAAK,uBAAuB,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,wBAAwB,EAC7B,KAAK,oBAAoB,EACzB,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACtB,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,YAAY,EAClB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,2BAA2B,EAChC,KAAK,0BAA0B,EAC/B,KAAK,UAAU,EACf,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EACzB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC/D,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,qBAAqB,EAC1B,KAAK,kBAAkB,EACvB,KAAK,sBAAsB,EAC3B,gBAAgB,EACjB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACL,KAAK,sBAAsB,EAC3B,gBAAgB,EAChB,wBAAwB,EACxB,aAAa,EACb,eAAe,EACf,iBAAiB,EACjB,aAAa,EACb,iBAAiB,EACjB,cAAc,EACd,kBAAkB,EACnB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACpE,YAAY,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAElE,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,oBAAoB,EACrB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,0BAA0B,EAC1B,eAAe,EACf,kBAAkB,EAClB,yBAAyB,EACzB,KAAK,gCAAgC,EACrC,KAAK,sBAAsB,EAC5B,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,gBAAgB,EAAE,KAAK,uBAAuB,EAAE,MAAM,cAAc,CAAC"}
package/dist/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  export {} from "./core/host.js";
2
2
  export {} from "./core/provider.js";
3
+ export { EventGate } from "./core/event-gate.js";
3
4
  export { ProviderRegistry } from "./core/registry.js";
4
5
  export { Router } from "./core/router.js";
5
6
  export { WasmRoutePlanner } from "./core/route-planner.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@independo/inderun-web",
3
- "version": "0.3.0-dev.1",
3
+ "version": "0.3.0-dev.3",
4
4
  "description": "TypeScript/Web SDK for IndeRun.",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -55,8 +55,8 @@
55
55
  "README.md"
56
56
  ],
57
57
  "dependencies": {
58
- "@independo/inderun-route-core-wasm": "^0.3.0-dev.1",
59
- "@independo/inderun-contracts": "^0.3.0-dev.1"
58
+ "@independo/inderun-contracts": "^0.3.0-dev.3",
59
+ "@independo/inderun-route-core-wasm": "^0.3.0-dev.3"
60
60
  },
61
61
  "peerDependencies": {
62
62
  "@huggingface/transformers": "^4.0.0"