@theokit/sdk 4.6.0 → 4.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 +19 -0
- package/dist/a2a/index.cjs +2 -1
- package/dist/a2a/index.cjs.map +1 -1
- package/dist/a2a/index.js +2 -1
- package/dist/a2a/index.js.map +1 -1
- package/dist/cron.cjs +49 -12
- package/dist/cron.cjs.map +1 -1
- package/dist/cron.js +49 -12
- package/dist/cron.js.map +1 -1
- package/dist/eval.cjs +49 -12
- package/dist/eval.cjs.map +1 -1
- package/dist/eval.js +49 -12
- package/dist/eval.js.map +1 -1
- package/dist/index.cjs +49 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +49 -12
- package/dist/index.js.map +1 -1
- package/dist/internal/llm/types.d.ts +14 -1
- package/dist/internal/runtime/registry/agent-registry-store.d.ts +4 -3
- package/package.json +13 -12
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 4.7.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 6871152: M35 (multimodal) — implement image input end-to-end. `agent.send({ text, images })` (the `SDKUserMessage` form) previously carried the `images` TYPE but the runtime dropped them (only `.text` was used). Now `prepareRunContext` carries the images, the agent loop attaches them as `image` content parts (new `LlmImagePart`), and the provider adapters serialize them: OpenAI/OpenRouter to a content-array with an `image_url` data URL, Anthropic to a native base64 image block. Text-only turns are byte-unchanged (back-compat). Zero new dependencies.
|
|
8
|
+
|
|
9
|
+
## 4.6.1
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- 4b70ff1: Per-subagent config (M33) review fixes.
|
|
14
|
+
|
|
15
|
+
- **Sandbox is no longer default-open.** A delegated child of a sandboxed parent now inherits the parent's shell-sandbox posture unless its role opts out; `AgentDefinition.sandbox` absent ⇒ inherit (as documented), `sandbox: false` explicitly confines-off, `sandbox: true` confines-on. Previously a child ran unsandboxed whenever its role omitted `sandbox` — a default-open the wiring exists to prevent.
|
|
16
|
+
- **`model: inherit` + `reasoning_effort` is now a typed load error** instead of silently dropping the effort (the inherited model id is unknown at load, so the `thinking` param has nothing to attach to).
|
|
17
|
+
- **`tools` and `sandbox` now survive persist→resume** for inline subagents (`serializeAgents`); dropping them was a default-open on resume (a confined child came back unconfined). The model's reasoning `params` are persisted too. `mcpServers` stays stripped (may carry secrets).
|
|
18
|
+
- **Quoted `model`/`reasoning_effort` scalars are stripped** (`model: "openai/gpt-4o"`), which previously passed validation and failed only at the provider.
|
|
19
|
+
|
|
20
|
+
Note on the 4.6.0 loader: rejecting unknown/unsupported frontmatter fields is a fail-closed **contract narrowing** (pre-4.6.0 silently dropped them), not a pure addition. Every subagent role in the ecosystem uses only accepted fields, so there is no known real-world break, and the failure is a diagnosable typed `ConfigurationError` — but downstreams pinned to `^4.5` whose roles carried extra keys should be aware.
|
|
21
|
+
|
|
3
22
|
## 4.6.0
|
|
4
23
|
|
|
5
24
|
### Minor Changes
|
package/dist/a2a/index.cjs
CHANGED
|
@@ -148,10 +148,11 @@ ${lines.join("\n")}
|
|
|
148
148
|
}
|
|
149
149
|
function buildChildCreateOptions(spec, inherited) {
|
|
150
150
|
const model = spec.model !== void 0 ? typeof spec.model === "string" ? { id: spec.model } : spec.model : inherited?.model;
|
|
151
|
+
const sandbox = spec.sandbox ?? inherited?.sandbox;
|
|
151
152
|
return {
|
|
152
153
|
...inherited?.apiKey !== void 0 ? { apiKey: inherited.apiKey } : {},
|
|
153
154
|
...model !== void 0 ? { model } : {},
|
|
154
|
-
...
|
|
155
|
+
...sandbox !== void 0 ? { local: { sandboxOptions: { enabled: sandbox } } } : {},
|
|
155
156
|
...inherited?.plugins !== void 0 ? { plugins: inherited.plugins } : {},
|
|
156
157
|
systemPrompt: spec.instructions,
|
|
157
158
|
tools: spec.tools ?? []
|
package/dist/a2a/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/a2a/agent-mailbox.ts","../../src/a2a/message-bus.ts","../../src/internal/runtime/registry/agent-factory-registry.ts","../../src/a2a/subagent.ts"],"names":["z"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * AgentMailbox — per-agent inbox for A2A communication (T20.1, ADR D453).\n *\n * Wraps MessageBus registration with a convenient API for sending,\n * receiving, and requesting messages.\n *\n * @public\n */\n\nimport type { MessageBus, RequestOptions } from \"./message-bus.js\";\nimport type { A2AMessage, MessageHandler } from \"./types.js\";\n\nexport class AgentMailbox {\n readonly agentId: string;\n private readonly _bus: MessageBus;\n private _handler: MessageHandler | null = null;\n\n constructor(agentId: string, bus: MessageBus) {\n this.agentId = agentId;\n this._bus = bus;\n this._bus.register(agentId, (msg) => this._dispatch(msg));\n }\n\n onMessage(handler: MessageHandler): void {\n this._handler = handler;\n }\n\n async send(to: string, partial: { type: string; payload: unknown }): Promise<void> {\n return this._bus.send(this.agentId, to, partial);\n }\n\n async request(\n to: string,\n partial: { type: string; payload: unknown },\n opts?: RequestOptions,\n ): Promise<unknown> {\n return this._bus.request(this.agentId, to, partial, opts);\n }\n\n dispose(): void {\n this._bus.unregister(this.agentId);\n this._handler = null;\n }\n\n private _dispatch(msg: A2AMessage): unknown {\n if (this._handler) {\n return this._handler(msg);\n }\n }\n}\n","/**\n * MessageBus — in-process typed message router for A2A (T20.1, ADR D453).\n *\n * Routes messages between agents by ID. Supports fire-and-forget (send)\n * and request/response (request with timeout).\n *\n * @public\n */\n\nimport type { A2AMessage, MessageHandler } from \"./types.js\";\n\nexport interface RequestOptions {\n timeoutMs?: number;\n}\n\nexport class MessageBus {\n private readonly _handlers = new Map<string, MessageHandler>();\n\n register(agentId: string, handler: MessageHandler): void {\n this._handlers.set(agentId, handler);\n }\n\n unregister(agentId: string): void {\n this._handlers.delete(agentId);\n }\n\n async send(from: string, to: string, partial: { type: string; payload: unknown }): Promise<void> {\n const handler = this._handlers.get(to);\n if (!handler) {\n throw new Error(`Agent \"${to}\" not registered on MessageBus`);\n }\n const message: A2AMessage = {\n ...partial,\n from,\n to,\n timestamp: Date.now(),\n // SE3 — provenance projection of the sender address (thin view over `from`).\n origin: { kind: \"peer\", from },\n };\n // Fire-and-forget: invoke handler but don't await result\n handler(message);\n }\n\n async request(\n from: string,\n to: string,\n partial: { type: string; payload: unknown },\n opts?: RequestOptions,\n ): Promise<unknown> {\n const handler = this._handlers.get(to);\n if (!handler) {\n throw new Error(`Agent \"${to}\" not registered on MessageBus`);\n }\n const timeoutMs = opts?.timeoutMs ?? 30_000;\n const message: A2AMessage = {\n ...partial,\n from,\n to,\n timestamp: Date.now(),\n // SE3 — provenance projection of the sender address (thin view over `from`).\n origin: { kind: \"peer\", from },\n };\n // Hold the timer so it can be cleared once the race settles — otherwise a\n // successful request leaks a live `setTimeout` that keeps the Node event loop\n // alive (the process hangs after the reply). Cleared in `finally`.\n let timer: ReturnType<typeof setTimeout> | undefined;\n try {\n return await Promise.race([\n Promise.resolve(handler(message)),\n new Promise((_, reject) => {\n timer = setTimeout(\n () =>\n reject(new Error(`A2A request timeout: ${to} did not respond within ${timeoutMs}ms`)),\n timeoutMs,\n );\n }),\n ]);\n } finally {\n if (timer !== undefined) clearTimeout(timer);\n }\n }\n\n has(agentId: string): boolean {\n return this._handlers.has(agentId);\n }\n\n listAgents(): string[] {\n return [...this._handlers.keys()];\n }\n}\n","/**\n * Internal DI seam for the public `Agent` facade.\n *\n * Several internal subsystems (`LocalAgent.runUntil`/`fork`, eval, scorers,\n * cron) need to invoke `Agent.create`/`prompt`/`get`/`resume`/`batch`. A direct\n * `import { Agent }` would invert the public-api -> internal dependency\n * direction (and `agent.ts` already imports much of `internal/`). This module\n * is the inversion seam: `agent.ts` registers the facade at module-init time;\n * internal consumers read it on-demand via `getAgentFacade()`. The\n * `internal-must-not-import-facade` dependency-cruiser rule enforces that no\n * `internal/*` module bypasses this seam with a direct facade import.\n *\n * Throws if accessed before registration — should never happen because\n * `agent.ts` evaluation always precedes any internal call (the consumer must\n * obtain a handle from the `Agent` facade first).\n *\n * @internal\n */\n\nimport type { AgentOptions, SDKAgent, SDKAgentInfo } from \"../../../types/agent.js\";\nimport type { BatchItem, BatchOptions, BatchResult } from \"../../../types/batch.js\";\nimport type { RunResult } from \"../../../types/run.js\";\n\n/**\n * The subset of the public `Agent` static surface that internal subsystems\n * consume through the inversion seam. Each member mirrors the matching\n * `Agent.*` signature so registration is a thin pass-through.\n *\n * @internal\n */\nexport interface AgentFacadePort {\n create: (options: AgentOptions) => Promise<SDKAgent>;\n delete: (agentId: string) => Promise<void>;\n prompt: (message: string, options: AgentOptions) => Promise<RunResult>;\n get: (agentId: string) => Promise<SDKAgentInfo>;\n resume: (agentId: string, options?: Partial<AgentOptions>) => Promise<SDKAgent>;\n batch: (\n prompts: ReadonlyArray<string | BatchItem>,\n options: BatchOptions,\n ) => Promise<BatchResult[]>;\n}\n\n/**\n * The registration slot lives on `globalThis` under a `Symbol.for` key — NOT a module-level `let` —\n * so it is a **process-wide singleton** shared by every copy of this module. `tsup` builds each public\n * entry (`.`, `./a2a`, `./cron`, `./eval`, …) with `splitting: false`, which INLINES this module once\n * per entry; a module-level `let` would give each bundled copy its own `registered` slot, and a\n * subagent invoked through `./a2a` would read a copy that `agent.ts` (in the `.` entry) never set —\n * the classic duplicated-singleton hazard (see issue: a2a \"Agent facade not registered\"). `Symbol.for`\n * (global symbol registry) + the one `globalThis` object guarantees all copies read/write ONE slot.\n */\nconst FACADE_KEY: unique symbol = Symbol.for(\n \"theokit.internal.runtime.agentFacade\",\n) as typeof FACADE_KEY;\n\ntype FacadeHost = { [FACADE_KEY]?: AgentFacadePort };\n\n/**\n * Registered by `agent.ts` at module-init time. Idempotent: re-registration\n * replaces the previous reference (useful for tests that swap implementations).\n *\n * @internal\n */\nexport function setAgentFacade(facade: AgentFacadePort): void {\n (globalThis as unknown as FacadeHost)[FACADE_KEY] = facade;\n}\n\n/**\n * Resolve the registered `Agent` facade for internal subsystems.\n *\n * @internal\n */\nexport function getAgentFacade(): AgentFacadePort {\n const registered = (globalThis as unknown as FacadeHost)[FACADE_KEY];\n if (registered === undefined) {\n throw new Error(\n \"internal: Agent facade not registered. The `agent.ts` module must be loaded before internal subsystems (LocalAgent.runUntil/fork, eval, scorers, cron) invoke it.\",\n );\n }\n return registered;\n}\n","/**\n * Subagent delegation — declarative child agent invocable as a tool.\n *\n * Per ADR D2: `defineSubAgent(spec)` returns a `CustomTool` that, when\n * invoked by the LLM, creates a child agent and sends the input as a\n * message. EC-2: delegation depth tracked to prevent infinite recursion.\n *\n * SE10 — the handler forwards the parent run's `AbortSignal` to the child.\n * SE11 — optional `onDelegationStart` / `onDelegationComplete` lifecycle hooks\n * let the caller reject, rewrite, observe, or annotate a delegation.\n *\n * @public\n */\n\nimport { z } from \"zod\";\nimport type { Plugin } from \"../internal/plugins/types.js\";\nimport { getAgentFacade } from \"../internal/runtime/registry/agent-factory-registry.js\";\nimport type {\n AgentDefinition,\n AgentOptions,\n CustomTool,\n ToolContextMessage,\n} from \"../types/agent.js\";\nimport type { ModelSelection } from \"../types/agent-prims.js\";\nimport type { Run } from \"../types/run.js\";\n\n/**\n * Credentials a parent agent hands down to its subagent tools so the child\n * inherits the parent's auth (and, absent an explicit `spec.model`, its model).\n * @internal\n */\nexport interface InheritedCredentials {\n readonly apiKey?: string;\n readonly model?: ModelSelection;\n /**\n * #55 — the parent's code-registered plugins (e.g. a `PermissionPlugin`) handed\n * down so the child runs under the SAME policy. Without this, a delegated child's\n * inner tool calls escape the parent's argument-level permission gate. First-party\n * delegation path only — never exposed to third-party tool `ctx`.\n */\n readonly plugins?: readonly Plugin[];\n}\n\n/**\n * Private per-tool setter installed on subagent tools. Kept off the public\n * `CustomTool` shape (and off every tool handler's `ctx`) so the parent's API\n * key never reaches third-party tool code — only the SDK's own delegation path.\n */\n// `Symbol.for` (global registry), NOT `Symbol()`: with `tsup splitting: false` each public entry\n// (`.`, `./a2a`) inlines its own copy of this module. A unique `Symbol()` would give each copy a\n// DIFFERENT sink key — the local runtime (bundled in `.`) calls `inheritSubAgentCredentials` with the\n// `.`-copy key, but a `SubAgent` created via `@theokit/sdk/a2a` installed its sink under the `/a2a`-copy\n// key, so the lookup missed and the child inherited NO `apiKey` (→ `provider_unresolved`, \"(no response)\").\n// `Symbol.for` makes both copies agree on ONE key. (Same duplicated-singleton class as the facade fix, #142.)\nconst INHERIT_CREDENTIALS = Symbol.for(\"theokit.subagent.inheritCredentials\");\n\ntype CredentialSink = (creds: InheritedCredentials) => void;\n\n/**\n * Called by the local runtime for every tool in a run: if the tool is a\n * subagent, its child agent inherits the parent's `apiKey`/`model`. A no-op for\n * any other tool (third-party tools never receive the parent's credentials).\n * @internal\n */\nexport function inheritSubAgentCredentials(tool: CustomTool, creds: InheritedCredentials): void {\n const sink = (tool as { [INHERIT_CREDENTIALS]?: CredentialSink })[INHERIT_CREDENTIALS];\n if (typeof sink === \"function\") sink(creds);\n}\n\n/** Arguments passed to {@link SubAgentSpec.messageFilter} (SE12). */\nexport interface MessageFilterArgs {\n /** The supervisor transcript (read-only text projection) available to this delegation. */\n messages: readonly ToolContextMessage[];\n /** The prompt about to be delegated (after any `onDelegationStart` rewrite). */\n input: string;\n /** The subagent's name. */\n name: string;\n}\n\n/** Context passed to {@link SubAgentSpec.onDelegationStart} before the child runs. */\nexport interface DelegationStartContext {\n input: string;\n name: string;\n /**\n * SE15 — 1-based count of times THIS subagent tool has been invoked (a\n * per-`defineSubAgent`-instance counter). Incremented before this hook runs;\n * a rejected delegation still counts. Enables reject-after-N patterns.\n */\n iteration: number;\n}\n\n/**\n * Decision returned from {@link SubAgentSpec.onDelegationStart}. Discriminated on\n * `proceed` so a rejection (`proceed: false` + `rejectionReason`) and an approval\n * (`modifiedInput`) cannot be mixed into one nonsensical object.\n */\nexport type DelegationStartDecision =\n | { proceed: false; rejectionReason?: string }\n | {\n proceed?: true;\n modifiedInput?: string;\n /** SE13 — cap the child's iteration count (forwarded as `SendOptions.maxIterations`). */\n modifiedMaxSteps?: number;\n };\n\n/** Context passed to {@link SubAgentSpec.onDelegationComplete} after the child settles. */\nexport interface DelegationCompleteContext {\n input: string;\n name: string;\n /** The child's text result (present on success). */\n result?: string;\n /** The error the child threw (present on failure); the error is still re-thrown. */\n error?: unknown;\n /** SE15 — the same 1-based iteration this delegation's `onDelegationStart` saw. */\n iteration: number;\n}\n\n/**\n * The return of a delegation hook: a decision, a promise of one, or nothing —\n * `void` lets a side-effect-only callback (`(ctx) => { log(ctx) }`) type-check,\n * which is the common case (mirrors a peer framework's `async ctx => { ... }` hooks).\n */\n// biome-ignore lint/suspicious/noConfusingVoidType: `void` is the idiomatic return for an optional-return callback; the rule false-positives on callback return unions.\ntype DelegationHookResult<T> = T | void | Promise<T | void>;\n\n/** Decision returned from {@link SubAgentSpec.onDelegationComplete}. */\nexport interface DelegationCompleteDecision {\n /** Appended to the child's result string. */\n feedback?: string;\n}\n\nexport interface SubAgentSpec {\n name: string;\n description: string;\n instructions: string;\n /**\n * A bare id string (back-compat) OR a full {@link ModelSelection} carrying\n * `params` (e.g. `[{ id: \"thinking\", value: \"low\" }]` for reasoning effort). The\n * object form is required for per-subagent reasoning effort to survive to the child\n * — the pre-M33 path took only `.id` and dropped params.\n */\n model?: string | ModelSelection;\n tools?: CustomTool[];\n /** Per-subagent shell sandbox toggle (M33). `true` ⇒ child `local.sandboxOptions.enabled`. */\n sandbox?: boolean;\n maxDelegationDepth?: number;\n /**\n * SE11 — called before the supervisor delegates. Return `{ proceed: false }`\n * to reject (the child never runs and `rejectionReason` becomes the tool\n * result), or `{ modifiedInput }` to rewrite the delegated prompt. A throwing\n * hook surfaces (never silently swallowed).\n */\n onDelegationStart?: (\n ctx: DelegationStartContext,\n ) => DelegationHookResult<DelegationStartDecision>;\n /**\n * SE11 — called after the delegation settles. On success `ctx.result` is set\n * and an optional `{ feedback }` is appended to it. On failure `ctx.error` is\n * set and the original error is ALWAYS re-thrown after this hook runs — a throw\n * from this hook on the error path is suppressed so it cannot mask the\n * delegation's real failure (on the success path a throw does propagate).\n */\n onDelegationComplete?: (\n ctx: DelegationCompleteContext,\n ) => DelegationHookResult<DelegationCompleteDecision>;\n /**\n * SE12 — opt-in parent-context forwarding. When set, the supervisor transcript\n * (`ctx.messages`, a read-only text projection) is passed to this filter and the\n * returned subset is forwarded to the child as a role-tagged context preamble\n * prepended to the delegated input. When ABSENT the child runs input-only —\n * memory isolation stays the default. A filter returning `[]` forwards nothing.\n * A throwing filter propagates (fail-fast, never swallowed — same contract as\n * `onDelegationStart`); the delegation surfaces as a tool error.\n */\n messageFilter?: (args: MessageFilterArgs) => readonly ToolContextMessage[];\n /**\n * SE14 — opt-in subagent result-context control. When `true`, the child's\n * completed tool-call results (name + result) are appended to the delegation\n * payload returned to the supervisor, inside a `<subagent-tool-results>` block.\n * When absent/`false` the delegation returns the child's final text only —\n * text-only stays the default (a peer framework's scoped posture). See ADR 0006.\n */\n includeToolResults?: boolean;\n}\n\nexport class MaxDelegationDepthError extends Error {\n readonly code = \"max_delegation_depth\" as const;\n constructor(\n public readonly currentDepth: number,\n public readonly maxDepth: number,\n ) {\n super(`Max delegation depth ${maxDepth} exceeded (current: ${currentDepth})`);\n this.name = \"MaxDelegationDepthError\";\n }\n}\n\n/**\n * Run the `onDelegationStart` hook; returns either a rejection or the (possibly\n * rewritten) input plus the optional SE13 `maxSteps` cap.\n */\nasync function applyDelegationStart(\n spec: SubAgentSpec,\n input: string,\n iteration: number,\n): Promise<{ reject: string } | { input: string; maxSteps?: number }> {\n if (spec.onDelegationStart === undefined) return { input };\n const decision = await spec.onDelegationStart({ input, name: spec.name, iteration });\n if (decision === undefined) return { input };\n if (decision.proceed === false)\n return { reject: decision.rejectionReason ?? \"(delegation rejected)\" };\n return {\n input: decision.modifiedInput ?? input,\n ...(decision.modifiedMaxSteps !== undefined ? { maxSteps: decision.modifiedMaxSteps } : {}),\n };\n}\n\n/**\n * SE14 — replay the child run's stream (a safe post-`wait()` idiom — the run buffers\n * events, `stream()` replays them) and collect every completed tool-call result into\n * a delimited block. Returns `\"\"` when the child ran no completed tool calls. See ADR 0006.\n */\nasync function collectChildToolResults(run: Run): Promise<string> {\n const lines: string[] = [];\n for await (const event of run.stream()) {\n if (event.type === \"tool_call\" && event.status === \"completed\") {\n const rendered =\n typeof event.result === \"string\" ? event.result : JSON.stringify(event.result ?? null);\n lines.push(`${event.name}: ${rendered}`);\n }\n }\n if (lines.length === 0) return \"\";\n return `\\n\\n<subagent-tool-results>\\n${lines.join(\"\\n\")}\\n</subagent-tool-results>`;\n}\n\n/**\n * Create the transient child agent and send the input, composing every forwarded\n * `SendOptions` onto ONE `send` call — SE10 `signal` + SE13 `maxIterations`. Absent\n * every option ⇒ the pre-SE10 single-arg `send(input)` shape. SE14 — when\n * `includeToolResults` is set, append the child's completed tool results. Dispose in `finally`.\n */\n/**\n * Build the child agent's `Agent.create` options: the child inherits the parent's\n * apiKey (else `Agent.create` throws \"Missing API key\"), its model (unless the spec\n * overrides it), and — #55 — the parent's plugins (permission gate/guards) so the\n * child's inner tool calls run under the same policy.\n */\nexport function buildChildCreateOptions(\n spec: SubAgentSpec,\n inherited: InheritedCredentials | undefined,\n): AgentOptions {\n // M33 — carry the WHOLE model (a bare id becomes `{ id }`; a ModelSelection with\n // `params` keeps its reasoning effort). The pre-M33 path wrapped `spec.model` as\n // `{ id: spec.model }`, which only worked because spec.model was a string and\n // silently dropped reasoning params.\n const model: string | ModelSelection | undefined =\n spec.model !== undefined\n ? typeof spec.model === \"string\"\n ? { id: spec.model }\n : spec.model\n : inherited?.model;\n return {\n ...(inherited?.apiKey !== undefined ? { apiKey: inherited.apiKey } : {}),\n ...(model !== undefined ? { model } : {}),\n ...(spec.sandbox === true ? { local: { sandboxOptions: { enabled: true } } } : {}),\n ...(inherited?.plugins !== undefined ? { plugins: inherited.plugins } : {}),\n systemPrompt: spec.instructions,\n tools: spec.tools ?? [],\n };\n}\n\nasync function runChildAgent(\n spec: SubAgentSpec,\n input: string,\n signal: AbortSignal | undefined,\n maxSteps: number | undefined,\n inherited: InheritedCredentials | undefined,\n): Promise<string> {\n // SE45 cycle 3 — use the registered Agent facade via the DIP seam\n // (agent-factory-registry) instead of a dynamic `import(\"../agent.js\")`.\n // This removes the last madge cycle (a2a/subagent -> agent -> ... -> real-local-run-tools\n // -> a2a/subagent): the facade registers itself at module-init via setAgentFacade,\n // so subagent depends only on the registry port, never on the facade module.\n const agent = await getAgentFacade().create(buildChildCreateOptions(spec, inherited));\n try {\n const sendOptions: {\n signal?: AbortSignal;\n maxIterations?: number;\n origin?: import(\"../types/run.js\").MessageOrigin;\n } = {\n ...(signal !== undefined ? { signal } : {}),\n ...(maxSteps !== undefined ? { maxIterations: maxSteps } : {}),\n // SE3 — a delegated child's turn is initiated by the coordinating parent.\n origin: { kind: \"coordinator\" },\n };\n const run = await agent.send(input, sendOptions);\n const result = await run.wait();\n // Fail-fast, don't swallow (Rule 8): a child that ended in error must surface — otherwise a real\n // failure (e.g. `provider_unresolved`) is hidden behind \"(no response)\" and the parent loops on it.\n if (result.status === \"error\") {\n const cause = (result as { error?: { message?: string } }).error;\n throw new Error(\n `subagent \"${spec.name}\" run failed: ${cause?.message ?? \"unknown error\"}`,\n cause !== undefined ? { cause } : undefined,\n );\n }\n const text = result.result ?? \"(no response)\";\n // SE14 — text-only by default; opt-in appends the child's tool results.\n return spec.includeToolResults === true ? text + (await collectChildToolResults(run)) : text;\n } finally {\n agent.dispose();\n }\n}\n\n/**\n * Best-effort error-path notification: run `onDelegationComplete` with the child's\n * error so the caller can observe the failure. The observer's own throw (sync or\n * async) is suppressed here so it cannot mask the delegation's real error, which the\n * handler re-throws next.\n */\nasync function notifyDelegationError(\n spec: SubAgentSpec,\n input: string,\n error: unknown,\n iteration: number,\n): Promise<void> {\n if (spec.onDelegationComplete === undefined) return;\n try {\n await spec.onDelegationComplete({ input, name: spec.name, error, iteration });\n } catch {\n // Subordinate to `error`; the child's real cause wins.\n }\n}\n\n/**\n * SE12 — apply `messageFilter` (if set) and prepend the filtered supervisor\n * transcript to the delegated input as a role-tagged context preamble. Absent\n * filter OR no messages OR an empty filtered subset ⇒ the original input\n * (isolation-by-default preserved).\n */\nfunction applyMessageFilter(\n spec: SubAgentSpec,\n input: string,\n messages: readonly ToolContextMessage[] | undefined,\n): string {\n if (spec.messageFilter === undefined || messages === undefined) return input;\n const filtered = spec.messageFilter({ messages, input, name: spec.name });\n if (filtered.length === 0) return input;\n const preamble = filtered.map((m) => `${m.role}: ${m.content}`).join(\"\\n\");\n return `Prior conversation:\\n${preamble}\\n\\nTask:\\n${input}`;\n}\n\n/** Run the success-path `onDelegationComplete` hook; appends its `feedback` to the result. */\nasync function applyDelegationComplete(\n spec: SubAgentSpec,\n input: string,\n result: string,\n iteration: number,\n): Promise<string> {\n if (spec.onDelegationComplete === undefined) return result;\n const completion = await spec.onDelegationComplete({ input, name: spec.name, result, iteration });\n return completion?.feedback !== undefined ? result + completion.feedback : result;\n}\n\nfunction defineSubAgent(spec: SubAgentSpec, _parentDepth = 0): CustomTool {\n const currentDepth = _parentDepth + 1;\n const maxDepth = spec.maxDelegationDepth ?? 3;\n\n if (currentDepth > maxDepth) {\n throw new MaxDelegationDepthError(currentDepth, maxDepth);\n }\n\n // Zod for RUNTIME validation of the tool_use input …\n const inputZod = z.object({\n input: z.string().describe(\"Task for the subagent\"),\n });\n // … and a real Draft-7 JSON Schema for the LLM. `CustomTool.inputSchema` is sent\n // to the model verbatim; a raw Zod object would serialize to garbage, so the\n // model emits malformed input that fails `inputZod.parse` and the delegation\n // never runs (the previous bug — the schema and the validator are now distinct).\n const inputSchema: Record<string, unknown> = {\n type: \"object\",\n properties: {\n input: { type: \"string\", description: \"Task for the subagent\" },\n },\n required: [\"input\"],\n additionalProperties: false,\n };\n\n // SE15 — per-instance delegation counter, surfaced as `iteration` on the hook\n // contexts. Incremented once per handler invocation before onDelegationStart.\n let iteration = 0;\n\n // Credentials handed down by the parent runtime (see `inheritSubAgentCredentials`).\n let inherited: InheritedCredentials | undefined;\n\n const tool: CustomTool = {\n name: spec.name,\n description: spec.description,\n inputSchema,\n handler: async (\n rawInput: Record<string, unknown>,\n ctx?: {\n signal?: AbortSignal;\n context?: unknown;\n messages?: readonly ToolContextMessage[];\n },\n ): Promise<string> => {\n const { input: parsed } = inputZod.parse(rawInput);\n iteration += 1; // SE15 — before onDelegationStart; a rejected delegation still counts.\n // Pin THIS invocation's iteration before any await so a concurrent invocation\n // bumping the shared counter cannot change the value onDelegationComplete /\n // notifyDelegationError observe — they see the same iteration onDelegationStart did.\n const capturedIteration = iteration;\n\n const start = await applyDelegationStart(spec, parsed, capturedIteration);\n if (\"reject\" in start) return start.reject;\n // SE12 — opt-in: forward the filtered supervisor transcript as a preamble.\n const input = applyMessageFilter(spec, start.input, ctx?.messages);\n\n let result: string;\n try {\n // SE13 — apply the optional onDelegationStart maxSteps cap on the child send.\n result = await runChildAgent(spec, input, ctx?.signal, start.maxSteps, inherited);\n } catch (error) {\n // SE11 — notify the completion hook of the failure (best-effort observer),\n // then re-throw the ORIGINAL error (Rule 8: never swallow the delegation's\n // own failure).\n await notifyDelegationError(spec, input, error, capturedIteration);\n throw error;\n }\n return applyDelegationComplete(spec, input, result, capturedIteration);\n },\n };\n\n // Install the private credential sink (off the public shape + off every ctx).\n Object.defineProperty(tool, INHERIT_CREDENTIALS, {\n value: ((creds: InheritedCredentials) => {\n inherited = creds;\n }) satisfies CredentialSink,\n enumerable: false,\n });\n\n return tool;\n}\n\n/** SE36 — `SubAgent.create` replaces `defineSubAgent` (ADR 0015). @public */\nexport class SubAgent {\n private constructor() {}\n static create(spec: SubAgentSpec, parentDepth = 0): CustomTool {\n return defineSubAgent(spec, parentDepth);\n }\n}\n\n/**\n * Convert a parent's declarative `agents` map ({@link AgentDefinition} per key)\n * into delegation tools for the LOCAL runtime — the counterpart of the\n * cloud/fixture subagent wiring. Each child inherits the parent's `apiKey`/model\n * via {@link inheritSubAgentCredentials}; `def.model` overrides the model\n * (`\"inherit\"` keeps the parent's), and `def.tools` scopes the child to that\n * subset of the parent's tools (absent → the parent's full toolset, per the\n * `AgentDefinition.tools` contract).\n *\n * M33 — per-subagent `model` (with reasoning `params`) and `sandbox` are now wired\n * into local delegation: each is carried onto the {@link SubAgentSpec} and applied to\n * the child in {@link buildChildCreateOptions}. `\"inherit\"` (or an absent field) keeps\n * the parent's value. Per-subagent `mcp` is rejected at load (see subagents-loader) —\n * resolving server names→config on the local path is a follow-up.\n *\n * @internal\n */\nexport function subAgentToolsFromDefinitions(\n agents: Record<string, AgentDefinition>,\n parentTools: readonly CustomTool[],\n): CustomTool[] {\n return Object.entries(agents).map(([name, def]) => {\n const whitelist =\n Array.isArray(def.tools) && def.tools.length > 0 ? new Set(def.tools) : undefined;\n const childTools = whitelist ? parentTools.filter((t) => whitelist.has(t.name)) : parentTools;\n return defineSubAgent({\n name,\n description: def.description,\n instructions: def.prompt,\n // Carry the FULL ModelSelection (id + reasoning params), not just the id, so\n // per-subagent reasoning effort survives to buildChildCreateOptions.\n ...(def.model !== undefined && def.model !== \"inherit\" ? { model: def.model } : {}),\n ...(def.sandbox !== undefined ? { sandbox: def.sandbox } : {}),\n tools: [...childTools],\n });\n });\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/a2a/agent-mailbox.ts","../../src/a2a/message-bus.ts","../../src/internal/runtime/registry/agent-factory-registry.ts","../../src/a2a/subagent.ts"],"names":["z"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * AgentMailbox — per-agent inbox for A2A communication (T20.1, ADR D453).\n *\n * Wraps MessageBus registration with a convenient API for sending,\n * receiving, and requesting messages.\n *\n * @public\n */\n\nimport type { MessageBus, RequestOptions } from \"./message-bus.js\";\nimport type { A2AMessage, MessageHandler } from \"./types.js\";\n\nexport class AgentMailbox {\n readonly agentId: string;\n private readonly _bus: MessageBus;\n private _handler: MessageHandler | null = null;\n\n constructor(agentId: string, bus: MessageBus) {\n this.agentId = agentId;\n this._bus = bus;\n this._bus.register(agentId, (msg) => this._dispatch(msg));\n }\n\n onMessage(handler: MessageHandler): void {\n this._handler = handler;\n }\n\n async send(to: string, partial: { type: string; payload: unknown }): Promise<void> {\n return this._bus.send(this.agentId, to, partial);\n }\n\n async request(\n to: string,\n partial: { type: string; payload: unknown },\n opts?: RequestOptions,\n ): Promise<unknown> {\n return this._bus.request(this.agentId, to, partial, opts);\n }\n\n dispose(): void {\n this._bus.unregister(this.agentId);\n this._handler = null;\n }\n\n private _dispatch(msg: A2AMessage): unknown {\n if (this._handler) {\n return this._handler(msg);\n }\n }\n}\n","/**\n * MessageBus — in-process typed message router for A2A (T20.1, ADR D453).\n *\n * Routes messages between agents by ID. Supports fire-and-forget (send)\n * and request/response (request with timeout).\n *\n * @public\n */\n\nimport type { A2AMessage, MessageHandler } from \"./types.js\";\n\nexport interface RequestOptions {\n timeoutMs?: number;\n}\n\nexport class MessageBus {\n private readonly _handlers = new Map<string, MessageHandler>();\n\n register(agentId: string, handler: MessageHandler): void {\n this._handlers.set(agentId, handler);\n }\n\n unregister(agentId: string): void {\n this._handlers.delete(agentId);\n }\n\n async send(from: string, to: string, partial: { type: string; payload: unknown }): Promise<void> {\n const handler = this._handlers.get(to);\n if (!handler) {\n throw new Error(`Agent \"${to}\" not registered on MessageBus`);\n }\n const message: A2AMessage = {\n ...partial,\n from,\n to,\n timestamp: Date.now(),\n // SE3 — provenance projection of the sender address (thin view over `from`).\n origin: { kind: \"peer\", from },\n };\n // Fire-and-forget: invoke handler but don't await result\n handler(message);\n }\n\n async request(\n from: string,\n to: string,\n partial: { type: string; payload: unknown },\n opts?: RequestOptions,\n ): Promise<unknown> {\n const handler = this._handlers.get(to);\n if (!handler) {\n throw new Error(`Agent \"${to}\" not registered on MessageBus`);\n }\n const timeoutMs = opts?.timeoutMs ?? 30_000;\n const message: A2AMessage = {\n ...partial,\n from,\n to,\n timestamp: Date.now(),\n // SE3 — provenance projection of the sender address (thin view over `from`).\n origin: { kind: \"peer\", from },\n };\n // Hold the timer so it can be cleared once the race settles — otherwise a\n // successful request leaks a live `setTimeout` that keeps the Node event loop\n // alive (the process hangs after the reply). Cleared in `finally`.\n let timer: ReturnType<typeof setTimeout> | undefined;\n try {\n return await Promise.race([\n Promise.resolve(handler(message)),\n new Promise((_, reject) => {\n timer = setTimeout(\n () =>\n reject(new Error(`A2A request timeout: ${to} did not respond within ${timeoutMs}ms`)),\n timeoutMs,\n );\n }),\n ]);\n } finally {\n if (timer !== undefined) clearTimeout(timer);\n }\n }\n\n has(agentId: string): boolean {\n return this._handlers.has(agentId);\n }\n\n listAgents(): string[] {\n return [...this._handlers.keys()];\n }\n}\n","/**\n * Internal DI seam for the public `Agent` facade.\n *\n * Several internal subsystems (`LocalAgent.runUntil`/`fork`, eval, scorers,\n * cron) need to invoke `Agent.create`/`prompt`/`get`/`resume`/`batch`. A direct\n * `import { Agent }` would invert the public-api -> internal dependency\n * direction (and `agent.ts` already imports much of `internal/`). This module\n * is the inversion seam: `agent.ts` registers the facade at module-init time;\n * internal consumers read it on-demand via `getAgentFacade()`. The\n * `internal-must-not-import-facade` dependency-cruiser rule enforces that no\n * `internal/*` module bypasses this seam with a direct facade import.\n *\n * Throws if accessed before registration — should never happen because\n * `agent.ts` evaluation always precedes any internal call (the consumer must\n * obtain a handle from the `Agent` facade first).\n *\n * @internal\n */\n\nimport type { AgentOptions, SDKAgent, SDKAgentInfo } from \"../../../types/agent.js\";\nimport type { BatchItem, BatchOptions, BatchResult } from \"../../../types/batch.js\";\nimport type { RunResult } from \"../../../types/run.js\";\n\n/**\n * The subset of the public `Agent` static surface that internal subsystems\n * consume through the inversion seam. Each member mirrors the matching\n * `Agent.*` signature so registration is a thin pass-through.\n *\n * @internal\n */\nexport interface AgentFacadePort {\n create: (options: AgentOptions) => Promise<SDKAgent>;\n delete: (agentId: string) => Promise<void>;\n prompt: (message: string, options: AgentOptions) => Promise<RunResult>;\n get: (agentId: string) => Promise<SDKAgentInfo>;\n resume: (agentId: string, options?: Partial<AgentOptions>) => Promise<SDKAgent>;\n batch: (\n prompts: ReadonlyArray<string | BatchItem>,\n options: BatchOptions,\n ) => Promise<BatchResult[]>;\n}\n\n/**\n * The registration slot lives on `globalThis` under a `Symbol.for` key — NOT a module-level `let` —\n * so it is a **process-wide singleton** shared by every copy of this module. `tsup` builds each public\n * entry (`.`, `./a2a`, `./cron`, `./eval`, …) with `splitting: false`, which INLINES this module once\n * per entry; a module-level `let` would give each bundled copy its own `registered` slot, and a\n * subagent invoked through `./a2a` would read a copy that `agent.ts` (in the `.` entry) never set —\n * the classic duplicated-singleton hazard (see issue: a2a \"Agent facade not registered\"). `Symbol.for`\n * (global symbol registry) + the one `globalThis` object guarantees all copies read/write ONE slot.\n */\nconst FACADE_KEY: unique symbol = Symbol.for(\n \"theokit.internal.runtime.agentFacade\",\n) as typeof FACADE_KEY;\n\ntype FacadeHost = { [FACADE_KEY]?: AgentFacadePort };\n\n/**\n * Registered by `agent.ts` at module-init time. Idempotent: re-registration\n * replaces the previous reference (useful for tests that swap implementations).\n *\n * @internal\n */\nexport function setAgentFacade(facade: AgentFacadePort): void {\n (globalThis as unknown as FacadeHost)[FACADE_KEY] = facade;\n}\n\n/**\n * Resolve the registered `Agent` facade for internal subsystems.\n *\n * @internal\n */\nexport function getAgentFacade(): AgentFacadePort {\n const registered = (globalThis as unknown as FacadeHost)[FACADE_KEY];\n if (registered === undefined) {\n throw new Error(\n \"internal: Agent facade not registered. The `agent.ts` module must be loaded before internal subsystems (LocalAgent.runUntil/fork, eval, scorers, cron) invoke it.\",\n );\n }\n return registered;\n}\n","/**\n * Subagent delegation — declarative child agent invocable as a tool.\n *\n * Per ADR D2: `defineSubAgent(spec)` returns a `CustomTool` that, when\n * invoked by the LLM, creates a child agent and sends the input as a\n * message. EC-2: delegation depth tracked to prevent infinite recursion.\n *\n * SE10 — the handler forwards the parent run's `AbortSignal` to the child.\n * SE11 — optional `onDelegationStart` / `onDelegationComplete` lifecycle hooks\n * let the caller reject, rewrite, observe, or annotate a delegation.\n *\n * @public\n */\n\nimport { z } from \"zod\";\nimport type { Plugin } from \"../internal/plugins/types.js\";\nimport { getAgentFacade } from \"../internal/runtime/registry/agent-factory-registry.js\";\nimport type {\n AgentDefinition,\n AgentOptions,\n CustomTool,\n ToolContextMessage,\n} from \"../types/agent.js\";\nimport type { ModelSelection } from \"../types/agent-prims.js\";\nimport type { Run } from \"../types/run.js\";\n\n/**\n * Credentials a parent agent hands down to its subagent tools so the child\n * inherits the parent's auth (and, absent an explicit `spec.model`, its model).\n * @internal\n */\nexport interface InheritedCredentials {\n readonly apiKey?: string;\n readonly model?: ModelSelection;\n /**\n * The parent's shell-sandbox posture (`local.sandboxOptions.enabled`), handed down so a delegated\n * child of a sandboxed parent stays sandboxed unless its role explicitly opts out. Without this a\n * child ran unsandboxed whenever its role omitted `sandbox` — a default-open the sandbox wiring exists\n * to prevent.\n */\n readonly sandbox?: boolean;\n /**\n * #55 — the parent's code-registered plugins (e.g. a `PermissionPlugin`) handed\n * down so the child runs under the SAME policy. Without this, a delegated child's\n * inner tool calls escape the parent's argument-level permission gate. First-party\n * delegation path only — never exposed to third-party tool `ctx`.\n */\n readonly plugins?: readonly Plugin[];\n}\n\n/**\n * Private per-tool setter installed on subagent tools. Kept off the public\n * `CustomTool` shape (and off every tool handler's `ctx`) so the parent's API\n * key never reaches third-party tool code — only the SDK's own delegation path.\n */\n// `Symbol.for` (global registry), NOT `Symbol()`: with `tsup splitting: false` each public entry\n// (`.`, `./a2a`) inlines its own copy of this module. A unique `Symbol()` would give each copy a\n// DIFFERENT sink key — the local runtime (bundled in `.`) calls `inheritSubAgentCredentials` with the\n// `.`-copy key, but a `SubAgent` created via `@theokit/sdk/a2a` installed its sink under the `/a2a`-copy\n// key, so the lookup missed and the child inherited NO `apiKey` (→ `provider_unresolved`, \"(no response)\").\n// `Symbol.for` makes both copies agree on ONE key. (Same duplicated-singleton class as the facade fix, #142.)\nconst INHERIT_CREDENTIALS = Symbol.for(\"theokit.subagent.inheritCredentials\");\n\ntype CredentialSink = (creds: InheritedCredentials) => void;\n\n/**\n * Called by the local runtime for every tool in a run: if the tool is a\n * subagent, its child agent inherits the parent's `apiKey`/`model`. A no-op for\n * any other tool (third-party tools never receive the parent's credentials).\n * @internal\n */\nexport function inheritSubAgentCredentials(tool: CustomTool, creds: InheritedCredentials): void {\n const sink = (tool as { [INHERIT_CREDENTIALS]?: CredentialSink })[INHERIT_CREDENTIALS];\n if (typeof sink === \"function\") sink(creds);\n}\n\n/** Arguments passed to {@link SubAgentSpec.messageFilter} (SE12). */\nexport interface MessageFilterArgs {\n /** The supervisor transcript (read-only text projection) available to this delegation. */\n messages: readonly ToolContextMessage[];\n /** The prompt about to be delegated (after any `onDelegationStart` rewrite). */\n input: string;\n /** The subagent's name. */\n name: string;\n}\n\n/** Context passed to {@link SubAgentSpec.onDelegationStart} before the child runs. */\nexport interface DelegationStartContext {\n input: string;\n name: string;\n /**\n * SE15 — 1-based count of times THIS subagent tool has been invoked (a\n * per-`defineSubAgent`-instance counter). Incremented before this hook runs;\n * a rejected delegation still counts. Enables reject-after-N patterns.\n */\n iteration: number;\n}\n\n/**\n * Decision returned from {@link SubAgentSpec.onDelegationStart}. Discriminated on\n * `proceed` so a rejection (`proceed: false` + `rejectionReason`) and an approval\n * (`modifiedInput`) cannot be mixed into one nonsensical object.\n */\nexport type DelegationStartDecision =\n | { proceed: false; rejectionReason?: string }\n | {\n proceed?: true;\n modifiedInput?: string;\n /** SE13 — cap the child's iteration count (forwarded as `SendOptions.maxIterations`). */\n modifiedMaxSteps?: number;\n };\n\n/** Context passed to {@link SubAgentSpec.onDelegationComplete} after the child settles. */\nexport interface DelegationCompleteContext {\n input: string;\n name: string;\n /** The child's text result (present on success). */\n result?: string;\n /** The error the child threw (present on failure); the error is still re-thrown. */\n error?: unknown;\n /** SE15 — the same 1-based iteration this delegation's `onDelegationStart` saw. */\n iteration: number;\n}\n\n/**\n * The return of a delegation hook: a decision, a promise of one, or nothing —\n * `void` lets a side-effect-only callback (`(ctx) => { log(ctx) }`) type-check,\n * which is the common case (mirrors a peer framework's `async ctx => { ... }` hooks).\n */\n// biome-ignore lint/suspicious/noConfusingVoidType: `void` is the idiomatic return for an optional-return callback; the rule false-positives on callback return unions.\ntype DelegationHookResult<T> = T | void | Promise<T | void>;\n\n/** Decision returned from {@link SubAgentSpec.onDelegationComplete}. */\nexport interface DelegationCompleteDecision {\n /** Appended to the child's result string. */\n feedback?: string;\n}\n\nexport interface SubAgentSpec {\n name: string;\n description: string;\n instructions: string;\n /**\n * A bare id string (back-compat) OR a full {@link ModelSelection} carrying\n * `params` (e.g. `[{ id: \"thinking\", value: \"low\" }]` for reasoning effort). The\n * object form is required for per-subagent reasoning effort to survive to the child\n * — the pre-M33 path took only `.id` and dropped params.\n */\n model?: string | ModelSelection;\n tools?: CustomTool[];\n /** Per-subagent shell sandbox toggle (M33). `true` ⇒ child `local.sandboxOptions.enabled`. */\n sandbox?: boolean;\n maxDelegationDepth?: number;\n /**\n * SE11 — called before the supervisor delegates. Return `{ proceed: false }`\n * to reject (the child never runs and `rejectionReason` becomes the tool\n * result), or `{ modifiedInput }` to rewrite the delegated prompt. A throwing\n * hook surfaces (never silently swallowed).\n */\n onDelegationStart?: (\n ctx: DelegationStartContext,\n ) => DelegationHookResult<DelegationStartDecision>;\n /**\n * SE11 — called after the delegation settles. On success `ctx.result` is set\n * and an optional `{ feedback }` is appended to it. On failure `ctx.error` is\n * set and the original error is ALWAYS re-thrown after this hook runs — a throw\n * from this hook on the error path is suppressed so it cannot mask the\n * delegation's real failure (on the success path a throw does propagate).\n */\n onDelegationComplete?: (\n ctx: DelegationCompleteContext,\n ) => DelegationHookResult<DelegationCompleteDecision>;\n /**\n * SE12 — opt-in parent-context forwarding. When set, the supervisor transcript\n * (`ctx.messages`, a read-only text projection) is passed to this filter and the\n * returned subset is forwarded to the child as a role-tagged context preamble\n * prepended to the delegated input. When ABSENT the child runs input-only —\n * memory isolation stays the default. A filter returning `[]` forwards nothing.\n * A throwing filter propagates (fail-fast, never swallowed — same contract as\n * `onDelegationStart`); the delegation surfaces as a tool error.\n */\n messageFilter?: (args: MessageFilterArgs) => readonly ToolContextMessage[];\n /**\n * SE14 — opt-in subagent result-context control. When `true`, the child's\n * completed tool-call results (name + result) are appended to the delegation\n * payload returned to the supervisor, inside a `<subagent-tool-results>` block.\n * When absent/`false` the delegation returns the child's final text only —\n * text-only stays the default (a peer framework's scoped posture). See ADR 0006.\n */\n includeToolResults?: boolean;\n}\n\nexport class MaxDelegationDepthError extends Error {\n readonly code = \"max_delegation_depth\" as const;\n constructor(\n public readonly currentDepth: number,\n public readonly maxDepth: number,\n ) {\n super(`Max delegation depth ${maxDepth} exceeded (current: ${currentDepth})`);\n this.name = \"MaxDelegationDepthError\";\n }\n}\n\n/**\n * Run the `onDelegationStart` hook; returns either a rejection or the (possibly\n * rewritten) input plus the optional SE13 `maxSteps` cap.\n */\nasync function applyDelegationStart(\n spec: SubAgentSpec,\n input: string,\n iteration: number,\n): Promise<{ reject: string } | { input: string; maxSteps?: number }> {\n if (spec.onDelegationStart === undefined) return { input };\n const decision = await spec.onDelegationStart({ input, name: spec.name, iteration });\n if (decision === undefined) return { input };\n if (decision.proceed === false)\n return { reject: decision.rejectionReason ?? \"(delegation rejected)\" };\n return {\n input: decision.modifiedInput ?? input,\n ...(decision.modifiedMaxSteps !== undefined ? { maxSteps: decision.modifiedMaxSteps } : {}),\n };\n}\n\n/**\n * SE14 — replay the child run's stream (a safe post-`wait()` idiom — the run buffers\n * events, `stream()` replays them) and collect every completed tool-call result into\n * a delimited block. Returns `\"\"` when the child ran no completed tool calls. See ADR 0006.\n */\nasync function collectChildToolResults(run: Run): Promise<string> {\n const lines: string[] = [];\n for await (const event of run.stream()) {\n if (event.type === \"tool_call\" && event.status === \"completed\") {\n const rendered =\n typeof event.result === \"string\" ? event.result : JSON.stringify(event.result ?? null);\n lines.push(`${event.name}: ${rendered}`);\n }\n }\n if (lines.length === 0) return \"\";\n return `\\n\\n<subagent-tool-results>\\n${lines.join(\"\\n\")}\\n</subagent-tool-results>`;\n}\n\n/**\n * Create the transient child agent and send the input, composing every forwarded\n * `SendOptions` onto ONE `send` call — SE10 `signal` + SE13 `maxIterations`. Absent\n * every option ⇒ the pre-SE10 single-arg `send(input)` shape. SE14 — when\n * `includeToolResults` is set, append the child's completed tool results. Dispose in `finally`.\n */\n/**\n * Build the child agent's `Agent.create` options: the child inherits the parent's\n * apiKey (else `Agent.create` throws \"Missing API key\"), its model (unless the spec\n * overrides it), and — #55 — the parent's plugins (permission gate/guards) so the\n * child's inner tool calls run under the same policy.\n */\nexport function buildChildCreateOptions(\n spec: SubAgentSpec,\n inherited: InheritedCredentials | undefined,\n): AgentOptions {\n // M33 — carry the WHOLE model (a bare id becomes `{ id }`; a ModelSelection with\n // `params` keeps its reasoning effort). The pre-M33 path wrapped `spec.model` as\n // `{ id: spec.model }`, which only worked because spec.model was a string and\n // silently dropped reasoning params.\n const model: string | ModelSelection | undefined =\n spec.model !== undefined\n ? typeof spec.model === \"string\"\n ? { id: spec.model }\n : spec.model\n : inherited?.model;\n // M33 — the role's own `sandbox` wins; when it omits the field, inherit the parent's posture. A role's\n // explicit `sandbox: false` therefore confines-OFF a child of a sandboxed parent (distinct from absent).\n const sandbox = spec.sandbox ?? inherited?.sandbox;\n return {\n ...(inherited?.apiKey !== undefined ? { apiKey: inherited.apiKey } : {}),\n ...(model !== undefined ? { model } : {}),\n ...(sandbox !== undefined ? { local: { sandboxOptions: { enabled: sandbox } } } : {}),\n ...(inherited?.plugins !== undefined ? { plugins: inherited.plugins } : {}),\n systemPrompt: spec.instructions,\n tools: spec.tools ?? [],\n };\n}\n\nasync function runChildAgent(\n spec: SubAgentSpec,\n input: string,\n signal: AbortSignal | undefined,\n maxSteps: number | undefined,\n inherited: InheritedCredentials | undefined,\n): Promise<string> {\n // SE45 cycle 3 — use the registered Agent facade via the DIP seam\n // (agent-factory-registry) instead of a dynamic `import(\"../agent.js\")`.\n // This removes the last madge cycle (a2a/subagent -> agent -> ... -> real-local-run-tools\n // -> a2a/subagent): the facade registers itself at module-init via setAgentFacade,\n // so subagent depends only on the registry port, never on the facade module.\n const agent = await getAgentFacade().create(buildChildCreateOptions(spec, inherited));\n try {\n const sendOptions: {\n signal?: AbortSignal;\n maxIterations?: number;\n origin?: import(\"../types/run.js\").MessageOrigin;\n } = {\n ...(signal !== undefined ? { signal } : {}),\n ...(maxSteps !== undefined ? { maxIterations: maxSteps } : {}),\n // SE3 — a delegated child's turn is initiated by the coordinating parent.\n origin: { kind: \"coordinator\" },\n };\n const run = await agent.send(input, sendOptions);\n const result = await run.wait();\n // Fail-fast, don't swallow (Rule 8): a child that ended in error must surface — otherwise a real\n // failure (e.g. `provider_unresolved`) is hidden behind \"(no response)\" and the parent loops on it.\n if (result.status === \"error\") {\n const cause = (result as { error?: { message?: string } }).error;\n throw new Error(\n `subagent \"${spec.name}\" run failed: ${cause?.message ?? \"unknown error\"}`,\n cause !== undefined ? { cause } : undefined,\n );\n }\n const text = result.result ?? \"(no response)\";\n // SE14 — text-only by default; opt-in appends the child's tool results.\n return spec.includeToolResults === true ? text + (await collectChildToolResults(run)) : text;\n } finally {\n agent.dispose();\n }\n}\n\n/**\n * Best-effort error-path notification: run `onDelegationComplete` with the child's\n * error so the caller can observe the failure. The observer's own throw (sync or\n * async) is suppressed here so it cannot mask the delegation's real error, which the\n * handler re-throws next.\n */\nasync function notifyDelegationError(\n spec: SubAgentSpec,\n input: string,\n error: unknown,\n iteration: number,\n): Promise<void> {\n if (spec.onDelegationComplete === undefined) return;\n try {\n await spec.onDelegationComplete({ input, name: spec.name, error, iteration });\n } catch {\n // Subordinate to `error`; the child's real cause wins.\n }\n}\n\n/**\n * SE12 — apply `messageFilter` (if set) and prepend the filtered supervisor\n * transcript to the delegated input as a role-tagged context preamble. Absent\n * filter OR no messages OR an empty filtered subset ⇒ the original input\n * (isolation-by-default preserved).\n */\nfunction applyMessageFilter(\n spec: SubAgentSpec,\n input: string,\n messages: readonly ToolContextMessage[] | undefined,\n): string {\n if (spec.messageFilter === undefined || messages === undefined) return input;\n const filtered = spec.messageFilter({ messages, input, name: spec.name });\n if (filtered.length === 0) return input;\n const preamble = filtered.map((m) => `${m.role}: ${m.content}`).join(\"\\n\");\n return `Prior conversation:\\n${preamble}\\n\\nTask:\\n${input}`;\n}\n\n/** Run the success-path `onDelegationComplete` hook; appends its `feedback` to the result. */\nasync function applyDelegationComplete(\n spec: SubAgentSpec,\n input: string,\n result: string,\n iteration: number,\n): Promise<string> {\n if (spec.onDelegationComplete === undefined) return result;\n const completion = await spec.onDelegationComplete({ input, name: spec.name, result, iteration });\n return completion?.feedback !== undefined ? result + completion.feedback : result;\n}\n\nfunction defineSubAgent(spec: SubAgentSpec, _parentDepth = 0): CustomTool {\n const currentDepth = _parentDepth + 1;\n const maxDepth = spec.maxDelegationDepth ?? 3;\n\n if (currentDepth > maxDepth) {\n throw new MaxDelegationDepthError(currentDepth, maxDepth);\n }\n\n // Zod for RUNTIME validation of the tool_use input …\n const inputZod = z.object({\n input: z.string().describe(\"Task for the subagent\"),\n });\n // … and a real Draft-7 JSON Schema for the LLM. `CustomTool.inputSchema` is sent\n // to the model verbatim; a raw Zod object would serialize to garbage, so the\n // model emits malformed input that fails `inputZod.parse` and the delegation\n // never runs (the previous bug — the schema and the validator are now distinct).\n const inputSchema: Record<string, unknown> = {\n type: \"object\",\n properties: {\n input: { type: \"string\", description: \"Task for the subagent\" },\n },\n required: [\"input\"],\n additionalProperties: false,\n };\n\n // SE15 — per-instance delegation counter, surfaced as `iteration` on the hook\n // contexts. Incremented once per handler invocation before onDelegationStart.\n let iteration = 0;\n\n // Credentials handed down by the parent runtime (see `inheritSubAgentCredentials`).\n let inherited: InheritedCredentials | undefined;\n\n const tool: CustomTool = {\n name: spec.name,\n description: spec.description,\n inputSchema,\n handler: async (\n rawInput: Record<string, unknown>,\n ctx?: {\n signal?: AbortSignal;\n context?: unknown;\n messages?: readonly ToolContextMessage[];\n },\n ): Promise<string> => {\n const { input: parsed } = inputZod.parse(rawInput);\n iteration += 1; // SE15 — before onDelegationStart; a rejected delegation still counts.\n // Pin THIS invocation's iteration before any await so a concurrent invocation\n // bumping the shared counter cannot change the value onDelegationComplete /\n // notifyDelegationError observe — they see the same iteration onDelegationStart did.\n const capturedIteration = iteration;\n\n const start = await applyDelegationStart(spec, parsed, capturedIteration);\n if (\"reject\" in start) return start.reject;\n // SE12 — opt-in: forward the filtered supervisor transcript as a preamble.\n const input = applyMessageFilter(spec, start.input, ctx?.messages);\n\n let result: string;\n try {\n // SE13 — apply the optional onDelegationStart maxSteps cap on the child send.\n result = await runChildAgent(spec, input, ctx?.signal, start.maxSteps, inherited);\n } catch (error) {\n // SE11 — notify the completion hook of the failure (best-effort observer),\n // then re-throw the ORIGINAL error (Rule 8: never swallow the delegation's\n // own failure).\n await notifyDelegationError(spec, input, error, capturedIteration);\n throw error;\n }\n return applyDelegationComplete(spec, input, result, capturedIteration);\n },\n };\n\n // Install the private credential sink (off the public shape + off every ctx).\n Object.defineProperty(tool, INHERIT_CREDENTIALS, {\n value: ((creds: InheritedCredentials) => {\n inherited = creds;\n }) satisfies CredentialSink,\n enumerable: false,\n });\n\n return tool;\n}\n\n/** SE36 — `SubAgent.create` replaces `defineSubAgent` (ADR 0015). @public */\nexport class SubAgent {\n private constructor() {}\n static create(spec: SubAgentSpec, parentDepth = 0): CustomTool {\n return defineSubAgent(spec, parentDepth);\n }\n}\n\n/**\n * Convert a parent's declarative `agents` map ({@link AgentDefinition} per key)\n * into delegation tools for the LOCAL runtime — the counterpart of the\n * cloud/fixture subagent wiring. Each child inherits the parent's `apiKey`/model\n * via {@link inheritSubAgentCredentials}; `def.model` overrides the model\n * (`\"inherit\"` keeps the parent's), and `def.tools` scopes the child to that\n * subset of the parent's tools (absent → the parent's full toolset, per the\n * `AgentDefinition.tools` contract).\n *\n * M33 — per-subagent `model` (with reasoning `params`) and `sandbox` are now wired\n * into local delegation: each is carried onto the {@link SubAgentSpec} and applied to\n * the child in {@link buildChildCreateOptions}. `\"inherit\"` (or an absent field) keeps\n * the parent's value. Per-subagent `mcp` is rejected at load (see subagents-loader) —\n * resolving server names→config on the local path is a follow-up.\n *\n * @internal\n */\nexport function subAgentToolsFromDefinitions(\n agents: Record<string, AgentDefinition>,\n parentTools: readonly CustomTool[],\n): CustomTool[] {\n return Object.entries(agents).map(([name, def]) => {\n const whitelist =\n Array.isArray(def.tools) && def.tools.length > 0 ? new Set(def.tools) : undefined;\n const childTools = whitelist ? parentTools.filter((t) => whitelist.has(t.name)) : parentTools;\n return defineSubAgent({\n name,\n description: def.description,\n instructions: def.prompt,\n // Carry the FULL ModelSelection (id + reasoning params), not just the id, so\n // per-subagent reasoning effort survives to buildChildCreateOptions.\n ...(def.model !== undefined && def.model !== \"inherit\" ? { model: def.model } : {}),\n ...(def.sandbox !== undefined ? { sandbox: def.sandbox } : {}),\n tools: [...childTools],\n });\n });\n}\n"]}
|
package/dist/a2a/index.js
CHANGED
|
@@ -146,10 +146,11 @@ ${lines.join("\n")}
|
|
|
146
146
|
}
|
|
147
147
|
function buildChildCreateOptions(spec, inherited) {
|
|
148
148
|
const model = spec.model !== void 0 ? typeof spec.model === "string" ? { id: spec.model } : spec.model : inherited?.model;
|
|
149
|
+
const sandbox = spec.sandbox ?? inherited?.sandbox;
|
|
149
150
|
return {
|
|
150
151
|
...inherited?.apiKey !== void 0 ? { apiKey: inherited.apiKey } : {},
|
|
151
152
|
...model !== void 0 ? { model } : {},
|
|
152
|
-
...
|
|
153
|
+
...sandbox !== void 0 ? { local: { sandboxOptions: { enabled: sandbox } } } : {},
|
|
153
154
|
...inherited?.plugins !== void 0 ? { plugins: inherited.plugins } : {},
|
|
154
155
|
systemPrompt: spec.instructions,
|
|
155
156
|
tools: spec.tools ?? []
|
package/dist/a2a/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/a2a/agent-mailbox.ts","../../src/a2a/message-bus.ts","../../src/internal/runtime/registry/agent-factory-registry.ts","../../src/a2a/subagent.ts"],"names":[],"mappings":";;;AAYO,IAAM,eAAN,MAAmB;AAAA,EACf,OAAA;AAAA,EACQ,IAAA;AAAA,EACT,QAAA,GAAkC,IAAA;AAAA,EAE1C,WAAA,CAAY,SAAiB,GAAA,EAAiB;AAC5C,IAAA,IAAA,CAAK,OAAA,GAAU,OAAA;AACf,IAAA,IAAA,CAAK,IAAA,GAAO,GAAA;AACZ,IAAA,IAAA,CAAK,IAAA,CAAK,SAAS,OAAA,EAAS,CAAC,QAAQ,IAAA,CAAK,SAAA,CAAU,GAAG,CAAC,CAAA;AAAA,EAC1D;AAAA,EAEA,UAAU,OAAA,EAA+B;AACvC,IAAA,IAAA,CAAK,QAAA,GAAW,OAAA;AAAA,EAClB;AAAA,EAEA,MAAM,IAAA,CAAK,EAAA,EAAY,OAAA,EAA4D;AACjF,IAAA,OAAO,KAAK,IAAA,CAAK,IAAA,CAAK,IAAA,CAAK,OAAA,EAAS,IAAI,OAAO,CAAA;AAAA,EACjD;AAAA,EAEA,MAAM,OAAA,CACJ,EAAA,EACA,OAAA,EACA,IAAA,EACkB;AAClB,IAAA,OAAO,KAAK,IAAA,CAAK,OAAA,CAAQ,KAAK,OAAA,EAAS,EAAA,EAAI,SAAS,IAAI,CAAA;AAAA,EAC1D;AAAA,EAEA,OAAA,GAAgB;AACd,IAAA,IAAA,CAAK,IAAA,CAAK,UAAA,CAAW,IAAA,CAAK,OAAO,CAAA;AACjC,IAAA,IAAA,CAAK,QAAA,GAAW,IAAA;AAAA,EAClB;AAAA,EAEQ,UAAU,GAAA,EAA0B;AAC1C,IAAA,IAAI,KAAK,QAAA,EAAU;AACjB,MAAA,OAAO,IAAA,CAAK,SAAS,GAAG,CAAA;AAAA,IAC1B;AAAA,EACF;AACF;;;AClCO,IAAM,aAAN,MAAiB;AAAA,EACL,SAAA,uBAAgB,GAAA,EAA4B;AAAA,EAE7D,QAAA,CAAS,SAAiB,OAAA,EAA+B;AACvD,IAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAA,EAAS,OAAO,CAAA;AAAA,EACrC;AAAA,EAEA,WAAW,OAAA,EAAuB;AAChC,IAAA,IAAA,CAAK,SAAA,CAAU,OAAO,OAAO,CAAA;AAAA,EAC/B;AAAA,EAEA,MAAM,IAAA,CAAK,IAAA,EAAc,EAAA,EAAY,OAAA,EAA4D;AAC/F,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,EAAE,CAAA;AACrC,IAAA,IAAI,CAAC,OAAA,EAAS;AACZ,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,OAAA,EAAU,EAAE,CAAA,8BAAA,CAAgC,CAAA;AAAA,IAC9D;AACA,IAAA,MAAM,OAAA,GAAsB;AAAA,MAC1B,GAAG,OAAA;AAAA,MACH,IAAA;AAAA,MACA,EAAA;AAAA,MACA,SAAA,EAAW,KAAK,GAAA,EAAI;AAAA;AAAA,MAEpB,MAAA,EAAQ,EAAE,IAAA,EAAM,MAAA,EAAQ,IAAA;AAAK,KAC/B;AAEA,IAAA,OAAA,CAAQ,OAAO,CAAA;AAAA,EACjB;AAAA,EAEA,MAAM,OAAA,CACJ,IAAA,EACA,EAAA,EACA,SACA,IAAA,EACkB;AAClB,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,EAAE,CAAA;AACrC,IAAA,IAAI,CAAC,OAAA,EAAS;AACZ,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,OAAA,EAAU,EAAE,CAAA,8BAAA,CAAgC,CAAA;AAAA,IAC9D;AACA,IAAA,MAAM,SAAA,GAAY,MAAM,SAAA,IAAa,GAAA;AACrC,IAAA,MAAM,OAAA,GAAsB;AAAA,MAC1B,GAAG,OAAA;AAAA,MACH,IAAA;AAAA,MACA,EAAA;AAAA,MACA,SAAA,EAAW,KAAK,GAAA,EAAI;AAAA;AAAA,MAEpB,MAAA,EAAQ,EAAE,IAAA,EAAM,MAAA,EAAQ,IAAA;AAAK,KAC/B;AAIA,IAAA,IAAI,KAAA;AACJ,IAAA,IAAI;AACF,MAAA,OAAO,MAAM,QAAQ,IAAA,CAAK;AAAA,QACxB,OAAA,CAAQ,OAAA,CAAQ,OAAA,CAAQ,OAAO,CAAC,CAAA;AAAA,QAChC,IAAI,OAAA,CAAQ,CAAC,CAAA,EAAG,MAAA,KAAW;AACzB,UAAA,KAAA,GAAQ,UAAA;AAAA,YACN,MACE,OAAO,IAAI,KAAA,CAAM,wBAAwB,EAAE,CAAA,wBAAA,EAA2B,SAAS,CAAA,EAAA,CAAI,CAAC,CAAA;AAAA,YACtF;AAAA,WACF;AAAA,QACF,CAAC;AAAA,OACF,CAAA;AAAA,IACH,CAAA,SAAE;AACA,MAAA,IAAI,KAAA,KAAU,MAAA,EAAW,YAAA,CAAa,KAAK,CAAA;AAAA,IAC7C;AAAA,EACF;AAAA,EAEA,IAAI,OAAA,EAA0B;AAC5B,IAAA,OAAO,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAO,CAAA;AAAA,EACnC;AAAA,EAEA,UAAA,GAAuB;AACrB,IAAA,OAAO,CAAC,GAAG,IAAA,CAAK,SAAA,CAAU,MAAM,CAAA;AAAA,EAClC;AACF;;;ACtCA,IAAM,6BAA4B,MAAA,CAAO,GAAA;AAAA,EACvC;AACF,CAAA;AAmBO,SAAS,cAAA,GAAkC;AAChD,EAAA,MAAM,UAAA,GAAc,WAAqC,UAAU,CAAA;AACnE,EAAA,IAAI,eAAe,MAAA,EAAW;AAC5B,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AACA,EAAA,OAAO,UAAA;AACT;;;AC1BA,IAAM,mBAAA,mBAAsB,MAAA,CAAO,GAAA,CAAI,qCAAqC,CAAA;AAmIrE,IAAM,uBAAA,GAAN,cAAsC,KAAA,CAAM;AAAA,EAEjD,WAAA,CACkB,cACA,QAAA,EAChB;AACA,IAAA,KAAA,CAAM,CAAA,qBAAA,EAAwB,QAAQ,CAAA,oBAAA,EAAuB,YAAY,CAAA,CAAA,CAAG,CAAA;AAH5D,IAAA,IAAA,CAAA,YAAA,GAAA,YAAA;AACA,IAAA,IAAA,CAAA,QAAA,GAAA,QAAA;AAGhB,IAAA,IAAA,CAAK,IAAA,GAAO,yBAAA;AAAA,EACd;AAAA,EALkB,YAAA;AAAA,EACA,QAAA;AAAA,EAHT,IAAA,GAAO,sBAAA;AAQlB;AAMA,eAAe,oBAAA,CACb,IAAA,EACA,KAAA,EACA,SAAA,EACoE;AACpE,EAAA,IAAI,IAAA,CAAK,iBAAA,KAAsB,MAAA,EAAW,OAAO,EAAE,KAAA,EAAM;AACzD,EAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,iBAAA,CAAkB,EAAE,OAAO,IAAA,EAAM,IAAA,CAAK,IAAA,EAAM,SAAA,EAAW,CAAA;AACnF,EAAA,IAAI,QAAA,KAAa,MAAA,EAAW,OAAO,EAAE,KAAA,EAAM;AAC3C,EAAA,IAAI,SAAS,OAAA,KAAY,KAAA;AACvB,IAAA,OAAO,EAAE,MAAA,EAAQ,QAAA,CAAS,eAAA,IAAmB,uBAAA,EAAwB;AACvE,EAAA,OAAO;AAAA,IACL,KAAA,EAAO,SAAS,aAAA,IAAiB,KAAA;AAAA,IACjC,GAAI,SAAS,gBAAA,KAAqB,MAAA,GAAY,EAAE,QAAA,EAAU,QAAA,CAAS,gBAAA,EAAiB,GAAI;AAAC,GAC3F;AACF;AAOA,eAAe,wBAAwB,GAAA,EAA2B;AAChE,EAAA,MAAM,QAAkB,EAAC;AACzB,EAAA,WAAA,MAAiB,KAAA,IAAS,GAAA,CAAI,MAAA,EAAO,EAAG;AACtC,IAAA,IAAI,KAAA,CAAM,IAAA,KAAS,WAAA,IAAe,KAAA,CAAM,WAAW,WAAA,EAAa;AAC9D,MAAA,MAAM,QAAA,GACJ,OAAO,KAAA,CAAM,MAAA,KAAW,QAAA,GAAW,KAAA,CAAM,MAAA,GAAS,IAAA,CAAK,SAAA,CAAU,KAAA,CAAM,MAAA,IAAU,IAAI,CAAA;AACvF,MAAA,KAAA,CAAM,KAAK,CAAA,EAAG,KAAA,CAAM,IAAI,CAAA,EAAA,EAAK,QAAQ,CAAA,CAAE,CAAA;AAAA,IACzC;AAAA,EACF;AACA,EAAA,IAAI,KAAA,CAAM,MAAA,KAAW,CAAA,EAAG,OAAO,EAAA;AAC/B,EAAA,OAAO;;AAAA;AAAA,EAAgC,KAAA,CAAM,IAAA,CAAK,IAAI,CAAC;AAAA,wBAAA,CAAA;AACzD;AAcO,SAAS,uBAAA,CACd,MACA,SAAA,EACc;AAKd,EAAA,MAAM,KAAA,GACJ,IAAA,CAAK,KAAA,KAAU,MAAA,GACX,OAAO,IAAA,CAAK,KAAA,KAAU,QAAA,GACpB,EAAE,IAAI,IAAA,CAAK,KAAA,EAAM,GACjB,IAAA,CAAK,QACP,SAAA,EAAW,KAAA;AACjB,EAAA,OAAO;AAAA,IACL,GAAI,WAAW,MAAA,KAAW,MAAA,GAAY,EAAE,MAAA,EAAQ,SAAA,CAAU,MAAA,EAAO,GAAI,EAAC;AAAA,IACtE,GAAI,KAAA,KAAU,MAAA,GAAY,EAAE,KAAA,KAAU,EAAC;AAAA,IACvC,GAAI,IAAA,CAAK,OAAA,KAAY,IAAA,GAAO,EAAE,KAAA,EAAO,EAAE,cAAA,EAAgB,EAAE,OAAA,EAAS,IAAA,EAAK,EAAE,KAAM,EAAC;AAAA,IAChF,GAAI,WAAW,OAAA,KAAY,MAAA,GAAY,EAAE,OAAA,EAAS,SAAA,CAAU,OAAA,EAAQ,GAAI,EAAC;AAAA,IACzE,cAAc,IAAA,CAAK,YAAA;AAAA,IACnB,KAAA,EAAO,IAAA,CAAK,KAAA,IAAS;AAAC,GACxB;AACF;AAEA,eAAe,aAAA,CACb,IAAA,EACA,KAAA,EACA,MAAA,EACA,UACA,SAAA,EACiB;AAMjB,EAAA,MAAM,KAAA,GAAQ,MAAM,cAAA,EAAe,CAAE,OAAO,uBAAA,CAAwB,IAAA,EAAM,SAAS,CAAC,CAAA;AACpF,EAAA,IAAI;AACF,IAAA,MAAM,WAAA,GAIF;AAAA,MACF,GAAI,MAAA,KAAW,KAAA,CAAA,GAAY,EAAE,MAAA,KAAW,EAAC;AAAA,MACzC,GAAI,QAAA,KAAa,KAAA,CAAA,GAAY,EAAE,aAAA,EAAe,QAAA,KAAa,EAAC;AAAA;AAAA,MAE5D,MAAA,EAAQ,EAAE,IAAA,EAAM,aAAA;AAAc,KAChC;AACA,IAAA,MAAM,GAAA,GAAM,MAAM,KAAA,CAAM,IAAA,CAAK,OAAO,WAAW,CAAA;AAC/C,IAAA,MAAM,MAAA,GAAS,MAAM,GAAA,CAAI,IAAA,EAAK;AAG9B,IAAA,IAAI,MAAA,CAAO,WAAW,OAAA,EAAS;AAC7B,MAAA,MAAM,QAAS,MAAA,CAA4C,KAAA;AAC3D,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,aAAa,IAAA,CAAK,IAAI,CAAA,cAAA,EAAiB,KAAA,EAAO,WAAW,eAAe,CAAA,CAAA;AAAA,QACxE,KAAA,KAAU,KAAA,CAAA,GAAY,EAAE,KAAA,EAAM,GAAI,KAAA;AAAA,OACpC;AAAA,IACF;AACA,IAAA,MAAM,IAAA,GAAO,OAAO,MAAA,IAAU,eAAA;AAE9B,IAAA,OAAO,KAAK,kBAAA,KAAuB,IAAA,GAAO,OAAQ,MAAM,uBAAA,CAAwB,GAAG,CAAA,GAAK,IAAA;AAAA,EAC1F,CAAA,SAAE;AACA,IAAA,KAAA,CAAM,OAAA,EAAQ;AAAA,EAChB;AACF;AAQA,eAAe,qBAAA,CACb,IAAA,EACA,KAAA,EACA,KAAA,EACA,SAAA,EACe;AACf,EAAA,IAAI,IAAA,CAAK,yBAAyB,MAAA,EAAW;AAC7C,EAAA,IAAI;AACF,IAAA,MAAM,IAAA,CAAK,qBAAqB,EAAE,KAAA,EAAO,MAAM,IAAA,CAAK,IAAA,EAAM,KAAA,EAAO,SAAA,EAAW,CAAA;AAAA,EAC9E,CAAA,CAAA,MAAQ;AAAA,EAER;AACF;AAQA,SAAS,kBAAA,CACP,IAAA,EACA,KAAA,EACA,QAAA,EACQ;AACR,EAAA,IAAI,IAAA,CAAK,aAAA,KAAkB,MAAA,IAAa,QAAA,KAAa,QAAW,OAAO,KAAA;AACvE,EAAA,MAAM,QAAA,GAAW,KAAK,aAAA,CAAc,EAAE,UAAU,KAAA,EAAO,IAAA,EAAM,IAAA,CAAK,IAAA,EAAM,CAAA;AACxE,EAAA,IAAI,QAAA,CAAS,MAAA,KAAW,CAAA,EAAG,OAAO,KAAA;AAClC,EAAA,MAAM,QAAA,GAAW,QAAA,CAAS,GAAA,CAAI,CAAC,MAAM,CAAA,EAAG,CAAA,CAAE,IAAI,CAAA,EAAA,EAAK,CAAA,CAAE,OAAO,CAAA,CAAE,CAAA,CAAE,KAAK,IAAI,CAAA;AACzE,EAAA,OAAO,CAAA;AAAA,EAAwB,QAAQ;;AAAA;AAAA,EAAc,KAAK,CAAA,CAAA;AAC5D;AAGA,eAAe,uBAAA,CACb,IAAA,EACA,KAAA,EACA,MAAA,EACA,SAAA,EACiB;AACjB,EAAA,IAAI,IAAA,CAAK,oBAAA,KAAyB,MAAA,EAAW,OAAO,MAAA;AACpD,EAAA,MAAM,UAAA,GAAa,MAAM,IAAA,CAAK,oBAAA,CAAqB,EAAE,KAAA,EAAO,IAAA,EAAM,IAAA,CAAK,IAAA,EAAM,MAAA,EAAQ,SAAA,EAAW,CAAA;AAChG,EAAA,OAAO,UAAA,EAAY,QAAA,KAAa,MAAA,GAAY,MAAA,GAAS,WAAW,QAAA,GAAW,MAAA;AAC7E;AAEA,SAAS,cAAA,CAAe,IAAA,EAAoB,YAAA,GAAe,CAAA,EAAe;AACxE,EAAA,MAAM,eAAe,YAAA,GAAe,CAAA;AACpC,EAAA,MAAM,QAAA,GAAW,KAAK,kBAAA,IAAsB,CAAA;AAE5C,EAAA,IAAI,eAAe,QAAA,EAAU;AAC3B,IAAA,MAAM,IAAI,uBAAA,CAAwB,YAAA,EAAc,QAAQ,CAAA;AAAA,EAC1D;AAGA,EAAA,MAAM,QAAA,GAAW,EAAE,MAAA,CAAO;AAAA,IACxB,KAAA,EAAO,CAAA,CAAE,MAAA,EAAO,CAAE,SAAS,uBAAuB;AAAA,GACnD,CAAA;AAKD,EAAA,MAAM,WAAA,GAAuC;AAAA,IAC3C,IAAA,EAAM,QAAA;AAAA,IACN,UAAA,EAAY;AAAA,MACV,KAAA,EAAO,EAAE,IAAA,EAAM,QAAA,EAAU,aAAa,uBAAA;AAAwB,KAChE;AAAA,IACA,QAAA,EAAU,CAAC,OAAO,CAAA;AAAA,IAClB,oBAAA,EAAsB;AAAA,GACxB;AAIA,EAAA,IAAI,SAAA,GAAY,CAAA;AAGhB,EAAA,IAAI,SAAA;AAEJ,EAAA,MAAM,IAAA,GAAmB;AAAA,IACvB,MAAM,IAAA,CAAK,IAAA;AAAA,IACX,aAAa,IAAA,CAAK,WAAA;AAAA,IAClB,WAAA;AAAA,IACA,OAAA,EAAS,OACP,QAAA,EACA,GAAA,KAKoB;AACpB,MAAA,MAAM,EAAE,KAAA,EAAO,MAAA,EAAO,GAAI,QAAA,CAAS,MAAM,QAAQ,CAAA;AACjD,MAAA,SAAA,IAAa,CAAA;AAIb,MAAA,MAAM,iBAAA,GAAoB,SAAA;AAE1B,MAAA,MAAM,KAAA,GAAQ,MAAM,oBAAA,CAAqB,IAAA,EAAM,QAAQ,iBAAiB,CAAA;AACxE,MAAA,IAAI,QAAA,IAAY,KAAA,EAAO,OAAO,KAAA,CAAM,MAAA;AAEpC,MAAA,MAAM,QAAQ,kBAAA,CAAmB,IAAA,EAAM,KAAA,CAAM,KAAA,EAAO,KAAK,QAAQ,CAAA;AAEjE,MAAA,IAAI,MAAA;AACJ,MAAA,IAAI;AAEF,QAAA,MAAA,GAAS,MAAM,cAAc,IAAA,EAAM,KAAA,EAAO,KAAK,MAAA,EAAQ,KAAA,CAAM,UAAU,SAAS,CAAA;AAAA,MAClF,SAAS,KAAA,EAAO;AAId,QAAA,MAAM,qBAAA,CAAsB,IAAA,EAAM,KAAA,EAAO,KAAA,EAAO,iBAAiB,CAAA;AACjE,QAAA,MAAM,KAAA;AAAA,MACR;AACA,MAAA,OAAO,uBAAA,CAAwB,IAAA,EAAM,KAAA,EAAO,MAAA,EAAQ,iBAAiB,CAAA;AAAA,IACvE;AAAA,GACF;AAGA,EAAA,MAAA,CAAO,cAAA,CAAe,MAAM,mBAAA,EAAqB;AAAA,IAC/C,KAAA,GAAQ,CAAC,KAAA,KAAgC;AACvC,MAAA,SAAA,GAAY,KAAA;AAAA,IACd,CAAA,CAAA;AAAA,IACA,UAAA,EAAY;AAAA,GACb,CAAA;AAED,EAAA,OAAO,IAAA;AACT;AAGO,IAAM,WAAN,MAAe;AAAA,EACZ,WAAA,GAAc;AAAA,EAAC;AAAA,EACvB,OAAO,MAAA,CAAO,IAAA,EAAoB,WAAA,GAAc,CAAA,EAAe;AAC7D,IAAA,OAAO,cAAA,CAAe,MAAM,WAAW,CAAA;AAAA,EACzC;AACF","file":"index.js","sourcesContent":["/**\n * AgentMailbox — per-agent inbox for A2A communication (T20.1, ADR D453).\n *\n * Wraps MessageBus registration with a convenient API for sending,\n * receiving, and requesting messages.\n *\n * @public\n */\n\nimport type { MessageBus, RequestOptions } from \"./message-bus.js\";\nimport type { A2AMessage, MessageHandler } from \"./types.js\";\n\nexport class AgentMailbox {\n readonly agentId: string;\n private readonly _bus: MessageBus;\n private _handler: MessageHandler | null = null;\n\n constructor(agentId: string, bus: MessageBus) {\n this.agentId = agentId;\n this._bus = bus;\n this._bus.register(agentId, (msg) => this._dispatch(msg));\n }\n\n onMessage(handler: MessageHandler): void {\n this._handler = handler;\n }\n\n async send(to: string, partial: { type: string; payload: unknown }): Promise<void> {\n return this._bus.send(this.agentId, to, partial);\n }\n\n async request(\n to: string,\n partial: { type: string; payload: unknown },\n opts?: RequestOptions,\n ): Promise<unknown> {\n return this._bus.request(this.agentId, to, partial, opts);\n }\n\n dispose(): void {\n this._bus.unregister(this.agentId);\n this._handler = null;\n }\n\n private _dispatch(msg: A2AMessage): unknown {\n if (this._handler) {\n return this._handler(msg);\n }\n }\n}\n","/**\n * MessageBus — in-process typed message router for A2A (T20.1, ADR D453).\n *\n * Routes messages between agents by ID. Supports fire-and-forget (send)\n * and request/response (request with timeout).\n *\n * @public\n */\n\nimport type { A2AMessage, MessageHandler } from \"./types.js\";\n\nexport interface RequestOptions {\n timeoutMs?: number;\n}\n\nexport class MessageBus {\n private readonly _handlers = new Map<string, MessageHandler>();\n\n register(agentId: string, handler: MessageHandler): void {\n this._handlers.set(agentId, handler);\n }\n\n unregister(agentId: string): void {\n this._handlers.delete(agentId);\n }\n\n async send(from: string, to: string, partial: { type: string; payload: unknown }): Promise<void> {\n const handler = this._handlers.get(to);\n if (!handler) {\n throw new Error(`Agent \"${to}\" not registered on MessageBus`);\n }\n const message: A2AMessage = {\n ...partial,\n from,\n to,\n timestamp: Date.now(),\n // SE3 — provenance projection of the sender address (thin view over `from`).\n origin: { kind: \"peer\", from },\n };\n // Fire-and-forget: invoke handler but don't await result\n handler(message);\n }\n\n async request(\n from: string,\n to: string,\n partial: { type: string; payload: unknown },\n opts?: RequestOptions,\n ): Promise<unknown> {\n const handler = this._handlers.get(to);\n if (!handler) {\n throw new Error(`Agent \"${to}\" not registered on MessageBus`);\n }\n const timeoutMs = opts?.timeoutMs ?? 30_000;\n const message: A2AMessage = {\n ...partial,\n from,\n to,\n timestamp: Date.now(),\n // SE3 — provenance projection of the sender address (thin view over `from`).\n origin: { kind: \"peer\", from },\n };\n // Hold the timer so it can be cleared once the race settles — otherwise a\n // successful request leaks a live `setTimeout` that keeps the Node event loop\n // alive (the process hangs after the reply). Cleared in `finally`.\n let timer: ReturnType<typeof setTimeout> | undefined;\n try {\n return await Promise.race([\n Promise.resolve(handler(message)),\n new Promise((_, reject) => {\n timer = setTimeout(\n () =>\n reject(new Error(`A2A request timeout: ${to} did not respond within ${timeoutMs}ms`)),\n timeoutMs,\n );\n }),\n ]);\n } finally {\n if (timer !== undefined) clearTimeout(timer);\n }\n }\n\n has(agentId: string): boolean {\n return this._handlers.has(agentId);\n }\n\n listAgents(): string[] {\n return [...this._handlers.keys()];\n }\n}\n","/**\n * Internal DI seam for the public `Agent` facade.\n *\n * Several internal subsystems (`LocalAgent.runUntil`/`fork`, eval, scorers,\n * cron) need to invoke `Agent.create`/`prompt`/`get`/`resume`/`batch`. A direct\n * `import { Agent }` would invert the public-api -> internal dependency\n * direction (and `agent.ts` already imports much of `internal/`). This module\n * is the inversion seam: `agent.ts` registers the facade at module-init time;\n * internal consumers read it on-demand via `getAgentFacade()`. The\n * `internal-must-not-import-facade` dependency-cruiser rule enforces that no\n * `internal/*` module bypasses this seam with a direct facade import.\n *\n * Throws if accessed before registration — should never happen because\n * `agent.ts` evaluation always precedes any internal call (the consumer must\n * obtain a handle from the `Agent` facade first).\n *\n * @internal\n */\n\nimport type { AgentOptions, SDKAgent, SDKAgentInfo } from \"../../../types/agent.js\";\nimport type { BatchItem, BatchOptions, BatchResult } from \"../../../types/batch.js\";\nimport type { RunResult } from \"../../../types/run.js\";\n\n/**\n * The subset of the public `Agent` static surface that internal subsystems\n * consume through the inversion seam. Each member mirrors the matching\n * `Agent.*` signature so registration is a thin pass-through.\n *\n * @internal\n */\nexport interface AgentFacadePort {\n create: (options: AgentOptions) => Promise<SDKAgent>;\n delete: (agentId: string) => Promise<void>;\n prompt: (message: string, options: AgentOptions) => Promise<RunResult>;\n get: (agentId: string) => Promise<SDKAgentInfo>;\n resume: (agentId: string, options?: Partial<AgentOptions>) => Promise<SDKAgent>;\n batch: (\n prompts: ReadonlyArray<string | BatchItem>,\n options: BatchOptions,\n ) => Promise<BatchResult[]>;\n}\n\n/**\n * The registration slot lives on `globalThis` under a `Symbol.for` key — NOT a module-level `let` —\n * so it is a **process-wide singleton** shared by every copy of this module. `tsup` builds each public\n * entry (`.`, `./a2a`, `./cron`, `./eval`, …) with `splitting: false`, which INLINES this module once\n * per entry; a module-level `let` would give each bundled copy its own `registered` slot, and a\n * subagent invoked through `./a2a` would read a copy that `agent.ts` (in the `.` entry) never set —\n * the classic duplicated-singleton hazard (see issue: a2a \"Agent facade not registered\"). `Symbol.for`\n * (global symbol registry) + the one `globalThis` object guarantees all copies read/write ONE slot.\n */\nconst FACADE_KEY: unique symbol = Symbol.for(\n \"theokit.internal.runtime.agentFacade\",\n) as typeof FACADE_KEY;\n\ntype FacadeHost = { [FACADE_KEY]?: AgentFacadePort };\n\n/**\n * Registered by `agent.ts` at module-init time. Idempotent: re-registration\n * replaces the previous reference (useful for tests that swap implementations).\n *\n * @internal\n */\nexport function setAgentFacade(facade: AgentFacadePort): void {\n (globalThis as unknown as FacadeHost)[FACADE_KEY] = facade;\n}\n\n/**\n * Resolve the registered `Agent` facade for internal subsystems.\n *\n * @internal\n */\nexport function getAgentFacade(): AgentFacadePort {\n const registered = (globalThis as unknown as FacadeHost)[FACADE_KEY];\n if (registered === undefined) {\n throw new Error(\n \"internal: Agent facade not registered. The `agent.ts` module must be loaded before internal subsystems (LocalAgent.runUntil/fork, eval, scorers, cron) invoke it.\",\n );\n }\n return registered;\n}\n","/**\n * Subagent delegation — declarative child agent invocable as a tool.\n *\n * Per ADR D2: `defineSubAgent(spec)` returns a `CustomTool` that, when\n * invoked by the LLM, creates a child agent and sends the input as a\n * message. EC-2: delegation depth tracked to prevent infinite recursion.\n *\n * SE10 — the handler forwards the parent run's `AbortSignal` to the child.\n * SE11 — optional `onDelegationStart` / `onDelegationComplete` lifecycle hooks\n * let the caller reject, rewrite, observe, or annotate a delegation.\n *\n * @public\n */\n\nimport { z } from \"zod\";\nimport type { Plugin } from \"../internal/plugins/types.js\";\nimport { getAgentFacade } from \"../internal/runtime/registry/agent-factory-registry.js\";\nimport type {\n AgentDefinition,\n AgentOptions,\n CustomTool,\n ToolContextMessage,\n} from \"../types/agent.js\";\nimport type { ModelSelection } from \"../types/agent-prims.js\";\nimport type { Run } from \"../types/run.js\";\n\n/**\n * Credentials a parent agent hands down to its subagent tools so the child\n * inherits the parent's auth (and, absent an explicit `spec.model`, its model).\n * @internal\n */\nexport interface InheritedCredentials {\n readonly apiKey?: string;\n readonly model?: ModelSelection;\n /**\n * #55 — the parent's code-registered plugins (e.g. a `PermissionPlugin`) handed\n * down so the child runs under the SAME policy. Without this, a delegated child's\n * inner tool calls escape the parent's argument-level permission gate. First-party\n * delegation path only — never exposed to third-party tool `ctx`.\n */\n readonly plugins?: readonly Plugin[];\n}\n\n/**\n * Private per-tool setter installed on subagent tools. Kept off the public\n * `CustomTool` shape (and off every tool handler's `ctx`) so the parent's API\n * key never reaches third-party tool code — only the SDK's own delegation path.\n */\n// `Symbol.for` (global registry), NOT `Symbol()`: with `tsup splitting: false` each public entry\n// (`.`, `./a2a`) inlines its own copy of this module. A unique `Symbol()` would give each copy a\n// DIFFERENT sink key — the local runtime (bundled in `.`) calls `inheritSubAgentCredentials` with the\n// `.`-copy key, but a `SubAgent` created via `@theokit/sdk/a2a` installed its sink under the `/a2a`-copy\n// key, so the lookup missed and the child inherited NO `apiKey` (→ `provider_unresolved`, \"(no response)\").\n// `Symbol.for` makes both copies agree on ONE key. (Same duplicated-singleton class as the facade fix, #142.)\nconst INHERIT_CREDENTIALS = Symbol.for(\"theokit.subagent.inheritCredentials\");\n\ntype CredentialSink = (creds: InheritedCredentials) => void;\n\n/**\n * Called by the local runtime for every tool in a run: if the tool is a\n * subagent, its child agent inherits the parent's `apiKey`/`model`. A no-op for\n * any other tool (third-party tools never receive the parent's credentials).\n * @internal\n */\nexport function inheritSubAgentCredentials(tool: CustomTool, creds: InheritedCredentials): void {\n const sink = (tool as { [INHERIT_CREDENTIALS]?: CredentialSink })[INHERIT_CREDENTIALS];\n if (typeof sink === \"function\") sink(creds);\n}\n\n/** Arguments passed to {@link SubAgentSpec.messageFilter} (SE12). */\nexport interface MessageFilterArgs {\n /** The supervisor transcript (read-only text projection) available to this delegation. */\n messages: readonly ToolContextMessage[];\n /** The prompt about to be delegated (after any `onDelegationStart` rewrite). */\n input: string;\n /** The subagent's name. */\n name: string;\n}\n\n/** Context passed to {@link SubAgentSpec.onDelegationStart} before the child runs. */\nexport interface DelegationStartContext {\n input: string;\n name: string;\n /**\n * SE15 — 1-based count of times THIS subagent tool has been invoked (a\n * per-`defineSubAgent`-instance counter). Incremented before this hook runs;\n * a rejected delegation still counts. Enables reject-after-N patterns.\n */\n iteration: number;\n}\n\n/**\n * Decision returned from {@link SubAgentSpec.onDelegationStart}. Discriminated on\n * `proceed` so a rejection (`proceed: false` + `rejectionReason`) and an approval\n * (`modifiedInput`) cannot be mixed into one nonsensical object.\n */\nexport type DelegationStartDecision =\n | { proceed: false; rejectionReason?: string }\n | {\n proceed?: true;\n modifiedInput?: string;\n /** SE13 — cap the child's iteration count (forwarded as `SendOptions.maxIterations`). */\n modifiedMaxSteps?: number;\n };\n\n/** Context passed to {@link SubAgentSpec.onDelegationComplete} after the child settles. */\nexport interface DelegationCompleteContext {\n input: string;\n name: string;\n /** The child's text result (present on success). */\n result?: string;\n /** The error the child threw (present on failure); the error is still re-thrown. */\n error?: unknown;\n /** SE15 — the same 1-based iteration this delegation's `onDelegationStart` saw. */\n iteration: number;\n}\n\n/**\n * The return of a delegation hook: a decision, a promise of one, or nothing —\n * `void` lets a side-effect-only callback (`(ctx) => { log(ctx) }`) type-check,\n * which is the common case (mirrors a peer framework's `async ctx => { ... }` hooks).\n */\n// biome-ignore lint/suspicious/noConfusingVoidType: `void` is the idiomatic return for an optional-return callback; the rule false-positives on callback return unions.\ntype DelegationHookResult<T> = T | void | Promise<T | void>;\n\n/** Decision returned from {@link SubAgentSpec.onDelegationComplete}. */\nexport interface DelegationCompleteDecision {\n /** Appended to the child's result string. */\n feedback?: string;\n}\n\nexport interface SubAgentSpec {\n name: string;\n description: string;\n instructions: string;\n /**\n * A bare id string (back-compat) OR a full {@link ModelSelection} carrying\n * `params` (e.g. `[{ id: \"thinking\", value: \"low\" }]` for reasoning effort). The\n * object form is required for per-subagent reasoning effort to survive to the child\n * — the pre-M33 path took only `.id` and dropped params.\n */\n model?: string | ModelSelection;\n tools?: CustomTool[];\n /** Per-subagent shell sandbox toggle (M33). `true` ⇒ child `local.sandboxOptions.enabled`. */\n sandbox?: boolean;\n maxDelegationDepth?: number;\n /**\n * SE11 — called before the supervisor delegates. Return `{ proceed: false }`\n * to reject (the child never runs and `rejectionReason` becomes the tool\n * result), or `{ modifiedInput }` to rewrite the delegated prompt. A throwing\n * hook surfaces (never silently swallowed).\n */\n onDelegationStart?: (\n ctx: DelegationStartContext,\n ) => DelegationHookResult<DelegationStartDecision>;\n /**\n * SE11 — called after the delegation settles. On success `ctx.result` is set\n * and an optional `{ feedback }` is appended to it. On failure `ctx.error` is\n * set and the original error is ALWAYS re-thrown after this hook runs — a throw\n * from this hook on the error path is suppressed so it cannot mask the\n * delegation's real failure (on the success path a throw does propagate).\n */\n onDelegationComplete?: (\n ctx: DelegationCompleteContext,\n ) => DelegationHookResult<DelegationCompleteDecision>;\n /**\n * SE12 — opt-in parent-context forwarding. When set, the supervisor transcript\n * (`ctx.messages`, a read-only text projection) is passed to this filter and the\n * returned subset is forwarded to the child as a role-tagged context preamble\n * prepended to the delegated input. When ABSENT the child runs input-only —\n * memory isolation stays the default. A filter returning `[]` forwards nothing.\n * A throwing filter propagates (fail-fast, never swallowed — same contract as\n * `onDelegationStart`); the delegation surfaces as a tool error.\n */\n messageFilter?: (args: MessageFilterArgs) => readonly ToolContextMessage[];\n /**\n * SE14 — opt-in subagent result-context control. When `true`, the child's\n * completed tool-call results (name + result) are appended to the delegation\n * payload returned to the supervisor, inside a `<subagent-tool-results>` block.\n * When absent/`false` the delegation returns the child's final text only —\n * text-only stays the default (a peer framework's scoped posture). See ADR 0006.\n */\n includeToolResults?: boolean;\n}\n\nexport class MaxDelegationDepthError extends Error {\n readonly code = \"max_delegation_depth\" as const;\n constructor(\n public readonly currentDepth: number,\n public readonly maxDepth: number,\n ) {\n super(`Max delegation depth ${maxDepth} exceeded (current: ${currentDepth})`);\n this.name = \"MaxDelegationDepthError\";\n }\n}\n\n/**\n * Run the `onDelegationStart` hook; returns either a rejection or the (possibly\n * rewritten) input plus the optional SE13 `maxSteps` cap.\n */\nasync function applyDelegationStart(\n spec: SubAgentSpec,\n input: string,\n iteration: number,\n): Promise<{ reject: string } | { input: string; maxSteps?: number }> {\n if (spec.onDelegationStart === undefined) return { input };\n const decision = await spec.onDelegationStart({ input, name: spec.name, iteration });\n if (decision === undefined) return { input };\n if (decision.proceed === false)\n return { reject: decision.rejectionReason ?? \"(delegation rejected)\" };\n return {\n input: decision.modifiedInput ?? input,\n ...(decision.modifiedMaxSteps !== undefined ? { maxSteps: decision.modifiedMaxSteps } : {}),\n };\n}\n\n/**\n * SE14 — replay the child run's stream (a safe post-`wait()` idiom — the run buffers\n * events, `stream()` replays them) and collect every completed tool-call result into\n * a delimited block. Returns `\"\"` when the child ran no completed tool calls. See ADR 0006.\n */\nasync function collectChildToolResults(run: Run): Promise<string> {\n const lines: string[] = [];\n for await (const event of run.stream()) {\n if (event.type === \"tool_call\" && event.status === \"completed\") {\n const rendered =\n typeof event.result === \"string\" ? event.result : JSON.stringify(event.result ?? null);\n lines.push(`${event.name}: ${rendered}`);\n }\n }\n if (lines.length === 0) return \"\";\n return `\\n\\n<subagent-tool-results>\\n${lines.join(\"\\n\")}\\n</subagent-tool-results>`;\n}\n\n/**\n * Create the transient child agent and send the input, composing every forwarded\n * `SendOptions` onto ONE `send` call — SE10 `signal` + SE13 `maxIterations`. Absent\n * every option ⇒ the pre-SE10 single-arg `send(input)` shape. SE14 — when\n * `includeToolResults` is set, append the child's completed tool results. Dispose in `finally`.\n */\n/**\n * Build the child agent's `Agent.create` options: the child inherits the parent's\n * apiKey (else `Agent.create` throws \"Missing API key\"), its model (unless the spec\n * overrides it), and — #55 — the parent's plugins (permission gate/guards) so the\n * child's inner tool calls run under the same policy.\n */\nexport function buildChildCreateOptions(\n spec: SubAgentSpec,\n inherited: InheritedCredentials | undefined,\n): AgentOptions {\n // M33 — carry the WHOLE model (a bare id becomes `{ id }`; a ModelSelection with\n // `params` keeps its reasoning effort). The pre-M33 path wrapped `spec.model` as\n // `{ id: spec.model }`, which only worked because spec.model was a string and\n // silently dropped reasoning params.\n const model: string | ModelSelection | undefined =\n spec.model !== undefined\n ? typeof spec.model === \"string\"\n ? { id: spec.model }\n : spec.model\n : inherited?.model;\n return {\n ...(inherited?.apiKey !== undefined ? { apiKey: inherited.apiKey } : {}),\n ...(model !== undefined ? { model } : {}),\n ...(spec.sandbox === true ? { local: { sandboxOptions: { enabled: true } } } : {}),\n ...(inherited?.plugins !== undefined ? { plugins: inherited.plugins } : {}),\n systemPrompt: spec.instructions,\n tools: spec.tools ?? [],\n };\n}\n\nasync function runChildAgent(\n spec: SubAgentSpec,\n input: string,\n signal: AbortSignal | undefined,\n maxSteps: number | undefined,\n inherited: InheritedCredentials | undefined,\n): Promise<string> {\n // SE45 cycle 3 — use the registered Agent facade via the DIP seam\n // (agent-factory-registry) instead of a dynamic `import(\"../agent.js\")`.\n // This removes the last madge cycle (a2a/subagent -> agent -> ... -> real-local-run-tools\n // -> a2a/subagent): the facade registers itself at module-init via setAgentFacade,\n // so subagent depends only on the registry port, never on the facade module.\n const agent = await getAgentFacade().create(buildChildCreateOptions(spec, inherited));\n try {\n const sendOptions: {\n signal?: AbortSignal;\n maxIterations?: number;\n origin?: import(\"../types/run.js\").MessageOrigin;\n } = {\n ...(signal !== undefined ? { signal } : {}),\n ...(maxSteps !== undefined ? { maxIterations: maxSteps } : {}),\n // SE3 — a delegated child's turn is initiated by the coordinating parent.\n origin: { kind: \"coordinator\" },\n };\n const run = await agent.send(input, sendOptions);\n const result = await run.wait();\n // Fail-fast, don't swallow (Rule 8): a child that ended in error must surface — otherwise a real\n // failure (e.g. `provider_unresolved`) is hidden behind \"(no response)\" and the parent loops on it.\n if (result.status === \"error\") {\n const cause = (result as { error?: { message?: string } }).error;\n throw new Error(\n `subagent \"${spec.name}\" run failed: ${cause?.message ?? \"unknown error\"}`,\n cause !== undefined ? { cause } : undefined,\n );\n }\n const text = result.result ?? \"(no response)\";\n // SE14 — text-only by default; opt-in appends the child's tool results.\n return spec.includeToolResults === true ? text + (await collectChildToolResults(run)) : text;\n } finally {\n agent.dispose();\n }\n}\n\n/**\n * Best-effort error-path notification: run `onDelegationComplete` with the child's\n * error so the caller can observe the failure. The observer's own throw (sync or\n * async) is suppressed here so it cannot mask the delegation's real error, which the\n * handler re-throws next.\n */\nasync function notifyDelegationError(\n spec: SubAgentSpec,\n input: string,\n error: unknown,\n iteration: number,\n): Promise<void> {\n if (spec.onDelegationComplete === undefined) return;\n try {\n await spec.onDelegationComplete({ input, name: spec.name, error, iteration });\n } catch {\n // Subordinate to `error`; the child's real cause wins.\n }\n}\n\n/**\n * SE12 — apply `messageFilter` (if set) and prepend the filtered supervisor\n * transcript to the delegated input as a role-tagged context preamble. Absent\n * filter OR no messages OR an empty filtered subset ⇒ the original input\n * (isolation-by-default preserved).\n */\nfunction applyMessageFilter(\n spec: SubAgentSpec,\n input: string,\n messages: readonly ToolContextMessage[] | undefined,\n): string {\n if (spec.messageFilter === undefined || messages === undefined) return input;\n const filtered = spec.messageFilter({ messages, input, name: spec.name });\n if (filtered.length === 0) return input;\n const preamble = filtered.map((m) => `${m.role}: ${m.content}`).join(\"\\n\");\n return `Prior conversation:\\n${preamble}\\n\\nTask:\\n${input}`;\n}\n\n/** Run the success-path `onDelegationComplete` hook; appends its `feedback` to the result. */\nasync function applyDelegationComplete(\n spec: SubAgentSpec,\n input: string,\n result: string,\n iteration: number,\n): Promise<string> {\n if (spec.onDelegationComplete === undefined) return result;\n const completion = await spec.onDelegationComplete({ input, name: spec.name, result, iteration });\n return completion?.feedback !== undefined ? result + completion.feedback : result;\n}\n\nfunction defineSubAgent(spec: SubAgentSpec, _parentDepth = 0): CustomTool {\n const currentDepth = _parentDepth + 1;\n const maxDepth = spec.maxDelegationDepth ?? 3;\n\n if (currentDepth > maxDepth) {\n throw new MaxDelegationDepthError(currentDepth, maxDepth);\n }\n\n // Zod for RUNTIME validation of the tool_use input …\n const inputZod = z.object({\n input: z.string().describe(\"Task for the subagent\"),\n });\n // … and a real Draft-7 JSON Schema for the LLM. `CustomTool.inputSchema` is sent\n // to the model verbatim; a raw Zod object would serialize to garbage, so the\n // model emits malformed input that fails `inputZod.parse` and the delegation\n // never runs (the previous bug — the schema and the validator are now distinct).\n const inputSchema: Record<string, unknown> = {\n type: \"object\",\n properties: {\n input: { type: \"string\", description: \"Task for the subagent\" },\n },\n required: [\"input\"],\n additionalProperties: false,\n };\n\n // SE15 — per-instance delegation counter, surfaced as `iteration` on the hook\n // contexts. Incremented once per handler invocation before onDelegationStart.\n let iteration = 0;\n\n // Credentials handed down by the parent runtime (see `inheritSubAgentCredentials`).\n let inherited: InheritedCredentials | undefined;\n\n const tool: CustomTool = {\n name: spec.name,\n description: spec.description,\n inputSchema,\n handler: async (\n rawInput: Record<string, unknown>,\n ctx?: {\n signal?: AbortSignal;\n context?: unknown;\n messages?: readonly ToolContextMessage[];\n },\n ): Promise<string> => {\n const { input: parsed } = inputZod.parse(rawInput);\n iteration += 1; // SE15 — before onDelegationStart; a rejected delegation still counts.\n // Pin THIS invocation's iteration before any await so a concurrent invocation\n // bumping the shared counter cannot change the value onDelegationComplete /\n // notifyDelegationError observe — they see the same iteration onDelegationStart did.\n const capturedIteration = iteration;\n\n const start = await applyDelegationStart(spec, parsed, capturedIteration);\n if (\"reject\" in start) return start.reject;\n // SE12 — opt-in: forward the filtered supervisor transcript as a preamble.\n const input = applyMessageFilter(spec, start.input, ctx?.messages);\n\n let result: string;\n try {\n // SE13 — apply the optional onDelegationStart maxSteps cap on the child send.\n result = await runChildAgent(spec, input, ctx?.signal, start.maxSteps, inherited);\n } catch (error) {\n // SE11 — notify the completion hook of the failure (best-effort observer),\n // then re-throw the ORIGINAL error (Rule 8: never swallow the delegation's\n // own failure).\n await notifyDelegationError(spec, input, error, capturedIteration);\n throw error;\n }\n return applyDelegationComplete(spec, input, result, capturedIteration);\n },\n };\n\n // Install the private credential sink (off the public shape + off every ctx).\n Object.defineProperty(tool, INHERIT_CREDENTIALS, {\n value: ((creds: InheritedCredentials) => {\n inherited = creds;\n }) satisfies CredentialSink,\n enumerable: false,\n });\n\n return tool;\n}\n\n/** SE36 — `SubAgent.create` replaces `defineSubAgent` (ADR 0015). @public */\nexport class SubAgent {\n private constructor() {}\n static create(spec: SubAgentSpec, parentDepth = 0): CustomTool {\n return defineSubAgent(spec, parentDepth);\n }\n}\n\n/**\n * Convert a parent's declarative `agents` map ({@link AgentDefinition} per key)\n * into delegation tools for the LOCAL runtime — the counterpart of the\n * cloud/fixture subagent wiring. Each child inherits the parent's `apiKey`/model\n * via {@link inheritSubAgentCredentials}; `def.model` overrides the model\n * (`\"inherit\"` keeps the parent's), and `def.tools` scopes the child to that\n * subset of the parent's tools (absent → the parent's full toolset, per the\n * `AgentDefinition.tools` contract).\n *\n * M33 — per-subagent `model` (with reasoning `params`) and `sandbox` are now wired\n * into local delegation: each is carried onto the {@link SubAgentSpec} and applied to\n * the child in {@link buildChildCreateOptions}. `\"inherit\"` (or an absent field) keeps\n * the parent's value. Per-subagent `mcp` is rejected at load (see subagents-loader) —\n * resolving server names→config on the local path is a follow-up.\n *\n * @internal\n */\nexport function subAgentToolsFromDefinitions(\n agents: Record<string, AgentDefinition>,\n parentTools: readonly CustomTool[],\n): CustomTool[] {\n return Object.entries(agents).map(([name, def]) => {\n const whitelist =\n Array.isArray(def.tools) && def.tools.length > 0 ? new Set(def.tools) : undefined;\n const childTools = whitelist ? parentTools.filter((t) => whitelist.has(t.name)) : parentTools;\n return defineSubAgent({\n name,\n description: def.description,\n instructions: def.prompt,\n // Carry the FULL ModelSelection (id + reasoning params), not just the id, so\n // per-subagent reasoning effort survives to buildChildCreateOptions.\n ...(def.model !== undefined && def.model !== \"inherit\" ? { model: def.model } : {}),\n ...(def.sandbox !== undefined ? { sandbox: def.sandbox } : {}),\n tools: [...childTools],\n });\n });\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/a2a/agent-mailbox.ts","../../src/a2a/message-bus.ts","../../src/internal/runtime/registry/agent-factory-registry.ts","../../src/a2a/subagent.ts"],"names":[],"mappings":";;;AAYO,IAAM,eAAN,MAAmB;AAAA,EACf,OAAA;AAAA,EACQ,IAAA;AAAA,EACT,QAAA,GAAkC,IAAA;AAAA,EAE1C,WAAA,CAAY,SAAiB,GAAA,EAAiB;AAC5C,IAAA,IAAA,CAAK,OAAA,GAAU,OAAA;AACf,IAAA,IAAA,CAAK,IAAA,GAAO,GAAA;AACZ,IAAA,IAAA,CAAK,IAAA,CAAK,SAAS,OAAA,EAAS,CAAC,QAAQ,IAAA,CAAK,SAAA,CAAU,GAAG,CAAC,CAAA;AAAA,EAC1D;AAAA,EAEA,UAAU,OAAA,EAA+B;AACvC,IAAA,IAAA,CAAK,QAAA,GAAW,OAAA;AAAA,EAClB;AAAA,EAEA,MAAM,IAAA,CAAK,EAAA,EAAY,OAAA,EAA4D;AACjF,IAAA,OAAO,KAAK,IAAA,CAAK,IAAA,CAAK,IAAA,CAAK,OAAA,EAAS,IAAI,OAAO,CAAA;AAAA,EACjD;AAAA,EAEA,MAAM,OAAA,CACJ,EAAA,EACA,OAAA,EACA,IAAA,EACkB;AAClB,IAAA,OAAO,KAAK,IAAA,CAAK,OAAA,CAAQ,KAAK,OAAA,EAAS,EAAA,EAAI,SAAS,IAAI,CAAA;AAAA,EAC1D;AAAA,EAEA,OAAA,GAAgB;AACd,IAAA,IAAA,CAAK,IAAA,CAAK,UAAA,CAAW,IAAA,CAAK,OAAO,CAAA;AACjC,IAAA,IAAA,CAAK,QAAA,GAAW,IAAA;AAAA,EAClB;AAAA,EAEQ,UAAU,GAAA,EAA0B;AAC1C,IAAA,IAAI,KAAK,QAAA,EAAU;AACjB,MAAA,OAAO,IAAA,CAAK,SAAS,GAAG,CAAA;AAAA,IAC1B;AAAA,EACF;AACF;;;AClCO,IAAM,aAAN,MAAiB;AAAA,EACL,SAAA,uBAAgB,GAAA,EAA4B;AAAA,EAE7D,QAAA,CAAS,SAAiB,OAAA,EAA+B;AACvD,IAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAA,EAAS,OAAO,CAAA;AAAA,EACrC;AAAA,EAEA,WAAW,OAAA,EAAuB;AAChC,IAAA,IAAA,CAAK,SAAA,CAAU,OAAO,OAAO,CAAA;AAAA,EAC/B;AAAA,EAEA,MAAM,IAAA,CAAK,IAAA,EAAc,EAAA,EAAY,OAAA,EAA4D;AAC/F,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,EAAE,CAAA;AACrC,IAAA,IAAI,CAAC,OAAA,EAAS;AACZ,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,OAAA,EAAU,EAAE,CAAA,8BAAA,CAAgC,CAAA;AAAA,IAC9D;AACA,IAAA,MAAM,OAAA,GAAsB;AAAA,MAC1B,GAAG,OAAA;AAAA,MACH,IAAA;AAAA,MACA,EAAA;AAAA,MACA,SAAA,EAAW,KAAK,GAAA,EAAI;AAAA;AAAA,MAEpB,MAAA,EAAQ,EAAE,IAAA,EAAM,MAAA,EAAQ,IAAA;AAAK,KAC/B;AAEA,IAAA,OAAA,CAAQ,OAAO,CAAA;AAAA,EACjB;AAAA,EAEA,MAAM,OAAA,CACJ,IAAA,EACA,EAAA,EACA,SACA,IAAA,EACkB;AAClB,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,EAAE,CAAA;AACrC,IAAA,IAAI,CAAC,OAAA,EAAS;AACZ,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,OAAA,EAAU,EAAE,CAAA,8BAAA,CAAgC,CAAA;AAAA,IAC9D;AACA,IAAA,MAAM,SAAA,GAAY,MAAM,SAAA,IAAa,GAAA;AACrC,IAAA,MAAM,OAAA,GAAsB;AAAA,MAC1B,GAAG,OAAA;AAAA,MACH,IAAA;AAAA,MACA,EAAA;AAAA,MACA,SAAA,EAAW,KAAK,GAAA,EAAI;AAAA;AAAA,MAEpB,MAAA,EAAQ,EAAE,IAAA,EAAM,MAAA,EAAQ,IAAA;AAAK,KAC/B;AAIA,IAAA,IAAI,KAAA;AACJ,IAAA,IAAI;AACF,MAAA,OAAO,MAAM,QAAQ,IAAA,CAAK;AAAA,QACxB,OAAA,CAAQ,OAAA,CAAQ,OAAA,CAAQ,OAAO,CAAC,CAAA;AAAA,QAChC,IAAI,OAAA,CAAQ,CAAC,CAAA,EAAG,MAAA,KAAW;AACzB,UAAA,KAAA,GAAQ,UAAA;AAAA,YACN,MACE,OAAO,IAAI,KAAA,CAAM,wBAAwB,EAAE,CAAA,wBAAA,EAA2B,SAAS,CAAA,EAAA,CAAI,CAAC,CAAA;AAAA,YACtF;AAAA,WACF;AAAA,QACF,CAAC;AAAA,OACF,CAAA;AAAA,IACH,CAAA,SAAE;AACA,MAAA,IAAI,KAAA,KAAU,MAAA,EAAW,YAAA,CAAa,KAAK,CAAA;AAAA,IAC7C;AAAA,EACF;AAAA,EAEA,IAAI,OAAA,EAA0B;AAC5B,IAAA,OAAO,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAO,CAAA;AAAA,EACnC;AAAA,EAEA,UAAA,GAAuB;AACrB,IAAA,OAAO,CAAC,GAAG,IAAA,CAAK,SAAA,CAAU,MAAM,CAAA;AAAA,EAClC;AACF;;;ACtCA,IAAM,6BAA4B,MAAA,CAAO,GAAA;AAAA,EACvC;AACF,CAAA;AAmBO,SAAS,cAAA,GAAkC;AAChD,EAAA,MAAM,UAAA,GAAc,WAAqC,UAAU,CAAA;AACnE,EAAA,IAAI,eAAe,MAAA,EAAW;AAC5B,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AACA,EAAA,OAAO,UAAA;AACT;;;ACnBA,IAAM,mBAAA,mBAAsB,MAAA,CAAO,GAAA,CAAI,qCAAqC,CAAA;AAmIrE,IAAM,uBAAA,GAAN,cAAsC,KAAA,CAAM;AAAA,EAEjD,WAAA,CACkB,cACA,QAAA,EAChB;AACA,IAAA,KAAA,CAAM,CAAA,qBAAA,EAAwB,QAAQ,CAAA,oBAAA,EAAuB,YAAY,CAAA,CAAA,CAAG,CAAA;AAH5D,IAAA,IAAA,CAAA,YAAA,GAAA,YAAA;AACA,IAAA,IAAA,CAAA,QAAA,GAAA,QAAA;AAGhB,IAAA,IAAA,CAAK,IAAA,GAAO,yBAAA;AAAA,EACd;AAAA,EALkB,YAAA;AAAA,EACA,QAAA;AAAA,EAHT,IAAA,GAAO,sBAAA;AAQlB;AAMA,eAAe,oBAAA,CACb,IAAA,EACA,KAAA,EACA,SAAA,EACoE;AACpE,EAAA,IAAI,IAAA,CAAK,iBAAA,KAAsB,MAAA,EAAW,OAAO,EAAE,KAAA,EAAM;AACzD,EAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,iBAAA,CAAkB,EAAE,OAAO,IAAA,EAAM,IAAA,CAAK,IAAA,EAAM,SAAA,EAAW,CAAA;AACnF,EAAA,IAAI,QAAA,KAAa,MAAA,EAAW,OAAO,EAAE,KAAA,EAAM;AAC3C,EAAA,IAAI,SAAS,OAAA,KAAY,KAAA;AACvB,IAAA,OAAO,EAAE,MAAA,EAAQ,QAAA,CAAS,eAAA,IAAmB,uBAAA,EAAwB;AACvE,EAAA,OAAO;AAAA,IACL,KAAA,EAAO,SAAS,aAAA,IAAiB,KAAA;AAAA,IACjC,GAAI,SAAS,gBAAA,KAAqB,MAAA,GAAY,EAAE,QAAA,EAAU,QAAA,CAAS,gBAAA,EAAiB,GAAI;AAAC,GAC3F;AACF;AAOA,eAAe,wBAAwB,GAAA,EAA2B;AAChE,EAAA,MAAM,QAAkB,EAAC;AACzB,EAAA,WAAA,MAAiB,KAAA,IAAS,GAAA,CAAI,MAAA,EAAO,EAAG;AACtC,IAAA,IAAI,KAAA,CAAM,IAAA,KAAS,WAAA,IAAe,KAAA,CAAM,WAAW,WAAA,EAAa;AAC9D,MAAA,MAAM,QAAA,GACJ,OAAO,KAAA,CAAM,MAAA,KAAW,QAAA,GAAW,KAAA,CAAM,MAAA,GAAS,IAAA,CAAK,SAAA,CAAU,KAAA,CAAM,MAAA,IAAU,IAAI,CAAA;AACvF,MAAA,KAAA,CAAM,KAAK,CAAA,EAAG,KAAA,CAAM,IAAI,CAAA,EAAA,EAAK,QAAQ,CAAA,CAAE,CAAA;AAAA,IACzC;AAAA,EACF;AACA,EAAA,IAAI,KAAA,CAAM,MAAA,KAAW,CAAA,EAAG,OAAO,EAAA;AAC/B,EAAA,OAAO;;AAAA;AAAA,EAAgC,KAAA,CAAM,IAAA,CAAK,IAAI,CAAC;AAAA,wBAAA,CAAA;AACzD;AAcO,SAAS,uBAAA,CACd,MACA,SAAA,EACc;AAKd,EAAA,MAAM,KAAA,GACJ,IAAA,CAAK,KAAA,KAAU,MAAA,GACX,OAAO,IAAA,CAAK,KAAA,KAAU,QAAA,GACpB,EAAE,IAAI,IAAA,CAAK,KAAA,EAAM,GACjB,IAAA,CAAK,QACP,SAAA,EAAW,KAAA;AAGjB,EAAA,MAAM,OAAA,GAAU,IAAA,CAAK,OAAA,IAAW,SAAA,EAAW,OAAA;AAC3C,EAAA,OAAO;AAAA,IACL,GAAI,WAAW,MAAA,KAAW,MAAA,GAAY,EAAE,MAAA,EAAQ,SAAA,CAAU,MAAA,EAAO,GAAI,EAAC;AAAA,IACtE,GAAI,KAAA,KAAU,MAAA,GAAY,EAAE,KAAA,KAAU,EAAC;AAAA,IACvC,GAAI,OAAA,KAAY,MAAA,GAAY,EAAE,KAAA,EAAO,EAAE,cAAA,EAAgB,EAAE,OAAA,EAAS,OAAA,EAAQ,EAAE,KAAM,EAAC;AAAA,IACnF,GAAI,WAAW,OAAA,KAAY,MAAA,GAAY,EAAE,OAAA,EAAS,SAAA,CAAU,OAAA,EAAQ,GAAI,EAAC;AAAA,IACzE,cAAc,IAAA,CAAK,YAAA;AAAA,IACnB,KAAA,EAAO,IAAA,CAAK,KAAA,IAAS;AAAC,GACxB;AACF;AAEA,eAAe,aAAA,CACb,IAAA,EACA,KAAA,EACA,MAAA,EACA,UACA,SAAA,EACiB;AAMjB,EAAA,MAAM,KAAA,GAAQ,MAAM,cAAA,EAAe,CAAE,OAAO,uBAAA,CAAwB,IAAA,EAAM,SAAS,CAAC,CAAA;AACpF,EAAA,IAAI;AACF,IAAA,MAAM,WAAA,GAIF;AAAA,MACF,GAAI,MAAA,KAAW,KAAA,CAAA,GAAY,EAAE,MAAA,KAAW,EAAC;AAAA,MACzC,GAAI,QAAA,KAAa,KAAA,CAAA,GAAY,EAAE,aAAA,EAAe,QAAA,KAAa,EAAC;AAAA;AAAA,MAE5D,MAAA,EAAQ,EAAE,IAAA,EAAM,aAAA;AAAc,KAChC;AACA,IAAA,MAAM,GAAA,GAAM,MAAM,KAAA,CAAM,IAAA,CAAK,OAAO,WAAW,CAAA;AAC/C,IAAA,MAAM,MAAA,GAAS,MAAM,GAAA,CAAI,IAAA,EAAK;AAG9B,IAAA,IAAI,MAAA,CAAO,WAAW,OAAA,EAAS;AAC7B,MAAA,MAAM,QAAS,MAAA,CAA4C,KAAA;AAC3D,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,aAAa,IAAA,CAAK,IAAI,CAAA,cAAA,EAAiB,KAAA,EAAO,WAAW,eAAe,CAAA,CAAA;AAAA,QACxE,KAAA,KAAU,KAAA,CAAA,GAAY,EAAE,KAAA,EAAM,GAAI,KAAA;AAAA,OACpC;AAAA,IACF;AACA,IAAA,MAAM,IAAA,GAAO,OAAO,MAAA,IAAU,eAAA;AAE9B,IAAA,OAAO,KAAK,kBAAA,KAAuB,IAAA,GAAO,OAAQ,MAAM,uBAAA,CAAwB,GAAG,CAAA,GAAK,IAAA;AAAA,EAC1F,CAAA,SAAE;AACA,IAAA,KAAA,CAAM,OAAA,EAAQ;AAAA,EAChB;AACF;AAQA,eAAe,qBAAA,CACb,IAAA,EACA,KAAA,EACA,KAAA,EACA,SAAA,EACe;AACf,EAAA,IAAI,IAAA,CAAK,yBAAyB,MAAA,EAAW;AAC7C,EAAA,IAAI;AACF,IAAA,MAAM,IAAA,CAAK,qBAAqB,EAAE,KAAA,EAAO,MAAM,IAAA,CAAK,IAAA,EAAM,KAAA,EAAO,SAAA,EAAW,CAAA;AAAA,EAC9E,CAAA,CAAA,MAAQ;AAAA,EAER;AACF;AAQA,SAAS,kBAAA,CACP,IAAA,EACA,KAAA,EACA,QAAA,EACQ;AACR,EAAA,IAAI,IAAA,CAAK,aAAA,KAAkB,MAAA,IAAa,QAAA,KAAa,QAAW,OAAO,KAAA;AACvE,EAAA,MAAM,QAAA,GAAW,KAAK,aAAA,CAAc,EAAE,UAAU,KAAA,EAAO,IAAA,EAAM,IAAA,CAAK,IAAA,EAAM,CAAA;AACxE,EAAA,IAAI,QAAA,CAAS,MAAA,KAAW,CAAA,EAAG,OAAO,KAAA;AAClC,EAAA,MAAM,QAAA,GAAW,QAAA,CAAS,GAAA,CAAI,CAAC,MAAM,CAAA,EAAG,CAAA,CAAE,IAAI,CAAA,EAAA,EAAK,CAAA,CAAE,OAAO,CAAA,CAAE,CAAA,CAAE,KAAK,IAAI,CAAA;AACzE,EAAA,OAAO,CAAA;AAAA,EAAwB,QAAQ;;AAAA;AAAA,EAAc,KAAK,CAAA,CAAA;AAC5D;AAGA,eAAe,uBAAA,CACb,IAAA,EACA,KAAA,EACA,MAAA,EACA,SAAA,EACiB;AACjB,EAAA,IAAI,IAAA,CAAK,oBAAA,KAAyB,MAAA,EAAW,OAAO,MAAA;AACpD,EAAA,MAAM,UAAA,GAAa,MAAM,IAAA,CAAK,oBAAA,CAAqB,EAAE,KAAA,EAAO,IAAA,EAAM,IAAA,CAAK,IAAA,EAAM,MAAA,EAAQ,SAAA,EAAW,CAAA;AAChG,EAAA,OAAO,UAAA,EAAY,QAAA,KAAa,MAAA,GAAY,MAAA,GAAS,WAAW,QAAA,GAAW,MAAA;AAC7E;AAEA,SAAS,cAAA,CAAe,IAAA,EAAoB,YAAA,GAAe,CAAA,EAAe;AACxE,EAAA,MAAM,eAAe,YAAA,GAAe,CAAA;AACpC,EAAA,MAAM,QAAA,GAAW,KAAK,kBAAA,IAAsB,CAAA;AAE5C,EAAA,IAAI,eAAe,QAAA,EAAU;AAC3B,IAAA,MAAM,IAAI,uBAAA,CAAwB,YAAA,EAAc,QAAQ,CAAA;AAAA,EAC1D;AAGA,EAAA,MAAM,QAAA,GAAW,EAAE,MAAA,CAAO;AAAA,IACxB,KAAA,EAAO,CAAA,CAAE,MAAA,EAAO,CAAE,SAAS,uBAAuB;AAAA,GACnD,CAAA;AAKD,EAAA,MAAM,WAAA,GAAuC;AAAA,IAC3C,IAAA,EAAM,QAAA;AAAA,IACN,UAAA,EAAY;AAAA,MACV,KAAA,EAAO,EAAE,IAAA,EAAM,QAAA,EAAU,aAAa,uBAAA;AAAwB,KAChE;AAAA,IACA,QAAA,EAAU,CAAC,OAAO,CAAA;AAAA,IAClB,oBAAA,EAAsB;AAAA,GACxB;AAIA,EAAA,IAAI,SAAA,GAAY,CAAA;AAGhB,EAAA,IAAI,SAAA;AAEJ,EAAA,MAAM,IAAA,GAAmB;AAAA,IACvB,MAAM,IAAA,CAAK,IAAA;AAAA,IACX,aAAa,IAAA,CAAK,WAAA;AAAA,IAClB,WAAA;AAAA,IACA,OAAA,EAAS,OACP,QAAA,EACA,GAAA,KAKoB;AACpB,MAAA,MAAM,EAAE,KAAA,EAAO,MAAA,EAAO,GAAI,QAAA,CAAS,MAAM,QAAQ,CAAA;AACjD,MAAA,SAAA,IAAa,CAAA;AAIb,MAAA,MAAM,iBAAA,GAAoB,SAAA;AAE1B,MAAA,MAAM,KAAA,GAAQ,MAAM,oBAAA,CAAqB,IAAA,EAAM,QAAQ,iBAAiB,CAAA;AACxE,MAAA,IAAI,QAAA,IAAY,KAAA,EAAO,OAAO,KAAA,CAAM,MAAA;AAEpC,MAAA,MAAM,QAAQ,kBAAA,CAAmB,IAAA,EAAM,KAAA,CAAM,KAAA,EAAO,KAAK,QAAQ,CAAA;AAEjE,MAAA,IAAI,MAAA;AACJ,MAAA,IAAI;AAEF,QAAA,MAAA,GAAS,MAAM,cAAc,IAAA,EAAM,KAAA,EAAO,KAAK,MAAA,EAAQ,KAAA,CAAM,UAAU,SAAS,CAAA;AAAA,MAClF,SAAS,KAAA,EAAO;AAId,QAAA,MAAM,qBAAA,CAAsB,IAAA,EAAM,KAAA,EAAO,KAAA,EAAO,iBAAiB,CAAA;AACjE,QAAA,MAAM,KAAA;AAAA,MACR;AACA,MAAA,OAAO,uBAAA,CAAwB,IAAA,EAAM,KAAA,EAAO,MAAA,EAAQ,iBAAiB,CAAA;AAAA,IACvE;AAAA,GACF;AAGA,EAAA,MAAA,CAAO,cAAA,CAAe,MAAM,mBAAA,EAAqB;AAAA,IAC/C,KAAA,GAAQ,CAAC,KAAA,KAAgC;AACvC,MAAA,SAAA,GAAY,KAAA;AAAA,IACd,CAAA,CAAA;AAAA,IACA,UAAA,EAAY;AAAA,GACb,CAAA;AAED,EAAA,OAAO,IAAA;AACT;AAGO,IAAM,WAAN,MAAe;AAAA,EACZ,WAAA,GAAc;AAAA,EAAC;AAAA,EACvB,OAAO,MAAA,CAAO,IAAA,EAAoB,WAAA,GAAc,CAAA,EAAe;AAC7D,IAAA,OAAO,cAAA,CAAe,MAAM,WAAW,CAAA;AAAA,EACzC;AACF","file":"index.js","sourcesContent":["/**\n * AgentMailbox — per-agent inbox for A2A communication (T20.1, ADR D453).\n *\n * Wraps MessageBus registration with a convenient API for sending,\n * receiving, and requesting messages.\n *\n * @public\n */\n\nimport type { MessageBus, RequestOptions } from \"./message-bus.js\";\nimport type { A2AMessage, MessageHandler } from \"./types.js\";\n\nexport class AgentMailbox {\n readonly agentId: string;\n private readonly _bus: MessageBus;\n private _handler: MessageHandler | null = null;\n\n constructor(agentId: string, bus: MessageBus) {\n this.agentId = agentId;\n this._bus = bus;\n this._bus.register(agentId, (msg) => this._dispatch(msg));\n }\n\n onMessage(handler: MessageHandler): void {\n this._handler = handler;\n }\n\n async send(to: string, partial: { type: string; payload: unknown }): Promise<void> {\n return this._bus.send(this.agentId, to, partial);\n }\n\n async request(\n to: string,\n partial: { type: string; payload: unknown },\n opts?: RequestOptions,\n ): Promise<unknown> {\n return this._bus.request(this.agentId, to, partial, opts);\n }\n\n dispose(): void {\n this._bus.unregister(this.agentId);\n this._handler = null;\n }\n\n private _dispatch(msg: A2AMessage): unknown {\n if (this._handler) {\n return this._handler(msg);\n }\n }\n}\n","/**\n * MessageBus — in-process typed message router for A2A (T20.1, ADR D453).\n *\n * Routes messages between agents by ID. Supports fire-and-forget (send)\n * and request/response (request with timeout).\n *\n * @public\n */\n\nimport type { A2AMessage, MessageHandler } from \"./types.js\";\n\nexport interface RequestOptions {\n timeoutMs?: number;\n}\n\nexport class MessageBus {\n private readonly _handlers = new Map<string, MessageHandler>();\n\n register(agentId: string, handler: MessageHandler): void {\n this._handlers.set(agentId, handler);\n }\n\n unregister(agentId: string): void {\n this._handlers.delete(agentId);\n }\n\n async send(from: string, to: string, partial: { type: string; payload: unknown }): Promise<void> {\n const handler = this._handlers.get(to);\n if (!handler) {\n throw new Error(`Agent \"${to}\" not registered on MessageBus`);\n }\n const message: A2AMessage = {\n ...partial,\n from,\n to,\n timestamp: Date.now(),\n // SE3 — provenance projection of the sender address (thin view over `from`).\n origin: { kind: \"peer\", from },\n };\n // Fire-and-forget: invoke handler but don't await result\n handler(message);\n }\n\n async request(\n from: string,\n to: string,\n partial: { type: string; payload: unknown },\n opts?: RequestOptions,\n ): Promise<unknown> {\n const handler = this._handlers.get(to);\n if (!handler) {\n throw new Error(`Agent \"${to}\" not registered on MessageBus`);\n }\n const timeoutMs = opts?.timeoutMs ?? 30_000;\n const message: A2AMessage = {\n ...partial,\n from,\n to,\n timestamp: Date.now(),\n // SE3 — provenance projection of the sender address (thin view over `from`).\n origin: { kind: \"peer\", from },\n };\n // Hold the timer so it can be cleared once the race settles — otherwise a\n // successful request leaks a live `setTimeout` that keeps the Node event loop\n // alive (the process hangs after the reply). Cleared in `finally`.\n let timer: ReturnType<typeof setTimeout> | undefined;\n try {\n return await Promise.race([\n Promise.resolve(handler(message)),\n new Promise((_, reject) => {\n timer = setTimeout(\n () =>\n reject(new Error(`A2A request timeout: ${to} did not respond within ${timeoutMs}ms`)),\n timeoutMs,\n );\n }),\n ]);\n } finally {\n if (timer !== undefined) clearTimeout(timer);\n }\n }\n\n has(agentId: string): boolean {\n return this._handlers.has(agentId);\n }\n\n listAgents(): string[] {\n return [...this._handlers.keys()];\n }\n}\n","/**\n * Internal DI seam for the public `Agent` facade.\n *\n * Several internal subsystems (`LocalAgent.runUntil`/`fork`, eval, scorers,\n * cron) need to invoke `Agent.create`/`prompt`/`get`/`resume`/`batch`. A direct\n * `import { Agent }` would invert the public-api -> internal dependency\n * direction (and `agent.ts` already imports much of `internal/`). This module\n * is the inversion seam: `agent.ts` registers the facade at module-init time;\n * internal consumers read it on-demand via `getAgentFacade()`. The\n * `internal-must-not-import-facade` dependency-cruiser rule enforces that no\n * `internal/*` module bypasses this seam with a direct facade import.\n *\n * Throws if accessed before registration — should never happen because\n * `agent.ts` evaluation always precedes any internal call (the consumer must\n * obtain a handle from the `Agent` facade first).\n *\n * @internal\n */\n\nimport type { AgentOptions, SDKAgent, SDKAgentInfo } from \"../../../types/agent.js\";\nimport type { BatchItem, BatchOptions, BatchResult } from \"../../../types/batch.js\";\nimport type { RunResult } from \"../../../types/run.js\";\n\n/**\n * The subset of the public `Agent` static surface that internal subsystems\n * consume through the inversion seam. Each member mirrors the matching\n * `Agent.*` signature so registration is a thin pass-through.\n *\n * @internal\n */\nexport interface AgentFacadePort {\n create: (options: AgentOptions) => Promise<SDKAgent>;\n delete: (agentId: string) => Promise<void>;\n prompt: (message: string, options: AgentOptions) => Promise<RunResult>;\n get: (agentId: string) => Promise<SDKAgentInfo>;\n resume: (agentId: string, options?: Partial<AgentOptions>) => Promise<SDKAgent>;\n batch: (\n prompts: ReadonlyArray<string | BatchItem>,\n options: BatchOptions,\n ) => Promise<BatchResult[]>;\n}\n\n/**\n * The registration slot lives on `globalThis` under a `Symbol.for` key — NOT a module-level `let` —\n * so it is a **process-wide singleton** shared by every copy of this module. `tsup` builds each public\n * entry (`.`, `./a2a`, `./cron`, `./eval`, …) with `splitting: false`, which INLINES this module once\n * per entry; a module-level `let` would give each bundled copy its own `registered` slot, and a\n * subagent invoked through `./a2a` would read a copy that `agent.ts` (in the `.` entry) never set —\n * the classic duplicated-singleton hazard (see issue: a2a \"Agent facade not registered\"). `Symbol.for`\n * (global symbol registry) + the one `globalThis` object guarantees all copies read/write ONE slot.\n */\nconst FACADE_KEY: unique symbol = Symbol.for(\n \"theokit.internal.runtime.agentFacade\",\n) as typeof FACADE_KEY;\n\ntype FacadeHost = { [FACADE_KEY]?: AgentFacadePort };\n\n/**\n * Registered by `agent.ts` at module-init time. Idempotent: re-registration\n * replaces the previous reference (useful for tests that swap implementations).\n *\n * @internal\n */\nexport function setAgentFacade(facade: AgentFacadePort): void {\n (globalThis as unknown as FacadeHost)[FACADE_KEY] = facade;\n}\n\n/**\n * Resolve the registered `Agent` facade for internal subsystems.\n *\n * @internal\n */\nexport function getAgentFacade(): AgentFacadePort {\n const registered = (globalThis as unknown as FacadeHost)[FACADE_KEY];\n if (registered === undefined) {\n throw new Error(\n \"internal: Agent facade not registered. The `agent.ts` module must be loaded before internal subsystems (LocalAgent.runUntil/fork, eval, scorers, cron) invoke it.\",\n );\n }\n return registered;\n}\n","/**\n * Subagent delegation — declarative child agent invocable as a tool.\n *\n * Per ADR D2: `defineSubAgent(spec)` returns a `CustomTool` that, when\n * invoked by the LLM, creates a child agent and sends the input as a\n * message. EC-2: delegation depth tracked to prevent infinite recursion.\n *\n * SE10 — the handler forwards the parent run's `AbortSignal` to the child.\n * SE11 — optional `onDelegationStart` / `onDelegationComplete` lifecycle hooks\n * let the caller reject, rewrite, observe, or annotate a delegation.\n *\n * @public\n */\n\nimport { z } from \"zod\";\nimport type { Plugin } from \"../internal/plugins/types.js\";\nimport { getAgentFacade } from \"../internal/runtime/registry/agent-factory-registry.js\";\nimport type {\n AgentDefinition,\n AgentOptions,\n CustomTool,\n ToolContextMessage,\n} from \"../types/agent.js\";\nimport type { ModelSelection } from \"../types/agent-prims.js\";\nimport type { Run } from \"../types/run.js\";\n\n/**\n * Credentials a parent agent hands down to its subagent tools so the child\n * inherits the parent's auth (and, absent an explicit `spec.model`, its model).\n * @internal\n */\nexport interface InheritedCredentials {\n readonly apiKey?: string;\n readonly model?: ModelSelection;\n /**\n * The parent's shell-sandbox posture (`local.sandboxOptions.enabled`), handed down so a delegated\n * child of a sandboxed parent stays sandboxed unless its role explicitly opts out. Without this a\n * child ran unsandboxed whenever its role omitted `sandbox` — a default-open the sandbox wiring exists\n * to prevent.\n */\n readonly sandbox?: boolean;\n /**\n * #55 — the parent's code-registered plugins (e.g. a `PermissionPlugin`) handed\n * down so the child runs under the SAME policy. Without this, a delegated child's\n * inner tool calls escape the parent's argument-level permission gate. First-party\n * delegation path only — never exposed to third-party tool `ctx`.\n */\n readonly plugins?: readonly Plugin[];\n}\n\n/**\n * Private per-tool setter installed on subagent tools. Kept off the public\n * `CustomTool` shape (and off every tool handler's `ctx`) so the parent's API\n * key never reaches third-party tool code — only the SDK's own delegation path.\n */\n// `Symbol.for` (global registry), NOT `Symbol()`: with `tsup splitting: false` each public entry\n// (`.`, `./a2a`) inlines its own copy of this module. A unique `Symbol()` would give each copy a\n// DIFFERENT sink key — the local runtime (bundled in `.`) calls `inheritSubAgentCredentials` with the\n// `.`-copy key, but a `SubAgent` created via `@theokit/sdk/a2a` installed its sink under the `/a2a`-copy\n// key, so the lookup missed and the child inherited NO `apiKey` (→ `provider_unresolved`, \"(no response)\").\n// `Symbol.for` makes both copies agree on ONE key. (Same duplicated-singleton class as the facade fix, #142.)\nconst INHERIT_CREDENTIALS = Symbol.for(\"theokit.subagent.inheritCredentials\");\n\ntype CredentialSink = (creds: InheritedCredentials) => void;\n\n/**\n * Called by the local runtime for every tool in a run: if the tool is a\n * subagent, its child agent inherits the parent's `apiKey`/`model`. A no-op for\n * any other tool (third-party tools never receive the parent's credentials).\n * @internal\n */\nexport function inheritSubAgentCredentials(tool: CustomTool, creds: InheritedCredentials): void {\n const sink = (tool as { [INHERIT_CREDENTIALS]?: CredentialSink })[INHERIT_CREDENTIALS];\n if (typeof sink === \"function\") sink(creds);\n}\n\n/** Arguments passed to {@link SubAgentSpec.messageFilter} (SE12). */\nexport interface MessageFilterArgs {\n /** The supervisor transcript (read-only text projection) available to this delegation. */\n messages: readonly ToolContextMessage[];\n /** The prompt about to be delegated (after any `onDelegationStart` rewrite). */\n input: string;\n /** The subagent's name. */\n name: string;\n}\n\n/** Context passed to {@link SubAgentSpec.onDelegationStart} before the child runs. */\nexport interface DelegationStartContext {\n input: string;\n name: string;\n /**\n * SE15 — 1-based count of times THIS subagent tool has been invoked (a\n * per-`defineSubAgent`-instance counter). Incremented before this hook runs;\n * a rejected delegation still counts. Enables reject-after-N patterns.\n */\n iteration: number;\n}\n\n/**\n * Decision returned from {@link SubAgentSpec.onDelegationStart}. Discriminated on\n * `proceed` so a rejection (`proceed: false` + `rejectionReason`) and an approval\n * (`modifiedInput`) cannot be mixed into one nonsensical object.\n */\nexport type DelegationStartDecision =\n | { proceed: false; rejectionReason?: string }\n | {\n proceed?: true;\n modifiedInput?: string;\n /** SE13 — cap the child's iteration count (forwarded as `SendOptions.maxIterations`). */\n modifiedMaxSteps?: number;\n };\n\n/** Context passed to {@link SubAgentSpec.onDelegationComplete} after the child settles. */\nexport interface DelegationCompleteContext {\n input: string;\n name: string;\n /** The child's text result (present on success). */\n result?: string;\n /** The error the child threw (present on failure); the error is still re-thrown. */\n error?: unknown;\n /** SE15 — the same 1-based iteration this delegation's `onDelegationStart` saw. */\n iteration: number;\n}\n\n/**\n * The return of a delegation hook: a decision, a promise of one, or nothing —\n * `void` lets a side-effect-only callback (`(ctx) => { log(ctx) }`) type-check,\n * which is the common case (mirrors a peer framework's `async ctx => { ... }` hooks).\n */\n// biome-ignore lint/suspicious/noConfusingVoidType: `void` is the idiomatic return for an optional-return callback; the rule false-positives on callback return unions.\ntype DelegationHookResult<T> = T | void | Promise<T | void>;\n\n/** Decision returned from {@link SubAgentSpec.onDelegationComplete}. */\nexport interface DelegationCompleteDecision {\n /** Appended to the child's result string. */\n feedback?: string;\n}\n\nexport interface SubAgentSpec {\n name: string;\n description: string;\n instructions: string;\n /**\n * A bare id string (back-compat) OR a full {@link ModelSelection} carrying\n * `params` (e.g. `[{ id: \"thinking\", value: \"low\" }]` for reasoning effort). The\n * object form is required for per-subagent reasoning effort to survive to the child\n * — the pre-M33 path took only `.id` and dropped params.\n */\n model?: string | ModelSelection;\n tools?: CustomTool[];\n /** Per-subagent shell sandbox toggle (M33). `true` ⇒ child `local.sandboxOptions.enabled`. */\n sandbox?: boolean;\n maxDelegationDepth?: number;\n /**\n * SE11 — called before the supervisor delegates. Return `{ proceed: false }`\n * to reject (the child never runs and `rejectionReason` becomes the tool\n * result), or `{ modifiedInput }` to rewrite the delegated prompt. A throwing\n * hook surfaces (never silently swallowed).\n */\n onDelegationStart?: (\n ctx: DelegationStartContext,\n ) => DelegationHookResult<DelegationStartDecision>;\n /**\n * SE11 — called after the delegation settles. On success `ctx.result` is set\n * and an optional `{ feedback }` is appended to it. On failure `ctx.error` is\n * set and the original error is ALWAYS re-thrown after this hook runs — a throw\n * from this hook on the error path is suppressed so it cannot mask the\n * delegation's real failure (on the success path a throw does propagate).\n */\n onDelegationComplete?: (\n ctx: DelegationCompleteContext,\n ) => DelegationHookResult<DelegationCompleteDecision>;\n /**\n * SE12 — opt-in parent-context forwarding. When set, the supervisor transcript\n * (`ctx.messages`, a read-only text projection) is passed to this filter and the\n * returned subset is forwarded to the child as a role-tagged context preamble\n * prepended to the delegated input. When ABSENT the child runs input-only —\n * memory isolation stays the default. A filter returning `[]` forwards nothing.\n * A throwing filter propagates (fail-fast, never swallowed — same contract as\n * `onDelegationStart`); the delegation surfaces as a tool error.\n */\n messageFilter?: (args: MessageFilterArgs) => readonly ToolContextMessage[];\n /**\n * SE14 — opt-in subagent result-context control. When `true`, the child's\n * completed tool-call results (name + result) are appended to the delegation\n * payload returned to the supervisor, inside a `<subagent-tool-results>` block.\n * When absent/`false` the delegation returns the child's final text only —\n * text-only stays the default (a peer framework's scoped posture). See ADR 0006.\n */\n includeToolResults?: boolean;\n}\n\nexport class MaxDelegationDepthError extends Error {\n readonly code = \"max_delegation_depth\" as const;\n constructor(\n public readonly currentDepth: number,\n public readonly maxDepth: number,\n ) {\n super(`Max delegation depth ${maxDepth} exceeded (current: ${currentDepth})`);\n this.name = \"MaxDelegationDepthError\";\n }\n}\n\n/**\n * Run the `onDelegationStart` hook; returns either a rejection or the (possibly\n * rewritten) input plus the optional SE13 `maxSteps` cap.\n */\nasync function applyDelegationStart(\n spec: SubAgentSpec,\n input: string,\n iteration: number,\n): Promise<{ reject: string } | { input: string; maxSteps?: number }> {\n if (spec.onDelegationStart === undefined) return { input };\n const decision = await spec.onDelegationStart({ input, name: spec.name, iteration });\n if (decision === undefined) return { input };\n if (decision.proceed === false)\n return { reject: decision.rejectionReason ?? \"(delegation rejected)\" };\n return {\n input: decision.modifiedInput ?? input,\n ...(decision.modifiedMaxSteps !== undefined ? { maxSteps: decision.modifiedMaxSteps } : {}),\n };\n}\n\n/**\n * SE14 — replay the child run's stream (a safe post-`wait()` idiom — the run buffers\n * events, `stream()` replays them) and collect every completed tool-call result into\n * a delimited block. Returns `\"\"` when the child ran no completed tool calls. See ADR 0006.\n */\nasync function collectChildToolResults(run: Run): Promise<string> {\n const lines: string[] = [];\n for await (const event of run.stream()) {\n if (event.type === \"tool_call\" && event.status === \"completed\") {\n const rendered =\n typeof event.result === \"string\" ? event.result : JSON.stringify(event.result ?? null);\n lines.push(`${event.name}: ${rendered}`);\n }\n }\n if (lines.length === 0) return \"\";\n return `\\n\\n<subagent-tool-results>\\n${lines.join(\"\\n\")}\\n</subagent-tool-results>`;\n}\n\n/**\n * Create the transient child agent and send the input, composing every forwarded\n * `SendOptions` onto ONE `send` call — SE10 `signal` + SE13 `maxIterations`. Absent\n * every option ⇒ the pre-SE10 single-arg `send(input)` shape. SE14 — when\n * `includeToolResults` is set, append the child's completed tool results. Dispose in `finally`.\n */\n/**\n * Build the child agent's `Agent.create` options: the child inherits the parent's\n * apiKey (else `Agent.create` throws \"Missing API key\"), its model (unless the spec\n * overrides it), and — #55 — the parent's plugins (permission gate/guards) so the\n * child's inner tool calls run under the same policy.\n */\nexport function buildChildCreateOptions(\n spec: SubAgentSpec,\n inherited: InheritedCredentials | undefined,\n): AgentOptions {\n // M33 — carry the WHOLE model (a bare id becomes `{ id }`; a ModelSelection with\n // `params` keeps its reasoning effort). The pre-M33 path wrapped `spec.model` as\n // `{ id: spec.model }`, which only worked because spec.model was a string and\n // silently dropped reasoning params.\n const model: string | ModelSelection | undefined =\n spec.model !== undefined\n ? typeof spec.model === \"string\"\n ? { id: spec.model }\n : spec.model\n : inherited?.model;\n // M33 — the role's own `sandbox` wins; when it omits the field, inherit the parent's posture. A role's\n // explicit `sandbox: false` therefore confines-OFF a child of a sandboxed parent (distinct from absent).\n const sandbox = spec.sandbox ?? inherited?.sandbox;\n return {\n ...(inherited?.apiKey !== undefined ? { apiKey: inherited.apiKey } : {}),\n ...(model !== undefined ? { model } : {}),\n ...(sandbox !== undefined ? { local: { sandboxOptions: { enabled: sandbox } } } : {}),\n ...(inherited?.plugins !== undefined ? { plugins: inherited.plugins } : {}),\n systemPrompt: spec.instructions,\n tools: spec.tools ?? [],\n };\n}\n\nasync function runChildAgent(\n spec: SubAgentSpec,\n input: string,\n signal: AbortSignal | undefined,\n maxSteps: number | undefined,\n inherited: InheritedCredentials | undefined,\n): Promise<string> {\n // SE45 cycle 3 — use the registered Agent facade via the DIP seam\n // (agent-factory-registry) instead of a dynamic `import(\"../agent.js\")`.\n // This removes the last madge cycle (a2a/subagent -> agent -> ... -> real-local-run-tools\n // -> a2a/subagent): the facade registers itself at module-init via setAgentFacade,\n // so subagent depends only on the registry port, never on the facade module.\n const agent = await getAgentFacade().create(buildChildCreateOptions(spec, inherited));\n try {\n const sendOptions: {\n signal?: AbortSignal;\n maxIterations?: number;\n origin?: import(\"../types/run.js\").MessageOrigin;\n } = {\n ...(signal !== undefined ? { signal } : {}),\n ...(maxSteps !== undefined ? { maxIterations: maxSteps } : {}),\n // SE3 — a delegated child's turn is initiated by the coordinating parent.\n origin: { kind: \"coordinator\" },\n };\n const run = await agent.send(input, sendOptions);\n const result = await run.wait();\n // Fail-fast, don't swallow (Rule 8): a child that ended in error must surface — otherwise a real\n // failure (e.g. `provider_unresolved`) is hidden behind \"(no response)\" and the parent loops on it.\n if (result.status === \"error\") {\n const cause = (result as { error?: { message?: string } }).error;\n throw new Error(\n `subagent \"${spec.name}\" run failed: ${cause?.message ?? \"unknown error\"}`,\n cause !== undefined ? { cause } : undefined,\n );\n }\n const text = result.result ?? \"(no response)\";\n // SE14 — text-only by default; opt-in appends the child's tool results.\n return spec.includeToolResults === true ? text + (await collectChildToolResults(run)) : text;\n } finally {\n agent.dispose();\n }\n}\n\n/**\n * Best-effort error-path notification: run `onDelegationComplete` with the child's\n * error so the caller can observe the failure. The observer's own throw (sync or\n * async) is suppressed here so it cannot mask the delegation's real error, which the\n * handler re-throws next.\n */\nasync function notifyDelegationError(\n spec: SubAgentSpec,\n input: string,\n error: unknown,\n iteration: number,\n): Promise<void> {\n if (spec.onDelegationComplete === undefined) return;\n try {\n await spec.onDelegationComplete({ input, name: spec.name, error, iteration });\n } catch {\n // Subordinate to `error`; the child's real cause wins.\n }\n}\n\n/**\n * SE12 — apply `messageFilter` (if set) and prepend the filtered supervisor\n * transcript to the delegated input as a role-tagged context preamble. Absent\n * filter OR no messages OR an empty filtered subset ⇒ the original input\n * (isolation-by-default preserved).\n */\nfunction applyMessageFilter(\n spec: SubAgentSpec,\n input: string,\n messages: readonly ToolContextMessage[] | undefined,\n): string {\n if (spec.messageFilter === undefined || messages === undefined) return input;\n const filtered = spec.messageFilter({ messages, input, name: spec.name });\n if (filtered.length === 0) return input;\n const preamble = filtered.map((m) => `${m.role}: ${m.content}`).join(\"\\n\");\n return `Prior conversation:\\n${preamble}\\n\\nTask:\\n${input}`;\n}\n\n/** Run the success-path `onDelegationComplete` hook; appends its `feedback` to the result. */\nasync function applyDelegationComplete(\n spec: SubAgentSpec,\n input: string,\n result: string,\n iteration: number,\n): Promise<string> {\n if (spec.onDelegationComplete === undefined) return result;\n const completion = await spec.onDelegationComplete({ input, name: spec.name, result, iteration });\n return completion?.feedback !== undefined ? result + completion.feedback : result;\n}\n\nfunction defineSubAgent(spec: SubAgentSpec, _parentDepth = 0): CustomTool {\n const currentDepth = _parentDepth + 1;\n const maxDepth = spec.maxDelegationDepth ?? 3;\n\n if (currentDepth > maxDepth) {\n throw new MaxDelegationDepthError(currentDepth, maxDepth);\n }\n\n // Zod for RUNTIME validation of the tool_use input …\n const inputZod = z.object({\n input: z.string().describe(\"Task for the subagent\"),\n });\n // … and a real Draft-7 JSON Schema for the LLM. `CustomTool.inputSchema` is sent\n // to the model verbatim; a raw Zod object would serialize to garbage, so the\n // model emits malformed input that fails `inputZod.parse` and the delegation\n // never runs (the previous bug — the schema and the validator are now distinct).\n const inputSchema: Record<string, unknown> = {\n type: \"object\",\n properties: {\n input: { type: \"string\", description: \"Task for the subagent\" },\n },\n required: [\"input\"],\n additionalProperties: false,\n };\n\n // SE15 — per-instance delegation counter, surfaced as `iteration` on the hook\n // contexts. Incremented once per handler invocation before onDelegationStart.\n let iteration = 0;\n\n // Credentials handed down by the parent runtime (see `inheritSubAgentCredentials`).\n let inherited: InheritedCredentials | undefined;\n\n const tool: CustomTool = {\n name: spec.name,\n description: spec.description,\n inputSchema,\n handler: async (\n rawInput: Record<string, unknown>,\n ctx?: {\n signal?: AbortSignal;\n context?: unknown;\n messages?: readonly ToolContextMessage[];\n },\n ): Promise<string> => {\n const { input: parsed } = inputZod.parse(rawInput);\n iteration += 1; // SE15 — before onDelegationStart; a rejected delegation still counts.\n // Pin THIS invocation's iteration before any await so a concurrent invocation\n // bumping the shared counter cannot change the value onDelegationComplete /\n // notifyDelegationError observe — they see the same iteration onDelegationStart did.\n const capturedIteration = iteration;\n\n const start = await applyDelegationStart(spec, parsed, capturedIteration);\n if (\"reject\" in start) return start.reject;\n // SE12 — opt-in: forward the filtered supervisor transcript as a preamble.\n const input = applyMessageFilter(spec, start.input, ctx?.messages);\n\n let result: string;\n try {\n // SE13 — apply the optional onDelegationStart maxSteps cap on the child send.\n result = await runChildAgent(spec, input, ctx?.signal, start.maxSteps, inherited);\n } catch (error) {\n // SE11 — notify the completion hook of the failure (best-effort observer),\n // then re-throw the ORIGINAL error (Rule 8: never swallow the delegation's\n // own failure).\n await notifyDelegationError(spec, input, error, capturedIteration);\n throw error;\n }\n return applyDelegationComplete(spec, input, result, capturedIteration);\n },\n };\n\n // Install the private credential sink (off the public shape + off every ctx).\n Object.defineProperty(tool, INHERIT_CREDENTIALS, {\n value: ((creds: InheritedCredentials) => {\n inherited = creds;\n }) satisfies CredentialSink,\n enumerable: false,\n });\n\n return tool;\n}\n\n/** SE36 — `SubAgent.create` replaces `defineSubAgent` (ADR 0015). @public */\nexport class SubAgent {\n private constructor() {}\n static create(spec: SubAgentSpec, parentDepth = 0): CustomTool {\n return defineSubAgent(spec, parentDepth);\n }\n}\n\n/**\n * Convert a parent's declarative `agents` map ({@link AgentDefinition} per key)\n * into delegation tools for the LOCAL runtime — the counterpart of the\n * cloud/fixture subagent wiring. Each child inherits the parent's `apiKey`/model\n * via {@link inheritSubAgentCredentials}; `def.model` overrides the model\n * (`\"inherit\"` keeps the parent's), and `def.tools` scopes the child to that\n * subset of the parent's tools (absent → the parent's full toolset, per the\n * `AgentDefinition.tools` contract).\n *\n * M33 — per-subagent `model` (with reasoning `params`) and `sandbox` are now wired\n * into local delegation: each is carried onto the {@link SubAgentSpec} and applied to\n * the child in {@link buildChildCreateOptions}. `\"inherit\"` (or an absent field) keeps\n * the parent's value. Per-subagent `mcp` is rejected at load (see subagents-loader) —\n * resolving server names→config on the local path is a follow-up.\n *\n * @internal\n */\nexport function subAgentToolsFromDefinitions(\n agents: Record<string, AgentDefinition>,\n parentTools: readonly CustomTool[],\n): CustomTool[] {\n return Object.entries(agents).map(([name, def]) => {\n const whitelist =\n Array.isArray(def.tools) && def.tools.length > 0 ? new Set(def.tools) : undefined;\n const childTools = whitelist ? parentTools.filter((t) => whitelist.has(t.name)) : parentTools;\n return defineSubAgent({\n name,\n description: def.description,\n instructions: def.prompt,\n // Carry the FULL ModelSelection (id + reasoning params), not just the id, so\n // per-subagent reasoning effort survives to buildChildCreateOptions.\n ...(def.model !== undefined && def.model !== \"inherit\" ? { model: def.model } : {}),\n ...(def.sandbox !== undefined ? { sandbox: def.sandbox } : {}),\n tools: [...childTools],\n });\n });\n}\n"]}
|
package/dist/cron.cjs
CHANGED
|
@@ -3277,7 +3277,9 @@ function serializeAgents(agents2) {
|
|
|
3277
3277
|
out[name] = {
|
|
3278
3278
|
description: def.description,
|
|
3279
3279
|
prompt: def.prompt,
|
|
3280
|
-
...def.model !== void 0 ? { model: def.model } : {}
|
|
3280
|
+
...def.model !== void 0 ? { model: def.model } : {},
|
|
3281
|
+
...def.tools !== void 0 ? { tools: def.tools } : {},
|
|
3282
|
+
...def.sandbox !== void 0 ? { sandbox: def.sandbox } : {}
|
|
3281
3283
|
};
|
|
3282
3284
|
}
|
|
3283
3285
|
return out;
|
|
@@ -4368,7 +4370,8 @@ function applyExtraRunFields(base, script) {
|
|
|
4368
4370
|
// src/internal/runtime/fixtures/fixture-run-base.ts
|
|
4369
4371
|
function prepareRunContext(message) {
|
|
4370
4372
|
const userText = typeof message === "string" ? message : message.text;
|
|
4371
|
-
|
|
4373
|
+
const userImages = typeof message === "string" ? void 0 : message.images;
|
|
4374
|
+
return { userText, userImages, id: generateRunId(), startTime: Date.now() };
|
|
4372
4375
|
}
|
|
4373
4376
|
var FixtureRunBase = class {
|
|
4374
4377
|
id;
|
|
@@ -6758,9 +6761,9 @@ function rejectMcp(fields, filename) {
|
|
|
6758
6761
|
function resolveModel(fields, filename) {
|
|
6759
6762
|
const modelId = asString(fields.model);
|
|
6760
6763
|
const effort = asString(fields.reasoning_effort);
|
|
6761
|
-
if (effort !== void 0 && modelId === void 0) {
|
|
6764
|
+
if (effort !== void 0 && (modelId === void 0 || modelId === "inherit")) {
|
|
6762
6765
|
throw new ConfigurationError(
|
|
6763
|
-
`Subagent ${filename}: reasoning_effort requires a model (effort is a model parameter)`,
|
|
6766
|
+
`Subagent ${filename}: reasoning_effort requires a concrete model (effort is a model parameter; an absent model or "inherit" cannot carry it)`,
|
|
6764
6767
|
{ code: "subagent_reasoning_effort_without_model" }
|
|
6765
6768
|
);
|
|
6766
6769
|
}
|
|
@@ -6779,7 +6782,9 @@ function resolveSandbox(fields, filename) {
|
|
|
6779
6782
|
return fields.sandbox;
|
|
6780
6783
|
}
|
|
6781
6784
|
function asString(v) {
|
|
6782
|
-
|
|
6785
|
+
if (typeof v !== "string") return void 0;
|
|
6786
|
+
const m = /^(["'])(.*)\1$/.exec(v);
|
|
6787
|
+
return m ? m[2] : v;
|
|
6783
6788
|
}
|
|
6784
6789
|
function toStringList(v) {
|
|
6785
6790
|
if (Array.isArray(v)) return v.map((t) => t.trim()).filter((t) => t.length > 0);
|
|
@@ -9487,6 +9492,18 @@ function buildAssistantTurn(text, toolCalls) {
|
|
|
9487
9492
|
}
|
|
9488
9493
|
|
|
9489
9494
|
// src/internal/agent-loop/loop-context-init.ts
|
|
9495
|
+
function buildUserContent(text, images) {
|
|
9496
|
+
const content = [{ type: "text", text }];
|
|
9497
|
+
for (const img of images ?? []) {
|
|
9498
|
+
if ("data" in img) {
|
|
9499
|
+
content.push({
|
|
9500
|
+
type: "image",
|
|
9501
|
+
source: { type: "base64", media_type: img.mimeType, data: img.data }
|
|
9502
|
+
});
|
|
9503
|
+
}
|
|
9504
|
+
}
|
|
9505
|
+
return content;
|
|
9506
|
+
}
|
|
9490
9507
|
function buildAgentRef(inputs) {
|
|
9491
9508
|
return {
|
|
9492
9509
|
agentId: inputs.agentId,
|
|
@@ -9574,7 +9591,7 @@ async function initLoopContext(inputs) {
|
|
|
9574
9591
|
conversation: [],
|
|
9575
9592
|
messages: [
|
|
9576
9593
|
...priorMessages,
|
|
9577
|
-
{ role: "user", content:
|
|
9594
|
+
{ role: "user", content: buildUserContent(inputs.userMessage, inputs.userImages) }
|
|
9578
9595
|
],
|
|
9579
9596
|
tools,
|
|
9580
9597
|
finalText: "",
|
|
@@ -11595,6 +11612,9 @@ function toAnthropicWireMessage(message) {
|
|
|
11595
11612
|
if (part.type === "tool_use") {
|
|
11596
11613
|
return { type: "tool_use", id: part.id, name: part.name, input: part.input };
|
|
11597
11614
|
}
|
|
11615
|
+
if (part.type === "image") {
|
|
11616
|
+
return { type: "image", source: part.source };
|
|
11617
|
+
}
|
|
11598
11618
|
return {
|
|
11599
11619
|
type: "tool_result",
|
|
11600
11620
|
tool_use_id: part.toolUseId,
|
|
@@ -12896,7 +12916,20 @@ function userOrToolMessages(message) {
|
|
|
12896
12916
|
}
|
|
12897
12917
|
}
|
|
12898
12918
|
const userText = joinTextParts2(message);
|
|
12899
|
-
|
|
12919
|
+
const imageParts = message.content.filter((p) => p.type === "image");
|
|
12920
|
+
if (imageParts.length > 0) {
|
|
12921
|
+
const content = [];
|
|
12922
|
+
if (userText.length > 0) content.push({ type: "text", text: userText });
|
|
12923
|
+
for (const img of imageParts) {
|
|
12924
|
+
content.push({
|
|
12925
|
+
type: "image_url",
|
|
12926
|
+
image_url: { url: `data:${img.source.media_type};base64,${img.source.data}` }
|
|
12927
|
+
});
|
|
12928
|
+
}
|
|
12929
|
+
out.push({ role: "user", content });
|
|
12930
|
+
} else if (userText.length > 0) {
|
|
12931
|
+
out.push({ role: "user", content: userText });
|
|
12932
|
+
}
|
|
12900
12933
|
return out;
|
|
12901
12934
|
}
|
|
12902
12935
|
function assistantMessage(message) {
|
|
@@ -13866,10 +13899,11 @@ ${lines.join("\n")}
|
|
|
13866
13899
|
}
|
|
13867
13900
|
function buildChildCreateOptions(spec, inherited) {
|
|
13868
13901
|
const model = spec.model !== void 0 ? typeof spec.model === "string" ? { id: spec.model } : spec.model : inherited?.model;
|
|
13902
|
+
const sandbox = spec.sandbox ?? inherited?.sandbox;
|
|
13869
13903
|
return {
|
|
13870
13904
|
...inherited?.apiKey !== void 0 ? { apiKey: inherited.apiKey } : {},
|
|
13871
13905
|
...model !== void 0 ? { model } : {},
|
|
13872
|
-
...
|
|
13906
|
+
...sandbox !== void 0 ? { local: { sandboxOptions: { enabled: sandbox } } } : {},
|
|
13873
13907
|
...inherited?.plugins !== void 0 ? { plugins: inherited.plugins } : {},
|
|
13874
13908
|
systemPrompt: spec.instructions,
|
|
13875
13909
|
tools: spec.tools ?? []
|
|
@@ -14045,10 +14079,12 @@ function declarativeSubagentTools(agents2, parentTools) {
|
|
|
14045
14079
|
}
|
|
14046
14080
|
function bindParentCredentials(tools, agentOptions) {
|
|
14047
14081
|
const parentPlugins = Array.isArray(agentOptions.plugins) ? agentOptions.plugins : void 0;
|
|
14082
|
+
const parentSandbox = agentOptions.local?.sandboxOptions?.enabled;
|
|
14048
14083
|
const credentials = {
|
|
14049
14084
|
...agentOptions.apiKey !== void 0 ? { apiKey: agentOptions.apiKey } : {},
|
|
14050
14085
|
...typeof agentOptions.model === "object" ? { model: agentOptions.model } : {},
|
|
14051
|
-
...parentPlugins !== void 0 ? { plugins: parentPlugins } : {}
|
|
14086
|
+
...parentPlugins !== void 0 ? { plugins: parentPlugins } : {},
|
|
14087
|
+
...parentSandbox !== void 0 ? { sandbox: parentSandbox } : {}
|
|
14052
14088
|
};
|
|
14053
14089
|
for (const tool of tools) inheritSubAgentCredentials(tool, credentials);
|
|
14054
14090
|
}
|
|
@@ -14079,7 +14115,7 @@ function buildCustomToolsInput(agentOptions, sendOptions, pluginManager, persona
|
|
|
14079
14115
|
|
|
14080
14116
|
// src/internal/local-agent/real-local-run.ts
|
|
14081
14117
|
function createRealLocalRun(options) {
|
|
14082
|
-
const { userText, id, startTime } = prepareRunContext(options.message);
|
|
14118
|
+
const { userText, userImages, id, startTime } = prepareRunContext(options.message);
|
|
14083
14119
|
const supported = /* @__PURE__ */ new Set(["stream", "wait", "cancel", "conversation"]);
|
|
14084
14120
|
const runScript = {
|
|
14085
14121
|
events: [],
|
|
@@ -14098,7 +14134,7 @@ function createRealLocalRun(options) {
|
|
|
14098
14134
|
supportedOps: supported,
|
|
14099
14135
|
startTime
|
|
14100
14136
|
},
|
|
14101
|
-
() => buildLoopInputs(options, id, userText)
|
|
14137
|
+
() => buildLoopInputs(options, id, userText, userImages)
|
|
14102
14138
|
);
|
|
14103
14139
|
handle.bootstrap();
|
|
14104
14140
|
registerRun(handle);
|
|
@@ -14131,7 +14167,7 @@ function mergeExplicitApiKey(pools, primary, apiKey) {
|
|
|
14131
14167
|
if (existing !== void 0 && existing.length > 0) return pools;
|
|
14132
14168
|
return { ...pools ?? {}, [primary]: [apiKey] };
|
|
14133
14169
|
}
|
|
14134
|
-
function buildLoopInputs(options, runId, userText) {
|
|
14170
|
+
function buildLoopInputs(options, runId, userText, userImages) {
|
|
14135
14171
|
const maxIterations = options.sendOptions.maxIterations;
|
|
14136
14172
|
if (maxIterations !== void 0 && (!Number.isInteger(maxIterations) || maxIterations < 1)) {
|
|
14137
14173
|
throw new ConfigurationError(
|
|
@@ -14170,6 +14206,7 @@ function buildLoopInputs(options, runId, userText) {
|
|
|
14170
14206
|
...options.model?.params !== void 0 ? { params: options.model.params } : {}
|
|
14171
14207
|
},
|
|
14172
14208
|
userMessage: userText,
|
|
14209
|
+
...userImages !== void 0 ? { userImages } : {},
|
|
14173
14210
|
llm,
|
|
14174
14211
|
mcp: buildMcpMap(options),
|
|
14175
14212
|
hooks: options.hooks,
|