Skip to main content
Jev is a System One model that reads natural language but returns typed answers and calibrated probabilities instead of generated text. 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.
Keep your API key on the server. Do not expose it in browser code. Set 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 a TypeSafeClassifier, 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.
Answers are keyed by the question IDs you supplied in 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:
The request 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 to jev-latest.
  • apiKey: Overrides TYPESAFE_API_KEY.
  • baseUrl: Overrides TYPESAFE_BASE_URL.
  • timeout: Sets the per-request timeout in milliseconds. Defaults to 30000.
  • maxRetries: Sets the maximum number of retries. Defaults to 2; set it to 0 to disable retries.
  • fetch: Supplies a custom transport for proxies or tests.
Pass request configuration, such as signal, tags, and metadata, as the second argument to invoke.

Handle errors

The package exports TypeSafeError, 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 a type 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 accept TypeSafeClassifier 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.
The examples below use OpenAI models. Install LangChain and the OpenAI integration before using them:

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 error ToolMessage instead of running the tool. Only the tools you list are classified. Pass their names or tool objects:
Override instructions, or pass criteria: { true: ..., false: ... }, to describe risk for your own tools.
Do not put secrets in tool arguments or conversation state unless sending them to TypeSafe is acceptable. This middleware refuses risky calls. It does not request approval. Pair it with human-in-the-loop middleware when you want a person to approve them.

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:
Use any lifecycle hook that matches your decision point. For example, use 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