@theokit/sdk 3.5.0 → 3.6.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/dist/eval.cjs CHANGED
@@ -962,10 +962,10 @@ function buildToolPrompt(prompt) {
962
962
  Respond by calling the \`output\` tool with the structured answer that matches the schema.`;
963
963
  }
964
964
  function setupStructuredOutput(schema, maxRetries) {
965
- const z8 = requireZod();
965
+ const z9 = requireZod();
966
966
  const jsonSchema = toJsonSchema(schema, { unrepresentable: "any" });
967
967
  return {
968
- z: z8,
968
+ z: z9,
969
969
  jsonSchema,
970
970
  maxRetries: maxRetries ?? 1,
971
971
  initialUsage: { inputTokens: 0, outputTokens: 0 }
@@ -5755,6 +5755,213 @@ var init_subagents_loader = __esm({
5755
5755
  init_yaml_frontmatter();
5756
5756
  }
5757
5757
  });
5758
+ function loadJsonrepair() {
5759
+ if (cachedJsonrepair === void 0) {
5760
+ const req = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('eval.cjs', document.baseURI).href)));
5761
+ cachedJsonrepair = req("jsonrepair").jsonrepair;
5762
+ }
5763
+ return cachedJsonrepair;
5764
+ }
5765
+ function isPlainObject(v) {
5766
+ return v !== null && typeof v === "object" && !Array.isArray(v);
5767
+ }
5768
+ function toFiniteNumber(raw) {
5769
+ if (raw === "") return void 0;
5770
+ const n = Number(raw);
5771
+ return Number.isFinite(n) && String(n) === raw ? n : void 0;
5772
+ }
5773
+ function tryJson(raw, repair) {
5774
+ const t = raw.trimStart();
5775
+ if (!(t.startsWith("{") || t.startsWith("["))) return void 0;
5776
+ try {
5777
+ return JSON.parse(repair ? loadJsonrepair()(t) : t);
5778
+ } catch {
5779
+ return void 0;
5780
+ }
5781
+ }
5782
+ function heuristicCoerce(raw, repairJson) {
5783
+ if (raw === "true") return true;
5784
+ if (raw === "false") return false;
5785
+ if (raw === "null") return null;
5786
+ const n = toFiniteNumber(raw);
5787
+ if (n !== void 0) return n;
5788
+ const json = tryJson(raw, false) ?? (repairJson ? tryJson(raw, true) : void 0);
5789
+ return json === void 0 ? raw : json;
5790
+ }
5791
+ function coerceCandidates(raw, repairJson) {
5792
+ const out = [];
5793
+ if (raw === "true") out.push(true);
5794
+ else if (raw === "false") out.push(false);
5795
+ else if (raw === "null") out.push(null);
5796
+ const n = toFiniteNumber(raw);
5797
+ if (n !== void 0) out.push(n);
5798
+ const json = tryJson(raw, false) ?? (repairJson ? tryJson(raw, true) : void 0);
5799
+ if (json !== void 0) out.push(json);
5800
+ out.push(raw);
5801
+ return out;
5802
+ }
5803
+ function objectShape(schema) {
5804
+ const shape = schema?.shape;
5805
+ return shape !== null && typeof shape === "object" ? shape : void 0;
5806
+ }
5807
+ var cachedJsonrepair;
5808
+ var init_coerce = __esm({
5809
+ "src/sanitize/coerce.ts"() {
5810
+ }
5811
+ });
5812
+
5813
+ // src/sanitize/sanitize-tool-input.ts
5814
+ function applyTrim(key, value, ctx) {
5815
+ const trimmed = value.trim();
5816
+ if (trimmed !== value) ctx.notes.push(`trimmed "${key}"`);
5817
+ return trimmed;
5818
+ }
5819
+ function applyCoerce(key, raw, ctx) {
5820
+ const field = ctx.shape?.[key];
5821
+ let coerced = raw;
5822
+ if (field) {
5823
+ for (const candidate of coerceCandidates(raw, ctx.repairJson)) {
5824
+ if (field.safeParse(candidate).success) {
5825
+ coerced = candidate;
5826
+ break;
5827
+ }
5828
+ }
5829
+ } else {
5830
+ coerced = heuristicCoerce(raw, ctx.repairJson);
5831
+ }
5832
+ if (coerced !== raw) ctx.notes.push(`coerced "${key}"`);
5833
+ return coerced;
5834
+ }
5835
+ function applyRepair(key, value, ctx) {
5836
+ const repaired = tryJson(value, true);
5837
+ if (repaired === void 0) return value;
5838
+ ctx.notes.push(`repaired json "${key}"`);
5839
+ return repaired;
5840
+ }
5841
+ function sanitizeString(key, value, ctx) {
5842
+ let out = ctx.trim ? applyTrim(key, value, ctx) : value;
5843
+ if (ctx.coerce && typeof out === "string") out = applyCoerce(key, out, ctx);
5844
+ if (ctx.repairJson && !ctx.coerce && typeof out === "string") out = applyRepair(key, out, ctx);
5845
+ return out;
5846
+ }
5847
+ function walk(input, ctx, depth) {
5848
+ const out = {};
5849
+ for (const [key, value] of Object.entries(input)) {
5850
+ if (typeof value === "string") out[key] = sanitizeString(key, value, ctx);
5851
+ else if (ctx.deep && depth < ctx.maxDepth && isPlainObject(value))
5852
+ out[key] = walk(value, ctx, depth + 1);
5853
+ else out[key] = value;
5854
+ }
5855
+ return out;
5856
+ }
5857
+ function sanitizeToolInput(input, options) {
5858
+ if (!isPlainObject(input)) return { value: input, changed: false, notes: [] };
5859
+ const ctx = {
5860
+ trim: options?.trim ?? true,
5861
+ coerce: options?.coerce ?? false,
5862
+ repairJson: options?.repairJson ?? false,
5863
+ deep: options?.deep ?? false,
5864
+ maxDepth: options?.maxDepth ?? 8,
5865
+ shape: objectShape(options?.schema),
5866
+ notes: []
5867
+ };
5868
+ const value = walk(input, ctx, 0);
5869
+ return { value, changed: ctx.notes.length > 0, notes: ctx.notes };
5870
+ }
5871
+ var init_sanitize_tool_input = __esm({
5872
+ "src/sanitize/sanitize-tool-input.ts"() {
5873
+ init_coerce();
5874
+ }
5875
+ });
5876
+
5877
+ // src/define-tool.ts
5878
+ async function runValidated(spec, input, ctx) {
5879
+ const raw = spec.sanitize ? sanitizeToolInput(input, {
5880
+ ...spec.sanitize === true ? {} : spec.sanitize,
5881
+ schema: spec.inputSchema
5882
+ }).value : input;
5883
+ const parsed = spec.inputSchema.parse(raw);
5884
+ const out = await spec.handler(parsed, ctx);
5885
+ return spec.outputSchema === void 0 ? out : spec.outputSchema.parse(out);
5886
+ }
5887
+ function serializeOutput(validated) {
5888
+ return typeof validated === "string" ? validated : JSON.stringify(validated);
5889
+ }
5890
+ function shapeModelOutput(spec, validated) {
5891
+ if (spec.toModelOutput !== void 0) return spec.toModelOutput(validated);
5892
+ return serializeOutput(validated);
5893
+ }
5894
+ function defineTool(spec) {
5895
+ const inputSchema = toJsonSchema(spec.inputSchema, {
5896
+ unrepresentable: "any"
5897
+ });
5898
+ const handler = async (input, ctx) => {
5899
+ const validated = await runValidated(spec, input, ctx);
5900
+ return shapeModelOutput(spec, validated);
5901
+ };
5902
+ const tool = { name: spec.name, description: spec.description, inputSchema, handler };
5903
+ if (spec.toModelOutput !== void 0) {
5904
+ const resolver = async (input, ctx) => {
5905
+ const validated = await runValidated(spec, input, ctx);
5906
+ return { model: shapeModelOutput(spec, validated), app: serializeOutput(validated) };
5907
+ };
5908
+ handler[TOOL_SPLIT_RESOLVER] = resolver;
5909
+ }
5910
+ return tool;
5911
+ }
5912
+ var TOOL_SPLIT_RESOLVER, Tool;
5913
+ var init_define_tool = __esm({
5914
+ "src/define-tool.ts"() {
5915
+ init_to_json_schema();
5916
+ init_sanitize_tool_input();
5917
+ TOOL_SPLIT_RESOLVER = /* @__PURE__ */ Symbol("theokit.toolSplitResolver");
5918
+ Tool = class {
5919
+ constructor() {
5920
+ }
5921
+ static create(spec) {
5922
+ return defineTool(spec);
5923
+ }
5924
+ };
5925
+ }
5926
+ });
5927
+ function createThinkTool() {
5928
+ return Tool.create({
5929
+ name: "think",
5930
+ description: "Scratchpad: reason through ONE step before answering. No side effects \u2014 your private reasoning space. Call it repeatedly before the final answer.",
5931
+ inputSchema: zod.z.object({ thought: zod.z.string().min(1, "think: `thought` must be non-empty.") }),
5932
+ handler: ({ thought }) => thought
5933
+ });
5934
+ }
5935
+ function isNativeReasoning(model) {
5936
+ if (model === void 0 || typeof model === "string") return false;
5937
+ const params = model.params;
5938
+ if (params === void 0) return false;
5939
+ return params.some((p) => NATIVE_REASONING_PARAM_IDS.has(p.id));
5940
+ }
5941
+ function warnDoubleReasoningOnce() {
5942
+ if (warned2.has("double-reasoning")) return;
5943
+ warned2.add("double-reasoning");
5944
+ process.stderr.write(
5945
+ "[theokit-sdk] `reasoning: true` skipped \u2014 a native reasoning model is configured (model.params thinking/reasoning); native reasoning wins. Remove one to silence.\n"
5946
+ );
5947
+ }
5948
+ function reasoningActive(reasoning, model) {
5949
+ if (reasoning !== true) return false;
5950
+ if (isNativeReasoning(model)) {
5951
+ warnDoubleReasoningOnce();
5952
+ return false;
5953
+ }
5954
+ return true;
5955
+ }
5956
+ var NATIVE_REASONING_PARAM_IDS, REASONING_PREAMBLE, warned2;
5957
+ var init_native_reasoning = __esm({
5958
+ "src/internal/runtime/reasoning/native-reasoning.ts"() {
5959
+ init_define_tool();
5960
+ NATIVE_REASONING_PARAM_IDS = /* @__PURE__ */ new Set(["thinking", "reasoning", "reasoning_effort"]);
5961
+ REASONING_PREAMBLE = "Think step by step before answering: use the `think` tool to reason through each step, validate your work, then answer. Reason about magnitude before comparing numbers.";
5962
+ warned2 = /* @__PURE__ */ new Set();
5963
+ }
5964
+ });
5758
5965
 
