@relayflows/sdk 2.0.34 → 2.0.36
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/adapters/base.d.ts +16 -0
- package/dist/adapters/base.d.ts.map +1 -1
- package/dist/adapters/claude.d.ts.map +1 -1
- package/dist/adapters/claude.js +15 -0
- package/dist/adapters/claude.js.map +1 -1
- package/dist/adapters/codex.d.ts.map +1 -1
- package/dist/adapters/codex.js +4 -0
- package/dist/adapters/codex.js.map +1 -1
- package/dist/adapters/usage-limit.d.ts +2 -0
- package/dist/adapters/usage-limit.d.ts.map +1 -0
- package/dist/adapters/usage-limit.js +17 -0
- package/dist/adapters/usage-limit.js.map +1 -0
- package/dist/authored-activity.d.ts +17 -0
- package/dist/authored-activity.d.ts.map +1 -0
- package/dist/authored-activity.js +218 -0
- package/dist/authored-activity.js.map +1 -0
- package/dist/authored-child-run.d.ts +34 -0
- package/dist/authored-child-run.d.ts.map +1 -0
- package/dist/authored-child-run.js +128 -0
- package/dist/authored-child-run.js.map +1 -0
- package/dist/authored-dispatch.d.ts +24 -0
- package/dist/authored-dispatch.d.ts.map +1 -0
- package/dist/authored-dispatch.js +81 -0
- package/dist/authored-dispatch.js.map +1 -0
- package/dist/authored-flow-error.d.ts +32 -3
- package/dist/authored-flow-error.d.ts.map +1 -1
- package/dist/authored-flow-error.js +3 -1
- package/dist/authored-flow-error.js.map +1 -1
- package/dist/authored-flow-executor.d.ts +26 -1
- package/dist/authored-flow-executor.d.ts.map +1 -1
- package/dist/authored-flow-executor.js +122 -16
- package/dist/authored-flow-executor.js.map +1 -1
- package/dist/authored-flow-loader.d.ts.map +1 -1
- package/dist/authored-flow-loader.js +9 -0
- package/dist/authored-flow-loader.js.map +1 -1
- package/dist/authored-mcp.js +2 -2
- package/dist/authored-mcp.js.map +1 -1
- package/dist/authored-node-entry.js +4 -1
- package/dist/authored-node-entry.js.map +1 -1
- package/dist/authored-node-runner.d.ts.map +1 -1
- package/dist/authored-node-runner.js +40 -8
- package/dist/authored-node-runner.js.map +1 -1
- package/dist/authored-plugin-effect.js +2 -2
- package/dist/authored-plugin-effect.js.map +1 -1
- package/dist/authored-root.d.ts +10 -7
- package/dist/authored-root.d.ts.map +1 -1
- package/dist/authored-root.js +20 -0
- package/dist/authored-root.js.map +1 -1
- package/dist/authored-step-output.d.ts +24 -8
- package/dist/authored-step-output.d.ts.map +1 -1
- package/dist/authored-step-output.js +81 -15
- package/dist/authored-step-output.js.map +1 -1
- package/dist/authored-subscription-park.d.ts +5 -0
- package/dist/authored-subscription-park.d.ts.map +1 -0
- package/dist/authored-subscription-park.js +47 -0
- package/dist/authored-subscription-park.js.map +1 -0
- package/dist/authored-worker-step.d.ts +3 -1
- package/dist/authored-worker-step.d.ts.map +1 -1
- package/dist/authored-worker-step.js +25 -9
- package/dist/authored-worker-step.js.map +1 -1
- package/dist/cli/check-activities.d.ts +8 -0
- package/dist/cli/check-activities.d.ts.map +1 -0
- package/dist/cli/check-activities.js +155 -0
- package/dist/cli/check-activities.js.map +1 -0
- package/dist/cli/cli-probe.d.ts.map +1 -1
- package/dist/cli/cli-probe.js +14 -2
- package/dist/cli/cli-probe.js.map +1 -1
- package/dist/cli/direct-run.d.ts.map +1 -1
- package/dist/cli/direct-run.js +10 -2
- package/dist/cli/direct-run.js.map +1 -1
- package/dist/cli/run.d.ts +23 -5
- package/dist/cli/run.d.ts.map +1 -1
- package/dist/cli/run.js +32 -5
- package/dist/cli/run.js.map +1 -1
- package/dist/cli/subscription-report.d.ts +5 -0
- package/dist/cli/subscription-report.d.ts.map +1 -0
- package/dist/cli/subscription-report.js +48 -0
- package/dist/cli/subscription-report.js.map +1 -0
- package/dist/cli-adapter.d.ts +4 -2
- package/dist/cli-adapter.d.ts.map +1 -1
- package/dist/cli-adapter.js +4 -0
- package/dist/cli-adapter.js.map +1 -1
- package/dist/cli.d.ts +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +16 -5
- package/dist/cli.js.map +1 -1
- package/dist/cloud-mirror-step.d.ts +2 -0
- package/dist/cloud-mirror-step.d.ts.map +1 -1
- package/dist/cloud-mirror-step.js +9 -1
- package/dist/cloud-mirror-step.js.map +1 -1
- package/dist/cloud-mirror.d.ts.map +1 -1
- package/dist/cloud-mirror.js +17 -2
- package/dist/cloud-mirror.js.map +1 -1
- package/dist/failure-kinds.d.ts +2 -2
- package/dist/failure-kinds.d.ts.map +1 -1
- package/dist/failure-kinds.js +2 -0
- package/dist/failure-kinds.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/journal-client.d.ts +17 -2
- package/dist/journal-client.d.ts.map +1 -1
- package/dist/journal-client.js +33 -2
- package/dist/journal-client.js.map +1 -1
- package/dist/journal-reader.d.ts.map +1 -1
- package/dist/journal-reader.js +2 -0
- package/dist/journal-reader.js.map +1 -1
- package/dist/local-agent.d.ts +4 -1
- package/dist/local-agent.d.ts.map +1 -1
- package/dist/local-agent.js +14 -4
- package/dist/local-agent.js.map +1 -1
- package/dist/preflight.d.ts +6 -0
- package/dist/preflight.d.ts.map +1 -1
- package/dist/preflight.js +36 -10
- package/dist/preflight.js.map +1 -1
- package/dist/protocol.d.ts +166 -1
- package/dist/protocol.d.ts.map +1 -1
- package/dist/step-settling.d.ts +11 -0
- package/dist/step-settling.d.ts.map +1 -0
- package/dist/step-settling.js +22 -0
- package/dist/step-settling.js.map +1 -0
- package/dist/worker-slots.d.ts +15 -0
- package/dist/worker-slots.d.ts.map +1 -1
- package/dist/worker-slots.js +40 -3
- package/dist/worker-slots.js.map +1 -1
- package/package.json +2 -2
- package/src/adapters/base.ts +19 -0
- package/src/adapters/claude.ts +15 -0
- package/src/adapters/codex.ts +6 -0
- package/src/adapters/usage-limit.ts +17 -0
- package/src/authored-activity.ts +251 -0
- package/src/authored-child-run.ts +138 -0
- package/src/authored-dispatch.ts +113 -0
- package/src/authored-flow-error.ts +36 -0
- package/src/authored-flow-executor.ts +166 -15
- package/src/authored-flow-loader.ts +12 -0
- package/src/authored-mcp.ts +2 -2
- package/src/authored-node-entry.ts +4 -1
- package/src/authored-node-runner.ts +41 -8
- package/src/authored-plugin-effect.ts +2 -2
- package/src/authored-root.ts +28 -4
- package/src/authored-step-output.ts +88 -15
- package/src/authored-subscription-park.ts +46 -0
- package/src/authored-worker-step.ts +24 -8
- package/src/cli/check-activities.ts +144 -0
- package/src/cli/cli-probe.ts +15 -3
- package/src/cli/direct-run.ts +9 -0
- package/src/cli/run.ts +56 -9
- package/src/cli/subscription-report.ts +51 -0
- package/src/cli-adapter.ts +8 -2
- package/src/cli.ts +16 -6
- package/src/cloud-mirror-step.ts +16 -2
- package/src/cloud-mirror.ts +15 -2
- package/src/failure-kinds.ts +2 -0
- package/src/index.ts +6 -0
- package/src/journal-client.ts +47 -3
- package/src/journal-reader.ts +2 -0
- package/src/local-agent.ts +17 -3
- package/src/preflight.ts +46 -10
- package/src/protocol.ts +129 -0
- package/src/step-settling.ts +19 -0
- package/src/worker-slots.ts +63 -4
package/src/protocol.ts
CHANGED
|
@@ -53,8 +53,16 @@ export type Verb =
|
|
|
53
53
|
| 'effect.confirm'
|
|
54
54
|
| 'step.complete'
|
|
55
55
|
| 'step.wait'
|
|
56
|
+
| 'subscription.park'
|
|
56
57
|
| 'event.emit'
|
|
57
58
|
| 'event.submit'
|
|
59
|
+
| 'subscription.open'
|
|
60
|
+
| 'subscription.activate'
|
|
61
|
+
| 'subscription.deliver'
|
|
62
|
+
| 'subscription.inspect'
|
|
63
|
+
| 'subscription.fence_overflow'
|
|
64
|
+
| 'subscription.next'
|
|
65
|
+
| 'subscription.close'
|
|
58
66
|
| 'channel.append'
|
|
59
67
|
| 'channel.receive'
|
|
60
68
|
| 'channel.ack'
|
|
@@ -362,6 +370,10 @@ export interface EventEmitParams {
|
|
|
362
370
|
run_id: string;
|
|
363
371
|
event_key: string;
|
|
364
372
|
payload: unknown;
|
|
373
|
+
/** Provider delivery id for body activities. Required by Cloud; optional for legacy exact waits. */
|
|
374
|
+
delivery_id?: string;
|
|
375
|
+
/** Provider actor identity, used by the local router adapter for self filtering. */
|
|
376
|
+
actor?: string;
|
|
365
377
|
}
|
|
366
378
|
export interface EventEmitResult {
|
|
367
379
|
matched: number;
|
|
@@ -388,6 +400,111 @@ export interface EventSubmitResult {
|
|
|
388
400
|
run?: unknown;
|
|
389
401
|
}
|
|
390
402
|
|
|
403
|
+
/** Body-level activity open; the server acknowledges only after its fenced binding is durable. */
|
|
404
|
+
export interface SubscriptionOpenParams {
|
|
405
|
+
run_id: string;
|
|
406
|
+
subscription_id: string;
|
|
407
|
+
event_types: string[];
|
|
408
|
+
pattern?: Record<string, unknown>;
|
|
409
|
+
settle_ms: number;
|
|
410
|
+
idle_ms: number;
|
|
411
|
+
deadline_ms: number;
|
|
412
|
+
include_self: boolean;
|
|
413
|
+
}
|
|
414
|
+
export type SubscriptionOpenResult =
|
|
415
|
+
| {
|
|
416
|
+
/** Immutable snapshot from the durable `subscription.prepared` entry. */
|
|
417
|
+
state: 'prepared';
|
|
418
|
+
subscription_id: string;
|
|
419
|
+
event_types: string[];
|
|
420
|
+
pattern?: Record<string, unknown>;
|
|
421
|
+
stream: string;
|
|
422
|
+
settle_ms: number;
|
|
423
|
+
idle_ms: number;
|
|
424
|
+
deadline_at_ms: number;
|
|
425
|
+
include_self: boolean;
|
|
426
|
+
}
|
|
427
|
+
| {
|
|
428
|
+
state: 'active';
|
|
429
|
+
subscription_id: string;
|
|
430
|
+
stream: string;
|
|
431
|
+
deadline_at_ms: number;
|
|
432
|
+
};
|
|
433
|
+
|
|
434
|
+
/** Cloud supplies this receipt only after it has durably fenced its binding. */
|
|
435
|
+
export interface SubscriptionActivateParams {
|
|
436
|
+
run_id: string;
|
|
437
|
+
subscription_id: string;
|
|
438
|
+
ingress_offset: number;
|
|
439
|
+
router_binding: Record<string, unknown>;
|
|
440
|
+
}
|
|
441
|
+
export interface SubscriptionActivateResult {
|
|
442
|
+
state: 'active';
|
|
443
|
+
subscription_id: string;
|
|
444
|
+
stream: string;
|
|
445
|
+
deadline_at_ms: number;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
/** Targeted Cloud ingress; receipt must equal the journaled activation receipt. */
|
|
449
|
+
export interface SubscriptionDeliverParams {
|
|
450
|
+
run_id: string;
|
|
451
|
+
subscription_id: string;
|
|
452
|
+
router_binding: Record<string, unknown>;
|
|
453
|
+
delivery_id: string;
|
|
454
|
+
frame: unknown;
|
|
455
|
+
}
|
|
456
|
+
export interface SubscriptionDeliverResult {
|
|
457
|
+
/** False for an idempotent duplicate or a frame that closes on overflow. */
|
|
458
|
+
appended: boolean;
|
|
459
|
+
reason?: 'duplicate' | 'overflow';
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
/** Read-only projection of the kernel's durable subscription records. */
|
|
463
|
+
export interface SubscriptionSnapshot {
|
|
464
|
+
subscriptionId: string;
|
|
465
|
+
state: 'prepared' | 'active' | 'closed';
|
|
466
|
+
completionReason?: 'closed' | 'run_completed' | 'canceled' | 'deadline' | 'overflow';
|
|
467
|
+
routerBinding?: Record<string, unknown>;
|
|
468
|
+
ingressOffset?: number;
|
|
469
|
+
unreadFrames: number;
|
|
470
|
+
unreadBytes: number;
|
|
471
|
+
settleMs: number;
|
|
472
|
+
idleAtMs?: number;
|
|
473
|
+
deadlineAtMs: number;
|
|
474
|
+
}
|
|
475
|
+
export interface SubscriptionInspectParams { run_id: string }
|
|
476
|
+
export interface SubscriptionInspectResult { subscriptions: SubscriptionSnapshot[] }
|
|
477
|
+
export interface SubscriptionFenceOverflowParams {
|
|
478
|
+
run_id: string;
|
|
479
|
+
subscription_id: string;
|
|
480
|
+
router_binding: Record<string, unknown>;
|
|
481
|
+
}
|
|
482
|
+
export interface SubscriptionFenceOverflowResult { fenced: true }
|
|
483
|
+
|
|
484
|
+
export interface SubscriptionNextParams {
|
|
485
|
+
run_id: string;
|
|
486
|
+
subscription_id: string;
|
|
487
|
+
/** Internal durable receipt for the prior normal wake, supplied with the next pull. */
|
|
488
|
+
acknowledge_wait_id?: string;
|
|
489
|
+
/** Body call ordinal: replay this pull's durable wake across process restarts. */
|
|
490
|
+
sequence?: number;
|
|
491
|
+
}
|
|
492
|
+
export type SubscriptionNextResult =
|
|
493
|
+
| { kind: 'suspended'; subscription_id: string; stream: string; deadline_at_ms: number }
|
|
494
|
+
| { kind: 'events'; events: unknown[]; offset: number; acknowledge_wait_id?: string }
|
|
495
|
+
| { kind: 'idle'; acknowledge_wait_id?: string }
|
|
496
|
+
| { kind: 'deadline'; pending: { from: number; to: number } | null }
|
|
497
|
+
| { kind: 'overflow'; retained: number; bytes: number; from: number };
|
|
498
|
+
|
|
499
|
+
export interface SubscriptionCloseParams {
|
|
500
|
+
run_id: string;
|
|
501
|
+
subscription_id: string;
|
|
502
|
+
completion_reason: 'closed' | 'run_completed' | 'canceled';
|
|
503
|
+
}
|
|
504
|
+
export interface SubscriptionCloseResult {
|
|
505
|
+
closed: string;
|
|
506
|
+
}
|
|
507
|
+
|
|
391
508
|
export interface StreamAppendParams {
|
|
392
509
|
run_id: string;
|
|
393
510
|
stream: string;
|
|
@@ -441,8 +558,20 @@ export interface VerbContract {
|
|
|
441
558
|
'effect.confirm': { params: EffectConfirmParams; result: EffectConfirmResult };
|
|
442
559
|
'step.complete': { params: StepCompleteParams; result: StepCompleteResult };
|
|
443
560
|
'step.wait': { params: StepWaitParams; result: StepWaitResult };
|
|
561
|
+
'subscription.park': {
|
|
562
|
+
params: { run_id: string; step_id: string; attempt: number; idempotency_key: string;
|
|
563
|
+
subscription_id: string; phase: 'activation' | 'event_wait' };
|
|
564
|
+
result: RunOutcome;
|
|
565
|
+
};
|
|
444
566
|
'event.emit': { params: EventEmitParams; result: EventEmitResult };
|
|
445
567
|
'event.submit': { params: EventSubmitParams; result: EventSubmitResult };
|
|
568
|
+
'subscription.open': { params: SubscriptionOpenParams; result: SubscriptionOpenResult };
|
|
569
|
+
'subscription.activate': { params: SubscriptionActivateParams; result: SubscriptionActivateResult };
|
|
570
|
+
'subscription.deliver': { params: SubscriptionDeliverParams; result: SubscriptionDeliverResult };
|
|
571
|
+
'subscription.inspect': { params: SubscriptionInspectParams; result: SubscriptionInspectResult };
|
|
572
|
+
'subscription.fence_overflow': { params: SubscriptionFenceOverflowParams; result: SubscriptionFenceOverflowResult };
|
|
573
|
+
'subscription.next': { params: SubscriptionNextParams; result: SubscriptionNextResult };
|
|
574
|
+
'subscription.close': { params: SubscriptionCloseParams; result: SubscriptionCloseResult };
|
|
446
575
|
'stream.append': { params: StreamAppendParams; result: StreamAppendResult };
|
|
447
576
|
'stream.read': { params: StreamReadParams; result: StreamReadResult };
|
|
448
577
|
'journal.read': { params: JournalReadParams; result: JournalReadResult };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A step's LAST settling `step.completed`: the verdict the kernel settled the
|
|
3
|
+
* step on. `retry` and `park` completions record an attempt the kernel did
|
|
4
|
+
* NOT settle it on (relayflowd-core `Disposition`) — crash recovery's
|
|
5
|
+
* `crashed`, a `worker_error` with iterations left — and precede the attempt
|
|
6
|
+
* that did, so neither the first completion nor a completion count is the
|
|
7
|
+
* step's verdict. Shared by the authored reader and the Bun result verifier,
|
|
8
|
+
* which must agree on which completion a claim is judged against.
|
|
9
|
+
*/
|
|
10
|
+
export function settlingCompletion<T>(entries: readonly T[], stepId: string): T | undefined {
|
|
11
|
+
return entries.filter(entry => {
|
|
12
|
+
if (typeof entry !== 'object' || entry === null) return false;
|
|
13
|
+
const { entry_type: type, step_id: step, payload } = entry as Record<string, unknown>;
|
|
14
|
+
if (type !== 'step.completed' || step !== stepId) return false;
|
|
15
|
+
const disposition = typeof payload === 'object' && payload !== null
|
|
16
|
+
? (payload as Record<string, unknown>)['disposition'] : undefined;
|
|
17
|
+
return disposition !== 'retry' && disposition !== 'park';
|
|
18
|
+
}).at(-1);
|
|
19
|
+
}
|
package/src/worker-slots.ts
CHANGED
|
@@ -7,6 +7,16 @@ export function isAgentCapacity(value: unknown): value is number {
|
|
|
7
7
|
return Number.isInteger(value) && (value as number) >= 1 && (value as number) <= MAX_LOCAL_AGENT_CAPACITY;
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
+
export interface WorkerSlotScope {
|
|
11
|
+
run<T>(work: () => Promise<T>): Promise<T>;
|
|
12
|
+
/** Refuse this flow's queued/future work without closing the shared pool. */
|
|
13
|
+
close(reason: unknown): void;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
interface ScopeState {
|
|
17
|
+
closed?: { readonly reason: unknown };
|
|
18
|
+
}
|
|
19
|
+
|
|
10
20
|
/**
|
|
11
21
|
* First-come admission to a worker that holds `capacity` dispatches at once.
|
|
12
22
|
*
|
|
@@ -19,7 +29,11 @@ export function isAgentCapacity(value: unknown): value is number {
|
|
|
19
29
|
*/
|
|
20
30
|
export class WorkerSlots {
|
|
21
31
|
private held = 0;
|
|
22
|
-
private readonly waiting: Array<{
|
|
32
|
+
private readonly waiting: Array<{
|
|
33
|
+
resolve: () => void;
|
|
34
|
+
reject: (reason: unknown) => void;
|
|
35
|
+
scope?: ScopeState;
|
|
36
|
+
}> = [];
|
|
23
37
|
private closed: { readonly reason: unknown } | undefined;
|
|
24
38
|
|
|
25
39
|
constructor(readonly capacity: number) {
|
|
@@ -27,18 +41,37 @@ export class WorkerSlots {
|
|
|
27
41
|
}
|
|
28
42
|
|
|
29
43
|
async run<T>(work: () => Promise<T>): Promise<T> {
|
|
44
|
+
return this.runInScope(work);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** One independently closable admission scope over this shared capacity. */
|
|
48
|
+
scope(): WorkerSlotScope {
|
|
49
|
+
const scope: ScopeState = {};
|
|
50
|
+
return Object.freeze({
|
|
51
|
+
run: <T>(work: () => Promise<T>) => this.runInScope(work, scope),
|
|
52
|
+
close: (reason: unknown) => this.closeScope(scope, reason),
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
private async runInScope<T>(work: () => Promise<T>, scope?: ScopeState): Promise<T> {
|
|
30
57
|
if (this.closed !== undefined) throw this.closed.reason;
|
|
58
|
+
if (scope?.closed !== undefined) throw scope.closed.reason;
|
|
31
59
|
if (this.held < this.capacity) this.held++;
|
|
32
60
|
// A released slot is handed straight to the next waiter, so `held` never
|
|
33
61
|
// dips below capacity while anyone is queued and no later caller can jump it.
|
|
34
62
|
else {
|
|
35
|
-
await new Promise<void>((resolve, reject) => this.waiting.push({ resolve, reject }));
|
|
63
|
+
await new Promise<void>((resolve, reject) => this.waiting.push({ resolve, reject, scope }));
|
|
36
64
|
// Woken with the slot, but the body may have failed in between (see release).
|
|
37
65
|
const closed = this.closedReason();
|
|
38
66
|
if (closed !== undefined) {
|
|
39
67
|
this.release();
|
|
40
68
|
throw closed.reason;
|
|
41
69
|
}
|
|
70
|
+
const scopeClosed = scopeClosedReason(scope);
|
|
71
|
+
if (scopeClosed !== undefined) {
|
|
72
|
+
this.release();
|
|
73
|
+
throw scopeClosed.reason;
|
|
74
|
+
}
|
|
42
75
|
}
|
|
43
76
|
try {
|
|
44
77
|
return await work();
|
|
@@ -66,17 +99,28 @@ export class WorkerSlots {
|
|
|
66
99
|
return;
|
|
67
100
|
}
|
|
68
101
|
setImmediate(() => {
|
|
69
|
-
if (this.closed === undefined) {
|
|
102
|
+
if (this.closed === undefined && next.scope?.closed === undefined) {
|
|
70
103
|
next.resolve();
|
|
71
104
|
return;
|
|
72
105
|
}
|
|
73
106
|
// Closed meanwhile. `close` could not see this waiter (already taken off
|
|
74
107
|
// the queue), so refuse it here, and pass the slot on instead of leaking it.
|
|
75
|
-
next.reject(this.closed.reason);
|
|
108
|
+
next.reject(this.closed?.reason ?? next.scope!.closed!.reason);
|
|
76
109
|
this.release();
|
|
77
110
|
});
|
|
78
111
|
}
|
|
79
112
|
|
|
113
|
+
private closeScope(scope: ScopeState, reason: unknown): void {
|
|
114
|
+
if (scope.closed !== undefined) return;
|
|
115
|
+
scope.closed = { reason };
|
|
116
|
+
for (let index = this.waiting.length - 1; index >= 0; index--) {
|
|
117
|
+
const waiter = this.waiting[index]!;
|
|
118
|
+
if (waiter.scope !== scope) continue;
|
|
119
|
+
this.waiting.splice(index, 1);
|
|
120
|
+
waiter.reject(reason);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
80
124
|
/**
|
|
81
125
|
* Refuse every queued and future admission with `reason`; work already
|
|
82
126
|
* holding a slot is not interrupted. The authored body calls this when it
|
|
@@ -90,3 +134,18 @@ export class WorkerSlots {
|
|
|
90
134
|
for (const waiter of this.waiting.splice(0)) waiter.reject(reason);
|
|
91
135
|
}
|
|
92
136
|
}
|
|
137
|
+
|
|
138
|
+
/** Read through a call so a check after an `await` is not narrowed away. */
|
|
139
|
+
function scopeClosedReason(scope?: ScopeState): { readonly reason: unknown } | undefined {
|
|
140
|
+
return scope?.closed;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/** One run-tree-wide capacity pool, shared by parent and child flows. */
|
|
144
|
+
export interface AuthoredWorkerSlots {
|
|
145
|
+
readonly agent: WorkerSlots;
|
|
146
|
+
readonly llm: WorkerSlots;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
export function authoredWorkerSlots(capacity: number): AuthoredWorkerSlots {
|
|
150
|
+
return Object.freeze({ agent: new WorkerSlots(capacity), llm: new WorkerSlots(capacity) });
|
|
151
|
+
}
|