Skip to main content

Agent integrations

When a node runs a model-driven agent — LangChain, Microsoft.Extensions.AI, Semantic Kernel — the agent invokes its own tools. That bypasses mekik.tool, and with it the two things mekik.tool gives you for free. The integrations close that gap: wrap the agent's tools once and each one, when the agent calls it, gets the full mekik treatment.

The gap they close

An agent calling its own tool leaves two holes:

  1. No visibility. Nothing emits a tool_call frame, so the UI never learns a tool ran.
  2. No exactly-once. When a node pauses for a human and the graph resumes, the node re-runs from the top — and the agent calls its tools again. Only ctx.step makes a tool survive that replay.

Each integration owns the tool's invocation, so it can close both — plus add a third capability: pausing for human approval before a sensitive tool runs.

CapabilityWhat it does
Visibilitythe tool call surfaces as a tool_call running → completed/error trace
Approvalthe tool can pause the graph for a human before it runs
Exactly-oncethe tool executes inside ctx.step, so a pause/resume doesn't re-run it
Redactionnamed fields are masked in the surfaced trace; the tool still gets real values

The one policy shape

All three integrations share the same per-tool policy, so you learn it once:

interface ToolPolicy {
show?: boolean; // surface the trace (default true)
approve?: boolean | ApproveSpec; // pause for a human first (default false)
redact?: readonly string[]; // mask these fields in the surfaced trace
}
{
get_order: { show: true }, // trace shown
refund_payment: { show: true, approve: true }, // ask the human first
internal_lookup: { show: false }, // runs, not shown
charge: { show: true, redact: ["cardNumber"] }, // shown, masked
}

redact masks only what is surfaced — the tool itself always receives the real values. When a human declines an approve tool, it's never executed and the agent gets a plain refusal observation (denyMessage) so its loop can continue rather than crash.

The three integrations

IntegrationPackageWrap pointGuide
LangChain (TS)@mekik/langchainwithMekikTools(ctx, tools, policy)LangChain
Microsoft.Extensions.AI (.NET)Mekik.AgentsMekikTools.Wrap(ctx, funcs, policy)Microsoft.Extensions.AI
Semantic Kernel (.NET)Mekik.SemanticKernelkernel.UseMekik(ctx, policy) (a filter)Semantic Kernel

The LangChain and Microsoft.Extensions.AI integrations wrap the tools (each becomes a new tool that owns its invocation). Semantic Kernel uses a filter — the seam every SK call funnels through — so one registration covers direct calls, auto function calling, ChatCompletionAgent, and planners without converting plugins.

Wrapping vs. callbacks (the fallback)

There's a fallback for when you cannot wrap the tools (a prebuilt agent that owns them): a callback/observer that emits tool_call traces. But it's visibility only — it cannot journal the tool, so after a pause and resume the agent invokes its tools a second time. Prefer wrapping; reach for callbacks only when wrapping is impossible, and keep the tools behind it side-effect free. See LangChain → mekikCallbacks.

Approval renders as an ordinary interrupt

When a policy marks a tool approve, the pause is a normal mekik interrupt frame — chativa renders Approve/Reject chips (or a form if you pass ui), and the pause lives in ilmek's checkpoint, so it survives a restart like any other. Each tool gets its own stable interrupt key, so several approvals in one node stay separately addressable. See Human-in-the-loop.

Where to go next