Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.bitfab.ai/llms.txt

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

Bitfab integrates with LangGraph and LangChain via a callback handler that automatically captures graph node execution, LLM calls, tool invocations, and retriever queries as traced spans — no manual withSpan or @span decorators needed on your graph nodes. Canonical signatures: TypeScript reference · Python reference

Supported Languages

LanguageMethodStatus
TypeScriptgetLangGraphCallbackHandler()✅ Supported
Pythonget_langgraph_callback_handler()✅ Supported
RubyNot yet supported
GoNot yet supported

Quick Start

import { Bitfab } from "bitfab"

const bitfab = new Bitfab({ apiKey: process.env.BITFAB_API_KEY })
const handler = bitfab.getLangGraphCallbackHandler("my-agent")

const result = await agent.invoke(
  { messages: [{ role: "user", content: "What's the weather?" }] },
  { callbacks: [handler] },
)

What Gets Captured

The callback handler hooks into LangChain’s callback system and creates spans automatically:
EventSpan TypeCaptured Data
Graph nodes (chains)agentNode name, inputs, outputs, LangGraph metadata
Chat model callsllmModel name, messages (role/content), token usage, LangGraph metadata
LLM callsllmModel name, prompts, token usage, LangGraph metadata
Tool invocationsfunctionTool name, input, output
Retriever queriesfunctionRetriever name, query, documents

LangGraph Metadata

LangGraph-specific metadata is automatically extracted and stored as span context:
  • langgraph_step — Current step number
  • langgraph_node — Current node name
  • langgraph_triggers — What triggered this node
  • langgraph_path — Execution path
  • langgraph_checkpoint_ns — Checkpoint namespace

Token Usage

For LLM spans, token usage is captured from the LLM response:
  • inputTokens — Prompt tokens
  • outputTokens — Completion tokens
  • totalTokens — Total tokens
  • model — Model name (extracted from serialized config or metadata)

TypeScript

Installation

npm install bitfab @langchain/langgraph @langchain/openai

Method Signature

bitfab.getLangGraphCallbackHandler(traceFunctionKey: string): BitfabLangGraphCallbackHandler
Parameters:
  • traceFunctionKey (string, required) — Groups all traces from this handler under one key in Bitfab
Returns: A BitfabLangGraphCallbackHandler that implements the LangChain callback handler interface (duck-typed — no @langchain/core dependency required).

Usage

import { Bitfab } from "bitfab"
import { ChatOpenAI } from "@langchain/openai"
import { createReactAgent } from "@langchain/langgraph/prebuilt"
import { tool } from "@langchain/core/tools"
import { z } from "zod"

const bitfab = new Bitfab({ apiKey: process.env.BITFAB_API_KEY })

const getWeather = tool(
  async ({ city }) => {
    return `Sunny, 72°F in ${city}`
  },
  {
    name: "getWeather",
    description: "Get the current weather for a city.",
    schema: z.object({ city: z.string() }),
  },
)

const model = new ChatOpenAI({ model: "gpt-4o-mini" })
const agent = createReactAgent({ llm: model, tools: [getWeather] })

// Create the callback handler
const handler = bitfab.getLangGraphCallbackHandler("weather-agent")

// Pass as a callback — all graph execution is traced automatically
const result = await agent.invoke(
  { messages: [{ role: "user", content: "What's the weather in SF?" }] },
  { callbacks: [handler] },
)

Callback Methods

The handler implements these LangChain callback methods:
MethodCreates SpanType
handleChainStart(chain, inputs, runId, parentRunId?, tags?, metadata?)Yesagent
handleChainEnd(outputs, runId)Completes span
handleChainError(error, runId)Completes span with error
handleChatModelStart(llm, messages, runId, parentRunId?, ...)Yesllm
handleLLMStart(llm, prompts, runId, parentRunId?, ...)Yesllm
handleLLMEnd(output, runId)Completes span with tokens
handleLLMError(error, runId)Completes span with error
handleToolStart(tool, input, runId, parentRunId?, ...)Yesfunction
handleToolEnd(output, runId)Completes span
handleToolError(error, runId)Completes span with error
handleRetrieverStart(retriever, query, runId, ...)Yesfunction
handleRetrieverEnd(documents, runId)Completes span
handleRetrieverError(error, runId)Completes span with error

Nesting with Core Tracing