5759
5966
  // src/internal/runtime/skills/skill-frontmatter.ts
5760
5967
  function asString(v) {
@@ -6006,6 +6213,9 @@ async function buildAssemblyContext(inputs, userText, baseSystemPrompt, memoryFa
6006
6213
  if (activeMemorySummary !== void 0 && activeMemorySummary.length > 0) {
6007
6214
  assemblyCtx.activeMemorySummary = activeMemorySummary;
6008
6215
  }
6216
+ if (reasoningActive(inputs.options.reasoning, inputs.model)) {
6217
+ assemblyCtx.reasoning = true;
6218
+ }
6009
6219
  if (inputs.context !== void 0) {
6010
6220
  await inputs.context.applyScope(contextPaths);
6011
6221
  const internal = inputs.context.internalAssemblySnapshot();
@@ -6027,6 +6237,7 @@ async function assembleSystemPromptForSend(inputs, userText, baseSystemPrompt, m
6027
6237
  }
6028
6238
  var init_local_assembly = __esm({
6029
6239
  "src/internal/runtime/system-prompt/local-assembly.ts"() {
6240
+ init_native_reasoning();
6030
6241
  init_skills_manager();
6031
6242
  }
6032
6243
  });
@@ -6162,6 +6373,21 @@ ${lines.join("\n")}
6162
6373
  }
6163
6374
  });
