Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.inference.net/llms.txt

Use this file to discover all available pages before exploring further.

Catalyst uses the LangChain callback path for LangGraph workflows. A compiled graph emits a graph-level CHAIN span and node-level CHAIN spans parented under the graph run. If the graph is the implementation of a product agent, wrap graph.invoke() with agentSpan() / agent_span() and set a stable agent.id so executions group in the Agents dashboard.

Install

bun add @inference/tracing @langchain/core @langchain/langgraph

TypeScript State Graph

TypeScript
import { agentSpan, setup } from "@inference/tracing";
import * as CallbackManagerModule from "@langchain/core/callbacks/manager";
import { Annotation, END, START, StateGraph } from "@langchain/langgraph";

const tracing = await setup({
  serviceName: "counter-graph",
  modules: { langchainCallbacksManager: CallbackManagerModule },
});

const State = Annotation.Root({
  count: Annotation<number>({
    reducer: (_left, right) => right,
    default: () => 0,
  }),
});

const graph = new StateGraph(State)
  .addNode("increment", (state) => ({ count: state.count + 1 }))
  .addNode("double", (state) => ({ count: state.count * 2 }))
  .addEdge(START, "increment")
  .addEdge("increment", "double")
  .addEdge("double", END)
  .compile();

const result = await agentSpan(
  tracing.tracer,
  {
    agentId: "counter-graph-agent",
    name: "CounterGraphAgent",
    role: "workflow",
    system: "langgraph",
  },
  async (span) => {
    const input = { count: 1 };
    span.setInput(input);
    const output = await graph.invoke(input);
    span.setOutput(output);
    return output;
  },
);
console.log(result);

await tracing.shutdown();

Python State Graph

Python
from inference_catalyst_tracing import agent_span, setup
from langgraph.graph import END, START, StateGraph
from typing_extensions import TypedDict

class GraphState(TypedDict):
    count: int

tracing = setup(service_name="counter-graph")

def increment(state: GraphState) -> GraphState:
    return {"count": state["count"] + 1}

def double(state: GraphState) -> GraphState:
    return {"count": state["count"] * 2}

builder = StateGraph(GraphState)
builder.add_node("increment", increment)
builder.add_node("double", double)
builder.add_edge(START, "increment")
builder.add_edge("increment", "double")
builder.add_edge("double", END)

graph = builder.compile()
with agent_span(
    tracing.tracer,
    agent_id="counter-graph-agent",
    name="CounterGraphAgent",
    agent_role="workflow",
    system="langgraph",
) as span:
    input_state = {"count": 1}
    span.set_input(input_state)
    result = graph.invoke(input_state)
    span.set_output(result)
    print(result)

tracing.shutdown()

What To Look For

  • A graph span named LangGraph
  • Node spans named after graph nodes
  • openinference.span.kind=CHAIN on graph and node spans
  • Node spans parented under the graph span
  • An outer AGENT span with your stable agent.id when you wrap agent-style graph invocations
For agent-style graphs, model and tool spans created inside node functions appear below the active graph or node context.