Langchain integration

The LangChain integration is a single class: KyvvuLangChainHandler. It implements LangChain's BaseCallbackHandler and translates LangChain's native execution events into Kyvvu log entries. You pass it as a callback when invoking your agent — no decorators, no changes to your agent code.

pip install kyvvu langchain langchain-core langchain-openai

How events are mapped

LangChain fires callback events at every stage of execution. The handler maps them to Kyvvu node types automatically:

LangChain event
Kyvvu node type

Chain start (top-level)

START_NODE

LLM call

LLM_CALL

Agent decides to use a tool

DECISION

Tool executes

TOOL_CALL

Agent finishes

END_NODE

Any error

ERROR

Nested chains (e.g. a chain calling another chain) are tracked by depth — only the outermost chain generates START_NODE and END_NODE, keeping the task structure clean.


Setup

Instantiate KyvvuLangChainHandler with your agent's registration fields. This also registers the agent with Kyvvu immediately:

from kyvvu.integrations.langchain import KyvvuLangChainHandler

handler = KyvvuLangChainHandler(
    api_key="KvKey-your-api-key",
    api_url="http://localhost:8000",
    agent_key="my-langchain-agent",        # stable ID you choose
    name="My LangChain Agent",
    purpose="Answers customer questions",
    owner_id="[email protected]",
    risk_classification="limited",         # "minimal" | "limited" | "high"
    environment="production",              # "development" | "qa" | "staging" | "production"
)

Then pass the handler as a callback when invoking your agent:

That's the entire integration. Every LLM call, tool invocation, and decision made during that invoke() is automatically logged to Kyvvu.


Advanced options

tool_write_detection is a list of keywords checked against the tool name. If a tool's name contains any of these words, has_write_permission=True is set on its TOOL_CALL log entry — which policies can then enforce rules against.


Multiple invocations

The handler is stateful between invocations: task_started tracks whether a task is open. After on_agent_finish fires, the state resets automatically, so consecutive invoke() calls each produce their own clean task in Kyvvu.

If you need to reset manually (e.g. after an error that didn't reach on_agent_finish):


Error handling

If a policy is violated during execution and on_incident="raise", KyvvuPolicyViolationError is raised. Catch it the same way as with the base SDK:


Complete example

For more context on when to use the handler versus @kv.log_step decorators, see Custom Python Agent.

Last updated