import { ContentOriginKind, MergeGuardConfig, TrustClass } from "../lateral-leak/merge-guard.js"; import { AgentEvent, Usage } from "@graphorin/core"; //#region src/fanout/index.d.ts /** * Per-child budget. Defaults derived from the canonical 2026 * scaling-rule table for agent fan-out workloads. * * @stable */ interface PerChildBudget { /** * Max `usage.totalTokens` per child. Enforced **post-hoc** and only * for usage-reporting children (an `invoke` that resolves to a full * `AgentResult` - e.g. `() => child.run(input)`); a child returning a * plain value reports `tokensUsed: 0` and this cap cannot fire. */ readonly tokens?: number; /** * Max tool calls per child. Same usage-reporting contract as * {@link PerChildBudget.tokens} (counted from `state.steps`). */ readonly toolCalls?: number; /** Wall-clock cap, enforced for every child via a race timer. */ readonly durationMs?: number; } /** * Built-in merge-strategy taxonomy. * * @stable */ type MergeStrategy = { readonly kind: 'concat'; readonly separator?: string; } | { readonly kind: 'first-success'; } | { readonly kind: 'judge-merge'; readonly judge: (children: ReadonlyArray>) => Promise; } | { readonly kind: 'custom'; readonly merge: (children: ReadonlyArray>) => Promise; }; /** * Per-child outcome surfaced on * {@link FanOutResult.children}. Failed-child isolation: a child * that throws produces a `ChildResult` with `status: 'failed'` - * never an exception thrown from the fan-out call itself. * * @stable */ interface ChildResult { readonly agentId: string; readonly status: 'completed' | 'failed' | 'budget-exceeded' | 'cancelled'; readonly output?: TOutput; readonly error?: { readonly message: string; readonly code: string; }; readonly tokensUsed: number; readonly toolCallCount: number; readonly durationMs: number; /** * Full usage breakdown, present only for usage-reporting children * (an `invoke` resolving to a full `AgentResult`). */ readonly usage?: Usage; } /** * Aggregate result returned by `Agent.fanOut(...)`. * * @stable */ interface FanOutResult { readonly fanOutId: string; readonly output: TOutput; readonly children: ReadonlyArray>; readonly mergeDurationMs: number; /** * Sum of every usage-reporting child's usage; zero when no * child reported. The fan-out helper never mutates the parent run's * live state (it runs outside the loop and would race it) - folding * this into the parent run's accounting is the caller's decision. */ readonly usage: Usage; } /** * Per-call options accepted by `Agent.fanOut(...)`. * * @stable */ interface FanOutOptions { /** * The sub-agents to invoke. Each entry is invoked as a function * returning a `Promise` - the fan-out helper does not * impose an `Agent` shape on the children so the runtime can * adapt any callable surface. */ readonly children: ReadonlyArray<{ readonly agentId: string; /** * Child callable. Resolve to a plain `TOutput`, or to a full * `AgentResult` (e.g. `() => childAgent.run(input)`) - the fan-out * detects the result envelope structurally (`output` + numeric * `usage.totalTokens` + `state`), unwraps `output`, and harvests * `tokensUsed` / `toolCallCount` so per-child budgets can enforce. */ readonly invoke: () => Promise; /** Trust-class for the merge guard (default `'loopback'`). */ readonly trustClass?: TrustClass; /** Content-origin for the merge guard (default `'built-in'`). */ readonly origin?: ContentOriginKind; /** Rolling trust adjustment in `[0,1]` (default `1`). */ readonly historyAdjustment?: number; }>; /** Default `4` per the canonical 2026 production lesson. */ readonly maxConcurrentChildren?: number; /** Per-child budget; default unset. */ readonly perBudget?: PerChildBudget; /** Default `{ kind: 'concat' }`. */ readonly mergeStrategy?: MergeStrategy; readonly signal?: AbortSignal; /** Optional callback for per-child completion observability. */ readonly onChildResult?: (result: ChildResult) => void; /** Optional event emitter for `agent.fanout.spawned / merged`. */ readonly emit?: (event: AgentEvent) => void; /** * Sideways-injection merge guard: on `'judge-merge'` the * fan-out scores each child's source trust and contribution weight * against the judge's merged output; a biased merge emits * `agent.lateral-leak.detected` (vector `sideways-injection`) and - * under `strictness: 'detect-and-block'` - throws * {@link MergeBlockedError}. */ readonly mergeGuard?: MergeGuardConfig; /** Identifiers required to populate the events. */ readonly runId: string; readonly sessionId: string; readonly agentId: string; /** Default - generated from `runId + Date.now()`. */ readonly fanOutId?: string; } /** * Run a fan-out and produce the aggregate {@link FanOutResult}. * Pure with respect to side effects - the runtime emits events / * audit rows / counter increments via the supplied `emit` callback. * * @stable */ declare function runFanOut(opts: FanOutOptions): Promise>; //#endregion export { ChildResult, FanOutOptions, FanOutResult, MergeStrategy, PerChildBudget, runFanOut }; //# sourceMappingURL=index.d.ts.map