@theokit/sdk 4.2.9 → 4.3.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 +6 -0
- package/dist/a2a/index.cjs +8 -1
- package/dist/a2a/index.cjs.map +1 -1
- package/dist/a2a/index.js +8 -1
- package/dist/a2a/index.js.map +1 -1
- package/dist/cron.cjs +36 -1
- package/dist/cron.cjs.map +1 -1
- package/dist/cron.js +36 -1
- package/dist/cron.js.map +1 -1
- package/dist/eval.cjs +36 -1
- package/dist/eval.cjs.map +1 -1
- package/dist/eval.js +36 -1
- package/dist/eval.js.map +1 -1
- package/dist/index.cjs +36 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +36 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 4.2.10
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- aaa3e36: fix(a2a): subagent child now inherits the parent's `apiKey` + child errors surface instead of `"(no response)"` (#143). Two bugs kept a `SubAgent` child from ever returning content when driven through a host that reaches the `/a2a` build copy (e.g. the `@theokit/agents` in-process adapter): (1) the credential-inheritance sink key was a unique `Symbol()`, so with `tsup splitting: false` the local runtime (bundled in `.`) and a `SubAgent` created via `@theokit/sdk/a2a` used DIFFERENT sink symbols — the child inherited no `apiKey` and failed with `provider_unresolved`; now a shared `Symbol.for` key (same fix class as #142). (2) `runChildAgent` read only `result.result`, so an errored child was silently swallowed to `"(no response)"` and the parent looped on it — it now throws the child's error (Rule 8, fail-fast). Adds regression tests (global sink key; error surfaced). Validated end-to-end: a delegated child (reasoning and tool-using) now returns its answer.
|
|
8
|
+
|
|
3
9
|
## 4.2.9
|
|
4
10
|
|
|
5
11
|
### Patch Changes
|
package/dist/a2a/index.cjs
CHANGED
|
@@ -108,7 +108,7 @@ function getAgentFacade() {
|
|
|
108
108
|
}
|
|
109
109
|
|
|
110
110
|
// src/a2a/subagent.ts
|
|
111
|
-
var INHERIT_CREDENTIALS = /* @__PURE__ */ Symbol("theokit.subagent.inheritCredentials");
|
|
111
|
+
var INHERIT_CREDENTIALS = /* @__PURE__ */ Symbol.for("theokit.subagent.inheritCredentials");
|
|
112
112
|
var MaxDelegationDepthError = class extends Error {
|
|
113
113
|
constructor(currentDepth, maxDepth) {
|
|
114
114
|
super(`Max delegation depth ${maxDepth} exceeded (current: ${currentDepth})`);
|
|
@@ -167,6 +167,13 @@ async function runChildAgent(spec, input, signal, maxSteps, inherited) {
|
|
|
167
167
|
};
|
|
168
168
|
const run = await agent.send(input, sendOptions);
|
|
169
169
|
const result = await run.wait();
|
|
170
|
+
if (result.status === "error") {
|
|
171
|
+
const cause = result.error;
|
|
172
|
+
throw new Error(
|
|
173
|
+
`subagent "${spec.name}" run failed: ${cause?.message ?? "unknown error"}`,
|
|
174
|
+
cause !== void 0 ? { cause } : void 0
|
|
175
|
+
);
|
|
176
|
+
}
|
|
170
177
|
const text = result.result ?? "(no response)";
|
|
171
178
|
return spec.includeToolResults === true ? text + await collectChildToolResults(run) : text;
|
|
172
179
|
} finally {
|
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 */\nconst INHERIT_CREDENTIALS = Symbol(\"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 model?: string;\n tools?: CustomTool[];\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 */\nfunction buildChildCreateOptions(\n spec: SubAgentSpec,\n inherited: InheritedCredentials | undefined,\n): AgentOptions {\n const model: string | ModelSelection | undefined = spec.model\n ? { id: spec.model }\n : inherited?.model;\n return {\n ...(inherited?.apiKey !== undefined ? { apiKey: inherited.apiKey } : {}),\n ...(model !== undefined ? { model } : {}),\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 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 * Per-subagent `mcpServers` on an `AgentDefinition` is honored by the cloud\n * runtime only; it is not wired into local delegation here.\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 ...(def.model !== undefined && def.model !== \"inherit\" ? { model: def.model.id } : {}),\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 * #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 model?: string;\n tools?: CustomTool[];\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 */\nfunction buildChildCreateOptions(\n spec: SubAgentSpec,\n inherited: InheritedCredentials | undefined,\n): AgentOptions {\n const model: string | ModelSelection | undefined = spec.model\n ? { id: spec.model }\n : inherited?.model;\n return {\n ...(inherited?.apiKey !== undefined ? { apiKey: inherited.apiKey } : {}),\n ...(model !== undefined ? { model } : {}),\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 * Per-subagent `mcpServers` on an `AgentDefinition` is honored by the cloud\n * runtime only; it is not wired into local delegation here.\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 ...(def.model !== undefined && def.model !== \"inherit\" ? { model: def.model.id } : {}),\n tools: [...childTools],\n });\n });\n}\n"]}
|
package/dist/a2a/index.js
CHANGED
|
@@ -106,7 +106,7 @@ function getAgentFacade() {
|
|
|
106
106
|
}
|
|
107
107
|
|
|
108
108
|
// src/a2a/subagent.ts
|
|
109
|
-
var INHERIT_CREDENTIALS = /* @__PURE__ */ Symbol("theokit.subagent.inheritCredentials");
|
|
109
|
+
var INHERIT_CREDENTIALS = /* @__PURE__ */ Symbol.for("theokit.subagent.inheritCredentials");
|
|
110
110
|
var MaxDelegationDepthError = class extends Error {
|
|
111
111
|
constructor(currentDepth, maxDepth) {
|
|
112
112
|
super(`Max delegation depth ${maxDepth} exceeded (current: ${currentDepth})`);
|
|
@@ -165,6 +165,13 @@ async function runChildAgent(spec, input, signal, maxSteps, inherited) {
|
|
|
165
165
|
};
|
|
166
166
|
const run = await agent.send(input, sendOptions);
|
|
167
167
|
const result = await run.wait();
|
|
168
|
+
if (result.status === "error") {
|
|
169
|
+
const cause = result.error;
|
|
170
|
+
throw new Error(
|
|
171
|
+
`subagent "${spec.name}" run failed: ${cause?.message ?? "unknown error"}`,
|
|
172
|
+
cause !== void 0 ? { cause } : void 0
|
|
173
|
+
);
|
|
174
|
+
}
|
|
168
175
|
const text = result.result ?? "(no response)";
|
|
169
176
|
return spec.includeToolResults === true ? text + await collectChildToolResults(run) : text;
|
|
170
177
|
} finally {
|
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":"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","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 */\nconst INHERIT_CREDENTIALS = Symbol(\"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 model?: string;\n tools?: CustomTool[];\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 */\nfunction buildChildCreateOptions(\n spec: SubAgentSpec,\n inherited: InheritedCredentials | undefined,\n): AgentOptions {\n const model: string | ModelSelection | undefined = spec.model\n ? { id: spec.model }\n : inherited?.model;\n return {\n ...(inherited?.apiKey !== undefined ? { apiKey: inherited.apiKey } : {}),\n ...(model !== undefined ? { model } : {}),\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 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 * Per-subagent `mcpServers` on an `AgentDefinition` is honored by the cloud\n * runtime only; it is not wired into local delegation here.\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 ...(def.model !== undefined && def.model !== \"inherit\" ? { model: def.model.id } : {}),\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":"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","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 model?: string;\n tools?: CustomTool[];\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 */\nfunction buildChildCreateOptions(\n spec: SubAgentSpec,\n inherited: InheritedCredentials | undefined,\n): AgentOptions {\n const model: string | ModelSelection | undefined = spec.model\n ? { id: spec.model }\n : inherited?.model;\n return {\n ...(inherited?.apiKey !== undefined ? { apiKey: inherited.apiKey } : {}),\n ...(model !== undefined ? { model } : {}),\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 * Per-subagent `mcpServers` on an `AgentDefinition` is honored by the cloud\n * runtime only; it is not wired into local delegation here.\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 ...(def.model !== undefined && def.model !== \"inherit\" ? { model: def.model.id } : {}),\n tools: [...childTools],\n });\n });\n}\n"]}
|
package/dist/cron.cjs
CHANGED
|
@@ -10235,11 +10235,28 @@ async function runToolWithLifecycle(inputs, resolved, call, callId) {
|
|
|
10235
10235
|
conversationId: inputs.agentId,
|
|
10236
10236
|
callId
|
|
10237
10237
|
});
|
|
10238
|
+
await emitToolLifecycleDelta(inputs, {
|
|
10239
|
+
type: "tool-call-started",
|
|
10240
|
+
callId,
|
|
10241
|
+
toolCall: { callId, name: call.name, args: call.input },
|
|
10242
|
+
modelCallId: callId
|
|
10243
|
+
});
|
|
10238
10244
|
const result = await raceToolExecution(executeTool(inputs, resolved, call), {
|
|
10239
10245
|
signal: inputs.signal,
|
|
10240
10246
|
timeoutMs: inputs.perToolTimeoutMs
|
|
10241
10247
|
});
|
|
10242
10248
|
const durationMs = Date.now() - startAt;
|
|
10249
|
+
await emitToolLifecycleDelta(inputs, {
|
|
10250
|
+
type: "tool-call-completed",
|
|
10251
|
+
callId,
|
|
10252
|
+
toolCall: {
|
|
10253
|
+
callId,
|
|
10254
|
+
name: call.name,
|
|
10255
|
+
args: call.input,
|
|
10256
|
+
result: result.content !== void 0 ? result.content : renderToolResult(result)
|
|
10257
|
+
},
|
|
10258
|
+
modelCallId: callId
|
|
10259
|
+
});
|
|
10243
10260
|
inputs.telemetry?.recordHistogram(HISTOGRAM_NAMES.TOOL_CALL_DURATION_MS, durationMs, {
|
|
10244
10261
|
"tool.name": call.name
|
|
10245
10262
|
});
|
|
@@ -10305,6 +10322,17 @@ function finalizeSpanAndPostHook(inputs, call, callId, result, events, toolSpan)
|
|
|
10305
10322
|
...result.exitCode !== 0 && result.exitCode !== void 0 ? { isError: true } : {}
|
|
10306
10323
|
};
|
|
10307
10324
|
}
|
|
10325
|
+
async function emitToolLifecycleDelta(inputs, update) {
|
|
10326
|
+
if (inputs.onDelta === void 0) return;
|
|
10327
|
+
try {
|
|
10328
|
+
await inputs.onDelta({ update });
|
|
10329
|
+
} catch (err) {
|
|
10330
|
+
process.stderr.write(
|
|
10331
|
+
`[theokit-sdk] onDelta tool-lifecycle emit error (swallowed): ${err instanceof Error ? err.message : String(err)}
|
|
10332
|
+
`
|
|
10333
|
+
);
|
|
10334
|
+
}
|
|
10335
|
+
}
|
|
10308
10336
|
async function safeEmitToolHook(callback, event) {
|
|
10309
10337
|
if (callback === void 0) return;
|
|
10310
10338
|
try {
|
|
@@ -13737,7 +13765,7 @@ function detectPrimaryProvider() {
|
|
|
13737
13765
|
|
|
13738
13766
|
// src/a2a/subagent.ts
|
|
13739
13767
|
init_agent_factory_registry();
|
|
13740
|
-
var INHERIT_CREDENTIALS = /* @__PURE__ */ Symbol("theokit.subagent.inheritCredentials");
|
|
13768
|
+
var INHERIT_CREDENTIALS = /* @__PURE__ */ Symbol.for("theokit.subagent.inheritCredentials");
|
|
13741
13769
|
function inheritSubAgentCredentials(tool, creds) {
|
|
13742
13770
|
const sink = tool[INHERIT_CREDENTIALS];
|
|
13743
13771
|
if (typeof sink === "function") sink(creds);
|
|
@@ -13800,6 +13828,13 @@ async function runChildAgent(spec, input, signal, maxSteps, inherited) {
|
|
|
13800
13828
|
};
|
|
13801
13829
|
const run = await agent.send(input, sendOptions);
|
|
13802
13830
|
const result = await run.wait();
|
|
13831
|
+
if (result.status === "error") {
|
|
13832
|
+
const cause = result.error;
|
|
13833
|
+
throw new Error(
|
|
13834
|
+
`subagent "${spec.name}" run failed: ${cause?.message ?? "unknown error"}`,
|
|
13835
|
+
cause !== void 0 ? { cause } : void 0
|
|
13836
|
+
);
|
|
13837
|
+
}
|
|
13803
13838
|
const text = result.result ?? "(no response)";
|
|
13804
13839
|
return spec.includeToolResults === true ? text + await collectChildToolResults(run) : text;
|
|
13805
13840
|
} finally {
|