@graphorin/agent 0.6.0 → 0.7.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/CHANGELOG.md +96 -0
- package/README.md +31 -11
- package/dist/errors/index.d.ts +17 -4
- package/dist/errors/index.d.ts.map +1 -1
- package/dist/errors/index.js +19 -3
- package/dist/errors/index.js.map +1 -1
- package/dist/factory.d.ts.map +1 -1
- package/dist/factory.js +153 -1930
- package/dist/factory.js.map +1 -1
- package/dist/fanout/index.d.ts +13 -1
- package/dist/fanout/index.d.ts.map +1 -1
- package/dist/fanout/index.js +13 -4
- package/dist/fanout/index.js.map +1 -1
- package/dist/index.d.ts +7 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -9
- package/dist/index.js.map +1 -1
- package/dist/lateral-leak/index.js +1 -1
- package/dist/package.js +6 -0
- package/dist/package.js.map +1 -0
- package/dist/run-state/index.d.ts +32 -6
- package/dist/run-state/index.d.ts.map +1 -1
- package/dist/run-state/index.js +46 -22
- package/dist/run-state/index.js.map +1 -1
- package/dist/runtime/agent-surface.js +122 -0
- package/dist/runtime/agent-surface.js.map +1 -0
- package/dist/runtime/agent-to-tool.d.ts +51 -0
- package/dist/runtime/agent-to-tool.d.ts.map +1 -0
- package/dist/runtime/agent-to-tool.js +145 -0
- package/dist/runtime/agent-to-tool.js.map +1 -0
- package/dist/runtime/approvals.js +0 -0
- package/dist/runtime/approvals.js.map +1 -0
- package/dist/runtime/dispatch.js +108 -0
- package/dist/runtime/dispatch.js.map +1 -0
- package/dist/runtime/executor-wiring.js +128 -0
- package/dist/runtime/executor-wiring.js.map +1 -0
- package/dist/runtime/fallback-chain.js +139 -0
- package/dist/runtime/fallback-chain.js.map +1 -0
- package/dist/runtime/handoff.js +307 -0
- package/dist/runtime/handoff.js.map +1 -0
- package/dist/runtime/messages.d.ts +22 -0
- package/dist/runtime/messages.d.ts.map +1 -0
- package/dist/runtime/messages.js +204 -0
- package/dist/runtime/messages.js.map +1 -0
- package/dist/runtime/provider-events.js +117 -0
- package/dist/runtime/provider-events.js.map +1 -0
- package/dist/runtime/run-compaction.js +210 -0
- package/dist/runtime/run-compaction.js.map +1 -0
- package/dist/runtime/run-finish.js +48 -0
- package/dist/runtime/run-finish.js.map +1 -0
- package/dist/runtime/run-gates.js +336 -0
- package/dist/runtime/run-gates.js.map +1 -0
- package/dist/runtime/run-init.js +81 -0
- package/dist/runtime/run-init.js.map +1 -0
- package/dist/runtime/run-input.js +46 -0
- package/dist/runtime/run-input.js.map +1 -0
- package/dist/runtime/step-catalogue.js +173 -0
- package/dist/runtime/step-catalogue.js.map +1 -0
- package/dist/runtime/tool-call-walk.js +189 -0
- package/dist/runtime/tool-call-walk.js.map +1 -0
- package/dist/runtime/tool-wiring.js +159 -0
- package/dist/runtime/tool-wiring.js.map +1 -0
- package/dist/tooling/adapters.js +1 -1
- package/dist/tooling/dataflow.js +1 -1
- package/dist/tooling/policy.js +2 -0
- package/dist/tooling/policy.js.map +1 -1
- package/dist/types.d.ts +63 -13
- package/dist/types.d.ts.map +1 -1
- package/package.json +20 -20
- package/src/errors/index.ts +320 -0
- package/src/evaluator-optimizer/index.ts +212 -0
- package/src/factory.ts +957 -0
- package/src/fallback/index.ts +108 -0
- package/src/fanout/index.ts +523 -0
- package/src/filters/index.ts +347 -0
- package/src/index.ts +180 -0
- package/src/internal/ids.ts +46 -0
- package/src/internal/usage-accumulator.ts +90 -0
- package/src/lateral-leak/causality-monitor.ts +221 -0
- package/src/lateral-leak/index.ts +35 -0
- package/src/lateral-leak/merge-guard.ts +151 -0
- package/src/lateral-leak/protocol-guard.ts +222 -0
- package/src/preferred-model/index.ts +210 -0
- package/src/progress/index.ts +238 -0
- package/src/run-state/index.ts +607 -0
- package/src/runtime/agent-surface.ts +218 -0
- package/src/runtime/agent-to-tool.ts +323 -0
- package/src/runtime/approvals.ts +0 -0
- package/src/runtime/dispatch.ts +183 -0
- package/src/runtime/executor-wiring.ts +331 -0
- package/src/runtime/fallback-chain.ts +250 -0
- package/src/runtime/handoff.ts +428 -0
- package/src/runtime/messages.ts +309 -0
- package/src/runtime/provider-events.ts +175 -0
- package/src/runtime/run-compaction.ts +288 -0
- package/src/runtime/run-finish.ts +93 -0
- package/src/runtime/run-gates.ts +419 -0
- package/src/runtime/run-init.ts +169 -0
- package/src/runtime/run-input.ts +102 -0
- package/src/runtime/step-catalogue.ts +338 -0
- package/src/runtime/tool-call-walk.ts +301 -0
- package/src/runtime/tool-wiring.ts +218 -0
- package/src/testing/replay-provider.ts +121 -0
- package/src/tooling/adapters.ts +403 -0
- package/src/tooling/catalogue.ts +36 -0
- package/src/tooling/dataflow.ts +171 -0
- package/src/tooling/plan.ts +123 -0
- package/src/tooling/policy.ts +67 -0
- package/src/tooling/registry-build.ts +191 -0
- package/src/types.ts +696 -0
package/dist/fanout/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ContentOriginKind, MergeGuardConfig, TrustClass } from "../lateral-leak/merge-guard.js";
|
|
2
|
-
import { AgentEvent } from "@graphorin/core";
|
|
2
|
+
import { AgentEvent, Usage } from "@graphorin/core";
|
|
3
3
|
|
|
4
4
|
//#region src/fanout/index.d.ts
|
|
5
5
|
|
|
@@ -61,6 +61,11 @@ interface ChildResult<TOutput = unknown> {
|
|
|
61
61
|
readonly tokensUsed: number;
|
|
62
62
|
readonly toolCallCount: number;
|
|
63
63
|
readonly durationMs: number;
|
|
64
|
+
/**
|
|
65
|
+
* Full usage breakdown, present only for usage-reporting children
|
|
66
|
+
* (an `invoke` resolving to a full `AgentResult`, W-033).
|
|
67
|
+
*/
|
|
68
|
+
readonly usage?: Usage;
|
|
64
69
|
}
|
|
65
70
|
/**
|
|
66
71
|
* Aggregate result returned by `Agent.fanOut(...)`.
|
|
@@ -72,6 +77,13 @@ interface FanOutResult<TOutput = unknown> {
|
|
|
72
77
|
readonly output: TOutput;
|
|
73
78
|
readonly children: ReadonlyArray<ChildResult<TOutput>>;
|
|
74
79
|
readonly mergeDurationMs: number;
|
|
80
|
+
/**
|
|
81
|
+
* Sum of every usage-reporting child's usage (W-033); zero when no
|
|
82
|
+
* child reported. The fan-out helper never mutates the parent run's
|
|
83
|
+
* live state (it runs outside the loop and would race it) - folding
|
|
84
|
+
* this into the parent run's accounting is the caller's decision.
|
|
85
|
+
*/
|
|
86
|
+
readonly usage: Usage;
|
|
75
87
|
}
|
|
76
88
|
/**
|
|
77
89
|
* Per-call options accepted by `Agent.fanOut(...)`.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/fanout/index.ts"],"sourcesContent":[],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/fanout/index.ts"],"sourcesContent":[],"mappings":";;;;;;AA2EA;AAoBA;;;;AAGqB,UAjEJ,cAAA,CAiEI;EAQH;;AAQlB;;;;EAoBsB,SAAA,MAAA,CAAA,EAAA,MAAA;EAbD;;;;EAuBD,SAAA,SAAA,CAAA,EAAA,MAAA;EAE4B;EAAZ,SAAA,UAAA,CAAA,EAAA,MAAA;;;;AAsNpC;;;AAEwB,KAnTZ,aAmTY,CAAA,UAAA,OAAA,CAAA,GAAA;EAAb,SAAA,IAAA,EAAA,QAAA;EAAR,SAAA,SAAA,CAAA,EAAA,MAAA;CAAO,GAAA;;;;6BA9SuB,cAAc,YAAY,cAAc,QAAQ;;;6BAIhD,cAAc,YAAY,cAAc,QAAQ;;;;;;;;;;UAWhE;;;oBAGG;;;;;;;;;;;;mBASD;;;;;;;UAQF;;mBAEE;qBACE,cAAc,YAAY;;;;;;;;kBAQ7B;;;;;;;UAQD;;;;;;;qBAOI;;;;;;;;;2BASM,QAAQ;;0BAET;;sBAEJ;;;;;;;uBAOC;;2BAEI,cAAc;oBACrB;;oCAEgB,YAAY;;0BAEtB;;;;;;;;;wBASF;;;;;;;;;;;;;;;iBA2MF,yBACd,cAAc,WACnB,QAAQ,aAAa"}
|
package/dist/fanout/index.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { MergeBlockedError } from "../errors/index.js";
|
|
2
2
|
import { computeSourceTrust, evaluateMerge } from "../lateral-leak/merge-guard.js";
|
|
3
|
+
import { accumulateUsage } from "../runtime/messages.js";
|
|
4
|
+
import { zeroUsage } from "@graphorin/core";
|
|
3
5
|
import { createHash } from "node:crypto";
|
|
4
6
|
|
|
5
7
|
//#region src/fanout/index.ts
|
|
@@ -37,10 +39,12 @@ function harvestAgentResult(value) {
|
|
|
37
39
|
const calls = step.toolCalls;
|
|
38
40
|
if (Array.isArray(calls)) toolCallCount += calls.length;
|
|
39
41
|
}
|
|
42
|
+
const usage = typeof v.usage.promptTokens === "number" && typeof v.usage.completionTokens === "number" ? v.usage : void 0;
|
|
40
43
|
return {
|
|
41
44
|
output: v.output,
|
|
42
45
|
tokensUsed: v.usage.totalTokens,
|
|
43
|
-
toolCallCount
|
|
46
|
+
toolCallCount,
|
|
47
|
+
...usage !== void 0 ? { usage } : {}
|
|
44
48
|
};
|
|
45
49
|
}
|
|
46
50
|
/**
|
|
@@ -95,7 +99,8 @@ async function runWithSemaphore(children, cap, signal, perBudget, onChildResult)
|
|
|
95
99
|
},
|
|
96
100
|
tokensUsed,
|
|
97
101
|
toolCallCount,
|
|
98
|
-
durationMs: Date.now() - start
|
|
102
|
+
durationMs: Date.now() - start,
|
|
103
|
+
...report?.usage !== void 0 ? { usage: report.usage } : {}
|
|
99
104
|
};
|
|
100
105
|
return {
|
|
101
106
|
agentId: child.agentId,
|
|
@@ -103,7 +108,8 @@ async function runWithSemaphore(children, cap, signal, perBudget, onChildResult)
|
|
|
103
108
|
output,
|
|
104
109
|
tokensUsed,
|
|
105
110
|
toolCallCount,
|
|
106
|
-
durationMs: Date.now() - start
|
|
111
|
+
durationMs: Date.now() - start,
|
|
112
|
+
...report?.usage !== void 0 ? { usage: report.usage } : {}
|
|
107
113
|
};
|
|
108
114
|
} catch (cause) {
|
|
109
115
|
const message = cause instanceof Error ? cause.message : String(cause);
|
|
@@ -239,11 +245,14 @@ async function runFanOut(opts) {
|
|
|
239
245
|
mergeDurationMs,
|
|
240
246
|
childMetadata
|
|
241
247
|
});
|
|
248
|
+
const usage = zeroUsage();
|
|
249
|
+
for (const r of results) if (r.usage !== void 0) accumulateUsage(usage, r.usage);
|
|
242
250
|
return {
|
|
243
251
|
fanOutId,
|
|
244
252
|
output: merged,
|
|
245
253
|
children: results,
|
|
246
|
-
mergeDurationMs
|
|
254
|
+
mergeDurationMs,
|
|
255
|
+
usage
|
|
247
256
|
};
|
|
248
257
|
}
|
|
249
258
|
|
package/dist/fanout/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["results: ChildResult<TOutput>[]","running: Set<Promise<void>>","timer: ReturnType<typeof setTimeout> | undefined","status: ChildResult<TOutput>['status']","merge: MergeStrategy<TOutput>","merged: TOutput","parts: string[]","childMetadata: FanOutChildMetadata[]"],"sources":["../../src/fanout/index.ts"],"sourcesContent":["/**\n * Agent-step-level fan-out - `Agent.fanOut(...)` convenience that\n * spawns N sub-agents in parallel under a bounded-fanout cap with\n * per-child budgets and four built-in merge strategies.\n *\n * Boundary discipline against the workflow `Dispatch(...)`\n * primitive: fan-out is **agent-step-level inline result** (children\n * share parent `RunContext` lineage; result consumed by parent's\n * continuing loop within one or few `agent.run(...)` calls).\n * `Dispatch(...)` is workflow-step-level checkpointed durable graph.\n * The two compose orthogonally.\n *\n * @packageDocumentation\n */\n\nimport { createHash } from 'node:crypto';\nimport type { AgentEvent, FanOutChildMetadata } from '@graphorin/core';\nimport { MergeBlockedError } from '../errors/index.js';\nimport {\n type ContentOriginKind,\n computeSourceTrust,\n evaluateMerge,\n type MergeGuardConfig,\n type TrustClass,\n} from '../lateral-leak/merge-guard.js';\n\n/**\n * Per-child budget. Defaults derived from the canonical 2026\n * scaling-rule table for agent fan-out workloads.\n *\n * @stable\n */\nexport interface PerChildBudget {\n /**\n * Max `usage.totalTokens` per child. Enforced **post-hoc** and only\n * for usage-reporting children (an `invoke` that resolves to a full\n * `AgentResult` - e.g. `() => child.run(input)`); a child returning a\n * plain value reports `tokensUsed: 0` and this cap cannot fire.\n */\n readonly tokens?: number;\n /**\n * Max tool calls per child. Same usage-reporting contract as\n * {@link PerChildBudget.tokens} (counted from `state.steps`).\n */\n readonly toolCalls?: number;\n /** Wall-clock cap, enforced for every child via a race timer. */\n readonly durationMs?: number;\n}\n\n/**\n * Built-in merge-strategy taxonomy.\n *\n * @stable\n */\nexport type MergeStrategy<TOutput = unknown> =\n | { readonly kind: 'concat'; readonly separator?: string }\n | { readonly kind: 'first-success' }\n | {\n readonly kind: 'judge-merge';\n readonly judge: (children: ReadonlyArray<ChildResult<TOutput>>) => Promise<TOutput>;\n }\n | {\n readonly kind: 'custom';\n readonly merge: (children: ReadonlyArray<ChildResult<TOutput>>) => Promise<TOutput>;\n };\n\n/**\n * Per-child outcome surfaced on\n * {@link FanOutResult.children}. Failed-child isolation: a child\n * that throws produces a `ChildResult` with `status: 'failed'` -\n * never an exception thrown from the fan-out call itself.\n *\n * @stable\n */\nexport interface ChildResult<TOutput = unknown> {\n readonly agentId: string;\n readonly status: 'completed' | 'failed' | 'budget-exceeded' | 'cancelled';\n readonly output?: TOutput;\n readonly error?: { readonly message: string; readonly code: string };\n readonly tokensUsed: number;\n readonly toolCallCount: number;\n readonly durationMs: number;\n}\n\n/**\n * Aggregate result returned by `Agent.fanOut(...)`.\n *\n * @stable\n */\nexport interface FanOutResult<TOutput = unknown> {\n readonly fanOutId: string;\n readonly output: TOutput;\n readonly children: ReadonlyArray<ChildResult<TOutput>>;\n readonly mergeDurationMs: number;\n}\n\n/**\n * Per-call options accepted by `Agent.fanOut(...)`.\n *\n * @stable\n */\nexport interface FanOutOptions<TOutput = unknown> {\n /**\n * The sub-agents to invoke. Each entry is invoked as a function\n * returning a `Promise<TOutput>` - the fan-out helper does not\n * impose an `Agent` shape on the children so the runtime can\n * adapt any callable surface.\n */\n readonly children: ReadonlyArray<{\n readonly agentId: string;\n /**\n * Child callable. Resolve to a plain `TOutput`, or to a full\n * `AgentResult` (e.g. `() => childAgent.run(input)`) - the fan-out\n * detects the result envelope structurally (`output` + numeric\n * `usage.totalTokens` + `state`), unwraps `output`, and harvests\n * `tokensUsed` / `toolCallCount` so per-child budgets can enforce.\n */\n readonly invoke: () => Promise<TOutput>;\n /** Trust-class for the merge guard (default `'loopback'`). */\n readonly trustClass?: TrustClass;\n /** Content-origin for the merge guard (default `'built-in'`). */\n readonly origin?: ContentOriginKind;\n /** Rolling trust adjustment in `[0,1]` (default `1`). */\n readonly historyAdjustment?: number;\n }>;\n /** Default `4` per the canonical 2026 production lesson. */\n readonly maxConcurrentChildren?: number;\n /** Per-child budget; default unset. */\n readonly perBudget?: PerChildBudget;\n /** Default `{ kind: 'concat' }`. */\n readonly mergeStrategy?: MergeStrategy<TOutput>;\n readonly signal?: AbortSignal;\n /** Optional callback for per-child completion observability. */\n readonly onChildResult?: (result: ChildResult<TOutput>) => void;\n /** Optional event emitter for `agent.fanout.spawned / merged`. */\n readonly emit?: (event: AgentEvent) => void;\n /**\n * Sideways-injection merge guard (AG-7): on `'judge-merge'` the\n * fan-out scores each child's source trust and contribution weight\n * against the judge's merged output; a biased merge emits\n * `agent.lateral-leak.detected` (vector `sideways-injection`) and -\n * under `strictness: 'detect-and-block'` - throws\n * {@link MergeBlockedError}.\n */\n readonly mergeGuard?: MergeGuardConfig;\n /** Identifiers required to populate the events. */\n readonly runId: string;\n readonly sessionId: string;\n readonly agentId: string;\n /** Default - generated from `runId + Date.now()`. */\n readonly fanOutId?: string;\n}\n\nconst DEFAULT_MAX_CONCURRENT_CHILDREN = 4;\n\n/**\n * Structurally detect a full `AgentResult` returned by a child\n * `invoke` (AG-16): an object carrying `output`, a numeric\n * `usage.totalTokens`, and a `state` with string `id`/`status`. The\n * three-field match makes accidental collision with a user `TOutput`\n * negligible; children whose genuine output looks like this should\n * resolve a plain value instead.\n */\nfunction harvestAgentResult(\n value: unknown,\n):\n | { readonly output: unknown; readonly tokensUsed: number; readonly toolCallCount: number }\n | undefined {\n if (typeof value !== 'object' || value === null) return undefined;\n const v = value as {\n readonly output?: unknown;\n readonly usage?: { readonly totalTokens?: unknown };\n readonly state?: { readonly id?: unknown; readonly status?: unknown; readonly steps?: unknown };\n };\n if (!('output' in v)) return undefined;\n if (typeof v.usage?.totalTokens !== 'number') return undefined;\n if (typeof v.state?.id !== 'string' || typeof v.state.status !== 'string') return undefined;\n let toolCallCount = 0;\n if (Array.isArray(v.state.steps)) {\n for (const step of v.state.steps) {\n const calls = (step as { readonly toolCalls?: unknown }).toolCalls;\n if (Array.isArray(calls)) toolCallCount += calls.length;\n }\n }\n return { output: v.output, tokensUsed: v.usage.totalTokens, toolCallCount };\n}\n\n/**\n * Whitespace-token overlap of a child's output against the merged\n * output, in `[0,1]` - the contribution-weight estimate the merge\n * guard's docstring contracts (each child scored independently; a\n * judge parroting one child verbatim yields ~1.0 for that child).\n */\nfunction contributionWeight(childText: string, mergedText: string): number {\n if (childText.length === 0 || mergedText.length === 0) return 0;\n const mergedTokens = mergedText.split(/\\s+/).filter((t) => t.length > 0);\n if (mergedTokens.length === 0) return 0;\n const childTokens = new Set(childText.split(/\\s+/).filter((t) => t.length > 0));\n let hits = 0;\n for (const token of mergedTokens) {\n if (childTokens.has(token)) hits += 1;\n }\n return hits / mergedTokens.length;\n}\n\nasync function runWithSemaphore<TOutput>(\n children: ReadonlyArray<FanOutOptions<TOutput>['children'][number]>,\n cap: number,\n signal: AbortSignal | undefined,\n perBudget: PerChildBudget | undefined,\n onChildResult?: (r: ChildResult<TOutput>) => void,\n): Promise<ReadonlyArray<ChildResult<TOutput>>> {\n const results: ChildResult<TOutput>[] = new Array(children.length);\n let cursor = 0;\n const running: Set<Promise<void>> = new Set();\n const limit = Math.max(1, Math.min(cap, children.length));\n\n const launchOne = (index: number): Promise<void> => {\n const child = children[index];\n if (child === undefined) return Promise.resolve();\n const start = Date.now();\n const exec = async (): Promise<ChildResult<TOutput>> => {\n if (signal?.aborted) {\n return {\n agentId: child.agentId,\n status: 'cancelled',\n tokensUsed: 0,\n toolCallCount: 0,\n durationMs: 0,\n };\n }\n let timer: ReturnType<typeof setTimeout> | undefined;\n try {\n const timedPromise =\n perBudget?.durationMs !== undefined\n ? new Promise<TOutput>((_, reject) => {\n timer = setTimeout(\n () => reject(new Error('budget-exceeded:durationMs')),\n perBudget.durationMs,\n );\n })\n : undefined;\n const racePromise = timedPromise\n ? Promise.race([child.invoke(), timedPromise])\n : child.invoke();\n const raw = await racePromise;\n // AG-16: a child resolving to a full AgentResult reports its\n // real usage - unwrap the output and harvest the counters.\n const report = harvestAgentResult(raw);\n const output = (report === undefined ? raw : report.output) as TOutput;\n const tokensUsed = report?.tokensUsed ?? 0;\n const toolCallCount = report?.toolCallCount ?? 0;\n // Post-hoc budget enforcement (only fires for usage-reporting\n // children): the over-budget output is withheld from the merge.\n const exceeded =\n (perBudget?.tokens !== undefined && tokensUsed > perBudget.tokens\n ? `tokens ${tokensUsed} > ${perBudget.tokens}`\n : undefined) ??\n (perBudget?.toolCalls !== undefined && toolCallCount > perBudget.toolCalls\n ? `toolCalls ${toolCallCount} > ${perBudget.toolCalls}`\n : undefined);\n if (exceeded !== undefined) {\n return {\n agentId: child.agentId,\n status: 'budget-exceeded',\n error: { message: `budget-exceeded: ${exceeded}`, code: 'budget-exceeded' },\n tokensUsed,\n toolCallCount,\n durationMs: Date.now() - start,\n };\n }\n return {\n agentId: child.agentId,\n status: 'completed',\n output,\n tokensUsed,\n toolCallCount,\n durationMs: Date.now() - start,\n };\n } catch (cause) {\n const message = cause instanceof Error ? cause.message : String(cause);\n const aborted = signal?.aborted;\n const status: ChildResult<TOutput>['status'] = message.startsWith('budget-exceeded')\n ? 'budget-exceeded'\n : aborted\n ? 'cancelled'\n : 'failed';\n return {\n agentId: child.agentId,\n status,\n error: { message, code: status },\n tokensUsed: 0,\n toolCallCount: 0,\n durationMs: Date.now() - start,\n };\n } finally {\n // AG-16: the duration timer must die on EVERY path - leaving it\n // armed on rejection held the event loop open.\n if (timer !== undefined) clearTimeout(timer);\n }\n };\n const promise = exec().then((r) => {\n results[index] = r;\n onChildResult?.(r);\n });\n running.add(promise);\n promise.finally(() => running.delete(promise));\n return promise;\n };\n\n while (cursor < children.length || running.size > 0) {\n while (running.size < limit && cursor < children.length) {\n void launchOne(cursor);\n cursor += 1;\n }\n if (running.size > 0) {\n await Promise.race(running);\n }\n }\n return results;\n}\n\n/**\n * Run a fan-out and produce the aggregate {@link FanOutResult}.\n * Pure with respect to side effects - the runtime emits events /\n * audit rows / counter increments via the supplied `emit` callback.\n *\n * @stable\n */\nexport async function runFanOut<TOutput>(\n opts: FanOutOptions<TOutput>,\n): Promise<FanOutResult<TOutput>> {\n const fanOutId = opts.fanOutId ?? `fanout-${opts.runId.slice(-8)}-${Date.now().toString(36)}`;\n const merge: MergeStrategy<TOutput> = opts.mergeStrategy ?? {\n kind: 'concat',\n };\n const cap = opts.maxConcurrentChildren ?? DEFAULT_MAX_CONCURRENT_CHILDREN;\n\n opts.emit?.({\n type: 'agent.fanout.spawned',\n runId: opts.runId,\n sessionId: opts.sessionId,\n agentId: opts.agentId,\n fanOutId,\n childCount: opts.children.length,\n mergeStrategyKind: merge.kind,\n spawnedAtIso: new Date().toISOString(),\n });\n\n const results = await runWithSemaphore<TOutput>(\n opts.children,\n cap,\n opts.signal,\n opts.perBudget,\n opts.onChildResult,\n );\n\n const mergeStart = Date.now();\n let merged: TOutput;\n switch (merge.kind) {\n case 'concat': {\n const sep = merge.separator ?? '\\n\\n---\\n\\n';\n const parts: string[] = [];\n for (const r of results) {\n if (r.status === 'completed' && r.output !== undefined) {\n parts.push(typeof r.output === 'string' ? r.output : JSON.stringify(r.output));\n } else if (\n r.status === 'failed' ||\n r.status === 'budget-exceeded' ||\n r.status === 'cancelled'\n ) {\n parts.push(`[${r.status}: ${r.agentId}]`);\n }\n }\n merged = parts.join(sep) as unknown as TOutput;\n break;\n }\n case 'first-success': {\n const first = results.find((r) => r.status === 'completed');\n merged = first?.output ?? ('' as unknown as TOutput);\n break;\n }\n case 'judge-merge': {\n merged = await merge.judge(results);\n // AG-7: the sideways-injection merge guard scores each child's\n // source trust × contribution weight against the judge's merged\n // output. A biased merge emits `agent.lateral-leak.detected`;\n // 'detect-and-block' refuses the merge entirely.\n if (opts.mergeGuard !== undefined && opts.mergeGuard.strictness !== 'off') {\n const mergedText = typeof merged === 'string' ? merged : JSON.stringify(merged);\n const overrides = opts.mergeGuard.sourceTrustOverrides ?? {};\n const perChild = results.map((r, i) => {\n const c = opts.children[i];\n const childText =\n r.output === undefined\n ? ''\n : typeof r.output === 'string'\n ? r.output\n : JSON.stringify(r.output);\n return {\n agentId: r.agentId,\n sourceTrust: computeSourceTrust(\n {\n agentId: r.agentId,\n trustClass: c?.trustClass ?? 'loopback',\n origin: c?.origin ?? 'built-in',\n ...(c?.historyAdjustment !== undefined\n ? { historyAdjustment: c.historyAdjustment }\n : {}),\n },\n overrides,\n ),\n contributionWeight: contributionWeight(childText, mergedText),\n };\n });\n const verdict = evaluateMerge(perChild, opts.mergeGuard);\n if (verdict.biased) {\n opts.emit?.({\n type: 'agent.lateral-leak.detected',\n runId: opts.runId,\n sessionId: opts.sessionId,\n agentId: opts.agentId,\n vector: 'sideways-injection',\n severity: verdict.decision === 'block' ? 'block' : 'warn',\n causalityChain: verdict.offendingChild === undefined ? [] : [verdict.offendingChild],\n messageContentSha256: createHash('sha256').update(mergedText, 'utf8').digest('hex'),\n decision:\n verdict.decision === 'block'\n ? 'block'\n : verdict.decision === 'flag'\n ? 'flag'\n : 'detect',\n detectedAtIso: new Date().toISOString(),\n });\n if (verdict.decision === 'block') {\n throw new MergeBlockedError(\n fanOutId,\n `low-trust child '${verdict.offendingChild}' (sourceTrust ${verdict.sourceTrust?.toFixed(2)}) contributes ${(\n (verdict.contributionWeight ?? 0) * 100\n ).toFixed(0)}% of the merged output`,\n );\n }\n }\n }\n break;\n }\n case 'custom':\n merged = await merge.merge(results);\n break;\n default: {\n const _exhaustive: never = merge;\n void _exhaustive;\n merged = '' as unknown as TOutput;\n }\n }\n const mergeDurationMs = Date.now() - mergeStart;\n\n const childMetadata: FanOutChildMetadata[] = results.map((r) => ({\n agentId: r.agentId,\n status: r.status,\n tokensUsed: r.tokensUsed,\n toolCallCount: r.toolCallCount,\n durationMs: r.durationMs,\n }));\n const successfulChildCount = results.filter((r) => r.status === 'completed').length;\n\n opts.emit?.({\n type: 'agent.fanout.merged',\n runId: opts.runId,\n sessionId: opts.sessionId,\n agentId: opts.agentId,\n fanOutId,\n childCount: opts.children.length,\n successfulChildCount,\n mergeStrategyKind: merge.kind,\n mergeDurationMs,\n childMetadata,\n });\n\n return {\n fanOutId,\n output: merged,\n children: results,\n mergeDurationMs,\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["results: ChildResult<TOutput>[]","running: Set<Promise<void>>","timer: ReturnType<typeof setTimeout> | undefined","status: ChildResult<TOutput>['status']","merge: MergeStrategy<TOutput>","merged: TOutput","parts: string[]","childMetadata: FanOutChildMetadata[]"],"sources":["../../src/fanout/index.ts"],"sourcesContent":["/**\n * Agent-step-level fan-out - `Agent.fanOut(...)` convenience that\n * spawns N sub-agents in parallel under a bounded-fanout cap with\n * per-child budgets and four built-in merge strategies.\n *\n * Boundary discipline against the workflow `Dispatch(...)`\n * primitive: fan-out is **agent-step-level inline result** (children\n * share parent `RunContext` lineage; result consumed by parent's\n * continuing loop within one or few `agent.run(...)` calls).\n * `Dispatch(...)` is workflow-step-level checkpointed durable graph.\n * The two compose orthogonally.\n *\n * @packageDocumentation\n */\n\nimport { createHash } from 'node:crypto';\nimport { type AgentEvent, type FanOutChildMetadata, type Usage, zeroUsage } from '@graphorin/core';\nimport { MergeBlockedError } from '../errors/index.js';\nimport {\n type ContentOriginKind,\n computeSourceTrust,\n evaluateMerge,\n type MergeGuardConfig,\n type TrustClass,\n} from '../lateral-leak/merge-guard.js';\nimport { accumulateUsage } from '../runtime/messages.js';\n\n/**\n * Per-child budget. Defaults derived from the canonical 2026\n * scaling-rule table for agent fan-out workloads.\n *\n * @stable\n */\nexport interface PerChildBudget {\n /**\n * Max `usage.totalTokens` per child. Enforced **post-hoc** and only\n * for usage-reporting children (an `invoke` that resolves to a full\n * `AgentResult` - e.g. `() => child.run(input)`); a child returning a\n * plain value reports `tokensUsed: 0` and this cap cannot fire.\n */\n readonly tokens?: number;\n /**\n * Max tool calls per child. Same usage-reporting contract as\n * {@link PerChildBudget.tokens} (counted from `state.steps`).\n */\n readonly toolCalls?: number;\n /** Wall-clock cap, enforced for every child via a race timer. */\n readonly durationMs?: number;\n}\n\n/**\n * Built-in merge-strategy taxonomy.\n *\n * @stable\n */\nexport type MergeStrategy<TOutput = unknown> =\n | { readonly kind: 'concat'; readonly separator?: string }\n | { readonly kind: 'first-success' }\n | {\n readonly kind: 'judge-merge';\n readonly judge: (children: ReadonlyArray<ChildResult<TOutput>>) => Promise<TOutput>;\n }\n | {\n readonly kind: 'custom';\n readonly merge: (children: ReadonlyArray<ChildResult<TOutput>>) => Promise<TOutput>;\n };\n\n/**\n * Per-child outcome surfaced on\n * {@link FanOutResult.children}. Failed-child isolation: a child\n * that throws produces a `ChildResult` with `status: 'failed'` -\n * never an exception thrown from the fan-out call itself.\n *\n * @stable\n */\nexport interface ChildResult<TOutput = unknown> {\n readonly agentId: string;\n readonly status: 'completed' | 'failed' | 'budget-exceeded' | 'cancelled';\n readonly output?: TOutput;\n readonly error?: { readonly message: string; readonly code: string };\n readonly tokensUsed: number;\n readonly toolCallCount: number;\n readonly durationMs: number;\n /**\n * Full usage breakdown, present only for usage-reporting children\n * (an `invoke` resolving to a full `AgentResult`, W-033).\n */\n readonly usage?: Usage;\n}\n\n/**\n * Aggregate result returned by `Agent.fanOut(...)`.\n *\n * @stable\n */\nexport interface FanOutResult<TOutput = unknown> {\n readonly fanOutId: string;\n readonly output: TOutput;\n readonly children: ReadonlyArray<ChildResult<TOutput>>;\n readonly mergeDurationMs: number;\n /**\n * Sum of every usage-reporting child's usage (W-033); zero when no\n * child reported. The fan-out helper never mutates the parent run's\n * live state (it runs outside the loop and would race it) - folding\n * this into the parent run's accounting is the caller's decision.\n */\n readonly usage: Usage;\n}\n\n/**\n * Per-call options accepted by `Agent.fanOut(...)`.\n *\n * @stable\n */\nexport interface FanOutOptions<TOutput = unknown> {\n /**\n * The sub-agents to invoke. Each entry is invoked as a function\n * returning a `Promise<TOutput>` - the fan-out helper does not\n * impose an `Agent` shape on the children so the runtime can\n * adapt any callable surface.\n */\n readonly children: ReadonlyArray<{\n readonly agentId: string;\n /**\n * Child callable. Resolve to a plain `TOutput`, or to a full\n * `AgentResult` (e.g. `() => childAgent.run(input)`) - the fan-out\n * detects the result envelope structurally (`output` + numeric\n * `usage.totalTokens` + `state`), unwraps `output`, and harvests\n * `tokensUsed` / `toolCallCount` so per-child budgets can enforce.\n */\n readonly invoke: () => Promise<TOutput>;\n /** Trust-class for the merge guard (default `'loopback'`). */\n readonly trustClass?: TrustClass;\n /** Content-origin for the merge guard (default `'built-in'`). */\n readonly origin?: ContentOriginKind;\n /** Rolling trust adjustment in `[0,1]` (default `1`). */\n readonly historyAdjustment?: number;\n }>;\n /** Default `4` per the canonical 2026 production lesson. */\n readonly maxConcurrentChildren?: number;\n /** Per-child budget; default unset. */\n readonly perBudget?: PerChildBudget;\n /** Default `{ kind: 'concat' }`. */\n readonly mergeStrategy?: MergeStrategy<TOutput>;\n readonly signal?: AbortSignal;\n /** Optional callback for per-child completion observability. */\n readonly onChildResult?: (result: ChildResult<TOutput>) => void;\n /** Optional event emitter for `agent.fanout.spawned / merged`. */\n readonly emit?: (event: AgentEvent) => void;\n /**\n * Sideways-injection merge guard (AG-7): on `'judge-merge'` the\n * fan-out scores each child's source trust and contribution weight\n * against the judge's merged output; a biased merge emits\n * `agent.lateral-leak.detected` (vector `sideways-injection`) and -\n * under `strictness: 'detect-and-block'` - throws\n * {@link MergeBlockedError}.\n */\n readonly mergeGuard?: MergeGuardConfig;\n /** Identifiers required to populate the events. */\n readonly runId: string;\n readonly sessionId: string;\n readonly agentId: string;\n /** Default - generated from `runId + Date.now()`. */\n readonly fanOutId?: string;\n}\n\nconst DEFAULT_MAX_CONCURRENT_CHILDREN = 4;\n\n/**\n * Structurally detect a full `AgentResult` returned by a child\n * `invoke` (AG-16): an object carrying `output`, a numeric\n * `usage.totalTokens`, and a `state` with string `id`/`status`. The\n * three-field match makes accidental collision with a user `TOutput`\n * negligible; children whose genuine output looks like this should\n * resolve a plain value instead.\n */\nfunction harvestAgentResult(value: unknown):\n | {\n readonly output: unknown;\n readonly tokensUsed: number;\n readonly toolCallCount: number;\n readonly usage?: Usage;\n }\n | undefined {\n if (typeof value !== 'object' || value === null) return undefined;\n const v = value as {\n readonly output?: unknown;\n readonly usage?: {\n readonly totalTokens?: unknown;\n readonly promptTokens?: unknown;\n readonly completionTokens?: unknown;\n };\n readonly state?: { readonly id?: unknown; readonly status?: unknown; readonly steps?: unknown };\n };\n if (!('output' in v)) return undefined;\n if (typeof v.usage?.totalTokens !== 'number') return undefined;\n if (typeof v.state?.id !== 'string' || typeof v.state.status !== 'string') return undefined;\n let toolCallCount = 0;\n if (Array.isArray(v.state.steps)) {\n for (const step of v.state.steps) {\n const calls = (step as { readonly toolCalls?: unknown }).toolCalls;\n if (Array.isArray(calls)) toolCallCount += calls.length;\n }\n }\n const usage =\n typeof v.usage.promptTokens === 'number' && typeof v.usage.completionTokens === 'number'\n ? (v.usage as Usage)\n : undefined;\n return {\n output: v.output,\n tokensUsed: v.usage.totalTokens,\n toolCallCount,\n ...(usage !== undefined ? { usage } : {}),\n };\n}\n\n/**\n * Whitespace-token overlap of a child's output against the merged\n * output, in `[0,1]` - the contribution-weight estimate the merge\n * guard's docstring contracts (each child scored independently; a\n * judge parroting one child verbatim yields ~1.0 for that child).\n */\nfunction contributionWeight(childText: string, mergedText: string): number {\n if (childText.length === 0 || mergedText.length === 0) return 0;\n const mergedTokens = mergedText.split(/\\s+/).filter((t) => t.length > 0);\n if (mergedTokens.length === 0) return 0;\n const childTokens = new Set(childText.split(/\\s+/).filter((t) => t.length > 0));\n let hits = 0;\n for (const token of mergedTokens) {\n if (childTokens.has(token)) hits += 1;\n }\n return hits / mergedTokens.length;\n}\n\nasync function runWithSemaphore<TOutput>(\n children: ReadonlyArray<FanOutOptions<TOutput>['children'][number]>,\n cap: number,\n signal: AbortSignal | undefined,\n perBudget: PerChildBudget | undefined,\n onChildResult?: (r: ChildResult<TOutput>) => void,\n): Promise<ReadonlyArray<ChildResult<TOutput>>> {\n const results: ChildResult<TOutput>[] = new Array(children.length);\n let cursor = 0;\n const running: Set<Promise<void>> = new Set();\n const limit = Math.max(1, Math.min(cap, children.length));\n\n const launchOne = (index: number): Promise<void> => {\n const child = children[index];\n if (child === undefined) return Promise.resolve();\n const start = Date.now();\n const exec = async (): Promise<ChildResult<TOutput>> => {\n if (signal?.aborted) {\n return {\n agentId: child.agentId,\n status: 'cancelled',\n tokensUsed: 0,\n toolCallCount: 0,\n durationMs: 0,\n };\n }\n let timer: ReturnType<typeof setTimeout> | undefined;\n try {\n const timedPromise =\n perBudget?.durationMs !== undefined\n ? new Promise<TOutput>((_, reject) => {\n timer = setTimeout(\n () => reject(new Error('budget-exceeded:durationMs')),\n perBudget.durationMs,\n );\n })\n : undefined;\n const racePromise = timedPromise\n ? Promise.race([child.invoke(), timedPromise])\n : child.invoke();\n const raw = await racePromise;\n // AG-16: a child resolving to a full AgentResult reports its\n // real usage - unwrap the output and harvest the counters.\n const report = harvestAgentResult(raw);\n const output = (report === undefined ? raw : report.output) as TOutput;\n const tokensUsed = report?.tokensUsed ?? 0;\n const toolCallCount = report?.toolCallCount ?? 0;\n // Post-hoc budget enforcement (only fires for usage-reporting\n // children): the over-budget output is withheld from the merge.\n const exceeded =\n (perBudget?.tokens !== undefined && tokensUsed > perBudget.tokens\n ? `tokens ${tokensUsed} > ${perBudget.tokens}`\n : undefined) ??\n (perBudget?.toolCalls !== undefined && toolCallCount > perBudget.toolCalls\n ? `toolCalls ${toolCallCount} > ${perBudget.toolCalls}`\n : undefined);\n if (exceeded !== undefined) {\n return {\n agentId: child.agentId,\n status: 'budget-exceeded',\n error: { message: `budget-exceeded: ${exceeded}`, code: 'budget-exceeded' },\n tokensUsed,\n toolCallCount,\n durationMs: Date.now() - start,\n ...(report?.usage !== undefined ? { usage: report.usage } : {}),\n };\n }\n return {\n agentId: child.agentId,\n status: 'completed',\n output,\n tokensUsed,\n toolCallCount,\n durationMs: Date.now() - start,\n ...(report?.usage !== undefined ? { usage: report.usage } : {}),\n };\n } catch (cause) {\n const message = cause instanceof Error ? cause.message : String(cause);\n const aborted = signal?.aborted;\n const status: ChildResult<TOutput>['status'] = message.startsWith('budget-exceeded')\n ? 'budget-exceeded'\n : aborted\n ? 'cancelled'\n : 'failed';\n return {\n agentId: child.agentId,\n status,\n error: { message, code: status },\n tokensUsed: 0,\n toolCallCount: 0,\n durationMs: Date.now() - start,\n };\n } finally {\n // AG-16: the duration timer must die on EVERY path - leaving it\n // armed on rejection held the event loop open.\n if (timer !== undefined) clearTimeout(timer);\n }\n };\n const promise = exec().then((r) => {\n results[index] = r;\n onChildResult?.(r);\n });\n running.add(promise);\n promise.finally(() => running.delete(promise));\n return promise;\n };\n\n while (cursor < children.length || running.size > 0) {\n while (running.size < limit && cursor < children.length) {\n void launchOne(cursor);\n cursor += 1;\n }\n if (running.size > 0) {\n await Promise.race(running);\n }\n }\n return results;\n}\n\n/**\n * Run a fan-out and produce the aggregate {@link FanOutResult}.\n * Pure with respect to side effects - the runtime emits events /\n * audit rows / counter increments via the supplied `emit` callback.\n *\n * @stable\n */\nexport async function runFanOut<TOutput>(\n opts: FanOutOptions<TOutput>,\n): Promise<FanOutResult<TOutput>> {\n const fanOutId = opts.fanOutId ?? `fanout-${opts.runId.slice(-8)}-${Date.now().toString(36)}`;\n const merge: MergeStrategy<TOutput> = opts.mergeStrategy ?? {\n kind: 'concat',\n };\n const cap = opts.maxConcurrentChildren ?? DEFAULT_MAX_CONCURRENT_CHILDREN;\n\n opts.emit?.({\n type: 'agent.fanout.spawned',\n runId: opts.runId,\n sessionId: opts.sessionId,\n agentId: opts.agentId,\n fanOutId,\n childCount: opts.children.length,\n mergeStrategyKind: merge.kind,\n spawnedAtIso: new Date().toISOString(),\n });\n\n const results = await runWithSemaphore<TOutput>(\n opts.children,\n cap,\n opts.signal,\n opts.perBudget,\n opts.onChildResult,\n );\n\n const mergeStart = Date.now();\n let merged: TOutput;\n switch (merge.kind) {\n case 'concat': {\n const sep = merge.separator ?? '\\n\\n---\\n\\n';\n const parts: string[] = [];\n for (const r of results) {\n if (r.status === 'completed' && r.output !== undefined) {\n parts.push(typeof r.output === 'string' ? r.output : JSON.stringify(r.output));\n } else if (\n r.status === 'failed' ||\n r.status === 'budget-exceeded' ||\n r.status === 'cancelled'\n ) {\n parts.push(`[${r.status}: ${r.agentId}]`);\n }\n }\n merged = parts.join(sep) as unknown as TOutput;\n break;\n }\n case 'first-success': {\n const first = results.find((r) => r.status === 'completed');\n merged = first?.output ?? ('' as unknown as TOutput);\n break;\n }\n case 'judge-merge': {\n merged = await merge.judge(results);\n // AG-7: the sideways-injection merge guard scores each child's\n // source trust × contribution weight against the judge's merged\n // output. A biased merge emits `agent.lateral-leak.detected`;\n // 'detect-and-block' refuses the merge entirely.\n if (opts.mergeGuard !== undefined && opts.mergeGuard.strictness !== 'off') {\n const mergedText = typeof merged === 'string' ? merged : JSON.stringify(merged);\n const overrides = opts.mergeGuard.sourceTrustOverrides ?? {};\n const perChild = results.map((r, i) => {\n const c = opts.children[i];\n const childText =\n r.output === undefined\n ? ''\n : typeof r.output === 'string'\n ? r.output\n : JSON.stringify(r.output);\n return {\n agentId: r.agentId,\n sourceTrust: computeSourceTrust(\n {\n agentId: r.agentId,\n trustClass: c?.trustClass ?? 'loopback',\n origin: c?.origin ?? 'built-in',\n ...(c?.historyAdjustment !== undefined\n ? { historyAdjustment: c.historyAdjustment }\n : {}),\n },\n overrides,\n ),\n contributionWeight: contributionWeight(childText, mergedText),\n };\n });\n const verdict = evaluateMerge(perChild, opts.mergeGuard);\n if (verdict.biased) {\n opts.emit?.({\n type: 'agent.lateral-leak.detected',\n runId: opts.runId,\n sessionId: opts.sessionId,\n agentId: opts.agentId,\n vector: 'sideways-injection',\n severity: verdict.decision === 'block' ? 'block' : 'warn',\n causalityChain: verdict.offendingChild === undefined ? [] : [verdict.offendingChild],\n messageContentSha256: createHash('sha256').update(mergedText, 'utf8').digest('hex'),\n decision:\n verdict.decision === 'block'\n ? 'block'\n : verdict.decision === 'flag'\n ? 'flag'\n : 'detect',\n detectedAtIso: new Date().toISOString(),\n });\n if (verdict.decision === 'block') {\n throw new MergeBlockedError(\n fanOutId,\n `low-trust child '${verdict.offendingChild}' (sourceTrust ${verdict.sourceTrust?.toFixed(2)}) contributes ${(\n (verdict.contributionWeight ?? 0) * 100\n ).toFixed(0)}% of the merged output`,\n );\n }\n }\n }\n break;\n }\n case 'custom':\n merged = await merge.merge(results);\n break;\n default: {\n const _exhaustive: never = merge;\n void _exhaustive;\n merged = '' as unknown as TOutput;\n }\n }\n const mergeDurationMs = Date.now() - mergeStart;\n\n const childMetadata: FanOutChildMetadata[] = results.map((r) => ({\n agentId: r.agentId,\n status: r.status,\n tokensUsed: r.tokensUsed,\n toolCallCount: r.toolCallCount,\n durationMs: r.durationMs,\n }));\n const successfulChildCount = results.filter((r) => r.status === 'completed').length;\n\n opts.emit?.({\n type: 'agent.fanout.merged',\n runId: opts.runId,\n sessionId: opts.sessionId,\n agentId: opts.agentId,\n fanOutId,\n childCount: opts.children.length,\n successfulChildCount,\n mergeStrategyKind: merge.kind,\n mergeDurationMs,\n childMetadata,\n });\n\n const usage = zeroUsage();\n for (const r of results) {\n if (r.usage !== undefined) accumulateUsage(usage, r.usage);\n }\n\n return {\n fanOutId,\n output: merged,\n children: results,\n mergeDurationMs,\n usage,\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAsKA,MAAM,kCAAkC;;;;;;;;;AAUxC,SAAS,mBAAmB,OAOd;AACZ,KAAI,OAAO,UAAU,YAAY,UAAU,KAAM,QAAO;CACxD,MAAM,IAAI;AASV,KAAI,EAAE,YAAY,GAAI,QAAO;AAC7B,KAAI,OAAO,EAAE,OAAO,gBAAgB,SAAU,QAAO;AACrD,KAAI,OAAO,EAAE,OAAO,OAAO,YAAY,OAAO,EAAE,MAAM,WAAW,SAAU,QAAO;CAClF,IAAI,gBAAgB;AACpB,KAAI,MAAM,QAAQ,EAAE,MAAM,MAAM,CAC9B,MAAK,MAAM,QAAQ,EAAE,MAAM,OAAO;EAChC,MAAM,QAAS,KAA0C;AACzD,MAAI,MAAM,QAAQ,MAAM,CAAE,kBAAiB,MAAM;;CAGrD,MAAM,QACJ,OAAO,EAAE,MAAM,iBAAiB,YAAY,OAAO,EAAE,MAAM,qBAAqB,WAC3E,EAAE,QACH;AACN,QAAO;EACL,QAAQ,EAAE;EACV,YAAY,EAAE,MAAM;EACpB;EACA,GAAI,UAAU,SAAY,EAAE,OAAO,GAAG,EAAE;EACzC;;;;;;;;AASH,SAAS,mBAAmB,WAAmB,YAA4B;AACzE,KAAI,UAAU,WAAW,KAAK,WAAW,WAAW,EAAG,QAAO;CAC9D,MAAM,eAAe,WAAW,MAAM,MAAM,CAAC,QAAQ,MAAM,EAAE,SAAS,EAAE;AACxE,KAAI,aAAa,WAAW,EAAG,QAAO;CACtC,MAAM,cAAc,IAAI,IAAI,UAAU,MAAM,MAAM,CAAC,QAAQ,MAAM,EAAE,SAAS,EAAE,CAAC;CAC/E,IAAI,OAAO;AACX,MAAK,MAAM,SAAS,aAClB,KAAI,YAAY,IAAI,MAAM,CAAE,SAAQ;AAEtC,QAAO,OAAO,aAAa;;AAG7B,eAAe,iBACb,UACA,KACA,QACA,WACA,eAC8C;CAC9C,MAAMA,UAAkC,IAAI,MAAM,SAAS,OAAO;CAClE,IAAI,SAAS;CACb,MAAMC,0BAA8B,IAAI,KAAK;CAC7C,MAAM,QAAQ,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,SAAS,OAAO,CAAC;CAEzD,MAAM,aAAa,UAAiC;EAClD,MAAM,QAAQ,SAAS;AACvB,MAAI,UAAU,OAAW,QAAO,QAAQ,SAAS;EACjD,MAAM,QAAQ,KAAK,KAAK;EACxB,MAAM,OAAO,YAA2C;AACtD,OAAI,QAAQ,QACV,QAAO;IACL,SAAS,MAAM;IACf,QAAQ;IACR,YAAY;IACZ,eAAe;IACf,YAAY;IACb;GAEH,IAAIC;AACJ,OAAI;IACF,MAAM,eACJ,WAAW,eAAe,SACtB,IAAI,SAAkB,GAAG,WAAW;AAClC,aAAQ,iBACA,uBAAO,IAAI,MAAM,6BAA6B,CAAC,EACrD,UAAU,WACX;MACD,GACF;IAIN,MAAM,MAAM,OAHQ,eAChB,QAAQ,KAAK,CAAC,MAAM,QAAQ,EAAE,aAAa,CAAC,GAC5C,MAAM,QAAQ;IAIlB,MAAM,SAAS,mBAAmB,IAAI;IACtC,MAAM,SAAU,WAAW,SAAY,MAAM,OAAO;IACpD,MAAM,aAAa,QAAQ,cAAc;IACzC,MAAM,gBAAgB,QAAQ,iBAAiB;IAG/C,MAAM,YACH,WAAW,WAAW,UAAa,aAAa,UAAU,SACvD,UAAU,WAAW,KAAK,UAAU,WACpC,YACH,WAAW,cAAc,UAAa,gBAAgB,UAAU,YAC7D,aAAa,cAAc,KAAK,UAAU,cAC1C;AACN,QAAI,aAAa,OACf,QAAO;KACL,SAAS,MAAM;KACf,QAAQ;KACR,OAAO;MAAE,SAAS,oBAAoB;MAAY,MAAM;MAAmB;KAC3E;KACA;KACA,YAAY,KAAK,KAAK,GAAG;KACzB,GAAI,QAAQ,UAAU,SAAY,EAAE,OAAO,OAAO,OAAO,GAAG,EAAE;KAC/D;AAEH,WAAO;KACL,SAAS,MAAM;KACf,QAAQ;KACR;KACA;KACA;KACA,YAAY,KAAK,KAAK,GAAG;KACzB,GAAI,QAAQ,UAAU,SAAY,EAAE,OAAO,OAAO,OAAO,GAAG,EAAE;KAC/D;YACM,OAAO;IACd,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;IACtE,MAAM,UAAU,QAAQ;IACxB,MAAMC,SAAyC,QAAQ,WAAW,kBAAkB,GAChF,oBACA,UACE,cACA;AACN,WAAO;KACL,SAAS,MAAM;KACf;KACA,OAAO;MAAE;MAAS,MAAM;MAAQ;KAChC,YAAY;KACZ,eAAe;KACf,YAAY,KAAK,KAAK,GAAG;KAC1B;aACO;AAGR,QAAI,UAAU,OAAW,cAAa,MAAM;;;EAGhD,MAAM,UAAU,MAAM,CAAC,MAAM,MAAM;AACjC,WAAQ,SAAS;AACjB,mBAAgB,EAAE;IAClB;AACF,UAAQ,IAAI,QAAQ;AACpB,UAAQ,cAAc,QAAQ,OAAO,QAAQ,CAAC;AAC9C,SAAO;;AAGT,QAAO,SAAS,SAAS,UAAU,QAAQ,OAAO,GAAG;AACnD,SAAO,QAAQ,OAAO,SAAS,SAAS,SAAS,QAAQ;AACvD,GAAK,UAAU,OAAO;AACtB,aAAU;;AAEZ,MAAI,QAAQ,OAAO,EACjB,OAAM,QAAQ,KAAK,QAAQ;;AAG/B,QAAO;;;;;;;;;AAUT,eAAsB,UACpB,MACgC;CAChC,MAAM,WAAW,KAAK,YAAY,UAAU,KAAK,MAAM,MAAM,GAAG,CAAC,GAAG,KAAK,KAAK,CAAC,SAAS,GAAG;CAC3F,MAAMC,QAAgC,KAAK,iBAAiB,EAC1D,MAAM,UACP;CACD,MAAM,MAAM,KAAK,yBAAyB;AAE1C,MAAK,OAAO;EACV,MAAM;EACN,OAAO,KAAK;EACZ,WAAW,KAAK;EAChB,SAAS,KAAK;EACd;EACA,YAAY,KAAK,SAAS;EAC1B,mBAAmB,MAAM;EACzB,+BAAc,IAAI,MAAM,EAAC,aAAa;EACvC,CAAC;CAEF,MAAM,UAAU,MAAM,iBACpB,KAAK,UACL,KACA,KAAK,QACL,KAAK,WACL,KAAK,cACN;CAED,MAAM,aAAa,KAAK,KAAK;CAC7B,IAAIC;AACJ,SAAQ,MAAM,MAAd;EACE,KAAK,UAAU;GACb,MAAM,MAAM,MAAM,aAAa;GAC/B,MAAMC,QAAkB,EAAE;AAC1B,QAAK,MAAM,KAAK,QACd,KAAI,EAAE,WAAW,eAAe,EAAE,WAAW,OAC3C,OAAM,KAAK,OAAO,EAAE,WAAW,WAAW,EAAE,SAAS,KAAK,UAAU,EAAE,OAAO,CAAC;YAE9E,EAAE,WAAW,YACb,EAAE,WAAW,qBACb,EAAE,WAAW,YAEb,OAAM,KAAK,IAAI,EAAE,OAAO,IAAI,EAAE,QAAQ,GAAG;AAG7C,YAAS,MAAM,KAAK,IAAI;AACxB;;EAEF,KAAK;AAEH,YADc,QAAQ,MAAM,MAAM,EAAE,WAAW,YAAY,EAC3C,UAAW;AAC3B;EAEF,KAAK;AACH,YAAS,MAAM,MAAM,MAAM,QAAQ;AAKnC,OAAI,KAAK,eAAe,UAAa,KAAK,WAAW,eAAe,OAAO;IACzE,MAAM,aAAa,OAAO,WAAW,WAAW,SAAS,KAAK,UAAU,OAAO;IAC/E,MAAM,YAAY,KAAK,WAAW,wBAAwB,EAAE;IAyB5D,MAAM,UAAU,cAxBC,QAAQ,KAAK,GAAG,MAAM;KACrC,MAAM,IAAI,KAAK,SAAS;KACxB,MAAM,YACJ,EAAE,WAAW,SACT,KACA,OAAO,EAAE,WAAW,WAClB,EAAE,SACF,KAAK,UAAU,EAAE,OAAO;AAChC,YAAO;MACL,SAAS,EAAE;MACX,aAAa,mBACX;OACE,SAAS,EAAE;OACX,YAAY,GAAG,cAAc;OAC7B,QAAQ,GAAG,UAAU;OACrB,GAAI,GAAG,sBAAsB,SACzB,EAAE,mBAAmB,EAAE,mBAAmB,GAC1C,EAAE;OACP,EACD,UACD;MACD,oBAAoB,mBAAmB,WAAW,WAAW;MAC9D;MACD,EACsC,KAAK,WAAW;AACxD,QAAI,QAAQ,QAAQ;AAClB,UAAK,OAAO;MACV,MAAM;MACN,OAAO,KAAK;MACZ,WAAW,KAAK;MAChB,SAAS,KAAK;MACd,QAAQ;MACR,UAAU,QAAQ,aAAa,UAAU,UAAU;MACnD,gBAAgB,QAAQ,mBAAmB,SAAY,EAAE,GAAG,CAAC,QAAQ,eAAe;MACpF,sBAAsB,WAAW,SAAS,CAAC,OAAO,YAAY,OAAO,CAAC,OAAO,MAAM;MACnF,UACE,QAAQ,aAAa,UACjB,UACA,QAAQ,aAAa,SACnB,SACA;MACR,gCAAe,IAAI,MAAM,EAAC,aAAa;MACxC,CAAC;AACF,SAAI,QAAQ,aAAa,QACvB,OAAM,IAAI,kBACR,UACA,oBAAoB,QAAQ,eAAe,iBAAiB,QAAQ,aAAa,QAAQ,EAAE,CAAC,kBACzF,QAAQ,sBAAsB,KAAK,KACpC,QAAQ,EAAE,CAAC,wBACd;;;AAIP;EAEF,KAAK;AACH,YAAS,MAAM,MAAM,MAAM,QAAQ;AACnC;EACF,QAGE,UAAS;;CAGb,MAAM,kBAAkB,KAAK,KAAK,GAAG;CAErC,MAAMC,gBAAuC,QAAQ,KAAK,OAAO;EAC/D,SAAS,EAAE;EACX,QAAQ,EAAE;EACV,YAAY,EAAE;EACd,eAAe,EAAE;EACjB,YAAY,EAAE;EACf,EAAE;CACH,MAAM,uBAAuB,QAAQ,QAAQ,MAAM,EAAE,WAAW,YAAY,CAAC;AAE7E,MAAK,OAAO;EACV,MAAM;EACN,OAAO,KAAK;EACZ,WAAW,KAAK;EAChB,SAAS,KAAK;EACd;EACA,YAAY,KAAK,SAAS;EAC1B;EACA,mBAAmB,MAAM;EACzB;EACA;EACD,CAAC;CAEF,MAAM,QAAQ,WAAW;AACzB,MAAK,MAAM,KAAK,QACd,KAAI,EAAE,UAAU,OAAW,iBAAgB,OAAO,EAAE,MAAM;AAG5D,QAAO;EACL;EACA,QAAQ;EACR,UAAU;EACV;EACA;EACD"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
|
-
import { AgentResolutionError, AgentRuntimeError, AgentRuntimeErrorCode, EvaluatorOptimizerConfigError, InvalidAgentConfigError, InvalidPreferredModelError, MergeBlockedError, MultipleHandoffsInStepError, ProgressWriteError, ProtocolInjectionRejectError, ProviderMiddlewareOrderError, RunStateMalformedError, RunStateVersionUnsupportedError, ToolNotFoundError } from "./errors/index.js";
|
|
1
|
+
import { AgentResolutionError, AgentRuntimeError, AgentRuntimeErrorCode, EvaluatorOptimizerConfigError, InvalidAgentConfigError, InvalidPreferredModelError, MergeBlockedError, MultipleHandoffsInStepError, ProgressWriteError, ProtocolInjectionRejectError, ProviderMiddlewareOrderError, RunStateMalformedError, RunStateVersionUnsupportedError, SubAgentResumeTargetNotFoundError, ToolNotFoundError } from "./errors/index.js";
|
|
2
2
|
import { EvaluatorCallable, EvaluatorOptimizerOptions, EvaluatorOptimizerOutcome, EvaluatorOutcome, GeneratorCallable, Rubric, evaluatorOptimizer } from "./evaluator-optimizer/index.js";
|
|
3
3
|
import { AgentFallbackEligibility, AgentFallbackPolicy, AgentFallbackReason, isAgentFallbackEligible } from "./fallback/index.js";
|
|
4
4
|
import { ChildTrustInput, ContentOriginKind, MergeBiasDecision, MergeGuardConfig, TrustClass, computeSourceTrust, evaluateMerge } from "./lateral-leak/merge-guard.js";
|
|
5
5
|
import { ChildResult, FanOutOptions, FanOutResult, MergeStrategy, PerChildBudget, runFanOut } from "./fanout/index.js";
|
|
6
6
|
import { CausalityMonitor, CausalityMonitorCheck, CausalityMonitorConfig, CausalityMonitorStrictness, DEFAULT_DENIAL_PATTERNS, DEFAULT_MAX_CHAIN_DEPTH } from "./lateral-leak/causality-monitor.js";
|
|
7
7
|
import { ProgressIO, ProgressIOConfig, ProgressReadOptions, ProgressWriteOptions, createProgressIO } from "./progress/index.js";
|
|
8
|
-
import { AbortOptions, Agent, AgentCallOptions, AgentCapability, AgentConfig, AgentInput, AgentToToolOptions, CompactOptions, CompactionApiResult, OutputSpec, PostCompactionHook, PrepareStepHook, PrepareStepOverrides, ResponseVerifier, ResumeDirective, SkillsRegistryLike, VerifierResult } from "./types.js";
|
|
8
|
+
import { AbortOptions, Agent, AgentCallOptions, AgentCapability, AgentConfig, AgentInput, AgentToToolOptions, CompactOptions, CompactionApiResult, HandoffEntry, OutputSpec, PostCompactionHook, PrepareStepHook, PrepareStepOverrides, ResponseVerifier, ResumeDirective, SkillsRegistryLike, VerifierResult } from "./types.js";
|
|
9
9
|
import { createAgent } from "./factory.js";
|
|
10
10
|
import { DescribedFilter, FILTER_KIND_CUSTOM, bySensitivity, compose, custom, defaultHandoffFilter, filters, full, lastN, lastUser, stripReasoning, stripSensitiveOutputs, stripToolCalls, summary } from "./filters/index.js";
|
|
11
11
|
import { GuardOutcome, ProtocolBoundary, ProtocolEscapePolicy, ProtocolGuardConfig, guardOutboundContent, resolvePolicy } from "./lateral-leak/protocol-guard.js";
|
|
12
12
|
import "./lateral-leak/index.js";
|
|
13
13
|
import { PreferredModelResolution, ResolvePreferredModelInput, pickTopTierAcrossTools, resolvePreferredModel } from "./preferred-model/index.js";
|
|
14
|
-
import { RUN_STATE_SCHEMA_MAJOR_SUPPORTED, RUN_STATE_SCHEMA_VERSION, SerializeRunStateOptions, SerializedRunState, addModelUsage, aggregateUsageFromByModel, completedToolCallsFromState, createInitialRunState, deserializeRunState, runStateFromJSON, runStateToJSON, serializeRunState } from "./run-state/index.js";
|
|
14
|
+
import { RUN_STATE_SCHEMA_MAJOR_SUPPORTED, RUN_STATE_SCHEMA_VERSION, SerializeRunStateOptions, SerializedPendingSubRun, SerializedRunState, addModelUsage, aggregateUsageFromByModel, completedToolCallsFromState, createInitialRunState, deserializeRunState, runStateFromJSON, runStateToJSON, serializeRunState } from "./run-state/index.js";
|
|
15
|
+
import { SUBAGENT_TOOL, SubAgentFoldTaint, SubAgentToolRefs, getSubAgentToolRefs } from "./runtime/agent-to-tool.js";
|
|
16
|
+
import { foldChildRunUsage } from "./runtime/messages.js";
|
|
15
17
|
import { ReplayProviderOptions, createReplayProvider } from "./testing/replay-provider.js";
|
|
16
18
|
import { GuardrailContext, GuardrailDefinition, GuardrailResult, InputGuardrail, OutputGuardrail } from "@graphorin/security/guardrails";
|
|
17
19
|
|
|
@@ -45,8 +47,7 @@ import { GuardrailContext, GuardrailDefinition, GuardrailResult, InputGuardrail,
|
|
|
45
47
|
*
|
|
46
48
|
* @packageDocumentation
|
|
47
49
|
*/
|
|
48
|
-
|
|
49
|
-
declare const VERSION = "0.6.0";
|
|
50
|
+
declare const VERSION: string;
|
|
50
51
|
//#endregion
|
|
51
|
-
export { type AbortOptions, type Agent, type AgentCallOptions, type AgentCapability, type AgentConfig, type AgentFallbackEligibility, type AgentFallbackPolicy, type AgentFallbackReason, type AgentInput, AgentResolutionError, AgentRuntimeError, type AgentRuntimeErrorCode, type AgentToToolOptions, CausalityMonitor, type CausalityMonitorCheck, type CausalityMonitorConfig, type CausalityMonitorStrictness, type ChildResult, type ChildTrustInput, type CompactOptions, type CompactionApiResult, type ContentOriginKind, DEFAULT_DENIAL_PATTERNS, DEFAULT_MAX_CHAIN_DEPTH, type DescribedFilter, type EvaluatorCallable, EvaluatorOptimizerConfigError, type EvaluatorOptimizerOptions, type EvaluatorOptimizerOutcome, type EvaluatorOutcome, FILTER_KIND_CUSTOM, type FanOutOptions, type FanOutResult, type GeneratorCallable, type GuardOutcome, type GuardrailContext, type GuardrailDefinition, type GuardrailResult, type InputGuardrail, InvalidAgentConfigError, InvalidPreferredModelError, type MergeBiasDecision, MergeBlockedError, type MergeGuardConfig, type MergeStrategy, MultipleHandoffsInStepError, type OutputGuardrail, type OutputSpec, type PerChildBudget, type PostCompactionHook, type PreferredModelResolution, type PrepareStepHook, type PrepareStepOverrides, type ProgressIO, type ProgressIOConfig, type ProgressReadOptions, ProgressWriteError, type ProgressWriteOptions, type ProtocolBoundary, type ProtocolEscapePolicy, type ProtocolGuardConfig, ProtocolInjectionRejectError, ProviderMiddlewareOrderError, RUN_STATE_SCHEMA_MAJOR_SUPPORTED, RUN_STATE_SCHEMA_VERSION, type ReplayProviderOptions, type ResolvePreferredModelInput, type ResponseVerifier, type ResumeDirective, type Rubric, RunStateMalformedError, RunStateVersionUnsupportedError, type SerializeRunStateOptions, type SerializedRunState, type SkillsRegistryLike, ToolNotFoundError, type TrustClass, VERSION, type VerifierResult, addModelUsage, aggregateUsageFromByModel, bySensitivity, completedToolCallsFromState, compose, computeSourceTrust, createAgent, createInitialRunState, createProgressIO, createReplayProvider, custom, defaultHandoffFilter, deserializeRunState, evaluateMerge, evaluatorOptimizer, filters, full, guardOutboundContent, isAgentFallbackEligible, lastN, lastUser, pickTopTierAcrossTools, resolvePolicy, resolvePreferredModel, runFanOut, runStateFromJSON, runStateToJSON, serializeRunState, stripReasoning, stripSensitiveOutputs, stripToolCalls, summary };
|
|
52
|
+
export { type AbortOptions, type Agent, type AgentCallOptions, type AgentCapability, type AgentConfig, type AgentFallbackEligibility, type AgentFallbackPolicy, type AgentFallbackReason, type AgentInput, AgentResolutionError, AgentRuntimeError, type AgentRuntimeErrorCode, type AgentToToolOptions, CausalityMonitor, type CausalityMonitorCheck, type CausalityMonitorConfig, type CausalityMonitorStrictness, type ChildResult, type ChildTrustInput, type CompactOptions, type CompactionApiResult, type ContentOriginKind, DEFAULT_DENIAL_PATTERNS, DEFAULT_MAX_CHAIN_DEPTH, type DescribedFilter, type EvaluatorCallable, EvaluatorOptimizerConfigError, type EvaluatorOptimizerOptions, type EvaluatorOptimizerOutcome, type EvaluatorOutcome, FILTER_KIND_CUSTOM, type FanOutOptions, type FanOutResult, type GeneratorCallable, type GuardOutcome, type GuardrailContext, type GuardrailDefinition, type GuardrailResult, type HandoffEntry, type InputGuardrail, InvalidAgentConfigError, InvalidPreferredModelError, type MergeBiasDecision, MergeBlockedError, type MergeGuardConfig, type MergeStrategy, MultipleHandoffsInStepError, type OutputGuardrail, type OutputSpec, type PerChildBudget, type PostCompactionHook, type PreferredModelResolution, type PrepareStepHook, type PrepareStepOverrides, type ProgressIO, type ProgressIOConfig, type ProgressReadOptions, ProgressWriteError, type ProgressWriteOptions, type ProtocolBoundary, type ProtocolEscapePolicy, type ProtocolGuardConfig, ProtocolInjectionRejectError, ProviderMiddlewareOrderError, RUN_STATE_SCHEMA_MAJOR_SUPPORTED, RUN_STATE_SCHEMA_VERSION, type ReplayProviderOptions, type ResolvePreferredModelInput, type ResponseVerifier, type ResumeDirective, type Rubric, RunStateMalformedError, RunStateVersionUnsupportedError, SUBAGENT_TOOL, type SerializeRunStateOptions, type SerializedPendingSubRun, type SerializedRunState, type SkillsRegistryLike, type SubAgentFoldTaint, SubAgentResumeTargetNotFoundError, type SubAgentToolRefs, ToolNotFoundError, type TrustClass, VERSION, type VerifierResult, addModelUsage, aggregateUsageFromByModel, bySensitivity, completedToolCallsFromState, compose, computeSourceTrust, createAgent, createInitialRunState, createProgressIO, createReplayProvider, custom, defaultHandoffFilter, deserializeRunState, evaluateMerge, evaluatorOptimizer, filters, foldChildRunUsage, full, getSubAgentToolRefs, guardOutboundContent, isAgentFallbackEligible, lastN, lastUser, pickTopTierAcrossTools, resolvePolicy, resolvePreferredModel, runFanOut, runStateFromJSON, runStateToJSON, serializeRunState, stripReasoning, stripSensitiveOutputs, stripToolCalls, summary };
|
|
52
53
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/index.ts"],"sourcesContent":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/index.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCA;;;;;;;;cAAa"}
|
package/dist/index.js
CHANGED
|
@@ -1,16 +1,18 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { version } from "./package.js";
|
|
2
|
+
import { AgentResolutionError, AgentRuntimeError, EvaluatorOptimizerConfigError, InvalidAgentConfigError, InvalidPreferredModelError, MergeBlockedError, MultipleHandoffsInStepError, ProgressWriteError, ProtocolInjectionRejectError, ProviderMiddlewareOrderError, RunStateMalformedError, RunStateVersionUnsupportedError, SubAgentResumeTargetNotFoundError, ToolNotFoundError } from "./errors/index.js";
|
|
2
3
|
import { evaluatorOptimizer } from "./evaluator-optimizer/index.js";
|
|
3
|
-
import {
|
|
4
|
+
import { CausalityMonitor, DEFAULT_DENIAL_PATTERNS, DEFAULT_MAX_CHAIN_DEPTH } from "./lateral-leak/causality-monitor.js";
|
|
5
|
+
import { createProgressIO } from "./progress/index.js";
|
|
6
|
+
import { RUN_STATE_SCHEMA_MAJOR_SUPPORTED, RUN_STATE_SCHEMA_VERSION, addModelUsage, aggregateUsageFromByModel, completedToolCallsFromState, createInitialRunState, deserializeRunState, runStateFromJSON, runStateToJSON, serializeRunState } from "./run-state/index.js";
|
|
4
7
|
import { computeSourceTrust, evaluateMerge } from "./lateral-leak/merge-guard.js";
|
|
8
|
+
import { foldChildRunUsage } from "./runtime/messages.js";
|
|
5
9
|
import { runFanOut } from "./fanout/index.js";
|
|
10
|
+
import { SUBAGENT_TOOL, getSubAgentToolRefs } from "./runtime/agent-to-tool.js";
|
|
6
11
|
import { FILTER_KIND_CUSTOM, bySensitivity, compose, custom, defaultHandoffFilter, filters, full, lastN, lastUser, stripReasoning, stripSensitiveOutputs, stripToolCalls, summary } from "./filters/index.js";
|
|
7
|
-
import {
|
|
12
|
+
import { isAgentFallbackEligible } from "./fallback/index.js";
|
|
8
13
|
import { pickTopTierAcrossTools, resolvePreferredModel } from "./preferred-model/index.js";
|
|
9
|
-
import { createProgressIO } from "./progress/index.js";
|
|
10
|
-
import { RUN_STATE_SCHEMA_MAJOR_SUPPORTED, RUN_STATE_SCHEMA_VERSION, addModelUsage, aggregateUsageFromByModel, completedToolCallsFromState, createInitialRunState, deserializeRunState, runStateFromJSON, runStateToJSON, serializeRunState } from "./run-state/index.js";
|
|
11
14
|
import { createAgent } from "./factory.js";
|
|
12
15
|
import { guardOutboundContent, resolvePolicy } from "./lateral-leak/protocol-guard.js";
|
|
13
|
-
import "./lateral-leak/index.js";
|
|
14
16
|
import { createReplayProvider } from "./testing/replay-provider.js";
|
|
15
17
|
|
|
16
18
|
//#region src/index.ts
|
|
@@ -42,9 +44,9 @@ import { createReplayProvider } from "./testing/replay-provider.js";
|
|
|
42
44
|
*
|
|
43
45
|
* @packageDocumentation
|
|
44
46
|
*/
|
|
45
|
-
/** Canonical version constant
|
|
46
|
-
const VERSION =
|
|
47
|
+
/** Canonical version constant, derived from `package.json` at build time. */
|
|
48
|
+
const VERSION = version;
|
|
47
49
|
|
|
48
50
|
//#endregion
|
|
49
|
-
export { AgentResolutionError, AgentRuntimeError, CausalityMonitor, DEFAULT_DENIAL_PATTERNS, DEFAULT_MAX_CHAIN_DEPTH, EvaluatorOptimizerConfigError, FILTER_KIND_CUSTOM, InvalidAgentConfigError, InvalidPreferredModelError, MergeBlockedError, MultipleHandoffsInStepError, ProgressWriteError, ProtocolInjectionRejectError, ProviderMiddlewareOrderError, RUN_STATE_SCHEMA_MAJOR_SUPPORTED, RUN_STATE_SCHEMA_VERSION, RunStateMalformedError, RunStateVersionUnsupportedError, ToolNotFoundError, VERSION, addModelUsage, aggregateUsageFromByModel, bySensitivity, completedToolCallsFromState, compose, computeSourceTrust, createAgent, createInitialRunState, createProgressIO, createReplayProvider, custom, defaultHandoffFilter, deserializeRunState, evaluateMerge, evaluatorOptimizer, filters, full, guardOutboundContent, isAgentFallbackEligible, lastN, lastUser, pickTopTierAcrossTools, resolvePolicy, resolvePreferredModel, runFanOut, runStateFromJSON, runStateToJSON, serializeRunState, stripReasoning, stripSensitiveOutputs, stripToolCalls, summary };
|
|
51
|
+
export { AgentResolutionError, AgentRuntimeError, CausalityMonitor, DEFAULT_DENIAL_PATTERNS, DEFAULT_MAX_CHAIN_DEPTH, EvaluatorOptimizerConfigError, FILTER_KIND_CUSTOM, InvalidAgentConfigError, InvalidPreferredModelError, MergeBlockedError, MultipleHandoffsInStepError, ProgressWriteError, ProtocolInjectionRejectError, ProviderMiddlewareOrderError, RUN_STATE_SCHEMA_MAJOR_SUPPORTED, RUN_STATE_SCHEMA_VERSION, RunStateMalformedError, RunStateVersionUnsupportedError, SUBAGENT_TOOL, SubAgentResumeTargetNotFoundError, ToolNotFoundError, VERSION, addModelUsage, aggregateUsageFromByModel, bySensitivity, completedToolCallsFromState, compose, computeSourceTrust, createAgent, createInitialRunState, createProgressIO, createReplayProvider, custom, defaultHandoffFilter, deserializeRunState, evaluateMerge, evaluatorOptimizer, filters, foldChildRunUsage, full, getSubAgentToolRefs, guardOutboundContent, isAgentFallbackEligible, lastN, lastUser, pickTopTierAcrossTools, resolvePolicy, resolvePreferredModel, runFanOut, runStateFromJSON, runStateToJSON, serializeRunState, stripReasoning, stripSensitiveOutputs, stripToolCalls, summary };
|
|
50
52
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["/**\n * `@graphorin/agent` - agent runtime for the Graphorin framework.\n *\n * The package owns:\n *\n * - The `createAgent({...})` factory that wires the typed\n * `model -> tool calls -> model` loop, the streaming event\n * surface, the steering / followUp queues, durable HITL\n * approvals, multi-agent handoffs (`Agent.toTool`, the filter\n * library, secrets isolation), the agent-level model fallback\n * chain, the per-step compaction lifecycle, the per-tool\n * preferred-model resolution, the structured progress-artifact\n * APIs, and the lateral-leak defense layer.\n * - `runStateToJSON / runStateFromJSON` helpers for caller-managed\n * durable HITL.\n * - The handoff filter library.\n * - The agent-step-level fan-out helpers (`runFanOut`,\n * `evaluatorOptimizer`, the progress IO surface).\n * - Pure decision functions consulted by the loop\n * (`isAgentFallbackEligible`, `resolvePreferredModel`).\n * - Lateral-leak primitives (`CausalityMonitor`,\n * `MergeAgentSidewaysInjectionGuard` decision helpers,\n * protocol-injection guard).\n *\n * The full documentation lives in the package `README.md`.\n *\n * @packageDocumentation\n */\n\n/** Canonical version constant
|
|
1
|
+
{"version":3,"file":"index.js","names":["VERSION: string","pkg.version"],"sources":["../src/index.ts"],"sourcesContent":["/**\n * `@graphorin/agent` - agent runtime for the Graphorin framework.\n *\n * The package owns:\n *\n * - The `createAgent({...})` factory that wires the typed\n * `model -> tool calls -> model` loop, the streaming event\n * surface, the steering / followUp queues, durable HITL\n * approvals, multi-agent handoffs (`Agent.toTool`, the filter\n * library, secrets isolation), the agent-level model fallback\n * chain, the per-step compaction lifecycle, the per-tool\n * preferred-model resolution, the structured progress-artifact\n * APIs, and the lateral-leak defense layer.\n * - `runStateToJSON / runStateFromJSON` helpers for caller-managed\n * durable HITL.\n * - The handoff filter library.\n * - The agent-step-level fan-out helpers (`runFanOut`,\n * `evaluatorOptimizer`, the progress IO surface).\n * - Pure decision functions consulted by the loop\n * (`isAgentFallbackEligible`, `resolvePreferredModel`).\n * - Lateral-leak primitives (`CausalityMonitor`,\n * `MergeAgentSidewaysInjectionGuard` decision helpers,\n * protocol-injection guard).\n *\n * The full documentation lives in the package `README.md`.\n *\n * @packageDocumentation\n */\n\n/** Canonical version constant, derived from `package.json` at build time. */\nimport pkg from '../package.json' with { type: 'json' };\n\nexport const VERSION: string = pkg.version;\n\n// AG-2 / SDF-4: the canonical guardrail contract lives in\n// `@graphorin/security`; re-exported here for config ergonomics.\nexport type {\n GuardrailContext,\n GuardrailDefinition,\n GuardrailResult,\n InputGuardrail,\n OutputGuardrail,\n} from '@graphorin/security/guardrails';\nexport {\n AgentResolutionError,\n AgentRuntimeError,\n type AgentRuntimeErrorCode,\n EvaluatorOptimizerConfigError,\n InvalidAgentConfigError,\n InvalidPreferredModelError,\n MergeBlockedError,\n MultipleHandoffsInStepError,\n ProgressWriteError,\n ProtocolInjectionRejectError,\n ProviderMiddlewareOrderError,\n RunStateMalformedError,\n RunStateVersionUnsupportedError,\n SubAgentResumeTargetNotFoundError,\n ToolNotFoundError,\n} from './errors/index.js';\nexport {\n type EvaluatorCallable,\n type EvaluatorOptimizerOptions,\n type EvaluatorOptimizerOutcome,\n type EvaluatorOutcome,\n evaluatorOptimizer,\n type GeneratorCallable,\n type Rubric,\n} from './evaluator-optimizer/index.js';\nexport { createAgent } from './factory.js';\nexport {\n type AgentFallbackEligibility,\n type AgentFallbackPolicy,\n type AgentFallbackReason,\n isAgentFallbackEligible,\n} from './fallback/index.js';\nexport {\n type ChildResult,\n type FanOutOptions,\n type FanOutResult,\n type MergeStrategy,\n type PerChildBudget,\n runFanOut,\n} from './fanout/index.js';\nexport {\n bySensitivity,\n compose,\n custom,\n type DescribedFilter,\n defaultHandoffFilter,\n FILTER_KIND_CUSTOM,\n filters,\n full,\n lastN,\n lastUser,\n stripReasoning,\n stripSensitiveOutputs,\n stripToolCalls,\n summary,\n} from './filters/index.js';\nexport {\n CausalityMonitor,\n type CausalityMonitorCheck,\n type CausalityMonitorConfig,\n type CausalityMonitorStrictness,\n type ChildTrustInput,\n type ContentOriginKind,\n computeSourceTrust,\n DEFAULT_DENIAL_PATTERNS,\n DEFAULT_MAX_CHAIN_DEPTH,\n evaluateMerge,\n type GuardOutcome,\n guardOutboundContent,\n type MergeBiasDecision,\n type MergeGuardConfig,\n type ProtocolBoundary,\n type ProtocolEscapePolicy,\n type ProtocolGuardConfig,\n resolvePolicy,\n type TrustClass,\n} from './lateral-leak/index.js';\nexport {\n type PreferredModelResolution,\n pickTopTierAcrossTools,\n type ResolvePreferredModelInput,\n resolvePreferredModel,\n} from './preferred-model/index.js';\nexport {\n createProgressIO,\n type ProgressIO,\n type ProgressIOConfig,\n type ProgressReadOptions,\n type ProgressWriteOptions,\n} from './progress/index.js';\nexport {\n addModelUsage,\n aggregateUsageFromByModel,\n completedToolCallsFromState,\n createInitialRunState,\n deserializeRunState,\n RUN_STATE_SCHEMA_MAJOR_SUPPORTED,\n RUN_STATE_SCHEMA_VERSION,\n runStateFromJSON,\n runStateToJSON,\n type SerializedPendingSubRun,\n type SerializedRunState,\n type SerializeRunStateOptions,\n serializeRunState,\n} from './run-state/index.js';\nexport {\n getSubAgentToolRefs,\n SUBAGENT_TOOL,\n type SubAgentFoldTaint,\n type SubAgentToolRefs,\n} from './runtime/agent-to-tool.js';\nexport { foldChildRunUsage } from './runtime/messages.js';\nexport {\n createReplayProvider,\n type ReplayProviderOptions,\n} from './testing/replay-provider.js';\nexport type {\n AbortOptions,\n Agent,\n AgentCallOptions,\n AgentCapability,\n AgentConfig,\n AgentInput,\n AgentToToolOptions,\n CompactionApiResult,\n CompactOptions,\n HandoffEntry,\n OutputSpec,\n PostCompactionHook,\n PrepareStepHook,\n PrepareStepOverrides,\n ResponseVerifier,\n ResumeDirective,\n SkillsRegistryLike,\n VerifierResult,\n} from './types.js';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCA,MAAaA,UAAkBC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { computeSourceTrust, evaluateMerge } from "./merge-guard.js";
|
|
2
1
|
import { CausalityMonitor, DEFAULT_DENIAL_PATTERNS, DEFAULT_MAX_CHAIN_DEPTH } from "./causality-monitor.js";
|
|
2
|
+
import { computeSourceTrust, evaluateMerge } from "./merge-guard.js";
|
|
3
3
|
import { guardOutboundContent, resolvePolicy } from "./protocol-guard.js";
|
|
4
4
|
|
|
5
5
|
export { CausalityMonitor, DEFAULT_DENIAL_PATTERNS, DEFAULT_MAX_CHAIN_DEPTH, computeSourceTrust, evaluateMerge, guardOutboundContent, resolvePolicy };
|
package/dist/package.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"package.js","names":[],"sources":["../package.json"],"sourcesContent":["{\n \"name\": \"@graphorin/agent\",\n \"version\": \"0.7.0\",\n \"description\": \"Agent runtime for the Graphorin framework: createAgent({...}) factory, the typed model -> tool calls -> model loop, the AgentEvent<TOutput> discriminated event stream, steering / followUp queues, durable HITL approvals via runStateToJSON / runStateFromJSON, multi-agent handoffs (Agent.toTool, filter library, secrets isolation), agent-level model fallback chain, intra-loop reasoning preservation, post-compaction hook lifecycle, agent-step-level fan-out (Agent.fanOut + evaluatorOptimizer + progress artifacts), per-tool model-tier hint resolution, lateral-leak defense layer (CausalityMonitor + MergeAgentSidewaysInjectionGuard + protocol-guard), inbound-content sanitization preamble injection, and AbortSignal-aware hard-kill / drain cancellation. Created and maintained by Oleksiy Stepurenko.\",\n \"license\": \"MIT\",\n \"author\": \"Oleksiy Stepurenko\",\n \"homepage\": \"https://github.com/o-stepper/graphorin/tree/main/packages/agent\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/o-stepper/graphorin.git\",\n \"directory\": \"packages/agent\"\n },\n \"bugs\": {\n \"url\": \"https://github.com/o-stepper/graphorin/issues\"\n },\n \"keywords\": [\n \"graphorin\",\n \"ai\",\n \"agents\",\n \"framework\",\n \"agent-runtime\",\n \"agent-loop\",\n \"streaming\",\n \"multi-agent\",\n \"handoff\",\n \"hitl\",\n \"approval\",\n \"fanout\",\n \"evaluator-optimizer\",\n \"fallback-chain\",\n \"context-compaction\",\n \"lateral-leak\",\n \"causality-monitor\"\n ],\n \"type\": \"module\",\n \"sideEffects\": false,\n \"engines\": {\n \"node\": \">=22.12.0\"\n },\n \"main\": \"./dist/index.js\",\n \"module\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"default\": \"./dist/index.js\"\n },\n \"./factory\": {\n \"types\": \"./dist/factory.d.ts\",\n \"default\": \"./dist/factory.js\"\n },\n \"./run-state\": {\n \"types\": \"./dist/run-state/index.d.ts\",\n \"default\": \"./dist/run-state/index.js\"\n },\n \"./filters\": {\n \"types\": \"./dist/filters/index.d.ts\",\n \"default\": \"./dist/filters/index.js\"\n },\n \"./fallback\": {\n \"types\": \"./dist/fallback/index.d.ts\",\n \"default\": \"./dist/fallback/index.js\"\n },\n \"./preferred-model\": {\n \"types\": \"./dist/preferred-model/index.d.ts\",\n \"default\": \"./dist/preferred-model/index.js\"\n },\n \"./fanout\": {\n \"types\": \"./dist/fanout/index.d.ts\",\n \"default\": \"./dist/fanout/index.js\"\n },\n \"./evaluator-optimizer\": {\n \"types\": \"./dist/evaluator-optimizer/index.d.ts\",\n \"default\": \"./dist/evaluator-optimizer/index.js\"\n },\n \"./progress\": {\n \"types\": \"./dist/progress/index.d.ts\",\n \"default\": \"./dist/progress/index.js\"\n },\n \"./lateral-leak\": {\n \"types\": \"./dist/lateral-leak/index.d.ts\",\n \"default\": \"./dist/lateral-leak/index.js\"\n },\n \"./errors\": {\n \"types\": \"./dist/errors/index.d.ts\",\n \"default\": \"./dist/errors/index.js\"\n },\n \"./package.json\": \"./package.json\"\n },\n \"files\": [\n \"dist\",\n \"src\",\n \"README.md\",\n \"CHANGELOG.md\",\n \"LICENSE\"\n ],\n \"scripts\": {\n \"build\": \"tsdown\",\n \"typecheck\": \"tsc --noEmit && tsc -p tsconfig.tests.json\",\n \"test\": \"vitest run\",\n \"lint\": \"biome check .\",\n \"clean\": \"rimraf dist .turbo *.tsbuildinfo\"\n },\n \"dependencies\": {\n \"@graphorin/core\": \"workspace:*\",\n \"@graphorin/memory\": \"workspace:*\",\n \"@graphorin/security\": \"workspace:*\",\n \"@graphorin/skills\": \"workspace:*\",\n \"@graphorin/tools\": \"workspace:*\"\n },\n \"publishConfig\": {\n \"access\": \"public\",\n \"provenance\": true\n },\n \"devDependencies\": {\n \"zod\": \"^3.25.0\"\n }\n}\n"],"mappings":";cAEa"}
|
|
@@ -1,13 +1,19 @@
|
|
|
1
|
-
import { CompletedToolCall, HandoffRecord,
|
|
1
|
+
import { CompletedToolCall, HandoffRecord, RunState, RunStateUsageByModel, RunStatus, RunTaintSummary, TodoItem, ToolApproval, Usage, WireMessage, WireRunStep } from "@graphorin/core";
|
|
2
2
|
|
|
3
3
|
//#region src/run-state/index.d.ts
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Canonical schema id for serialized {@link RunState} payloads.
|
|
7
7
|
*
|
|
8
|
+
* 1.2 encodes binary message/tool-outcome payloads (`Uint8Array | URL`)
|
|
9
|
+
* through the core `WireRunState` projection (base64 / href envelopes)
|
|
10
|
+
* instead of letting `JSON.stringify` corrupt them. 1.0/1.1 payloads
|
|
11
|
+
* remain readable; their corrupted numeric-key byte objects are
|
|
12
|
+
* repaired best-effort on rehydration.
|
|
13
|
+
*
|
|
8
14
|
* @stable
|
|
9
15
|
*/
|
|
10
|
-
declare const RUN_STATE_SCHEMA_VERSION: "graphorin-run-state/1.
|
|
16
|
+
declare const RUN_STATE_SCHEMA_VERSION: "graphorin-run-state/1.2";
|
|
11
17
|
/**
|
|
12
18
|
* Reader-supported schema id range. Major version 1 only for v0.1.
|
|
13
19
|
*
|
|
@@ -16,7 +22,9 @@ declare const RUN_STATE_SCHEMA_VERSION: "graphorin-run-state/1.1";
|
|
|
16
22
|
declare const RUN_STATE_SCHEMA_MAJOR_SUPPORTED = 1;
|
|
17
23
|
/**
|
|
18
24
|
* On-disk payload returned by {@link serializeRunState} and accepted
|
|
19
|
-
* by {@link deserializeRunState}. The shape is JSON-stable
|
|
25
|
+
* by {@link deserializeRunState}. The shape is JSON-stable: binary
|
|
26
|
+
* message/tool-outcome payloads appear in their `WireMessage` /
|
|
27
|
+
* `WireRunStep` (base64 / href envelope) form.
|
|
20
28
|
*
|
|
21
29
|
* @stable
|
|
22
30
|
*/
|
|
@@ -28,8 +36,8 @@ interface SerializedRunState {
|
|
|
28
36
|
readonly sessionId: string;
|
|
29
37
|
readonly userId?: string;
|
|
30
38
|
readonly status: RunStatus;
|
|
31
|
-
readonly steps: ReadonlyArray<
|
|
32
|
-
readonly messages: ReadonlyArray<
|
|
39
|
+
readonly steps: ReadonlyArray<WireRunStep>;
|
|
40
|
+
readonly messages: ReadonlyArray<WireMessage>;
|
|
33
41
|
readonly pendingApprovals: ReadonlyArray<ToolApproval>;
|
|
34
42
|
readonly handoffs: ReadonlyArray<HandoffRecord>;
|
|
35
43
|
readonly usage: Usage;
|
|
@@ -40,6 +48,12 @@ interface SerializedRunState {
|
|
|
40
48
|
readonly promotedTools?: ReadonlyArray<string>;
|
|
41
49
|
/** D6: journaled structured plan/todo list. */
|
|
42
50
|
readonly todos?: ReadonlyArray<TodoItem>;
|
|
51
|
+
/**
|
|
52
|
+
* W-001: parked sub-agent runs. Each child snapshot is itself a full
|
|
53
|
+
* `SerializedRunState` - version-stamped and secret-redacted
|
|
54
|
+
* recursively, to any nesting depth.
|
|
55
|
+
*/
|
|
56
|
+
readonly pendingSubRuns?: ReadonlyArray<SerializedPendingSubRun>;
|
|
43
57
|
readonly startedAt: string;
|
|
44
58
|
readonly finishedAt?: string;
|
|
45
59
|
readonly error?: {
|
|
@@ -48,6 +62,18 @@ interface SerializedRunState {
|
|
|
48
62
|
readonly details?: unknown;
|
|
49
63
|
};
|
|
50
64
|
}
|
|
65
|
+
/**
|
|
66
|
+
* Serialized twin of core's `PendingSubRun` (W-001): the parked child
|
|
67
|
+
* state travels as its own versioned {@link SerializedRunState}.
|
|
68
|
+
*
|
|
69
|
+
* @stable
|
|
70
|
+
*/
|
|
71
|
+
interface SerializedPendingSubRun {
|
|
72
|
+
readonly toolCallId: string;
|
|
73
|
+
readonly toolName: string;
|
|
74
|
+
readonly targetAgentName: string;
|
|
75
|
+
readonly state: SerializedRunState;
|
|
76
|
+
}
|
|
51
77
|
/**
|
|
52
78
|
* Options accepted by {@link serializeRunState}.
|
|
53
79
|
*
|
|
@@ -150,5 +176,5 @@ declare function aggregateUsageFromByModel(byModel: RunStateUsageByModel | undef
|
|
|
150
176
|
*/
|
|
151
177
|
declare function completedToolCallsFromState(state: RunState): ReadonlyArray<CompletedToolCall>;
|
|
152
178
|
//#endregion
|
|
153
|
-
export { RUN_STATE_SCHEMA_MAJOR_SUPPORTED, RUN_STATE_SCHEMA_VERSION, SerializeRunStateOptions, SerializedRunState, addModelUsage, aggregateUsageFromByModel, completedToolCallsFromState, createInitialRunState, deserializeRunState, runStateFromJSON, runStateToJSON, serializeRunState };
|
|
179
|
+
export { RUN_STATE_SCHEMA_MAJOR_SUPPORTED, RUN_STATE_SCHEMA_VERSION, SerializeRunStateOptions, SerializedPendingSubRun, SerializedRunState, addModelUsage, aggregateUsageFromByModel, completedToolCallsFromState, createInitialRunState, deserializeRunState, runStateFromJSON, runStateToJSON, serializeRunState };
|
|
154
180
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/run-state/index.ts"],"sourcesContent":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/run-state/index.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;;;AAkF4B,cA1Cf,wBA0Ce,EAAA,yBAAA;;AAY5B;AAYA;AAoBA;;AAEW,cAjFE,gCAAA,GAiFF,CAAA;;;AAwGX;AAEC;AAiCD;AAuMA;AAkBA;AA+BA;AAwCgB,UAlfC,kBAAA,CAkfwB;EA6CzB,SAAA,OAAA,EAAA,OA9hBW,wBA8hBgB;EAAQ,SAAA,EAAA,EAAA,MAAA;EAAyB,SAAA,OAAA,EAAA,MAAA;EAAd,SAAA,cAAA,EAAA,MAAA;EAAa,SAAA,SAAA,EAAA,MAAA;;mBAxhBxD;kBACD,cAAc;qBACX,cAAc;6BACN,cAAc;qBACtB,cAAc;kBACjB;0BACQ;;0BAEA;;2BAEC;;mBAER,cAAc;;;;;;4BAML,cAAc;;;;;;;;;;;;;;;UAYzB,uBAAA;;;;kBAIC;;;;;;;UAQD,wBAAA;;;;;;;;;;;;;;;;;;;iBAoBD,iBAAA,QACP,oBACE,2BACR;;;;;;;;iBAuGa,cAAA,QAAsB,oBAAoB;UAIhD,kBAAA;;;;;;;;;;;;;;;;;;;;;;;;;;iBA+BM,mBAAA,6BAA+C,qBAA0B;;iBAuMzE,gBAAA,+BAA+C,qBAAqB;;;;;;;;iBAkBpE,qBAAA;;;;;;IAMZ;;;;;;;;;iBAyBY,aAAA,QAAqB,kCAAkC;;;;;;;;iBAwCvD,yBAAA,UAAmC,mCAAmC;;;;;;;;iBA6CtE,2BAAA,QAAmC,WAAW,cAAc"}
|
package/dist/run-state/index.js
CHANGED
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
import { RunStateMalformedError, RunStateVersionUnsupportedError } from "../errors/index.js";
|
|
2
|
-
import { zeroUsage } from "@graphorin/core";
|
|
2
|
+
import { fromJsonSafeRunState, toJsonSafeRunState, zeroUsage } from "@graphorin/core";
|
|
3
3
|
|
|
4
4
|
//#region src/run-state/index.ts
|
|
5
5
|
/**
|
|
6
6
|
* Canonical schema id for serialized {@link RunState} payloads.
|
|
7
7
|
*
|
|
8
|
+
* 1.2 encodes binary message/tool-outcome payloads (`Uint8Array | URL`)
|
|
9
|
+
* through the core `WireRunState` projection (base64 / href envelopes)
|
|
10
|
+
* instead of letting `JSON.stringify` corrupt them. 1.0/1.1 payloads
|
|
11
|
+
* remain readable; their corrupted numeric-key byte objects are
|
|
12
|
+
* repaired best-effort on rehydration.
|
|
13
|
+
*
|
|
8
14
|
* @stable
|
|
9
15
|
*/
|
|
10
|
-
const RUN_STATE_SCHEMA_VERSION = "graphorin-run-state/1.
|
|
16
|
+
const RUN_STATE_SCHEMA_VERSION = "graphorin-run-state/1.2";
|
|
11
17
|
/**
|
|
12
18
|
* Reader-supported schema id range. Major version 1 only for v0.1.
|
|
13
19
|
*
|
|
@@ -21,26 +27,34 @@ const RUN_STATE_SCHEMA_MAJOR_SUPPORTED = 1;
|
|
|
21
27
|
* @stable
|
|
22
28
|
*/
|
|
23
29
|
function serializeRunState(state, options = {}) {
|
|
30
|
+
const wire = toJsonSafeRunState(state);
|
|
31
|
+
const pendingSubRuns = state.pendingSubRuns !== void 0 && state.pendingSubRuns.length > 0 ? state.pendingSubRuns.map((sub) => ({
|
|
32
|
+
toolCallId: sub.toolCallId,
|
|
33
|
+
toolName: sub.toolName,
|
|
34
|
+
targetAgentName: sub.targetAgentName,
|
|
35
|
+
state: serializeRunState(sub.state, options)
|
|
36
|
+
})) : void 0;
|
|
24
37
|
const out = {
|
|
25
38
|
version: RUN_STATE_SCHEMA_VERSION,
|
|
26
|
-
id:
|
|
27
|
-
agentId:
|
|
28
|
-
currentAgentId:
|
|
29
|
-
sessionId:
|
|
30
|
-
...
|
|
31
|
-
status:
|
|
32
|
-
steps:
|
|
33
|
-
messages:
|
|
34
|
-
pendingApprovals:
|
|
35
|
-
handoffs:
|
|
36
|
-
usage:
|
|
37
|
-
...
|
|
38
|
-
...
|
|
39
|
-
...
|
|
40
|
-
...
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
...
|
|
39
|
+
id: wire.id,
|
|
40
|
+
agentId: wire.agentId,
|
|
41
|
+
currentAgentId: wire.currentAgentId,
|
|
42
|
+
sessionId: wire.sessionId,
|
|
43
|
+
...wire.userId !== void 0 ? { userId: wire.userId } : {},
|
|
44
|
+
status: wire.status,
|
|
45
|
+
steps: wire.steps,
|
|
46
|
+
messages: wire.messages,
|
|
47
|
+
pendingApprovals: wire.pendingApprovals,
|
|
48
|
+
handoffs: wire.handoffs,
|
|
49
|
+
usage: wire.usage,
|
|
50
|
+
...wire.usageByModel !== void 0 ? { usageByModel: wire.usageByModel } : {},
|
|
51
|
+
...wire.taintSummary !== void 0 ? { taintSummary: wire.taintSummary } : {},
|
|
52
|
+
...wire.promotedTools !== void 0 ? { promotedTools: wire.promotedTools } : {},
|
|
53
|
+
...wire.todos !== void 0 ? { todos: wire.todos } : {},
|
|
54
|
+
...pendingSubRuns !== void 0 ? { pendingSubRuns } : {},
|
|
55
|
+
startedAt: wire.startedAt,
|
|
56
|
+
...wire.finishedAt !== void 0 ? { finishedAt: wire.finishedAt } : {},
|
|
57
|
+
...wire.error !== void 0 ? { error: wire.error } : {}
|
|
44
58
|
};
|
|
45
59
|
const detached = JSON.parse(JSON.stringify(out));
|
|
46
60
|
if (options.stripTracingApiKey === true) redactSecretKeysInPlace(detached);
|
|
@@ -198,7 +212,7 @@ function deserializeRunState(payload, options = {}) {
|
|
|
198
212
|
content: t.content,
|
|
199
213
|
status: t.status
|
|
200
214
|
})) : void 0;
|
|
201
|
-
|
|
215
|
+
const rehydrated = fromJsonSafeRunState({
|
|
202
216
|
id,
|
|
203
217
|
agentId,
|
|
204
218
|
currentAgentId,
|
|
@@ -217,7 +231,17 @@ function deserializeRunState(payload, options = {}) {
|
|
|
217
231
|
startedAt,
|
|
218
232
|
...typeof finishedAtRaw === "string" ? { finishedAt: finishedAtRaw } : {},
|
|
219
233
|
...error !== void 0 ? { error } : {}
|
|
220
|
-
};
|
|
234
|
+
});
|
|
235
|
+
if (Array.isArray(payload.pendingSubRuns) && payload.pendingSubRuns.length > 0) {
|
|
236
|
+
const subs = payload.pendingSubRuns.filter(isRecord).filter((s) => typeof s.toolCallId === "string" && typeof s.toolName === "string").map((s) => ({
|
|
237
|
+
toolCallId: s.toolCallId,
|
|
238
|
+
toolName: s.toolName,
|
|
239
|
+
targetAgentName: typeof s.targetAgentName === "string" ? s.targetAgentName : s.toolName,
|
|
240
|
+
state: deserializeRunState(s.state, options)
|
|
241
|
+
}));
|
|
242
|
+
if (subs.length > 0) rehydrated.pendingSubRuns = subs;
|
|
243
|
+
}
|
|
244
|
+
return rehydrated;
|
|
221
245
|
}
|
|
222
246
|
/** Convenience JSON-string parser pairing with {@link runStateToJSON}. */
|
|
223
247
|
function runStateFromJSON(serialized, options) {
|