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
| Language | Method | Status |
|---|
| TypeScript | getLangGraphCallbackHandler() | ✅ Supported |
| Python | get_langgraph_callback_handler() | ✅ Supported |
| Ruby | — | Not yet supported |
| Go | — | Not 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:
| Event | Span Type | Captured Data |
|---|
| Graph nodes (chains) | agent | Node name, inputs, outputs, LangGraph metadata |
| Chat model calls | llm | Model name, messages (role/content), token usage, LangGraph metadata |
| LLM calls | llm | Model name, prompts, token usage, LangGraph metadata |
| Tool invocations | function | Tool name, input, output |
| Retriever queries | function | Retriever name, query, documents |
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:
| Method | Creates Span | Type |
|---|
handleChainStart(chain, inputs, runId, parentRunId?, tags?, metadata?) | Yes | agent |
handleChainEnd(outputs, runId) | Completes span | — |
handleChainError(error, runId) | Completes span with error | — |
handleChatModelStart(llm, messages, runId, parentRunId?, ...) | Yes | llm |
handleLLMStart(llm, prompts, runId, parentRunId?, ...) | Yes | llm |
handleLLMEnd(output, runId) | Completes span with tokens | — |
handleLLMError(error, runId) | Completes span with error | — |
handleToolStart(tool, input, runId, parentRunId?, ...) | Yes | function |
handleToolEnd(output, runId) | Completes span | — |
handleToolError(error, runId) | Completes span with error | — |
handleRetrieverStart(retriever, query, runId, ...) | Yes | function |
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:
| Method | Creates Span | Type |
|---|
on_chain_start(serialized, inputs, *, run_id, parent_run_id?, ...) | Yes | agent |
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, ...) | Yes | llm |
on_llm_start(serialized, prompts, *, run_id, ...) | Yes | llm |
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, ...) | Yes | function |
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, ...) | Yes | function |
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.