@theokit/agents 0.31.0 → 0.33.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.
@@ -13,6 +13,7 @@ import {
13
13
  getCompactionConfig,
14
14
  getContextWindowConfig,
15
15
  getGatewayConfig,
16
+ getGuardrailsConfig,
16
17
  getHumanInTheLoopConfig,
17
18
  getMcpConfig,
18
19
  getMemoryConfig,
@@ -21,7 +22,7 @@ import {
21
22
  getProjectContextConfig,
22
23
  getSkillsConfig,
23
24
  getSubAgents
24
- } from "./chunk-FI6ZG2YP.js";
25
+ } from "./chunk-MD35WBR4.js";
25
26
  import {
26
27
  __name
27
28
  } from "./chunk-7QVYU63E.js";
@@ -214,6 +215,7 @@ function walkAgentMetadata(AgentClass, toolboxClasses = []) {
214
215
  const memory = getMemoryConfig(AgentClass);
215
216
  const skills = getSkillsConfig(AgentClass);
216
217
  const mcpServers = getMcpConfig(AgentClass);
218
+ const guardrails = getGuardrailsConfig(AgentClass);
217
219
  const contextWindow = getContextWindowConfig(AgentClass);
218
220
  const projectContext = getProjectContextConfig(AgentClass);
219
221
  warnUnmappedDecoratorKnobs(AgentClass.name, contextWindow, projectContext);
@@ -235,6 +237,7 @@ function walkAgentMetadata(AgentClass, toolboxClasses = []) {
235
237
  contextWindow,
236
238
  projectContext,
237
239
  mcpServers,
240
+ guardrails,
238
241
  compaction,
239
242
  checkpoint
240
243
  };
@@ -342,6 +345,7 @@ function compileAgent(walkResult, toolboxInstances = /* @__PURE__ */ new Map())
342
345
  context: walkResult.contextWindow ? compileContextWindow(walkResult.contextWindow).context : void 0,
343
346
  projectContext: walkResult.projectContext,
344
347
  mcpServers: walkResult.mcpServers,
348
+ guardrails: walkResult.guardrails,
345
349
  maxIterations: walkResult.mainLoop.maxIterations ?? walkResult.agentConfig.maxIterations,
346
350
  timeoutMs: walkResult.mainLoop.timeoutMs ?? walkResult.agentConfig.timeoutMs,
347
351
  stream: walkResult.agentConfig.stream ?? true,
@@ -800,6 +804,63 @@ async function* extractThinkTagStream(source) {
800
804
  }
801
805
  __name(extractThinkTagStream, "extractThinkTagStream");
802
806
 
807
+ // src/bridge/sdk-adapter-create-options.ts
808
+ function assembleM8CreateOptions(compiled) {
809
+ const options = {};
810
+ const applied = [];
811
+ const base = compiled.systemPrompt;
812
+ if (compiled.skills) {
813
+ options.skills = compiled.skills;
814
+ options.local = {
815
+ settingSources: [
816
+ "project"
817
+ ]
818
+ };
819
+ applied.push("skills");
820
+ }
821
+ if (compiled.context) {
822
+ options.context = compiled.context;
823
+ applied.push("context");
824
+ }
825
+ if (compiled.projectContext) {
826
+ options.systemPrompt = compileProjectContext(compiled.projectContext, base);
827
+ applied.push("projectContext");
828
+ } else if (base !== void 0) {
829
+ options.systemPrompt = base;
830
+ }
831
+ if (compiled.mcpServers && Object.keys(compiled.mcpServers).length > 0) {
832
+ options.mcpServers = compiled.mcpServers;
833
+ applied.push("mcpServers");
834
+ }
835
+ return {
836
+ options,
837
+ applied
838
+ };
839
+ }
840
+ __name(assembleM8CreateOptions, "assembleM8CreateOptions");
841
+ function realUsageDone(result, t0) {
842
+ const u = result.usage;
843
+ const inputTokens = u?.inputTokens ?? 0;
844
+ const outputTokens = u?.outputTokens ?? 0;
845
+ return {
846
+ type: "done",
847
+ result: result.result ?? "",
848
+ // V4-O: forward the SDK reasoning/cache buckets (0 when the provider omits them) so a
849
+ // consumer keeps full per-turn usage through the loop into DelegationResult (passthrough — ADR D1).
850
+ usage: {
851
+ inputTokens,
852
+ outputTokens,
853
+ totalTokens: inputTokens + outputTokens,
854
+ reasoningTokens: u?.reasoningTokens ?? 0,
855
+ cacheReadTokens: u?.cacheReadTokens ?? 0,
856
+ cacheWriteTokens: u?.cacheWriteTokens ?? 0
857
+ },
858
+ durationMs: Date.now() - t0,
859
+ cost: result.cost?.amount ?? 0
860
+ };
861
+ }
862
+ __name(realUsageDone, "realUsageDone");
863
+
803
864
  // src/bridge/tool-dialect-stripper.ts
804
865
  var OPEN2 = "<function=";
805
866
  var CLOSE2 = "</tool_call>";
@@ -899,57 +960,6 @@ async function* stripToolDialectStream(source) {
899
960
  __name(stripToolDialectStream, "stripToolDialectStream");
900
961
 
901
962
  // src/bridge/sdk-adapter.ts
902
- function assembleM8CreateOptions(compiled) {
903
- const options = {};
904
- const applied = [];
905
- const base = compiled.systemPrompt;
906
- if (compiled.skills) {
907
- options.skills = compiled.skills;
908
- options.local = {
909
- settingSources: [
910
- "project"
911
- ]
912
- };
913
- applied.push("skills");
914
- }
915
- if (compiled.context) {
916
- options.context = compiled.context;
917
- applied.push("context");
918
- }
919
- if (compiled.projectContext) {
920
- options.systemPrompt = compileProjectContext(compiled.projectContext, base);
921
- applied.push("projectContext");
922
- } else if (base !== void 0) {
923
- options.systemPrompt = base;
924
- }
925
- return {
926
- options,
927
- applied
928
- };
929
- }
930
- __name(assembleM8CreateOptions, "assembleM8CreateOptions");
931
- function realUsageDone(result, t0) {
932
- const u = result.usage;
933
- const inputTokens = u?.inputTokens ?? 0;
934
- const outputTokens = u?.outputTokens ?? 0;
935
- return {
936
- type: "done",
937
- result: result.result ?? "",
938
- // V4-O: forward the SDK reasoning/cache buckets (0 when the provider omits them) so a
939
- // consumer keeps full per-turn usage through the loop into DelegationResult (passthrough — ADR D1).
940
- usage: {
941
- inputTokens,
942
- outputTokens,
943
- totalTokens: inputTokens + outputTokens,
944
- reasoningTokens: u?.reasoningTokens ?? 0,
945
- cacheReadTokens: u?.cacheReadTokens ?? 0,
946
- cacheWriteTokens: u?.cacheWriteTokens ?? 0
947
- },
948
- durationMs: Date.now() - t0,
949
- cost: result.cost?.amount ?? 0
950
- };
951
- }
952
- __name(realUsageDone, "realUsageDone");
953
963
  function withLeakedDialectRecovery(providers) {
954
964
  return {
955
965
  ...providers,
@@ -1555,6 +1565,10 @@ __name(agent, "agent");
1555
1565
  function createHitlPlugin(wiring) {
1556
1566
  return {
1557
1567
  name: "theokit-hitl",
1568
+ version: "1.0.0",
1569
+ // `kind: 'general'` is load-bearing — without it the SDK's isCodePlugin() drops this plugin and
1570
+ // the HITL veto never fires (the run would proceed WITHOUT waiting for human approval).
1571
+ kind: "general",
1558
1572
  register(ctx) {
1559
1573
  ctx.on("pre_tool_call", async (c) => {
1560
1574
  const opts = wiring.gated.get(c.name);
@@ -1567,12 +1581,25 @@ function createHitlPlugin(wiring) {
1567
1581
  question: opts.question,
1568
1582
  input: c.args,
1569
1583
  callbackUrl: `approve/${approvalId}`,
1570
- timeoutMs: opts.timeout ?? 3e5
1584
+ timeoutMs: opts.timeout ?? 3e5,
1585
+ // M20 — carry the declared custom-payload schema so the UI knows what to collect.
1586
+ ...opts.payloadSchema !== void 0 ? {
1587
+ payloadSchema: opts.payloadSchema
1588
+ } : {}
1571
1589
  });
1572
- const approved = await wiring.awaitApproval(approvalId, opts, c.name);
1573
- return approved ? void 0 : {
1590
+ const raw = await wiring.awaitApproval(approvalId, opts, c.name);
1591
+ const decision = typeof raw === "boolean" ? {
1592
+ approved: raw
1593
+ } : raw;
1594
+ if (decision.approved) return void 0;
1595
+ let message = `Tool '${c.name}' denied by human approver`;
1596
+ if (decision.reason) message += `: ${decision.reason}`;
1597
+ if (decision.payload !== void 0) {
1598
+ message += ` (payload: ${JSON.stringify(decision.payload)})`;
1599
+ }
1600
+ return {
1574
1601
  block: true,
1575
- message: `Tool '${c.name}' denied by human approver`
1602
+ message
1576
1603
  };
1577
1604
  });
1578
1605
  }
@@ -2509,8 +2536,12 @@ __name(delegate, "delegate");
2509
2536
  function createToolHooksPlugin(hooks) {
2510
2537
  return {
2511
2538
  name: "theokit-tool-hooks",
2539
+ version: "1.0.0",
2540
+ // `kind: 'general'` is load-bearing — without it the SDK's isCodePlugin() drops this plugin and
2541
+ // no hook fires (M10/M19 latent bug, proven via a real OpenRouter run).
2542
+ kind: "general",
2512
2543
  register(ctx) {
2513
- const { beforeToolCall, afterToolCall, beforeLLMCall, afterLLMCall } = hooks;
2544
+ const { beforeToolCall, afterToolCall, beforeLLMCall, afterLLMCall, processInput } = hooks;
2514
2545
  if (beforeToolCall) {
2515
2546
  ctx.on("pre_tool_call", (c) => beforeToolCall({
2516
2547
  name: c.name ?? "",
@@ -2537,11 +2568,167 @@ function createToolHooksPlugin(hooks) {
2537
2568
  iteration: c.iteration
2538
2569
  }));
2539
2570
  }
2571
+ if (processInput) {
2572
+ ctx.on("pre_user_send", async (c) => {
2573
+ const injected = await processInput({
2574
+ prompt: c.prompt ?? "",
2575
+ agentId: c.agentId,
2576
+ runId: c.runId
2577
+ });
2578
+ return injected !== void 0 && injected.length > 0 ? {
2579
+ recalledContext: injected
2580
+ } : void 0;
2581
+ });
2582
+ }
2540
2583
  }
2541
2584
  };
2542
2585
  }
2543
2586
  __name(createToolHooksPlugin, "createToolHooksPlugin");
2544
2587
 
2588
+ // src/bridge/api-error-handler.ts
2589
+ var DEFAULT_MAX_ATTEMPTS = 3;
2590
+ async function runWithApiErrorHandling(thunk, policy) {
2591
+ const maxAttempts = policy.maxAttempts ?? DEFAULT_MAX_ATTEMPTS;
2592
+ let attempt = 0;
2593
+ for (; ; ) {
2594
+ attempt += 1;
2595
+ try {
2596
+ return await thunk();
2597
+ } catch (error) {
2598
+ const decision = await policy.processApiError({
2599
+ error,
2600
+ attempt
2601
+ });
2602
+ if (decision.retry && attempt < maxAttempts) continue;
2603
+ if (!decision.retry && "fallback" in decision && decision.fallback !== void 0) {
2604
+ return decision.fallback;
2605
+ }
2606
+ throw error;
2607
+ }
2608
+ }
2609
+ }
2610
+ __name(runWithApiErrorHandling, "runWithApiErrorHandling");
2611
+ function createApiErrorHandler(policy) {
2612
+ return (thunk) => runWithApiErrorHandling(thunk, policy);
2613
+ }
2614
+ __name(createApiErrorHandler, "createApiErrorHandler");
2615
+
2616
+ // src/bridge/delegation-scoring.ts
2617
+ function delegateBackground(subAgent, message, opts = {}) {
2618
+ const { delegateFn = delegate, ...delegateOpts } = opts;
2619
+ let isSettled = false;
2620
+ const promise = delegateFn(subAgent, message, delegateOpts).finally(() => {
2621
+ isSettled = true;
2622
+ });
2623
+ promise.catch(() => void 0);
2624
+ return {
2625
+ wait: /* @__PURE__ */ __name(() => promise, "wait"),
2626
+ settled: /* @__PURE__ */ __name(() => isSettled, "settled")
2627
+ };
2628
+ }
2629
+ __name(delegateBackground, "delegateBackground");
2630
+ var DEFAULT_MAX_ROUNDS = 3;
2631
+ function defaultFeedbackTemplate(message, feedback) {
2632
+ return `${message}
2633
+
2634
+ Feedback from the reviewer (address this): ${feedback}`;
2635
+ }
2636
+ __name(defaultFeedbackTemplate, "defaultFeedbackTemplate");
2637
+ async function delegateWithScoring(subAgent, message, opts) {
2638
+ const { scorer, maxRounds: maxRoundsOpt = DEFAULT_MAX_ROUNDS, delegateFn = delegate, feedbackTemplate = defaultFeedbackTemplate, ...delegateOpts } = opts;
2639
+ const maxRounds = Math.max(1, maxRoundsOpt);
2640
+ const verdicts = [];
2641
+ let currentMessage = message;
2642
+ let lastResult;
2643
+ for (let round = 1; round <= maxRounds; round++) {
2644
+ const result = await delegateFn(subAgent, currentMessage, delegateOpts);
2645
+ lastResult = result;
2646
+ const verdict = await scorer(result);
2647
+ verdicts.push(verdict);
2648
+ if (verdict.pass) {
2649
+ return {
2650
+ result,
2651
+ rounds: round,
2652
+ passed: true,
2653
+ verdicts
2654
+ };
2655
+ }
2656
+ if (verdict.feedback) currentMessage = feedbackTemplate(message, verdict.feedback);
2657
+ }
2658
+ return {
2659
+ result: lastResult,
2660
+ rounds: maxRounds,
2661
+ passed: false,
2662
+ verdicts
2663
+ };
2664
+ }
2665
+ __name(delegateWithScoring, "delegateWithScoring");
2666
+
2667
+ // src/bridge/mcp-resolver.ts
2668
+ async function resolveMcpServers(selection, ctx) {
2669
+ if (selection === void 0) return void 0;
2670
+ if (typeof selection !== "function") return selection;
2671
+ const resolved = await selection(ctx);
2672
+ if (typeof resolved !== "object" || resolved === null) {
2673
+ throw new Error("[@theokit/agents] MCP resolver must return an McpServersMap object");
2674
+ }
2675
+ return resolved;
2676
+ }
2677
+ __name(resolveMcpServers, "resolveMcpServers");
2678
+ function mcpRegistry(config) {
2679
+ const registry = config.registry;
2680
+ if (registry === "composio") {
2681
+ const apps = config.apps ?? [];
2682
+ return {
2683
+ composio: {
2684
+ command: "npx",
2685
+ args: [
2686
+ "-y",
2687
+ "@composio/mcp",
2688
+ ...apps.length > 0 ? [
2689
+ "--apps",
2690
+ apps.join(",")
2691
+ ] : []
2692
+ ],
2693
+ env: {
2694
+ COMPOSIO_API_KEY: config.apiKey
2695
+ }
2696
+ }
2697
+ };
2698
+ }
2699
+ if (registry === "mcp.run") {
2700
+ return {
2701
+ "mcp.run": {
2702
+ command: "npx",
2703
+ args: [
2704
+ "-y",
2705
+ "@mcp.run/cli",
2706
+ "serve",
2707
+ ...config.profile ? [
2708
+ "--profile",
2709
+ config.profile
2710
+ ] : []
2711
+ ],
2712
+ env: {
2713
+ MCP_RUN_API_KEY: config.apiKey
2714
+ }
2715
+ }
2716
+ };
2717
+ }
2718
+ throw new Error(`mcpRegistry: unknown registry ${JSON.stringify(registry)} (supported: 'composio', 'mcp.run').`);
2719
+ }
2720
+ __name(mcpRegistry, "mcpRegistry");
2721
+ function mcpToolApprovals(specs) {
2722
+ const out = {};
2723
+ for (const [tool, spec] of Object.entries(specs)) {
2724
+ out[tool] = typeof spec === "string" ? {
2725
+ question: spec
2726
+ } : spec;
2727
+ }
2728
+ return out;
2729
+ }
2730
+ __name(mcpToolApprovals, "mcpToolApprovals");
2731
+
2545
2732
  // src/manifest/agent-manifest.ts
2546
2733
  function generateAgentManifest(walkResults) {
2547
2734
  return {
@@ -2729,7 +2916,14 @@ export {
2729
2916
  AgentRunnerBuilder,
2730
2917
  delegate,
2731
2918
  createToolHooksPlugin,
2919
+ runWithApiErrorHandling,
2920
+ createApiErrorHandler,
2921
+ delegateBackground,
2922
+ delegateWithScoring,
2923
+ resolveMcpServers,
2924
+ mcpRegistry,
2925
+ mcpToolApprovals,
2732
2926
  generateAgentManifest,
2733
2927
  agentsPlugin
2734
2928
  };
2735
- //# sourceMappingURL=chunk-BWYBOMKR.js.map
2929
+ //# sourceMappingURL=chunk-TXEY3IUO.js.map