The handler integrates with Bitfab’s span stack. If you create a withSpan wrapper around your agent invocation, the LangGraph spans nest as children:
const pipeline = bitfab.getFunction("my-pipeline")

const tracedRun = pipeline.withSpan(
  { name: "RunAgent", type: "agent" },
  async (query: string) => {
    const handler = bitfab.getLangGraphCallbackHandler("my-pipeline")
    return agent.invoke(
      { messages: [{ role: "user", content: query }] },
      { callbacks: [handler] },
    )
  },
)

await tracedRun("What's the weather?")
// LangGraph spans appear nested under the "RunAgent" span
Use the same trace function key in both places. Both bitfab.getFunction(...) and bitfab.getLangGraphCallbackHandler(...) take a key — pass the same key ("my-pipeline" above) to both. If you use two different keys here, the same flow will register as two separate overlapping trace functions in the dashboard — an anti-pattern to avoid.

Error Handling

  • GraphBubbleUp: LangGraph’s internal interrupt mechanism. Detected automatically and completed silently (no error recorded).
  • All other errors: Error message captured in the span. The handler never throws — all callbacks are wrapped in try/catch.
  • Reusability: The handler resets after each root span completes and can be reused across multiple invocations.

Python

Installation

pip install bitfab-py langchain-core langgraph

Method Signature

bitfab.get_langgraph_callback_handler(trace_function_key: str) -> BitfabLangGraphCallbackHandler
Parameters:
  • trace_function_key (str, required) — Groups all traces from this handler under one key in Bitfab
Returns: A BitfabLangGraphCallbackHandler instance that extends BaseCallbackHandler from langchain-core.

Usage

import os
from bitfab import Bitfab
from langchain_openai import ChatOpenAI
from langchain_core.tools import tool
from langgraph.prebuilt import create_react_agent

bitfab = Bitfab(api_key=os.environ["BITFAB_API_KEY"])

@tool
def get_weather(city: str) -> str:
    """Get the current weather for a city."""
    return f"Sunny, 72°F in {city}"

model = ChatOpenAI(model="gpt-4o-mini")
agent = create_react_agent(model, tools=[get_weather])

# Create the callback handler
handler = bitfab.get_langgraph_callback_handler("weather-agent")

# Pass as a callback — all graph execution is traced automatically
result = agent.invoke(
    {"messages": [{"role": "user", "content": "What's the weather in SF?"}]},
    config={"callbacks": [handler]},
)

Callback Methods

The handler implements these LangChain callback methods:
MethodCreates SpanType
on_chain_start(serialized, inputs, *, run_id, parent_run_id?, ...)Yesagent
on_chain_end(outputs, *, run_id, ...)Completes span
on_chain_error(error, *, run_id, ...)Completes span with error
on_chat_model_start(serialized, messages, *, run_id, ...)Yesllm
on_llm_start(serialized, prompts, *, run_id, ...)Yesllm
on_llm_end(response, *, run_id, ...)Completes span with tokens
on_llm_error(error, *, run_id, ...)Completes span with error
on_tool_start(serialized, input_str, *, run_id, ...)Yesfunction
on_tool_end(output, *, run_id, ...)Completes span
on_tool_error(error, *, run_id, ...)Completes span with error
on_retriever_start(serialized, query, *, run_id, ...)Yesfunction
on_retriever_end(documents, *, run_id, ...)Completes span
on_retriever_error(error, *, run_id, ...)Completes span with error

Nesting with Core Tracing

@bitfab.span("my-pipeline", type="agent")
def run_agent(query: str):
    handler = bitfab.get_langgraph_callback_handler("my-pipeline")
    return agent.invoke(
        {"messages": [{"role": "user", "content": query}]},
        config={"callbacks": [handler]},
    )

run_agent("What's the weather?")
# LangGraph spans appear nested under the "my-pipeline" span
Use the same trace function key in both places. @bitfab.span(...) and bitfab.get_langgraph_callback_handler(...) both take a key — pass the same key ("my-pipeline" above) to both. If you use two different keys here, the same flow will register as two separate overlapping trace functions in the dashboard — an anti-pattern to avoid.

Error Handling

  • GraphBubbleUp: LangGraph’s internal interrupt mechanism. Detected automatically and completed silently (no error recorded).
  • All other errors: repr(error) captured in the span. The handler never raises — all callbacks are wrapped in try/except.
  • Reusability: The handler resets after each root span completes and can be reused across multiple invocations.