@theokit/sdk 2.22.0 → 2.24.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 +52 -0
- package/dist/a2a/index.cjs +43 -15
- package/dist/a2a/index.cjs.map +1 -1
- package/dist/a2a/index.js +43 -15
- package/dist/a2a/index.js.map +1 -1
- package/dist/a2a/subagent.d.cts +27 -2
- package/dist/a2a/subagent.d.ts +27 -2
- package/dist/{cron-Bpt_1khA.d.cts → cron-Bd2oRD7A.d.cts} +1 -1
- package/dist/{cron-7CruUd_0.d.ts → cron-vjod0qVQ.d.ts} +1 -1
- package/dist/cron.cjs +3 -1
- 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 +3 -1
- package/dist/cron.js.map +1 -1
- package/dist/define-tool.d.ts +33 -20
- package/dist/{errors-CkCaIqVP.d.cts → errors-DIKBXffg.d.cts} +1 -1
- package/dist/{errors-BuwwkrAk.d.ts → errors-DRS-kqOK.d.ts} +1 -1
- package/dist/errors.d.cts +2 -2
- package/dist/eval.cjs +3 -1
- package/dist/eval.cjs.map +1 -1
- package/dist/eval.js +3 -1
- package/dist/eval.js.map +1 -1
- package/dist/index.cjs +10 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +37 -26
- package/dist/index.d.ts +37 -26
- package/dist/index.js +10 -2
- package/dist/index.js.map +1 -1
- package/dist/{run-CrIulPF7.d.cts → run-Cr0C6cOM.d.cts} +17 -0
- package/dist/{run-CrIulPF7.d.ts → run-Cr0C6cOM.d.ts} +17 -0
- package/dist/types/run.d.ts +17 -0
- package/dist/workflow.cjs +37 -0
- package/dist/workflow.cjs.map +1 -1
- package/dist/workflow.d.cts +47 -1
- package/dist/workflow.d.ts +47 -1
- package/dist/workflow.js +37 -2
- package/dist/workflow.js.map +1 -1
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,57 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2.24.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 7be1f18: **SE16 — `outputSchema` on `defineTool` (validate + infer the tool's return).**
|
|
8
|
+
|
|
9
|
+
`defineTool` (from `@theokit/sdk`) gains an optional `outputSchema` (a Zod schema). When set, the handler returns the STRUCTURED output inferred from it (`z.infer<outputSchema>`), the value is validated against the schema, and the tool result becomes its serialization — a string stays as-is, an object is JSON-stringified. A validation failure raises `ZodError` (converted to a `tool_result(isError)`), so a malformed tool output fails loudly instead of silently reaching the model.
|
|
10
|
+
|
|
11
|
+
Additive + fully backward-compatible: with no `outputSchema` the handler returns a plain `string` exactly as before (the handler return type is `string` when `outputSchema` is absent, `z.infer<outputSchema>` when present, via a conditional type). Mirrors Mastra `createTool`'s `outputSchema`. Pairs with SE17 (`toModelOutput`). From the Mastra Tools comparison (SDK Evolution roadmap SE16).
|
|
12
|
+
|
|
13
|
+
- f621734: **SE17 — `toModelOutput` on `defineTool` (model-facing vs app-facing output split).**
|
|
14
|
+
|
|
15
|
+
`defineTool` (from `@theokit/sdk`) gains an optional `toModelOutput`. The handler returns the FULL result (validated by SE16's `outputSchema`); `toModelOutput(output)` maps it to the compact / multimodal representation the MODEL sees in the `tool_result` — so rich app-facing detail is not forced into model context. It returns a `string` OR SE7 `ToolResultContentBlock[]` (text + image). Absent ⇒ the tool result is the serialized handler output (SE16 / pre-SE17 behavior, unchanged).
|
|
16
|
+
|
|
17
|
+
Mirrors Mastra's `toModelOutput` and the Vercel AI SDK. Additive + backward-compatible. From the Mastra Tools comparison (SDK Evolution roadmap SE17).
|
|
18
|
+
|
|
19
|
+
- 72435db: **SE18 — `SendOptions.activeTools` (per-send runtime tool subset).**
|
|
20
|
+
|
|
21
|
+
`agent.send(input, { activeTools })` restricts, per send, which of the agent's registered tools the model may actually call. A tool whose canonical name is not in the list is vetoed at dispatch (its handler never runs) — reusing the existing `withToolWhitelist` path that `Agent.fork`'s `allowedTools` uses, NOT `PermissionEngine`. Composes with `toolChoice`: `activeTools` narrows the set, `toolChoice` gates calling within it. Absent ⇒ the full toolset is available (unchanged).
|
|
22
|
+
|
|
23
|
+
The loop runs inside a `withToolWhitelist(new Set(activeTools))` scope when set. Additive + backward-compatible. Mirrors Mastra `activeTools` + the Vercel AI SDK. From the Mastra Tools comparison (SDK Evolution roadmap SE18).
|
|
24
|
+
|
|
25
|
+
- f92f720: **SE19 — `workflowAsTool` (expose a Workflow as an agent tool).**
|
|
26
|
+
|
|
27
|
+
`workflowAsTool(workflow, { name, description, inputSchema })` (from `@theokit/sdk/workflow`) turns a `Workflow` into an agent `CustomTool`, completing the Mastra "X as tools" trio (tools; agents-as-tools via `defineSubAgent`; workflows-as-tools). The handler validates the model's args against `spec.inputSchema`, runs the workflow, and returns its output (a string as-is, else JSON). A run that does not reach `status: "completed"` raises a typed `WorkflowToolError` (workflow step errors do NOT throw — they surface via `run.status === "failed"`).
|
|
28
|
+
|
|
29
|
+
Because a `Workflow` carries no top-level schema (`WorkflowOptions` is `name`/`persistence`/`workflowId`; schemas are per-step), the caller supplies the tool `inputSchema` in the spec (like `defineTool`). Accepts any `{ run }`-shaped workflow (structural), so it never imports the `Workflow` class. New exports: `workflowAsTool`, `WorkflowToolError`, `WorkflowAsToolSpec`. Additive. From the Mastra Tools comparison (SDK Evolution roadmap SE19).
|
|
30
|
+
|
|
31
|
+
## 2.23.0
|
|
32
|
+
|
|
33
|
+
### Minor Changes
|
|
34
|
+
|
|
35
|
+
- 271f6e4: **SE13 — `modifiedMaxSteps` on `onDelegationStart` (cap the subagent's iterations).**
|
|
36
|
+
|
|
37
|
+
`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).
|
|
38
|
+
|
|
39
|
+
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).
|
|
40
|
+
|
|
41
|
+
- b51dc6a: **SE14 — subagent result-context control (`SubAgentSpec.includeToolResults`).**
|
|
42
|
+
|
|
43
|
+
`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).
|
|
44
|
+
|
|
45
|
+
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.
|
|
46
|
+
|
|
47
|
+
Additive + backward-compatible (default `false` never touches the stream). From the Mastra supervisor-agents comparison (SDK Evolution roadmap SE14).
|
|
48
|
+
|
|
49
|
+
- 30e02d9: **SE15 — `iteration` count on the delegation-hook context (reject-after-N).**
|
|
50
|
+
|
|
51
|
+
`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.
|
|
52
|
+
|
|
53
|
+
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).
|
|
54
|
+
|
|
3
55
|
## 2.22.0
|
|
4
56
|
|
|
5
57
|
### Minor Changes
|
package/dist/a2a/index.cjs
CHANGED
|
@@ -12922,6 +12922,7 @@ function buildLoopInputs(options, runId, userText) {
|
|
|
12922
12922
|
...options.onStep !== void 0 ? { onStep: options.onStep } : {},
|
|
12923
12923
|
...options.onDelta !== void 0 ? { onDelta: options.onDelta } : {},
|
|
12924
12924
|
...options.sendOptions.toolChoice !== void 0 ? { toolChoice: options.sendOptions.toolChoice } : {},
|
|
12925
|
+
...options.sendOptions.activeTools !== void 0 ? { activeTools: options.sendOptions.activeTools } : {},
|
|
12925
12926
|
...options.priorMessages !== void 0 ? { priorMessages: options.priorMessages } : {},
|
|
12926
12927
|
...options.memoryTools !== void 0 && options.memoryTools.length > 0 ? { memoryTools: options.memoryTools } : {},
|
|
12927
12928
|
...buildCustomToolsInput(
|
|
@@ -13021,6 +13022,7 @@ var init_real_local_run = __esm({
|
|
|
13021
13022
|
init_register_plugin_providers();
|
|
13022
13023
|
init_tracer();
|
|
13023
13024
|
init_personality_filter();
|
|
13025
|
+
init_async_local_storage();
|
|
13024
13026
|
init_fixture_run_base();
|
|
13025
13027
|
init_run_registry();
|
|
13026
13028
|
pluginProvidersAnnounced = false;
|
|
@@ -13070,7 +13072,7 @@ var init_real_local_run = __esm({
|
|
|
13070
13072
|
}
|
|
13071
13073
|
async executeAgentLoop(inputs) {
|
|
13072
13074
|
try {
|
|
13073
|
-
const output = await runAgentLoop(inputs);
|
|
13075
|
+
const output = inputs.activeTools !== void 0 ? await withToolWhitelist(new Set(inputs.activeTools), () => runAgentLoop(inputs)) : await runAgentLoop(inputs);
|
|
13074
13076
|
this.applyAgentLoopOutput(output);
|
|
13075
13077
|
this.transitionTo(output.finalStatus);
|
|
13076
13078
|
} catch (cause) {
|
|
@@ -18426,15 +18428,33 @@ var MaxDelegationDepthError = class extends Error {
|
|
|
18426
18428
|
maxDepth;
|
|
18427
18429
|
code = "max_delegation_depth";
|
|
18428
18430
|
};
|
|
18429
|
-
async function applyDelegationStart(spec, input) {
|
|
18431
|
+
async function applyDelegationStart(spec, input, iteration) {
|
|
18430
18432
|
if (spec.onDelegationStart === void 0) return { input };
|
|
18431
|
-
const decision = await spec.onDelegationStart({ input, name: spec.name });
|
|
18433
|
+
const decision = await spec.onDelegationStart({ input, name: spec.name, iteration });
|
|
18432
18434
|
if (decision === void 0) return { input };
|
|
18433
18435
|
if (decision.proceed === false)
|
|
18434
18436
|
return { reject: decision.rejectionReason ?? "(delegation rejected)" };
|
|
18435
|
-
return {
|
|
18437
|
+
return {
|
|
18438
|
+
input: decision.modifiedInput ?? input,
|
|
18439
|
+
...decision.modifiedMaxSteps !== void 0 ? { maxSteps: decision.modifiedMaxSteps } : {}
|
|
18440
|
+
};
|
|
18436
18441
|
}
|
|
18437
|
-
async function
|
|
18442
|
+
async function collectChildToolResults(run) {
|
|
18443
|
+
const lines = [];
|
|
18444
|
+
for await (const event of run.stream()) {
|
|
18445
|
+
if (event.type === "tool_call" && event.status === "completed") {
|
|
18446
|
+
const rendered = typeof event.result === "string" ? event.result : JSON.stringify(event.result ?? null);
|
|
18447
|
+
lines.push(`${event.name}: ${rendered}`);
|
|
18448
|
+
}
|
|
18449
|
+
}
|
|
18450
|
+
if (lines.length === 0) return "";
|
|
18451
|
+
return `
|
|
18452
|
+
|
|
18453
|
+
<subagent-tool-results>
|
|
18454
|
+
${lines.join("\n")}
|
|
18455
|
+
</subagent-tool-results>`;
|
|
18456
|
+
}
|
|
18457
|
+
async function runChildAgent(spec, input, signal, maxSteps) {
|
|
18438
18458
|
const { Agent: Agent2 } = await Promise.resolve().then(() => (init_agent(), agent_exports));
|
|
18439
18459
|
const agent = await Agent2.create({
|
|
18440
18460
|
...spec.model ? { model: { id: spec.model } } : {},
|
|
@@ -18442,17 +18462,22 @@ async function runChildAgent(spec, input, signal) {
|
|
|
18442
18462
|
tools: spec.tools ?? []
|
|
18443
18463
|
});
|
|
18444
18464
|
try {
|
|
18445
|
-
const
|
|
18465
|
+
const sendOptions = {
|
|
18466
|
+
...signal !== void 0 ? { signal } : {},
|
|
18467
|
+
...maxSteps !== void 0 ? { maxIterations: maxSteps } : {}
|
|
18468
|
+
};
|
|
18469
|
+
const run = Object.keys(sendOptions).length > 0 ? await agent.send(input, sendOptions) : await agent.send(input);
|
|
18446
18470
|
const result = await run.wait();
|
|
18447
|
-
|
|
18471
|
+
const text = result.result ?? "(no response)";
|
|
18472
|
+
return spec.includeToolResults === true ? text + await collectChildToolResults(run) : text;
|
|
18448
18473
|
} finally {
|
|
18449
18474
|
agent.dispose();
|
|
18450
18475
|
}
|
|
18451
18476
|
}
|
|
18452
|
-
async function notifyDelegationError(spec, input, error) {
|
|
18477
|
+
async function notifyDelegationError(spec, input, error, iteration) {
|
|
18453
18478
|
if (spec.onDelegationComplete === void 0) return;
|
|
18454
18479
|
try {
|
|
18455
|
-
await spec.onDelegationComplete({ input, name: spec.name, error });
|
|
18480
|
+
await spec.onDelegationComplete({ input, name: spec.name, error, iteration });
|
|
18456
18481
|
} catch {
|
|
18457
18482
|
}
|
|
18458
18483
|
}
|
|
@@ -18467,9 +18492,9 @@ ${preamble}
|
|
|
18467
18492
|
Task:
|
|
18468
18493
|
${input}`;
|
|
18469
18494
|
}
|
|
18470
|
-
async function applyDelegationComplete(spec, input, result) {
|
|
18495
|
+
async function applyDelegationComplete(spec, input, result, iteration) {
|
|
18471
18496
|
if (spec.onDelegationComplete === void 0) return result;
|
|
18472
|
-
const completion = await spec.onDelegationComplete({ input, name: spec.name, result });
|
|
18497
|
+
const completion = await spec.onDelegationComplete({ input, name: spec.name, result, iteration });
|
|
18473
18498
|
return completion?.feedback !== void 0 ? result + completion.feedback : result;
|
|
18474
18499
|
}
|
|
18475
18500
|
function defineSubAgent(spec, _parentDepth = 0) {
|
|
@@ -18481,23 +18506,26 @@ function defineSubAgent(spec, _parentDepth = 0) {
|
|
|
18481
18506
|
const inputSchema = zod.z.object({
|
|
18482
18507
|
input: zod.z.string().describe("Task for the subagent")
|
|
18483
18508
|
});
|
|
18509
|
+
let iteration = 0;
|
|
18484
18510
|
return {
|
|
18485
18511
|
name: spec.name,
|
|
18486
18512
|
description: spec.description,
|
|
18487
18513
|
inputSchema,
|
|
18488
18514
|
handler: async (rawInput, ctx) => {
|
|
18489
18515
|
const { input: parsed } = inputSchema.parse(rawInput);
|
|
18490
|
-
|
|
18516
|
+
iteration += 1;
|
|
18517
|
+
const capturedIteration = iteration;
|
|
18518
|
+
const start = await applyDelegationStart(spec, parsed, capturedIteration);
|
|
18491
18519
|
if ("reject" in start) return start.reject;
|
|
18492
18520
|
const input = applyMessageFilter(spec, start.input, ctx?.messages);
|
|
18493
18521
|
let result;
|
|
18494
18522
|
try {
|
|
18495
|
-
result = await runChildAgent(spec, input, ctx?.signal);
|
|
18523
|
+
result = await runChildAgent(spec, input, ctx?.signal, start.maxSteps);
|
|
18496
18524
|
} catch (error) {
|
|
18497
|
-
await notifyDelegationError(spec, input, error);
|
|
18525
|
+
await notifyDelegationError(spec, input, error, capturedIteration);
|
|
18498
18526
|
throw error;
|
|
18499
18527
|
}
|
|
18500
|
-
return applyDelegationComplete(spec, input, result);
|
|
18528
|
+
return applyDelegationComplete(spec, input, result, capturedIteration);
|
|
18501
18529
|
}
|
|
18502
18530
|
};
|
|
18503
18531
|
}
|