@adhd/apigen-engine-runtime 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/batch.d.ts ADDED
@@ -0,0 +1,96 @@
1
+ import { Call, InvokeFn, InvokeOptions } from './invoke';
2
+
3
+ /** Concurrency ceiling used when the caller doesn't request one. */
4
+ export declare const BATCH_DEFAULT_CONCURRENCY = 4;
5
+ /**
6
+ * Hard cap on requested concurrency, enforced regardless of what the caller
7
+ * asks for (§3 — "Concurrency ceiling is framework-enforced, not advisory",
8
+ * the direct lesson of `BUG-AGENTMCP-TRIAGE-CONCURRENCY-001`'s unbounded
9
+ * fan-out incident).
10
+ */
11
+ export declare const BATCH_MAX_CONCURRENCY = 32;
12
+ /**
13
+ * Options accepted by {@link invokeBatch} (§3).
14
+ *
15
+ * The JSON-Schema-describable wire-contract half of this shape (what a
16
+ * non-TS host implements against) is specified independently in
17
+ * BATCH_0.0.1.md §F3/§5 and `apigen-core-client`'s `buildBatchKindSchema`
18
+ * branch shape — this TS interface is the runtime-only mirror of it.
19
+ */
20
+ export interface BatchOptions {
21
+ /**
22
+ * Caller-requested fan-out width. Clamped to `[1, BATCH_MAX_CONCURRENCY]`
23
+ * — never honored above the hard cap, and forced to `1` for
24
+ * `mode: 'serial' | 'chained'`.
25
+ * @default BATCH_DEFAULT_CONCURRENCY
26
+ */
27
+ concurrency?: number;
28
+ /**
29
+ * - `'parallel'` (default) — up to `concurrency` items in flight at once.
30
+ * - `'serial'` — one item at a time, in order; a failure does NOT stop
31
+ * later items unless `onItemError: 'abort'` is also set.
32
+ * - `'chained'` — one item at a time, in order, and a failure ALWAYS stops
33
+ * every remaining item (each result: `rejected`, reason: an "upstream
34
+ * item failed" error) regardless of `onItemError` — the DAG
35
+ * `depends_on`-style behavior §0's motivating incident hand-built
36
+ * (`BUG-AGENTMCP-TRIAGE-CONCURRENCY-001`). `calls` carries no explicit
37
+ * dependency edges in v1; `'chained'` is the single linear-chain case of
38
+ * that pattern, not a general DAG — a richer per-item dependency graph is
39
+ * out of scope for v1 (see BATCH_0.0.1.md §7 open-question 3's
40
+ * `batchId`/interactive-cancel deferral, same rationale).
41
+ * @default 'parallel'
42
+ */
43
+ mode?: 'parallel' | 'serial' | 'chained';
44
+ /**
45
+ * `'continue'` (default) — `Promise.allSettled` semantics: every item
46
+ * runs regardless of earlier failures.
47
+ * `'abort'` — once ANY item rejects, every not-yet-started item resolves
48
+ * as `rejected` without ever being invoked (in-flight items under
49
+ * `'parallel'` are allowed to finish; they are not force-cancelled by this
50
+ * setting alone — see `itemTimeoutMs` / the batch's own `AbortSignal` for
51
+ * that).
52
+ * @default 'continue'
53
+ */
54
+ onItemError?: 'continue' | 'abort';
55
+ /**
56
+ * (F4) Per-item timeout in milliseconds. When set, each item gets its own
57
+ * `AbortSignal` — DERIVED/LINKED from that item's `Call.signal` (the
58
+ * whole-batch/whole-request signal): aborting the batch signal aborts the
59
+ * item immediately, and the item additionally self-aborts after
60
+ * `itemTimeoutMs` if it hasn't settled. This composes rather than bypasses
61
+ * whole-batch cancellation (§3's "two distinct, composable operations").
62
+ */
63
+ itemTimeoutMs?: number;
64
+ }
65
+ /** Per-item result shape (§3). Mirrors `apigen-core-client`'s `batchItemResultSchema` wire fragment. */
66
+ export type BatchItemResult<T = unknown> = {
67
+ index: number;
68
+ status: 'fulfilled';
69
+ value: T;
70
+ } | {
71
+ index: number;
72
+ status: 'fulfilled';
73
+ chunks: unknown[];
74
+ } | {
75
+ index: number;
76
+ status: 'rejected';
77
+ reason: unknown;
78
+ chunksDelivered?: number;
79
+ };
80
+ /**
81
+ * Fan out `calls.length` invocations of `fnName` through the already-composed
82
+ * `invoke` function `createInvoker(layers)` returned — pure orchestration,
83
+ * never a bypass of the Layer stack (§3).
84
+ *
85
+ * @param invoke - The composed invoke function from `createInvoker(layers)`.
86
+ * @param fnName - The operation name to invoke for every item.
87
+ * @param calls - One {@link Call} per item — each carries its own
88
+ * `domainArgs`; `signal`/`envelope`/`ctx` are typically the
89
+ * same shared batch-level values across all items (F4:
90
+ * per-item cancellation is derived from `call.signal`, not
91
+ * a second signal the caller must fabricate per item).
92
+ * @param opts - `InvokeOptions` — same runtime dispatch options passed to
93
+ * `invoke` for every item.
94
+ * @param batch - {@link BatchOptions} — concurrency/mode/onItemError/itemTimeoutMs.
95
+ */
96
+ export declare function invokeBatch(invoke: InvokeFn, fnName: string, calls: readonly Call[], opts: InvokeOptions, batch?: BatchOptions): Promise<BatchItemResult[]>;
@@ -16,7 +16,22 @@ export interface UsePlugin {
16
16
  operations: (descriptor: {
17
17
  host: string;
18
18
  operations: unknown[];
19
- }, opts?: Record<string, unknown>) => Array<{
19
+ }, opts?: Record<string, unknown>, hostBridge?: {
20
+ invoke(fnName: string, call: {
21
+ domainArgs: Record<string, unknown>;
22
+ envelope: Record<string, unknown>;
23
+ signal?: AbortSignal;
24
+ }, opts: {
25
+ fns: Record<string, unknown>;
26
+ schemas: Record<string, unknown>;
27
+ createClient?: (envelope: Record<string, unknown>) => Promise<unknown>;
28
+ }): Promise<unknown>;
29
+ invokeOptions: {
30
+ fns: Record<string, unknown>;
31
+ schemas: Record<string, unknown>;
32
+ createClient?: (envelope: Record<string, unknown>) => Promise<unknown>;
33
+ };
34
+ }) => Array<{
20
35
  id: string;
21
36
  transports?: string[];
22
37
  handler: (call: unknown) => unknown;
package/package.json CHANGED
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "name": "@adhd/apigen-engine-runtime",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "dependencies": {
5
5
  "ajv": "^8.20.0",
6
6
  "ajv-formats": "2.1.1",
7
7
  "pino": "10.3.1",
8
- "@adhd/apigen-core-client": "^0.2.0",
8
+ "@adhd/apigen-core-client": "^0.2.1",
9
9
  "@adhd/apigen-base-logical": "^0.1.0",
10
10
  "@adhd/apigen-base-errors": "^0.2.0",
11
- "@adhd/apigen-engine-naming": "^0.2.0",
11
+ "@adhd/apigen-engine-naming": "^0.2.1",
12
12
  "better-sqlite3": "12.10.0"
13
13
  },
14
14
  "main": "./index.js",