LangChain Reference home pageLangChain ReferenceLangChain Reference
  • GitHub
  • Main Docs
Deep Agents
LangChain
LangGraph
Integrations
LangSmith
LangChain
  • Browser
  • Universal
  • Hub
  • Node
  • Load
  • Serializable
  • Encoder Backed
  • File System
  • In Memory
  • Tools
LangChain Core
  • Agents
  • Caches
  • Base
  • Dispatch
  • Web
  • Manager
  • Promises
  • Chat History
  • Context
  • Base
  • Langsmith
  • Documents
  • Embeddings
  • Errors
  • Example Selectors
  • Indexing
  • Base
  • Chat Models
  • Compat
  • Event
  • Llms
  • Profile
  • Stream
  • Structured Output
  • Load
  • Serializable
  • Memory
  • Messages
  • Tool
  • Output Parsers
  • Openai Functions
  • Openai Tools
  • Outputs
  • Prompt Values
  • Prompts
  • Retrievers
  • Document Compressors
  • Runnables
  • Graph
  • Singletons
  • Stores
  • Structured Query
  • Testing
  • Tools
  • Base
  • Console
  • Log Stream
  • Run Collector
  • Tracer Langchain
  • Stream
  • Async Caller
  • Chunk Array
  • Context
  • Env
  • Event Source Parse
  • Format
  • Function Calling
  • Hash
  • Json Patch
  • Json Schema
  • Math
  • Ssrf
  • Standard Schema
  • Stream
  • Testing
  • Tiktoken
  • Types
  • Uuid
  • Vectorstores
Text Splitters
MCP Adapters
⌘I

LangChain Assistant

Ask a question to get started

Enter to send•Shift+Enter new line

Menu

LangChain
BrowserUniversalHubNodeLoadSerializableEncoder BackedFile SystemIn MemoryTools
LangChain Core
AgentsCachesBaseDispatchWebManagerPromisesChat HistoryContextBaseLangsmithDocumentsEmbeddingsErrorsExample SelectorsIndexingBaseChat ModelsCompatEventLlmsProfileStreamStructured OutputLoadSerializableMemoryMessagesToolOutput ParsersOpenai FunctionsOpenai ToolsOutputsPrompt ValuesPromptsRetrieversDocument CompressorsRunnablesGraphSingletonsStoresStructured QueryTestingToolsBaseConsoleLog StreamRun CollectorTracer LangchainStreamAsync CallerChunk ArrayContextEnvEvent Source ParseFormatFunction CallingHashJson PatchJson SchemaMathSsrfStandard SchemaStreamTestingTiktokenTypesUuidVectorstores
Text Splitters
MCP Adapters
Language
Theme
JavaScriptlangchainbrowserAgentMiddleware
Interface●Since v1.2

AgentMiddleware

Base middleware interface.

Copy
interface AgentMiddleware

Properties

View source on GitHub

Example

property
afterAgent: AfterAgentHook<TSchema, TFullContext>
property
afterModel: AfterModelHook<TSchema, TFullContext>
property
beforeAgent: BeforeAgentHook<TSchema, TFullContext>
property
beforeModel: BeforeModelHook<TSchema, TFullContext>
property
contextSchema: TContextSchema
property
name: string
property
stateSchema: TSchema
property
tools: TTools
property
wrapModelCall: WrapModelCallHook<TSchema, TFullContext>
property
wrapToolCall: WrapToolCallHook<TSchema, TFullContext>

The function to run after the agent execution completes. This function is called once at the end of the agent invocation. It allows to modify the final state of the agent after all model calls and tool executions are complete.

The function to run after the model call. This function is called after the model is invoked and before any tools are called. It allows to modify the state of the agent after the model is invoked, e.g. to update tool call parameters.

The function to run before the agent execution starts. This function is called once at the start of the agent invocation. It allows to modify the state of the agent before any model calls or tool executions.

The function to run before the model call. This function is called before the model is invoked and before the wrapModelCall hook. It allows to modify the state of the agent.

The schema of the middleware context. Middleware context is read-only and not persisted between multiple invocations. It can be either:

  • A Zod object
  • A Zod optional object
  • A Zod default object
  • Undefined

The name of the tool being called

The schema of the middleware state. Middleware state is persisted between multiple invocations. It can be either:

  • A Zod object (InteropZodObject)
  • A StateSchema from LangGraph (supports ReducedValue, UntrackedValue)
  • An AnnotationRoot
  • Undefined

Wraps the model invocation with custom logic. This allows you to:

  • Modify the request before calling the model
  • Handle errors and retry with different parameters
  • Post-process the response
  • Implement custom caching, logging, or other cross-cutting concerns

Wraps tool execution with custom logic. This allows you to:

  • Modify tool call parameters before execution
  • Handle errors and retry with different parameters
  • Post-process tool results
  • Implement caching, logging, authentication, or other cross-cutting concerns
  • Return Command objects for advanced control flow

The handler receives a ToolCallRequest containing the tool call, state, and runtime, along with a handler function to execute the actual tool.

Copy
const middleware = createMiddleware({
  name: "myMiddleware",
  stateSchema: z.object({ count: z.number() }),
  tools: [myTool],
});
Copy
wrapModelCall: async (request, handler) => {
  // Modify request before calling
  const modifiedRequest = { ...request, systemPrompt: "You are helpful" };

  try {
    // Call the model
    return await handler(modifiedRequest);
  } catch (error) {
    // Handle errors and retry with fallback
    const fallbackRequest = { ...request, model: fallbackModel };
    return await handler(fallbackRequest);
  }
}
Copy
wrapToolCall: async (request, handler) => {
  console.log(`Calling tool: ${request.tool.name}`);
  console.log(`Tool description: ${request.tool.description}`);

  try {
    // Execute the tool
    const result = await handler(request);
    console.log(`Tool ${request.tool.name} succeeded`);
    return result;
  } catch (error) {
    console.error(`Tool ${request.tool.name} failed:`, error);
    // Could return a custom error message or retry
    throw error;
  }
}
Copy
wrapToolCall: async (request, handler) => {
  // Check if user is authorized for this tool
  if (!request.runtime.context.isAuthorized(request.tool.name)) {
    return new ToolMessage({
      content: "Unauthorized to call this tool",
      tool_call_id: request.toolCall.id,
    });
  }
  return handler(request);
}
Copy
const cache = new Map();
wrapToolCall: async (request, handler) => {
  const cacheKey = `${request.tool.name}:${JSON.stringify(request.toolCall.args)}`;
  if (cache.has(cacheKey)) {
    return cache.get(cacheKey);
  }
  const result = await handler(request);
  cache.set(cacheKey, result);
  return result;
}