@theokit/sdk 2.21.0 → 2.22.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 +33 -0
- package/dist/a2a/index.cjs +73 -19
- package/dist/a2a/index.cjs.map +1 -1
- package/dist/a2a/index.d.cts +2 -1
- package/dist/a2a/index.d.ts +2 -1
- package/dist/a2a/index.js +73 -19
- package/dist/a2a/index.js.map +1 -1
- package/dist/a2a/subagent.d.cts +70 -1
- package/dist/a2a/subagent.d.ts +70 -1
- package/dist/{cron-dpvtRoro.d.ts → cron-7CruUd_0.d.ts} +1 -1
- package/dist/{cron-YrmsszEN.d.cts → cron-Bpt_1khA.d.cts} +1 -1
- package/dist/cron.cjs +16 -6
- package/dist/cron.cjs.map +1 -1
- package/dist/cron.d.cts +2 -2
- package/dist/cron.d.ts +2 -2
- package/dist/cron.js +16 -6
- package/dist/cron.js.map +1 -1
- package/dist/{errors-C4vZPqXf.d.ts → errors-BuwwkrAk.d.ts} +1 -1
- package/dist/{errors-DrcpYVfZ.d.cts → errors-CkCaIqVP.d.cts} +1 -1
- package/dist/errors.d.cts +2 -2
- package/dist/eval.cjs +16 -6
- package/dist/eval.cjs.map +1 -1
- package/dist/eval.js +16 -6
- package/dist/eval.js.map +1 -1
- package/dist/index.cjs +16 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -6
- package/dist/index.d.ts +6 -6
- package/dist/index.js +16 -6
- package/dist/index.js.map +1 -1
- package/dist/{run-BMo8yRwK.d.cts → run-CrIulPF7.d.cts} +22 -2
- package/dist/{run-BMo8yRwK.d.ts → run-CrIulPF7.d.ts} +22 -2
- package/dist/types/agent-prims.d.ts +21 -1
- package/dist/types/agent.d.ts +1 -1
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,38 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2.22.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 12cb30d: **SE10 — subagent delegation forwards the parent's `AbortSignal` (cancellation propagation).**
|
|
8
|
+
|
|
9
|
+
`defineSubAgent()` (from `@theokit/sdk/a2a`) now threads the run's cancellation into the child agent. When the agent loop dispatches the subagent tool it already passes the run's `AbortSignal` as the handler's `ctx.signal`; the subagent handler now forwards that signal to the child `agent.send(input, { signal })`. Aborting the parent run cancels the in-flight subagent at its next step instead of letting it run to completion (and burn tokens).
|
|
10
|
+
|
|
11
|
+
- Additive + backward-compatible: a handler invoked with no `ctx` (single-arg call sites) behaves exactly as before — no signal, no cancellation.
|
|
12
|
+
- The child agent is still disposed in `finally`, including on cancel.
|
|
13
|
+
|
|
14
|
+
Matches the Mastra supervisor-agents "abortSignal forwarded to delegated subagents" behavior (SDK Evolution roadmap SE10).
|
|
15
|
+
|
|
16
|
+
- 8e3249d: **SE11 — delegation lifecycle hooks on `defineSubAgent` (`onDelegationStart` / `onDelegationComplete`).**
|
|
17
|
+
|
|
18
|
+
`SubAgentSpec` (from `@theokit/sdk/a2a`) gains two optional hooks that let the caller intercept a delegation as it happens:
|
|
19
|
+
|
|
20
|
+
- `onDelegationStart({ input, name })` — return `{ proceed: false, rejectionReason }` to reject the delegation (the child never runs; `rejectionReason` becomes the tool result), or `{ modifiedInput }` to rewrite the prompt sent to the child.
|
|
21
|
+
- `onDelegationComplete({ input, name, result?, error? })` — runs after the delegation settles; on success an optional `{ feedback }` is appended to the child's result, and on failure `ctx.error` is set (the error is still re-thrown — never swallowed, Unbreakable Rule 8).
|
|
22
|
+
|
|
23
|
+
Additive + backward-compatible: specs without hooks behave exactly as before. New exported types: `DelegationStartContext`, `DelegationStartDecision`, `DelegationCompleteContext`, `DelegationCompleteDecision`.
|
|
24
|
+
|
|
25
|
+
Matches the Mastra supervisor `onDelegationStart` / `onDelegationComplete` control points (SDK Evolution roadmap SE11).
|
|
26
|
+
|
|
27
|
+
- d2d0d16: **SE12 — opt-in parent-context forwarding for subagents (`messageFilter`).**
|
|
28
|
+
|
|
29
|
+
`SubAgentSpec` (from `@theokit/sdk/a2a`) gains an optional `messageFilter`. When set, `defineSubAgent` forwards a filtered view of the supervisor's conversation to the child; when absent, the child runs input-only — **memory isolation stays the default**.
|
|
30
|
+
|
|
31
|
+
- New `ctx.messages` on the custom-tool handler `ToolContext`: a **read-only, text-only** projection of the current turn's transcript (`ToolContextMessage[]`), threaded by the agent loop the same way `ctx.signal` (#65) and `ctx.context` (M7) are. Non-text parts (tool calls / results) are dropped — a tool never sees raw wire parts or nested tool args.
|
|
32
|
+
- `messageFilter({ messages, input, name })` returns the subset to forward; `defineSubAgent` prepends it to the delegated input as a role-tagged context preamble. A filter returning `[]` forwards nothing. A filter that drops sensitive turns (e.g. anything `confidential`) provably keeps them out of the child context.
|
|
33
|
+
|
|
34
|
+
New exported types: `ToolContextMessage`, `MessageFilterArgs`. Additive + backward-compatible. Rationale + the transcript-exposure trade-off are recorded in ADR 0005. From the Mastra supervisor-agents comparison (SDK Evolution roadmap SE12).
|
|
35
|
+
|
|
3
36
|
## 2.21.0
|
|
4
37
|
|
|
5
38
|
### Minor Changes
|
package/dist/a2a/index.cjs
CHANGED
|
@@ -8326,21 +8326,21 @@ async function executeTool(inputs, resolved, call) {
|
|
|
8326
8326
|
if (resolved.origin === "shell") return runShellTool(inputs, call);
|
|
8327
8327
|
if (resolved.origin === "memory") return runMemoryTool(resolved, call, inputs.context);
|
|
8328
8328
|
if (resolved.origin === "custom")
|
|
8329
|
-
return runCustomTool(resolved, call, inputs.signal, inputs.context);
|
|
8329
|
+
return runCustomTool(resolved, call, inputs.signal, inputs.context, inputs.messages);
|
|
8330
8330
|
return runMcpTool(inputs, resolved, call);
|
|
8331
8331
|
}
|
|
8332
8332
|
async function runMemoryTool(resolved, call, context) {
|
|
8333
8333
|
return runHandlerTool("memory", resolved.memoryHandler, call, void 0, context);
|
|
8334
8334
|
}
|
|
8335
|
-
async function runCustomTool(resolved, call, signal, context) {
|
|
8336
|
-
return runHandlerTool("custom", resolved.customHandler, call, signal, context);
|
|
8335
|
+
async function runCustomTool(resolved, call, signal, context, messages) {
|
|
8336
|
+
return runHandlerTool("custom", resolved.customHandler, call, signal, context, messages);
|
|
8337
8337
|
}
|
|
8338
|
-
async function runHandlerTool(kind, handler, call, signal, context) {
|
|
8338
|
+
async function runHandlerTool(kind, handler, call, signal, context, messages) {
|
|
8339
8339
|
if (handler === void 0) {
|
|
8340
8340
|
return { stdout: "", stderr: `${kind} tool ${call.name} has no handler`, exitCode: 127 };
|
|
8341
8341
|
}
|
|
8342
8342
|
try {
|
|
8343
|
-
const out = await handler(call.input, { signal, context });
|
|
8343
|
+
const out = await handler(call.input, { signal, context, messages });
|
|
8344
8344
|
if (typeof out !== "string") return { stdout: "", stderr: "", exitCode: 0, content: out };
|
|
8345
8345
|
return { stdout: out, stderr: "", exitCode: 0 };
|
|
8346
8346
|
} catch (cause) {
|
|
@@ -9165,6 +9165,14 @@ var init_usage_and_cost = __esm({
|
|
|
9165
9165
|
});
|
|
9166
9166
|
|
|
9167
9167
|
// src/internal/agent-loop/loop.ts
|
|
9168
|
+
function projectToolContextMessages(messages) {
|
|
9169
|
+
const projected = [];
|
|
9170
|
+
for (const m of messages) {
|
|
9171
|
+
const content = m.content.flatMap((p) => p.type === "text" ? [p.text] : []).join("");
|
|
9172
|
+
if (content !== "") projected.push({ role: m.role, content });
|
|
9173
|
+
}
|
|
9174
|
+
return projected;
|
|
9175
|
+
}
|
|
9168
9176
|
async function runAgentLoop(inputs) {
|
|
9169
9177
|
const sendSpan = inputs.telemetry?.startSpan("agent.send", {
|
|
9170
9178
|
agentId: inputs.agentId,
|
|
@@ -9405,7 +9413,9 @@ async function continueOrTerminate(inputs, ctx, llmOutput) {
|
|
|
9405
9413
|
const outText = await transformLlmOutputText(inputs, llmOutput.text, tCtx);
|
|
9406
9414
|
ctx.messages.push(buildAssistantTurn(outText, llmOutput.toolCalls));
|
|
9407
9415
|
const rawResults = await dispatchTools(
|
|
9408
|
-
|
|
9416
|
+
// SE12 — forward a read-only text projection of the transcript-so-far to tool
|
|
9417
|
+
// handlers via `ctx.messages` (consumed by defineSubAgent's messageFilter).
|
|
9418
|
+
{ ...inputs, messages: projectToolContextMessages(ctx.messages) },
|
|
9409
9419
|
ctx.tools,
|
|
9410
9420
|
llmOutput.toolCalls,
|
|
9411
9421
|
ctx.events,
|
|
@@ -18416,6 +18426,52 @@ var MaxDelegationDepthError = class extends Error {
|
|
|
18416
18426
|
maxDepth;
|
|
18417
18427
|
code = "max_delegation_depth";
|
|
18418
18428
|
};
|
|
18429
|
+
async function applyDelegationStart(spec, input) {
|
|
18430
|
+
if (spec.onDelegationStart === void 0) return { input };
|
|
18431
|
+
const decision = await spec.onDelegationStart({ input, name: spec.name });
|
|
18432
|
+
if (decision === void 0) return { input };
|
|
18433
|
+
if (decision.proceed === false)
|
|
18434
|
+
return { reject: decision.rejectionReason ?? "(delegation rejected)" };
|
|
18435
|
+
return { input: decision.modifiedInput ?? input };
|
|
18436
|
+
}
|
|
18437
|
+
async function runChildAgent(spec, input, signal) {
|
|
18438
|
+
const { Agent: Agent2 } = await Promise.resolve().then(() => (init_agent(), agent_exports));
|
|
18439
|
+
const agent = await Agent2.create({
|
|
18440
|
+
...spec.model ? { model: { id: spec.model } } : {},
|
|
18441
|
+
systemPrompt: spec.instructions,
|
|
18442
|
+
tools: spec.tools ?? []
|
|
18443
|
+
});
|
|
18444
|
+
try {
|
|
18445
|
+
const run = signal !== void 0 ? await agent.send(input, { signal }) : await agent.send(input);
|
|
18446
|
+
const result = await run.wait();
|
|
18447
|
+
return result.result ?? "(no response)";
|
|
18448
|
+
} finally {
|
|
18449
|
+
agent.dispose();
|
|
18450
|
+
}
|
|
18451
|
+
}
|
|
18452
|
+
async function notifyDelegationError(spec, input, error) {
|
|
18453
|
+
if (spec.onDelegationComplete === void 0) return;
|
|
18454
|
+
try {
|
|
18455
|
+
await spec.onDelegationComplete({ input, name: spec.name, error });
|
|
18456
|
+
} catch {
|
|
18457
|
+
}
|
|
18458
|
+
}
|
|
18459
|
+
function applyMessageFilter(spec, input, messages) {
|
|
18460
|
+
if (spec.messageFilter === void 0 || messages === void 0) return input;
|
|
18461
|
+
const filtered = spec.messageFilter({ messages, input, name: spec.name });
|
|
18462
|
+
if (filtered.length === 0) return input;
|
|
18463
|
+
const preamble = filtered.map((m) => `${m.role}: ${m.content}`).join("\n");
|
|
18464
|
+
return `Prior conversation:
|
|
18465
|
+
${preamble}
|
|
18466
|
+
|
|
18467
|
+
Task:
|
|
18468
|
+
${input}`;
|
|
18469
|
+
}
|
|
18470
|
+
async function applyDelegationComplete(spec, input, result) {
|
|
18471
|
+
if (spec.onDelegationComplete === void 0) return result;
|
|
18472
|
+
const completion = await spec.onDelegationComplete({ input, name: spec.name, result });
|
|
18473
|
+
return completion?.feedback !== void 0 ? result + completion.feedback : result;
|
|
18474
|
+
}
|
|
18419
18475
|
function defineSubAgent(spec, _parentDepth = 0) {
|
|
18420
18476
|
const currentDepth = _parentDepth + 1;
|
|
18421
18477
|
const maxDepth = spec.maxDelegationDepth ?? 3;
|
|
@@ -18429,21 +18485,19 @@ function defineSubAgent(spec, _parentDepth = 0) {
|
|
|
18429
18485
|
name: spec.name,
|
|
18430
18486
|
description: spec.description,
|
|
18431
18487
|
inputSchema,
|
|
18432
|
-
handler: async (rawInput) => {
|
|
18433
|
-
const { input } = inputSchema.parse(rawInput);
|
|
18434
|
-
const
|
|
18435
|
-
|
|
18436
|
-
|
|
18437
|
-
|
|
18438
|
-
tools: spec.tools ?? []
|
|
18439
|
-
});
|
|
18488
|
+
handler: async (rawInput, ctx) => {
|
|
18489
|
+
const { input: parsed } = inputSchema.parse(rawInput);
|
|
18490
|
+
const start = await applyDelegationStart(spec, parsed);
|
|
18491
|
+
if ("reject" in start) return start.reject;
|
|
18492
|
+
const input = applyMessageFilter(spec, start.input, ctx?.messages);
|
|
18493
|
+
let result;
|
|
18440
18494
|
try {
|
|
18441
|
-
|
|
18442
|
-
|
|
18443
|
-
|
|
18444
|
-
|
|
18445
|
-
agent.dispose();
|
|
18495
|
+
result = await runChildAgent(spec, input, ctx?.signal);
|
|
18496
|
+
} catch (error) {
|
|
18497
|
+
await notifyDelegationError(spec, input, error);
|
|
18498
|
+
throw error;
|
|
18446
18499
|
}
|
|
18500
|
+
return applyDelegationComplete(spec, input, result);
|
|
18447
18501
|
}
|
|
18448
18502
|
};
|
|
18449
18503
|
}
|