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.
Install
Section titled “Install”pip install "telem-sdk[langchain]"Graph calls vs. direct calls
Section titled “Graph calls vs. direct calls”- Inside a LangGraph tool node (
graph.invoke(...), aToolNode, an agent loop), LangGraph injectsToolRuntimeautomatically and the tool sends the active message branch plus flat session-threading metadata with every search, taggedHARNESS_ID = "langgraph". - Called directly —
tool.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.
Subagent lineage
Section titled “Subagent lineage”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 Telemfrom 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 modelprint(message.artifact) # typed SearchResponseInside 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.