@theokit/sdk 2.22.0 → 2.23.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 CHANGED
@@ -1,5 +1,29 @@
1
1
  # Changelog
2
2
 
3
+ ## 2.23.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 271f6e4: **SE13 — `modifiedMaxSteps` on `onDelegationStart` (cap the subagent's iterations).**
8
+
9
+ `DelegationStartDecision` (from `@theokit/sdk/a2a`) gains `modifiedMaxSteps?: number`. When an `onDelegationStart` hook returns it (and does not reject), `defineSubAgent` forwards it as `SendOptions.maxIterations` to the child `agent.send`, capping how many tool-loop rounds the subagent may run. Composes with SE10 (`signal`) and SE12 (`messageFilter` preamble) onto a single child `send`. Absent ⇒ the child uses its default iteration ceiling (unchanged).
10
+
11
+ Completes the SE11 `onDelegationStart` decision contract (the deferred `modifiedMaxSteps` — the `SendOptions.maxIterations` plumbing already existed). Additive + backward-compatible. From the Mastra supervisor-agents comparison (SDK Evolution roadmap SE13).
12
+
13
+ - b51dc6a: **SE14 — subagent result-context control (`SubAgentSpec.includeToolResults`).**
14
+
15
+ `defineSubAgent()` (from `@theokit/sdk/a2a`) gains an opt-in `includeToolResults`. When `true`, the child's completed tool-call results (name + result) are appended to the delegation payload returned to the supervisor, inside a delimited `<subagent-tool-results>` block; when absent/`false` the delegation returns the child's final text only — **text-only stays the default** (Mastra's scoped posture).
16
+
17
+ Implemented as a `run.stream()` replay after `run.wait()` (a proven, safe idiom — the run buffers events and `stream()` replays them) collecting `tool_call` events with `status: "completed"`. **No `RunResult` change** — reads the existing public stream surface; tool _args_ are never surfaced (only completed results). Rationale + the `RunResult`-field alternative are recorded in ADR 0006.
18
+
19
+ Additive + backward-compatible (default `false` never touches the stream). From the Mastra supervisor-agents comparison (SDK Evolution roadmap SE14).
20
+
21
+ - 30e02d9: **SE15 — `iteration` count on the delegation-hook context (reject-after-N).**
22
+
23
+ `DelegationStartContext` and `DelegationCompleteContext` (from `@theokit/sdk/a2a`) gain `iteration: number` — a 1-based per-`defineSubAgent`-instance invocation counter, incremented before `onDelegationStart` runs (a rejected delegation still counts). This enables the Mastra reject-after-N-iterations pattern: `onDelegationStart: (ctx) => ctx.iteration > 8 ? { proceed: false, rejectionReason } : { proceed: true }`. `onDelegationComplete` sees the same iteration its `onDelegationStart` did.
24
+
25
+ Also fixes a delegation-hook DX regression: `onDelegationStart` / `onDelegationComplete` now accept a **side-effect-only (void-returning) callback** (e.g. `(ctx) => { log(ctx) }`) — the common case, mirroring Mastra's `async ctx => { … }` hooks — via a shared `DelegationHookResult<T>` return type. Additive + backward-compatible. From the Mastra supervisor-agents comparison (SDK Evolution roadmap SE15).
26
+
3
27
  ## 2.22.0
4
28
 
5
29
  ### Minor Changes
@@ -18426,15 +18426,33 @@ var MaxDelegationDepthError = class extends Error {
18426
18426
  maxDepth;
18427
18427
  code = "max_delegation_depth";
18428
18428
  };
18429
- async function applyDelegationStart(spec, input) {
18429
+ async function applyDelegationStart(spec, input, iteration) {
18430
18430
  if (spec.onDelegationStart === void 0) return { input };
18431
- const decision = await spec.onDelegationStart({ input, name: spec.name });
18431
+ const decision = await spec.onDelegationStart({ input, name: spec.name, iteration });
18432
18432
  if (decision === void 0) return { input };
18433
18433
  if (decision.proceed === false)
18434
18434
  return { reject: decision.rejectionReason ?? "(delegation rejected)" };
18435
- return { input: decision.modifiedInput ?? input };
18435
+ return {
18436
+ input: decision.modifiedInput ?? input,
18437
+ ...decision.modifiedMaxSteps !== void 0 ? { maxSteps: decision.modifiedMaxSteps } : {}
18438
+ };
18439
+ }
18440
+ async function collectChildToolResults(run) {
18441
+ const lines = [];
18442
+ for await (const event of run.stream()) {
18443
+ if (event.type === "tool_call" && event.status === "completed") {
18444
+ const rendered = typeof event.result === "string" ? event.result : JSON.stringify(event.result ?? null);
18445
+ lines.push(`${event.name}: ${rendered}`);
18446
+ }
18447
+ }
18448
+ if (lines.length === 0) return "";
18449
+ return `
18450
+
18451
+ <subagent-tool-results>
18452
+ ${lines.join("\n")}
18453
+ </subagent-tool-results>`;
18436
18454
  }
18437
- async function runChildAgent(spec, input, signal) {
18455
+ async function runChildAgent(spec, input, signal, maxSteps) {
18438
18456
  const { Agent: Agent2 } = await Promise.resolve().then(() => (init_agent(), agent_exports));
18439
18457
  const agent = await Agent2.create({
18440
18458
  ...spec.model ? { model: { id: spec.model } } : {},
@@ -18442,17 +18460,22 @@ async function runChildAgent(spec, input, signal) {
18442
18460
  tools: spec.tools ?? []
18443
18461
  });
18444
18462
  try {
18445
- const run = signal !== void 0 ? await agent.send(input, { signal }) : await agent.send(input);
18463
+ const sendOptions = {
18464
+ ...signal !== void 0 ? { signal } : {},
18465
+ ...maxSteps !== void 0 ? { maxIterations: maxSteps } : {}
18466
+ };
18467
+ const run = Object.keys(sendOptions).length > 0 ? await agent.send(input, sendOptions) : await agent.send(input);
18446
18468
  const result = await run.wait();
18447
- return result.result ?? "(no response)";
18469
+ const text = result.result ?? "(no response)";
18470
+ return spec.includeToolResults === true ? text + await collectChildToolResults(run) : text;
18448
18471
  } finally {
18449
18472
  agent.dispose();
18450
18473
  }
18451
18474
  }
18452
- async function notifyDelegationError(spec, input, error) {
18475
+ async function notifyDelegationError(spec, input, error, iteration) {
18453
18476
  if (spec.onDelegationComplete === void 0) return;
18454
18477
  try {
18455
- await spec.onDelegationComplete({ input, name: spec.name, error });
18478
+ await spec.onDelegationComplete({ input, name: spec.name, error, iteration });
18456
18479
  } catch {
18457
18480
  }
18458
18481
  }
@@ -18467,9 +18490,9 @@ ${preamble}
18467
18490
  Task:
18468
18491
  ${input}`;
18469
18492
  }
18470
- async function applyDelegationComplete(spec, input, result) {
18493
+ async function applyDelegationComplete(spec, input, result, iteration) {
18471
18494
  if (spec.onDelegationComplete === void 0) return result;
18472
- const completion = await spec.onDelegationComplete({ input, name: spec.name, result });
18495
+ const completion = await spec.onDelegationComplete({ input, name: spec.name, result, iteration });
18473
18496
  return completion?.feedback !== void 0 ? result + completion.feedback : result;
18474
18497
  }
18475
18498
  function defineSubAgent(spec, _parentDepth = 0) {
@@ -18481,23 +18504,26 @@ function defineSubAgent(spec, _parentDepth = 0) {
18481
18504
  const inputSchema = zod.z.object({
18482
18505
  input: zod.z.string().describe("Task for the subagent")
18483
18506
  });
18507
+ let iteration = 0;
18484
18508
  return {
18485
18509
  name: spec.name,
18486
18510
  description: spec.description,
18487
18511
  inputSchema,
18488
18512
  handler: async (rawInput, ctx) => {
18489
18513
  const { input: parsed } = inputSchema.parse(rawInput);
18490
- const start = await applyDelegationStart(spec, parsed);
18514
+ iteration += 1;
18515
+ const capturedIteration = iteration;
18516
+ const start = await applyDelegationStart(spec, parsed, capturedIteration);
18491
18517
  if ("reject" in start) return start.reject;
18492
18518
  const input = applyMessageFilter(spec, start.input, ctx?.messages);
18493
18519
  let result;
18494
18520
  try {
18495
- result = await runChildAgent(spec, input, ctx?.signal);
18521
+ result = await runChildAgent(spec, input, ctx?.signal, start.maxSteps);
18496
18522
  } catch (error) {
18497
- await notifyDelegationError(spec, input, error);
18523
+ await notifyDelegationError(spec, input, error, capturedIteration);
18498
18524
  throw error;
18499
18525
  }
18500
- return applyDelegationComplete(spec, input, result);
18526
+ return applyDelegationComplete(spec, input, result, capturedIteration);
18501
18527
  }
18502
18528
  };
18503
18529
  }