TypeSafeClassifier implements the LangChain Decisions API through BaseDecisionModel from @langchain/core/decisions. It is a Runnable, so you can invoke, batch, or compose it with other runnables. It accepts strings, structured JSON, and LangChain message objects, and records traces and token usage in LangSmith. Use it for focused decisions such as routing a request, choosing a model, or checking whether a tool call is safe to run.
Use TypeSafe decisions in LangChain middleware to control createAgent behavior at specific lifecycle points, including with custom middleware that classifies agent state. See Agent middleware for examples.
Setup
The examples require
@langchain/typesafe 0.1.0 or later and @langchain/core 1.4.0 or later. This release uses the shared decision types in @langchain/core/decisions.dangerouslyAllowBrowser: false to reject browser use.
Create an API key in the TypeSafe console and export it:
Optional: Set
TYPESAFE_BASE_URL to use a compatible gateway, test server, or private deployment. The default is https://api.typesafe.ai.Quickstart
Create aTypeSafeClassifier, then pass the state and named questions together in each invocation. Questions that share state are evaluated independently and in parallel in one request:
Earlier versions configured
questions on TypeSafeClassifier and passed only the state to invoke. Pass both state and questions to invoke now. Every question requires instructions.response.answers, and grouped by type on nouls, choices, scores, and boxes. Answers are typed from the questions you pass: response.choices.team.choice is typed as "infra" | "billing", and an unknown question ID is a type error. The response also carries the model that answered, optional usage_metadata, and the TypeSafe requestId.
In version 0.1, token usage is usage_metadata, with input_tokens, output_tokens, and total_tokens. It replaces the earlier usage object. Check that it is defined before reading it:
state can be a string, a JSON object or array, or LangChain messages. Messages are converted to transcript text, including when nested inside a larger object.
Configure requests
Constructor options control the model, authentication, and request behavior:model: Sets the model or alias. Defaults tojev-latest.apiKey: OverridesTYPESAFE_API_KEY.baseUrl: OverridesTYPESAFE_BASE_URL.timeout: Sets the per-request timeout in milliseconds. Defaults to30000.maxRetries: Sets the maximum number of retries. Defaults to2; set it to0to disable retries.fetch: Supplies a custom transport for proxies or tests.
signal, tags, and metadata, as the second argument to invoke.
Handle errors
The package exportsTypeSafeError, TypeSafeAPIError, TypeSafeAuthenticationError, and TypeSafeRateLimitError. Use their isInstance(error) methods to identify failures. Avoid logging API error bodies indiscriminately: they can contain submitted state.
TypeSafe receives the state you submit, including message content and tool-call arguments. Remove secrets or sensitive data before invoking the classifier.
Decision types
Define questions as objects with atype of "noul", "choice", "score", or "box". Import the question and answer types, such as Noul, Choice, and ChoiceAnswer, from @langchain/core/decisions. The @langchain/typesafe type re-exports remain available for compatibility. Each question is one of four primitives:
A
noul answer has no confidence, since the probability is the answer. Use score rather than noul for a spectrum: a noul of 0.5 means an even split between yes and no, not “medium.”
TypeSafe accepts PNG and JPEG images as LangChain image content blocks containing base64 data or base64 data: URLs. Images can appear in state, question instructions, or criteria. Remote image URLs are not downloaded. For box questions, read response.boxes[questionId].box; its top, bottom, left, and right edges range from 0 to 1.
Agent middleware
LangChain provides two decision-driven middleware that acceptTypeSafeClassifier through classifier.
These middleware are in beta and require
langchain 1.6.5 or later. The @langchain/typesafe/middleware exports are deprecated as of @langchain/typesafe 0.1.0, with removal planned for 0.2.0. Import from langchain and pass classifier: new TypeSafeClassifier() instead.Model routing
Classifies the latest human message across your named models and uses the selected one for every model call in the run. Each choice pairs a model with the criterion for picking it:Tool-risk gating
Asks for the probability that a tool call is risky or insufficiently authorized. Calls that are determined risky return an errorToolMessage instead of running the tool. Only the tools you list are classified. Pass their names or tool objects:
instructions, or pass criteria: { true: ..., false: ... }, to describe risk for your own tools.
Custom middleware
TypeSafeClassifier accepts LangChain message objects directly, so a custom middleware hook can classify an agent’s conversation state without converting it first. This example classifies the conversation once at the start of each run and stores the complete ChoiceAnswer in agent state:
beforeModel to reclassify after each tool result, or wrapToolCall to classify a proposed action. See Custom middleware for all hooks and state patterns.
Tracing
TypeSafe classifications are traced in LangSmith, so you can inspect decisions and token usage alongside the rest of your agent.See also
Connect these docs to your agent of choice via MCP for real-time answers.

