Skip to content

LangChain

Installing Telem into a coding agent instead? The one-line curl detects the frameworks you already have and installs into as many as you select in one pass. This page is the Python library integration.

create_telem_search_tool(client) builds a native LangChain tool backed by a Telem client. Only query is exposed to the model; LangGraph’s ToolRuntime is injected as a hidden second argument that carries thread and graph state into Telem when the tool runs inside a graph.

Terminal window
pip install "telem-sdk[langchain]"
  • Inside a LangGraph tool node (graph.invoke(...), a ToolNode, an agent loop), LangGraph injects ToolRuntime automatically and the tool sends the active message branch plus flat session-threading metadata with every search, tagged HARNESS_ID = "langgraph".
  • Called directlytool.invoke(...) outside a graph — there is no runtime to inject, so the request stays history-free: just the query.

configurable.thread_id owns stable identity across calls in the same graph: it becomes the search’s conversation_id unless create_telem_child_config already set one. Without either, identity falls back to the first message’s id, then the tool call id.

create_telem_child_config() freezes the parent runtime’s active branch at call time and returns a LangGraph config for a child graph that appends that snapshot to the child’s ancestor chain, plus a new thread_id you choose:

child_config = create_telem_child_config(
parent_runtime,
child_thread_id="child-1",
)
child_graph.invoke({"messages": [...]}, config=child_config)

Call it from the parent tool that starts the child graph, not before — the snapshot is only as current as the parent’s state when you call it.

Never put thread state in a shared tool closure. ToolRuntime is injected per invocation so one tool object is safe to reuse across concurrent threads; storing thread_id in a closure leaks one thread’s identity into another’s requests.

The tool works the same with a sync Telem client (.invoke) or an async AsyncTelem client (.ainvoke). Called directly with no graph, it’s history-free:

from telem import Telem
from telem.integrations.langchain import create_telem_search_tool
with Telem() as client: # reads TELEM_API_KEY / TELEM_BASE_URL from the environment
search = create_telem_search_tool(client, num_results=2)
message = search.invoke({
"name": search.name,
"args": {"query": "what is the Telem search API"},
"id": "call-1",
"type": "tool_call",
})
print(message.content) # rendered text for the model
print(message.artifact) # typed SearchResponse

Inside a graph, pass config={"configurable": {"thread_id": ...}} and the tool node supplies ToolRuntime for you. Every other keyword argument forwards to search() — see Python SDK.