LangChain adapter
Connect a LangChain / LangGraph agent to the Astro runtime
astropods-adapter-langchain wraps a LangChain executor — either langchain.agents.create_agent or langgraph.prebuilt.create_react_agent — and connects it to the Astro messaging sidecar. It runs astream(stream_mode="updates") under the hood, translates graph updates into the shared StreamHooks lifecycle, and auto-configures OTEL tracing.
Install
Requires Python 3.10+.
Quick start
serve(adapter) connects to the messaging sidecar at localhost:9090 (or GRPC_SERVER_ADDR) and blocks until SIGINT / SIGTERM. Under ast dev and in production the address is injected for you.
API
LangChainAdapter(executor, name, system_prompt?, tools?, voice?)
serve(adapter, options?)
Re-exported from astropods-adapter-core. Connects the adapter and blocks until shutdown. Also calls setup_observability() so OTEL tracing comes up automatically when OTEL_EXPORTER_OTLP_ENDPOINT is set.
ServeOptions
How the executor maps to hooks
LangChainAdapter consumes executor.astream(..., stream_mode="updates"). Each graph update produces zero or more hook calls:
LangChain streams complete messages, not token-by-token deltas — so the user sees the reply appear all at once, not as a typing animation. (This is a LangChain limitation, not the adapter’s.) Choose Mastra if streaming-per-token UX matters.
The adapter also handles two LangChain content shapes:
- OpenAI-style —
content: "string"directly. - Anthropic-style —
content: [{"type": "text", "text": "..."}, ...]content blocks.
Both shapes are flattened to text before calling on_chunk().
Memory
LangChain doesn’t have built-in conversation memory. To persist context across turns, pass options.conversation_id into your own store (Redis, a database, a LangGraph checkpointer, etc.) inside your tool or executor wiring.
Voice (STT)
Pass an optional voice provider to enable audio input:
OpenAIVoice is bundled for convenience — it implements the VoiceProvider protocol against OpenAI’s Whisper API. You can pass any object with an async listen(data: bytes, config) -> str method.
The voice flow:
LangChain has no native TTS path, so the adapter does STT only. If you need TTS, post-process on_chunk() text and call hooks.on_audio_chunk() yourself (or use the Mastra adapter, which has TTS built in).
Tracing
When OTEL_EXPORTER_OTLP_ENDPOINT is set, serve() automatically instruments LangChain so every LLM call and tool invocation produces a trace span. No code changes needed — Astro sets the env var on deployed agents.
The adapter also derives the turn’s W3C trace context from its root span and attaches it to the responses it emits, so any response — and the feedback that references it — can be correlated back to its trace. This is automatic; see Trace context for the wire shape.
Example: an agent with tools
The tools= argument on LangChainAdapter is for playground display only — the actual tool wiring happens when you pass tools into create_agent. Pass the same list to both so the playground reflects what the agent can actually do.
Local development
ast dev runs the messaging sidecar on localhost:9090, sets GRPC_SERVER_ADDR, and serves the chat interface at http://localhost:3100. The same serve(adapter) code works locally and in production.