@limits/js and langchain—no extra package.
You can run guardrails and instructions on every model response (afterModel) and conditions before the model or agent (beforeModel / beforeAgent). On block or escalate, the middleware can return a replacement message and exit early.
SDK Policies
Result shape and
check(), evaluate(), guard().Prerequisites
| Requirement | Version |
|---|---|
| Node.js | >= 18.0.0 |
@limits/js | Latest |
langchain | Compatible with custom middleware |
| Limits API key | From Dashboard → API keys |
How it works
LangChain agents support custom middleware with hooks such asbeforeModel, afterModel, and beforeAgent. Your middleware receives the current state (including messages) and can call the Limits SDK. Depending on the result (allow, block, escalate), you continue normally or return a replacement message and jump to the end of execution.
Installation
Install the Limits SDK and LangChain:Step-by-step
- Create a Limits client —
new Limits({ apiKey }). Reuse it for all middleware calls. - Create middleware — Use
createMiddlewarefromlangchainwith anafterModelhook (and optionallybeforeModelfor conditions). - In
afterModel— Get the last human and AI messages fromstate.messages. UselastHuman.contentandlastAI.contentas the prompt and response strings. Calllimits.guard(...)and/orlimits.evaluate(...). On BLOCK or ESCALATE, return{ messages: [new AIMessage(reason)], jumpTo: "end" }. - Register middleware — Pass your middleware in
createAgent({ ..., middleware: [limitsMiddleware] }). - Invoke the agent — Use
agent.invoke({ messages: [...] })as usual. Policy runs automatically on each turn.
Full example: guardrails and instructions
This example runs guardrails and instructions after each model response. If Limits blocks or escalates, the middleware returns a single AI message and jumps to the end.#safety and #instructions with your policy keys or tags. The result shape is the same as other SDK methods—see Result shape and Errors.
Optional: conditions with beforeModel
To evaluate conditions before each model call (e.g. user or context checks), add a beforeModel hook. Build an input from state (and optionally runtime.context), call limits.check(policyKeyOrTag, input), and on BLOCK or ESCALATE return jumpTo: "end" with an optional message.
Result handling
| Limits result | Middleware action |
|---|---|
| ALLOW | Return nothing; execution continues to the model or next step. |
| BLOCK | Return { messages: [new AIMessage(reason)], jumpTo: "end" } (or your chosen message). |
| ESCALATE | Same as block, or return a “pending review” message and jumpTo: "end". |
data.action, data.reason, isAllowed, isBlocked, isEscalated), see Policies: Result shape.