6164
6375
 
6376
+ // src/internal/runtime/system-prompt/sources/reasoning-provider.ts
6377
+ var ReasoningPromptProvider;
6378
+ var init_reasoning_provider = __esm({
6379
+ "src/internal/runtime/system-prompt/sources/reasoning-provider.ts"() {
6380
+ init_native_reasoning();
6381
+ ReasoningPromptProvider = class {
6382
+ id = "reasoning";
6383
+ priority = 1;
6384
+ contribute(ctx) {
6385
+ return Promise.resolve(ctx.reasoning === true ? REASONING_PREAMBLE : void 0);
6386
+ }
6387
+ };
6388
+ }
6389
+ });
6390
+
6165
6391
  // src/internal/runtime/skills/skills-block.ts
6166
6392
  function buildSkillsBlock(skills) {
6167
6393
  if (skills.length === 0) return void 0;
@@ -6204,6 +6430,7 @@ var init_pipeline = __esm({
6204
6430
  init_base_provider();
6205
6431
  init_context_provider();
6206
6432
  init_memory_provider();
6433
+ init_reasoning_provider();
6207
6434
  init_skills_provider();
6208
6435
  SystemPromptPipeline = class _SystemPromptPipeline {
6209
6436
  providers;
@@ -6243,6 +6470,7 @@ var init_pipeline = __esm({
6243
6470
  */
6244
6471
  static default() {
6245
6472
  return new _SystemPromptPipeline([
6473
+ new ReasoningPromptProvider(),
6246
6474
  new ActiveMemoryPromptProvider(),
6247
6475
  new ContextPromptProvider(),
6248
6476
  new SkillsPromptProvider(),
@@ -7739,176 +7967,17 @@ var init_local_run = __esm({
7739
7967
  };
7740
7968
  }
7741
7969
  });
7742
- function inheritSubAgentCredentials(tool, creds) {
7743
- const sink = tool[INHERIT_CREDENTIALS];
7744
- if (typeof sink === "function") sink(creds);
7745
- }
7746
- async function applyDelegationStart(spec, input, iteration) {
7747
- if (spec.onDelegationStart === void 0) return { input };
7748
- const decision = await spec.onDelegationStart({ input, name: spec.name, iteration });
7749
- if (decision === void 0) return { input };
7750
- if (decision.proceed === false)
7751
- return { reject: decision.rejectionReason ?? "(delegation rejected)" };
7752
- return {
7753
- input: decision.modifiedInput ?? input,
7754
- ...decision.modifiedMaxSteps !== void 0 ? { maxSteps: decision.modifiedMaxSteps } : {}
7755
- };
7756
- }
7757
- async function collectChildToolResults(run) {
7758
- const lines = [];
7759
- for await (const event of run.stream()) {
7760
- if (event.type === "tool_call" && event.status === "completed") {
7761
- const rendered = typeof event.result === "string" ? event.result : JSON.stringify(event.result ?? null);
7762
- lines.push(`${event.name}: ${rendered}`);
7763
- }
7764
- }
7765
- if (lines.length === 0) return "";
7766
- return `
7767
7970
 
7768
- <subagent-tool-results>
7769
- ${lines.join("\n")}
7770
- </subagent-tool-results>`;
7771
- }
7772
- function buildChildCreateOptions(spec, inherited) {
7773
- const model = spec.model ? { id: spec.model } : inherited?.model;
7774
- return {
7775
- ...inherited?.apiKey !== void 0 ? { apiKey: inherited.apiKey } : {},
7776
- ...model !== void 0 ? { model } : {},
7777
- ...inherited?.plugins !== void 0 ? { plugins: inherited.plugins } : {},
7778
- systemPrompt: spec.instructions,
7779
- tools: spec.tools ?? []
7780
- };
7781
- }
7782
- async function runChildAgent(spec, input, signal, maxSteps, inherited) {
7783
- const { Agent: Agent2 } = await Promise.resolve().then(() => (init_agent(), agent_exports));
7784
- const agent = await Agent2.create(buildChildCreateOptions(spec, inherited));
7785
- try {
7786
- const sendOptions = {
7787
- ...signal !== void 0 ? { signal } : {},
7788
- ...maxSteps !== void 0 ? { maxIterations: maxSteps } : {},
7789
- // SE3 — a delegated child's turn is initiated by the coordinating parent.
7790
- origin: { kind: "coordinator" }
7791
- };
7792
- const run = await agent.send(input, sendOptions);
7793
- const result = await run.wait();
7794
- const text = result.result ?? "(no response)";
7795
- return spec.includeToolResults === true ? text + await collectChildToolResults(run) : text;
7796
- } finally {
7797
- agent.dispose();
7798
- }
7799
- }
7800
- async function notifyDelegationError(spec, input, error, iteration) {
7801
- if (spec.onDelegationComplete === void 0) return;
7971
+ // src/types/run-events.ts
7972
+ function emitRunEvent(sink, event) {
7973
+ if (sink === void 0) return;
7802
7974
  try {
7803
- await spec.onDelegationComplete({ input, name: spec.name, error, iteration });
7975
+ sink(event);
7804
7976
  } catch {
7805
7977
  }
7806
7978
  }
7807
- function applyMessageFilter(spec, input, messages) {
7808
- if (spec.messageFilter === void 0 || messages === void 0) return input;
7809
- const filtered = spec.messageFilter({ messages, input, name: spec.name });
7810
- if (filtered.length === 0) return input;
7811
- const preamble = filtered.map((m) => `${m.role}: ${m.content}`).join("\n");
7812
- return `Prior conversation:
7813
- ${preamble}
7814
-
7815
- Task:
7816
- ${input}`;
7817
- }
7818
- async function applyDelegationComplete(spec, input, result, iteration) {
7819
- if (spec.onDelegationComplete === void 0) return result;
7820
- const completion = await spec.onDelegationComplete({ input, name: spec.name, result, iteration });
7821
- return completion?.feedback !== void 0 ? result + completion.feedback : result;
7822
- }
7823
- function defineSubAgent(spec, _parentDepth = 0) {
7824
- const currentDepth = _parentDepth + 1;
7825
- const maxDepth = spec.maxDelegationDepth ?? 3;
7826
- if (currentDepth > maxDepth) {
7827
- throw new MaxDelegationDepthError(currentDepth, maxDepth);
7828
- }
7829
- const inputZod = zod.z.object({
7830
- input: zod.z.string().describe("Task for the subagent")
7831
- });
7832
- const inputSchema = {
7833
- type: "object",
7834
- properties: {
7835
- input: { type: "string", description: "Task for the subagent" }
7836
- },
7837
- required: ["input"],
7838
- additionalProperties: false
7839
- };
7840
- let iteration = 0;
7841
- let inherited;
7842
- const tool = {
7843
- name: spec.name,
7844
- description: spec.description,
7845
- inputSchema,
7846
- handler: async (rawInput, ctx) => {
7847
- const { input: parsed } = inputZod.parse(rawInput);
7848
- iteration += 1;
7849
- const capturedIteration = iteration;
7850
- const start = await applyDelegationStart(spec, parsed, capturedIteration);
7851
- if ("reject" in start) return start.reject;
7852
- const input = applyMessageFilter(spec, start.input, ctx?.messages);
7853
- let result;
7854
- try {
7855
- result = await runChildAgent(spec, input, ctx?.signal, start.maxSteps, inherited);
7856
- } catch (error) {
7857
- await notifyDelegationError(spec, input, error, capturedIteration);
7858
- throw error;
7859
- }
7860
- return applyDelegationComplete(spec, input, result, capturedIteration);
7861
- }
7862
- };
7863
- Object.defineProperty(tool, INHERIT_CREDENTIALS, {
7864
- value: ((creds) => {
7865
- inherited = creds;
7866
- }),
7867
- enumerable: false
7868
- });
7869
- return tool;
7870
- }
7871
- function subAgentToolsFromDefinitions(agents2, parentTools) {
7872
- return Object.entries(agents2).map(([name, def]) => {
7873
- const whitelist = Array.isArray(def.tools) && def.tools.length > 0 ? new Set(def.tools) : void 0;
7874
- const childTools = whitelist ? parentTools.filter((t) => whitelist.has(t.name)) : parentTools;
7875
- return defineSubAgent({
7876
- name,
7877
- description: def.description,
7878
- instructions: def.prompt,
7879
- ...def.model !== void 0 && def.model !== "inherit" ? { model: def.model.id } : {},
7880
- tools: [...childTools]
7881
- });
7882
- });
7883
- }
7884
- var INHERIT_CREDENTIALS, MaxDelegationDepthError;
7885
- var init_subagent = __esm({
7886
- "src/a2a/subagent.ts"() {
7887
- INHERIT_CREDENTIALS = /* @__PURE__ */ Symbol("theokit.subagent.inheritCredentials");
7888
- MaxDelegationDepthError = class extends Error {
7889
- constructor(currentDepth, maxDepth) {
7890
- super(`Max delegation depth ${maxDepth} exceeded (current: ${currentDepth})`);
7891
- this.currentDepth = currentDepth;
7892
- this.maxDepth = maxDepth;
7893
- this.name = "MaxDelegationDepthError";
7894
- }
7895
- currentDepth;
7896
- maxDepth;
7897
- code = "max_delegation_depth";
7898
- };
7899
- }
7900
- });
7901
-
7902
- // src/types/run-events.ts
7903
- function emitRunEvent(sink, event) {
7904
- if (sink === void 0) return;
7905
- try {
7906
- sink(event);
7907
- } catch {
7908
- }
7909
- }
7910
- var init_run_events = __esm({
7911
- "src/types/run-events.ts"() {
7979
+ var init_run_events = __esm({
7980
+ "src/types/run-events.ts"() {
7912
7981
  }
7913
7982
  });
7914
7983
 
@@ -8728,132 +8797,6 @@ var init_repair_middleware = __esm({
8728
8797
  DECIMAL_RE = /^-?\d+(\.\d+)?$/;
8729
8798
  }
8730
8799
  });
8731
- function loadJsonrepair() {
8732
- if (cachedJsonrepair === void 0) {
8733
- const req = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('eval.cjs', document.baseURI).href)));
8734
- cachedJsonrepair = req("jsonrepair").jsonrepair;
8735
- }
8736
- return cachedJsonrepair;
8737
- }
8738
- function isPlainObject(v) {
8739
- return v !== null && typeof v === "object" && !Array.isArray(v);
8740
- }
8741
- function toFiniteNumber(raw) {
8742
- if (raw === "") return void 0;
8743
- const n = Number(raw);
8744
- return Number.isFinite(n) && String(n) === raw ? n : void 0;
8745
- }
8746
- function tryJson(raw, repair) {
8747
- const t = raw.trimStart();
8748
- if (!(t.startsWith("{") || t.startsWith("["))) return void 0;
8749
- try {
8750
- return JSON.parse(repair ? loadJsonrepair()(t) : t);
8751
- } catch {
8752
- return void 0;
8753
- }
8754
- }
8755
- function heuristicCoerce(raw, repairJson) {
8756
- if (raw === "true") return true;
8757
- if (raw === "false") return false;
8758
- if (raw === "null") return null;
8759
- const n = toFiniteNumber(raw);
8760
- if (n !== void 0) return n;
8761
- const json = tryJson(raw, false) ?? (repairJson ? tryJson(raw, true) : void 0);
8762
- return json === void 0 ? raw : json;
8763
- }
8764
- function coerceCandidates(raw, repairJson) {
8765
- const out = [];
8766
- if (raw === "true") out.push(true);
8767
- else if (raw === "false") out.push(false);
8768
- else if (raw === "null") out.push(null);
8769
- const n = toFiniteNumber(raw);
8770
- if (n !== void 0) out.push(n);
8771
- const json = tryJson(raw, false) ?? (repairJson ? tryJson(raw, true) : void 0);
8772
- if (json !== void 0) out.push(json);
8773
- out.push(raw);
8774
- return out;
8775
- }
8776
- function objectShape(schema) {
8777
- const shape = schema?.shape;
8778
- return shape !== null && typeof shape === "object" ? shape : void 0;
8779
- }
8780
- var cachedJsonrepair;
8781
- var init_coerce = __esm({
8782
- "src/sanitize/coerce.ts"() {
8783
- }
8784
- });
8785
-
8786
- // src/sanitize/sanitize-tool-input.ts
8787
- function applyTrim(key, value, ctx) {
8788
- const trimmed = value.trim();
8789
- if (trimmed !== value) ctx.notes.push(`trimmed "${key}"`);
8790
- return trimmed;
8791
- }
8792
- function applyCoerce(key, raw, ctx) {
8793
- const field = ctx.shape?.[key];
8794
- let coerced = raw;
8795
- if (field) {
8796
- for (const candidate of coerceCandidates(raw, ctx.repairJson)) {
8797
- if (field.safeParse(candidate).success) {
8798
- coerced = candidate;
8799
- break;
8800
- }
8801
- }
8802
- } else {
8803
- coerced = heuristicCoerce(raw, ctx.repairJson);
8804
- }
8805
- if (coerced !== raw) ctx.notes.push(`coerced "${key}"`);
8806
- return coerced;
8807
- }
8808
- function applyRepair(key, value, ctx) {
8809
- const repaired = tryJson(value, true);
8810
- if (repaired === void 0) return value;
8811
- ctx.notes.push(`repaired json "${key}"`);
8812
- return repaired;
8813
- }
8814
- function sanitizeString(key, value, ctx) {
8815
- let out = ctx.trim ? applyTrim(key, value, ctx) : value;
8816
- if (ctx.coerce && typeof out === "string") out = applyCoerce(key, out, ctx);
8817
- if (ctx.repairJson && !ctx.coerce && typeof out === "string") out = applyRepair(key, out, ctx);
8818
- return out;
8819
- }
8820
- function walk(input, ctx, depth) {
8821
- const out = {};
8822
- for (const [key, value] of Object.entries(input)) {
8823
- if (typeof value === "string") out[key] = sanitizeString(key, value, ctx);
8824
- else if (ctx.deep && depth < ctx.maxDepth && isPlainObject(value))
8825
- out[key] = walk(value, ctx, depth + 1);
8826
- else out[key] = value;
8827
- }
8828
- return out;
8829
- }
8830
- function sanitizeToolInput(input, options) {
8831
- if (!isPlainObject(input)) return { value: input, changed: false, notes: [] };
8832
- const ctx = {
8833
- trim: options?.trim,
8834
- coerce: options?.coerce ?? false,
8835
- repairJson: options?.repairJson ?? false,
8836
- deep: options?.deep ?? false,
8837
- maxDepth: options?.maxDepth ?? 8,
8838
- shape: objectShape(options?.schema),
8839
- notes: []
8840
- };
8841
- const value = walk(input, ctx, 0);
8842
- return { value, changed: ctx.notes.length > 0, notes: ctx.notes };
8843
- }
8844
- var init_sanitize_tool_input = __esm({
8845
- "src/sanitize/sanitize-tool-input.ts"() {
8846
- init_coerce();
8847
- }
8848
- });
8849
-
8850
- // src/define-tool.ts
8851
- var TOOL_SPLIT_RESOLVER;
8852
- var init_define_tool = __esm({
8853
- "src/define-tool.ts"() {
8854
- TOOL_SPLIT_RESOLVER = /* @__PURE__ */ Symbol("theokit.toolSplitResolver");
8855
- }
8856
- });
8857
8800
 
8858
8801
  // src/tool-error.ts
8859
8802
  function renderToolErrorMessage(content) {
@@ -13291,6 +13234,198 @@ var init_register_plugin_providers = __esm({
13291
13234
  }
13292
13235
  });
13293
13236
 
13237
+ // src/internal/runtime/local-agent/real-local-run-provider.ts
13238
+ function inferProviderFromApiKey(apiKey) {
13239
+ if (apiKey === void 0 || apiKey.length === 0) return void 0;
13240
+ const byPrefix = [
13241
+ { provider: "openrouter", prefix: "sk-or-" },
13242
+ { provider: "anthropic", prefix: "sk-ant-" },
13243
+ { provider: "openai", prefix: "sk-" }
13244
+ ];
13245
+ for (const { provider, prefix } of byPrefix) {
13246
+ if (apiKey.startsWith(prefix) && getProviderProfile(provider) !== void 0) {
13247
+ return provider;
13248
+ }
13249
+ }
13250
+ return void 0;
13251
+ }
13252
+ function detectPrimaryProvider() {
13253
+ if (process.env.ANTHROPIC_API_KEY !== void 0 && process.env.ANTHROPIC_API_KEY.length > 0) {
13254
+ return "anthropic";
13255
+ }
13256
+ if (process.env.OPENAI_API_KEY !== void 0 && process.env.OPENAI_API_KEY.length > 0) {
13257
+ return "openai";
13258
+ }
13259
+ if (process.env.OPENROUTER_API_KEY !== void 0 && process.env.OPENROUTER_API_KEY.length > 0) {
13260
+ return "openrouter";
13261
+ }
13262
+ return "openai";
13263
+ }
13264
+ var init_real_local_run_provider = __esm({
13265
+ "src/internal/runtime/local-agent/real-local-run-provider.ts"() {
13266
+ init_providers();
13267
+ }
13268
+ });
13269
+ function inheritSubAgentCredentials(tool, creds) {
13270
+ const sink = tool[INHERIT_CREDENTIALS];
13271
+ if (typeof sink === "function") sink(creds);
13272
+ }
13273
+ async function applyDelegationStart(spec, input, iteration) {
13274
+ if (spec.onDelegationStart === void 0) return { input };
13275
+ const decision = await spec.onDelegationStart({ input, name: spec.name, iteration });
13276
+ if (decision === void 0) return { input };
13277
+ if (decision.proceed === false)
13278
+ return { reject: decision.rejectionReason ?? "(delegation rejected)" };
13279
+ return {
13280
+ input: decision.modifiedInput ?? input,
13281
+ ...decision.modifiedMaxSteps !== void 0 ? { maxSteps: decision.modifiedMaxSteps } : {}
13282
+ };
13283
+ }
13284
+ async function collectChildToolResults(run) {
13285
+ const lines = [];
13286
+ for await (const event of run.stream()) {
13287
+ if (event.type === "tool_call" && event.status === "completed") {
13288
+ const rendered = typeof event.result === "string" ? event.result : JSON.stringify(event.result ?? null);
13289
+ lines.push(`${event.name}: ${rendered}`);
13290
+ }
13291
+ }
13292
+ if (lines.length === 0) return "";
13293
+ return `
13294
+
13295
+ <subagent-tool-results>
13296
+ ${lines.join("\n")}
13297
+ </subagent-tool-results>`;
13298
+ }
13299
+ function buildChildCreateOptions(spec, inherited) {
13300
+ const model = spec.model ? { id: spec.model } : inherited?.model;
13301
+ return {
13302
+ ...inherited?.apiKey !== void 0 ? { apiKey: inherited.apiKey } : {},
13303
+ ...model !== void 0 ? { model } : {},
13304
+ ...inherited?.plugins !== void 0 ? { plugins: inherited.plugins } : {},
13305
+ systemPrompt: spec.instructions,
13306
+ tools: spec.tools ?? []
13307
+ };
13308
+ }
13309
+ async function runChildAgent(spec, input, signal, maxSteps, inherited) {
13310
+ const { Agent: Agent2 } = await Promise.resolve().then(() => (init_agent(), agent_exports));
13311
+ const agent = await Agent2.create(buildChildCreateOptions(spec, inherited));
13312
+ try {
13313
+ const sendOptions = {
13314
+ ...signal !== void 0 ? { signal } : {},
13315
+ ...maxSteps !== void 0 ? { maxIterations: maxSteps } : {},
13316
+ // SE3 — a delegated child's turn is initiated by the coordinating parent.
13317
+ origin: { kind: "coordinator" }
13318
+ };
13319
+ const run = await agent.send(input, sendOptions);
13320
+ const result = await run.wait();
13321
+ const text = result.result ?? "(no response)";
13322
+ return spec.includeToolResults === true ? text + await collectChildToolResults(run) : text;
13323
+ } finally {
13324
+ agent.dispose();
13325
+ }
13326
+ }
13327
+ async function notifyDelegationError(spec, input, error, iteration) {
13328
+ if (spec.onDelegationComplete === void 0) return;
13329
+ try {
13330
+ await spec.onDelegationComplete({ input, name: spec.name, error, iteration });
13331
+ } catch {
13332
+ }
13333
+ }
13334
+ function applyMessageFilter(spec, input, messages) {
13335
+ if (spec.messageFilter === void 0 || messages === void 0) return input;
13336
+ const filtered = spec.messageFilter({ messages, input, name: spec.name });
13337
+ if (filtered.length === 0) return input;
13338
+ const preamble = filtered.map((m) => `${m.role}: ${m.content}`).join("\n");
13339
+ return `Prior conversation:
13340
+ ${preamble}
13341
+
13342
+ Task:
13343
+ ${input}`;
13344
+ }
13345
+ async function applyDelegationComplete(spec, input, result, iteration) {
13346
+ if (spec.onDelegationComplete === void 0) return result;
13347
+ const completion = await spec.onDelegationComplete({ input, name: spec.name, result, iteration });
13348
+ return completion?.feedback !== void 0 ? result + completion.feedback : result;
13349
+ }
13350
+ function defineSubAgent(spec, _parentDepth = 0) {
13351
+ const currentDepth = _parentDepth + 1;
13352
+ const maxDepth = spec.maxDelegationDepth ?? 3;
13353
+ if (currentDepth > maxDepth) {
13354
+ throw new MaxDelegationDepthError(currentDepth, maxDepth);
13355
+ }
13356
+ const inputZod = zod.z.object({
13357
+ input: zod.z.string().describe("Task for the subagent")
13358
+ });
13359
+ const inputSchema = {
13360
+ type: "object",
13361
+ properties: {
13362
+ input: { type: "string", description: "Task for the subagent" }
13363
+ },
13364
+ required: ["input"],
13365
+ additionalProperties: false
13366
+ };
13367
+ let iteration = 0;
13368
+ let inherited;
13369
+ const tool = {
13370
+ name: spec.name,
13371
+ description: spec.description,
13372
+ inputSchema,
13373
+ handler: async (rawInput, ctx) => {
13374
+ const { input: parsed } = inputZod.parse(rawInput);
13375
+ iteration += 1;
13376
+ const capturedIteration = iteration;
13377
+ const start = await applyDelegationStart(spec, parsed, capturedIteration);
13378
+ if ("reject" in start) return start.reject;
13379
+ const input = applyMessageFilter(spec, start.input, ctx?.messages);
13380
+ let result;
13381
+ try {
13382
+ result = await runChildAgent(spec, input, ctx?.signal, start.maxSteps, inherited);
13383
+ } catch (error) {
13384
+ await notifyDelegationError(spec, input, error, capturedIteration);
13385
+ throw error;
13386
+ }
13387
+ return applyDelegationComplete(spec, input, result, capturedIteration);
13388
+ }
13389
+ };
13390
+ Object.defineProperty(tool, INHERIT_CREDENTIALS, {
13391
+ value: ((creds) => {
13392
+ inherited = creds;
13393
+ }),
13394
+ enumerable: false
13395
+ });
13396
+ return tool;
13397
+ }
13398
+ function subAgentToolsFromDefinitions(agents2, parentTools) {
13399
+ return Object.entries(agents2).map(([name, def]) => {
13400
+ const whitelist = Array.isArray(def.tools) && def.tools.length > 0 ? new Set(def.tools) : void 0;
13401
+ const childTools = whitelist ? parentTools.filter((t) => whitelist.has(t.name)) : parentTools;
13402
+ return defineSubAgent({
13403
+ name,
13404
+ description: def.description,
13405
+ instructions: def.prompt,
13406
+ ...def.model !== void 0 && def.model !== "inherit" ? { model: def.model.id } : {},
13407
+ tools: [...childTools]
13408
+ });
13409
+ });
13410
+ }
13411
+ var INHERIT_CREDENTIALS, MaxDelegationDepthError;
13412
+ var init_subagent = __esm({
13413
+ "src/a2a/subagent.ts"() {
13414
+ INHERIT_CREDENTIALS = /* @__PURE__ */ Symbol("theokit.subagent.inheritCredentials");
13415
+ MaxDelegationDepthError = class extends Error {
13416
+ constructor(currentDepth, maxDepth) {
13417
+ super(`Max delegation depth ${maxDepth} exceeded (current: ${currentDepth})`);
13418
+ this.currentDepth = currentDepth;
13419
+ this.maxDepth = maxDepth;
13420
+ this.name = "MaxDelegationDepthError";
13421
+ }
13422
+ currentDepth;
13423
+ maxDepth;
13424
+ code = "max_delegation_depth";
13425
+ };
13426
+ }
13427
+ });
13428
+
13294
13429
  // src/internal/tool-registry/personality-filter.ts
13295
13430
  function applyPersonalityFilter(exposedTools, whitelist, opts) {
13296
13431
  if (whitelist === void 0) return exposedTools;
@@ -13346,36 +13481,49 @@ var init_personality_filter = __esm({
13346
13481
  }
13347
13482
  });
13348
13483
 
13349
- // src/internal/runtime/local-agent/real-local-run-provider.ts
13350
- function inferProviderFromApiKey(apiKey) {
13351
- if (apiKey === void 0 || apiKey.length === 0) return void 0;
13352
- const byPrefix = [
13353
- { provider: "openrouter", prefix: "sk-or-" },
13354
- { provider: "anthropic", prefix: "sk-ant-" },
13355
- { provider: "openai", prefix: "sk-" }
13356
- ];
13357
- for (const { provider, prefix } of byPrefix) {
13358
- if (apiKey.startsWith(prefix) && getProviderProfile(provider) !== void 0) {
13359
- return provider;
13360
- }
13361
- }
13362
- return void 0;
13484
+ // src/internal/runtime/local-agent/real-local-run-tools.ts
13485
+ function declarativeSubagentTools(agents2, parentTools) {
13486
+ if (agents2 === void 0 || Object.keys(agents2).length === 0) return [];
13487
+ return subAgentToolsFromDefinitions(agents2, parentTools);
13363
13488
  }
13364
- function detectPrimaryProvider() {
13365
- if (process.env.ANTHROPIC_API_KEY !== void 0 && process.env.ANTHROPIC_API_KEY.length > 0) {
13366
- return "anthropic";
13367
- }
13368
- if (process.env.OPENAI_API_KEY !== void 0 && process.env.OPENAI_API_KEY.length > 0) {
13369
- return "openai";
13370
- }
13371
- if (process.env.OPENROUTER_API_KEY !== void 0 && process.env.OPENROUTER_API_KEY.length > 0) {
13372
- return "openrouter";
13489
+ function bindParentCredentials(tools, agentOptions) {
13490
+ const parentPlugins = Array.isArray(agentOptions.plugins) ? agentOptions.plugins : void 0;
13491
+ const credentials = {
13492
+ ...agentOptions.apiKey !== void 0 ? { apiKey: agentOptions.apiKey } : {},
13493
+ ...typeof agentOptions.model === "object" ? { model: agentOptions.model } : {},
13494
+ ...parentPlugins !== void 0 ? { plugins: parentPlugins } : {}
13495
+ };
13496
+ for (const tool of tools) inheritSubAgentCredentials(tool, credentials);
13497
+ }
13498
+ function buildCustomToolsInput(agentOptions, sendOptions, pluginManager, personalityToolWhitelist, agentId, personalityName, subagents, effectiveModel) {
13499
+ const baseTools = sendOptions?.tools ?? agentOptions.tools ?? [];
13500
+ const agentsForTools = subagents !== void 0 && Object.keys(subagents).length > 0 ? subagents : agentOptions.agents;
13501
+ const subagentTools = declarativeSubagentTools(agentsForTools, baseTools);
13502
+ const pluginTools = pluginManager?.aggregated.tools ?? [];
13503
+ const reasoningTools = reasoningActive(agentOptions.reasoning, effectiveModel) ? [createThinkTool()] : [];
13504
+ if (baseTools.length === 0 && subagentTools.length === 0 && pluginTools.length === 0 && reasoningTools.length === 0) {
13505
+ return {};
13373
13506
  }
13374
- return "openai";
13507
+ const allTools = [...baseTools, ...subagentTools, ...pluginTools, ...reasoningTools];
13508
+ bindParentCredentials(allTools, agentOptions);
13509
+ const merged = allTools.map((tool) => ({
13510
+ name: tool.name,
13511
+ description: tool.description,
13512
+ inputSchema: tool.inputSchema,
13513
+ handler: tool.handler
13514
+ }));
13515
+ const customTools = applyPersonalityFilter(merged, personalityToolWhitelist, {
13516
+ agentId,
13517
+ personalityName
13518
+ });
13519
+ if (customTools.length === 0 && personalityToolWhitelist === void 0) return {};
13520
+ return { customTools };
13375
13521
  }
13376
- var init_real_local_run_provider = __esm({
13377
- "src/internal/runtime/local-agent/real-local-run-provider.ts"() {
13378
- init_providers();
13522
+ var init_real_local_run_tools = __esm({
13523
+ "src/internal/runtime/local-agent/real-local-run-tools.ts"() {
13524
+ init_subagent();
13525
+ init_personality_filter();
13526
+ init_native_reasoning();
13379
13527
  }
13380
13528
  });
13381
13529
 
@@ -13494,7 +13642,8 @@ function buildLoopInputs(options, runId, userText) {
13494
13642
  options.personalityToolWhitelist,
13495
13643
  options.agentId,
13496
13644
  options.personalityName,
13497
- options.subagents
13645
+ options.subagents,
13646
+ options.model
13498
13647
  ),
13499
13648
  ...options.pluginManager !== void 0 ? { pluginManager: options.pluginManager } : {},
13500
13649
  // D318 — forward SendOptions.signal to the agent loop so streamLlmTurn
@@ -13532,40 +13681,6 @@ function buildLoopInputs(options, runId, userText) {
13532
13681
  ...options.agentOptions.memoryProvider !== void 0 ? { memoryProvider: options.agentOptions.memoryProvider } : {}
13533
13682
  };
13534
13683
  }
13535
- function declarativeSubagentTools(agents2, parentTools) {
13536
- if (agents2 === void 0 || Object.keys(agents2).length === 0) return [];
13537
- return subAgentToolsFromDefinitions(agents2, parentTools);
13538
- }
13539
- function bindParentCredentials(tools, agentOptions) {
13540
- const parentPlugins = Array.isArray(agentOptions.plugins) ? agentOptions.plugins : void 0;
13541
- const credentials = {
13542
- ...agentOptions.apiKey !== void 0 ? { apiKey: agentOptions.apiKey } : {},
13543
- ...typeof agentOptions.model === "object" ? { model: agentOptions.model } : {},
13544
- ...parentPlugins !== void 0 ? { plugins: parentPlugins } : {}
13545
- };
13546
- for (const tool of tools) inheritSubAgentCredentials(tool, credentials);
13547
- }
13548
- function buildCustomToolsInput(agentOptions, sendOptions, pluginManager, personalityToolWhitelist, agentId, personalityName, subagents) {
13549
- const baseTools = sendOptions?.tools ?? agentOptions.tools ?? [];
13550
- const agentsForTools = subagents !== void 0 && Object.keys(subagents).length > 0 ? subagents : agentOptions.agents;
13551
- const subagentTools = declarativeSubagentTools(agentsForTools, baseTools);
13552
- const pluginTools = pluginManager?.aggregated.tools ?? [];
13553
- if (baseTools.length === 0 && subagentTools.length === 0 && pluginTools.length === 0) return {};
13554
- const allTools = [...baseTools, ...subagentTools, ...pluginTools];
13555
- bindParentCredentials(allTools, agentOptions);
13556
- const merged = allTools.map((tool) => ({
13557
- name: tool.name,
13558
- description: tool.description,
13559
- inputSchema: tool.inputSchema,
13560
- handler: tool.handler
13561
- }));
13562
- const customTools = applyPersonalityFilter(merged, personalityToolWhitelist, {
13563
- agentId,
13564
- personalityName
13565
- });
13566
- if (customTools.length === 0 && personalityToolWhitelist === void 0) return {};
13567
- return { customTools };
13568
- }
13569
13684
  function buildMcpMap(options) {
13570
13685
  const map = /* @__PURE__ */ new Map();
13571
13686
  const inline = options.sendOptions.mcpServers ?? options.agentOptions.mcpServers;
@@ -13578,7 +13693,6 @@ function buildMcpMap(options) {
13578
13693
  var pluginProvidersAnnounced, RealLocalRun;
13579
13694
  var init_real_local_run = __esm({
13580
13695
  "src/internal/runtime/local-agent/real-local-run.ts"() {
13581
- init_subagent();
13582
13696
  init_errors();
13583
13697
  init_run_events();
13584
13698
  init_loop();
@@ -13591,11 +13705,11 @@ var init_real_local_run = __esm({
13591
13705
  init_providers();
13592
13706
  init_register_plugin_providers();
13593
13707
  init_tracer();
13594
- init_personality_filter();
13595
13708
  init_async_local_storage();
13596
13709
  init_fixture_run_base();
13597
13710
  init_run_registry();
13598
13711
  init_real_local_run_provider();
13712
+ init_real_local_run_tools();
13599
13713
  pluginProvidersAnnounced = false;
13600
13714
  RealLocalRun = class extends FixtureRunBase {
13601
13715
  buildInputs;