Docs / Integrations / LangGraph

LangGraph

Mesedi ships as a LangGraph.js callback handler with a one-line install helper. Call instrumentLangGraph(graph) on your compiled graph and every node entry / exit, sub-graph invocation, LLM call, and tool call inside a wrap() flows into Mesedi.

Install

npm install mesedi @langchain/langgraph @langchain/core

The adapter is duck-typed against @langchain/core's BaseCallbackHandler, so neither @langchain/core nor @langchain/langgraph is a required runtime dependency of mesedi. Customers who never import mesedi/integrations/langgraph pay no install cost.

Wire it up

import { configure, wrap } from "mesedi";
import { instrumentLangGraph } from "mesedi/integrations/langgraph";
import { StateGraph } from "@langchain/langgraph";

configure({ apiKey: process.env.MESEDI_API_KEY });

let graph = buildMyGraph().compile();
graph = instrumentLangGraph(graph);

export const runAgent = wrap(async (question: string) => {
  const result = await graph.invoke({ question });
  return result.answer;
});

wrap()owns the execution boundary; the instrumented graph emits intra-execution events. The instrumentation attaches Mesedi's callback handler at graph compile-time, so every node — current and future — gets telemetry with no per-node changes.

Callback-to-event mapping

LangGraph callbackMesedi eventNotes
onChainStart + onChainEndcheckpoint enter + exitNode name + truncated state repr. Feeds semantic_loop.
onChainStart on a sub-graphagent_handofffrom_agent → to_agent inferred from the most-recent node. Feeds cascading_failure and coordination_deadlock.
onChatModelStart + onLLMEndllm_callInherited via the LangChain dispatcher. Byte- identical to the LangChain adapter's events.
onToolStart + onToolEndtool_callAlso inherited via the LangChain dispatcher. Payload shape matches @mesedi.tool.

Current limitations

  • Streaming (graph.streamEvents) is not currently consumed. Events flow through on the terminal callback.
  • LangGraph checkpointer persistence is untouched. Mesedi emits telemetry parallel to it without reading or writing the stored state.
  • interrupt() is not auto-bridged. Use the existing HITL helpers (pauseForHuman, requestHumanIntervention) directly.
  • Outside a wrap, all callbacks silently no-op.

Related