@novu/framework/langchain lets you write agent handlers with LangChain. Return a LangChainAgentConfig from onMessage and Novu runs createAgent().invoke() for you — including tool approval gating and resume from ctx.history.
Before you start
Completed the Quickstart? Your agent, bridge, and project are already set up — jump to Minimal agent. Otherwise start with the Quickstart first. All three onboarding paths (dashboard, CLI, AI assistant) walk you through creating the agent and wiring the bridge. This page covers only what’s specific to the LangChain adapter.Prerequisites
Install the framework, LangChain, and a model provider:@novu/framework, langchain, and @langchain/core are required; pick one provider package. Examples on this page use OpenAI model strings — see the LangChain integrations catalog for others.
Minimal agent
Importagent from @novu/framework/langchain, then return a LangChainAgentConfig from onMessage:
'support-bot') matches the Identifier in your dashboard, and that this handler is registered on your bridge route — see Connecting your app.
For handlers, replies, signals, typing, and tool approval, see Building blocks. The sections below cover what’s specific to the LangChain adapter.
Returning from onMessage
On the LangChain path, onMessage (and onToolApproval) can return a LangChain result in addition to the usual reply types:
| Return | Behavior |
|---|---|
LangChainAgentConfig | Novu runs createAgent() and delivers the final assistant text |
{ messages: BaseMessage[] } | Novu delivers the final assistant text from your pre-invoked agent or graph |
BaseMessage | Delivered as a normal reply (assistant text extracted from the message) |
string / JSX Card | Delivered as a normal reply — see Reply |
| nothing | After you call ctx.reply() yourself |
onMessage: pass the handler directly.
toLangChainMessages()
Convert ctx.history into LangChain BaseMessage[] when you invoke an agent or graph yourself:
ctx.historyalready includes the current inbound message — do not append themessageargument on top of it.- Pass
systemonly when you are not settingsystemonLangChainAgentConfig— Novu forwards that field tocreateAgent({ prompt })for you. - Tool approval cycles in history are mapped automatically, so auto-resume (below) works.
Invoke your own agent
If you already run a LangChain agent or graph in your handler, return its messages and Novu delivers the final text — tool approval is not managed on this path:ReplyHandle.edit() as your graph produces chunks — the adapter does not stream token-by-token when you return a result.
Automatic tool approval
SetneedsApproval on LangChainAgentConfig. When the model calls a gated tool, Novu posts the Approve / Deny card and pauses the turn. After the user decides, Novu re-runs onMessage — toLangChainMessages(ctx.history) replays the approval cycle so the agent continues with no extra code from you.
onToolApproval when you need a hook after the click. See Tool approval for the full API.
Turn failures and onError
When Novu runs createAgent().invoke() for a returned LangChainAgentConfig and the invoke rejects — for example the provider errors or the model call fails — the failure propagates to the same dispatch boundary as a thrown handler error. The same applies when you await your own agent or graph in onMessage and the invoke throws before you return. Register onError on the agent to log, suppress user notification, send custom copy, or fall back to Novu’s generic message.
onError. See Handlers and context — onError for the full pipeline.
The adapter awaits
invoke() to completion when you return a config — it does not stream token-by-token. If you stream inside onMessage yourself, stream failures throw from your handler the same way as any other handler error.Related
AI SDK
Return AI SDK results from handlers with automatic tool approval resume.
Typing indicator
Show a Thinking… or custom status while your handler runs.
Reply
Markdown, attachments, and interactive cards.
Tool approval
The shared Approve / Deny primitive.
Other frameworks
Wire handlers without a Novu runtime adapter.