TypeSafeClassifier (#40542)
Adds a first-party `langchain-typesafe` partner package for making
structured decisions using the new and shiny `jev` model. It introduces
a new `TypeSafeClassifier` runnable while using the typesafe wire
protocol, message normalization, response parsing, and provider failures
behind a standard LangChain interface.
- Supports TypeSafe's `Choice`, `Noul`, and `Score` primitives with
typed answers, probabilities, confidence, usage metadata, and request
IDs.
- Resolves credentials and API configuration from explicit arguments or
`TYPESAFE_API_KEY` and `TYPESAFE_BASE_URL`.
- Supports injected `httpx2.Client` and `httpx2.AsyncClient` instances
for custom transports, proxies, test fixtures, and shared connection
pools (matching patterns of other provider packages in this repo)
---
There were a couple of rapid fire design decisions that I'll document
here to aid in review:
### Extending base `Runnable`
This is largely the impetus for this PR; we can use typesafe's native
python client, but we lose tracing if it isn't captured through the
runnable interface. I imagine because this is a different model we want
to attribute its costs and things in tracing (at a later point in time)
### Direct `httpx2` integration
This package implements the System One `POST /v1/systemone` contract
directly rather than wrapping `typesafe-sdk` (the status quo of other
integrations in langchain). This keeps the integration's public types
and behavior native, avoids adding a transitive dependency, and gives us
lower level controls which is harder to do when indirecting through
someone elses client.
Aspirationally this is a direction we've wanted to work towards for
integrations generally:
* The benefit of wrapping an external sdk is that we can stay tied to
the supply-chain of a package thats maintained first party (we don't
need to maintain types, the transitive dependency keeps capabilities up
to date, etc.)
* This was in a time when maintainer attention was limited, and the
focus wasn't on nitty gritty implementation details with a provider
* ^Agents are probably good enough to start shouldering most of the
burden we've encountered in the past
* There's an indirection tax we have to pay when we shove the
responsibility onto a separate package- it makes us harder to design
single abstractions around
Because this is a 0-1 integration, my intention is to trial typesafes'
implementation under a "langchain maintained client" paradigm to see if
this is something that could work more generally
### State typing and message normalization
I had to bifurcate the input state types into `State` and `_StateValue`
representations mostly to respect TypeSafe API invariants: input must be
a string, object, or array. Its private recursive `_StateValue`
representation permits ordinary scalars by itself and through
dicts/sequences.
I'm also adding langchain `BaseMessage` objects and `BaseMessage`
sequences at any nesting level. This is because messages are the most
common unit of context within langchain, and translating between agent
context and classifier context is a very important part of us plugging
jev into the ecosystem. I'm imagining something like this:
```python
class ClassifierMiddleware(AgentMiddleware[AgentState, ContextT, ResponseT]):
def after_model(self, state):
result = TypeSafeClassifier(...).invoke(state.messages)
# do something with results
```
This uses the `convert_to_openai_messages` utility exposed in core since
that is the most context friendly representation we have to pass
messages through to typesafe (which doesn't have any concept of an LLM
message)
### Typed request and response models
Question and answer models use Pydantic because they sit directly on
serialization and validation layers, and I was hoping to meet some of
the invariant criteria that the typesafe API has. Things like:
* request models requiring instructions for every question
* `Score` requiring at least two ordered levels
* rejecting empty model identifiers
Criteria remain JSON-capable rather than being narrowed to strings
because TypeSafe's advanced documentation supports structured
instructions and criteria, even though the compact HTTP reference
presents narrower examples.
(lmk if pydantic is defunct and we should pivot)
### Error handling infrastructure
I wanted to meet the same level of specification that the TypeSafe
Python SDK has with regards to how it represents errors. This package
exports a standard error reference (in `_client_utils.py`) that does
this while also inheriting from alngchains standard `Model*Error`
classes which we recently added. Callers can handle either
TypeSafe-specific metadata or provider-independent model failures.
The package mirrors the TypeSafe Python SDK's status, connection,
timeout, rate-limit, and response-validation exception names.
Status-specific provider errors also inherit from LangChain's standard
`Model*Error` classes, following the OpenAI integration pattern, so
callers can handle either TypeSafe-specific metadata or
provider-independent model failures.
API errors retain structured status, body, headers, request ID,
sanitized endpoint, response-validation field path, and rate-limit delay
metadata where applicable. TypeSafe's `529 Overloaded` response maps to
a retryable `ModelAPIError`, while `429` maps to `ModelRateLimitError`
and preserves `retry_after_ms`.
Automatic retry policy is intentionally outside the initial package
scope. The classified retryable errors and retry metadata provide the
foundation for a focused follow-up without coupling this integration to
a retry policy in its first release.
## Package infrastructure
- Introduces `langchain-typesafe` at version `0.0.1` with typed-package
markers, documentation, unit and integration-compilation coverage, and a
reproducible `uv` lockfile.
- Adds bounded `httpx2>=2.0.0,<3.0.0` and `langchain-core>=1.6.2,<2.0.0`
dependencies. The core minimum provides the standard `Model*Error`
hierarchy used by the provider exceptions.
- Registers the package with repository CI, release automation,
dependency updates, issue routing, and package labeling.
## Release note
Added the new `langchain-typesafe` integration package, including a
composable `TypeSafeClassifier` for typed classification, scoring, and
confidence-aware decisions with TypeSafe's Jev model.
---
This was developed with heavy assistance from Sol, earnestly reviewed by
me, and validated through similar CI patterns established in other
packages
The agent engineering platform.
LangChain is a framework for building agents and LLM-powered applications. It helps you chain together interoperable components and third-party integrations to simplify AI application development — all while future-proofing decisions as the underlying technology evolves.
Tip
Just getting started? Check out Deep Agents — a higher-level package built on LangChain for agents that have built-in capabilities for common usage patterns such as planning, subagents, file system usage, and more.
Quickstart
uv add langchain
from langchain.chat_models import init_chat_model
model = init_chat_model("openai:gpt-5.5")
result = model.invoke("Hello, world!")
If you're looking for more advanced customization or agent orchestration, check out LangGraph, our framework for building controllable agent workflows.
For an equivalent JS/TS library, check out LangChain.js.
Tip
For developing, debugging, and deploying AI agents and LLM applications, see LangSmith.
LangChain ecosystem
While the LangChain framework can be used standalone, it also integrates seamlessly with any LangChain product, giving developers a full suite of tools when building LLM applications.
- Deep Agents — Build agents that can plan, use subagents, and leverage file systems for complex tasks
- LangGraph — Build agents that can reliably handle complex tasks with our low-level agent orchestration framework
- Integrations — Chat & embedding models, tools & toolkits, and more
- LangSmith — Agent evals, observability, and debugging for LLM apps
- LangSmith Deployment — Deploy and scale agents with a purpose-built platform for long-running, stateful workflows
Why use LangChain?
LangChain helps developers build applications powered by LLMs through a standard interface for models, embeddings, vector stores, and more.
- Real-time data augmentation — Easily connect LLMs to diverse data sources and external/internal systems, drawing from LangChain's vast library of integrations with model providers, tools, vector stores, retrievers, and more
- Model interoperability — Swap models in and out as your engineering team experiments to find the best choice for your application's needs. As the industry frontier evolves, adapt quickly — LangChain's abstractions keep you moving without losing momentum
- Rapid prototyping — Quickly build and iterate on LLM applications with LangChain's modular, component-based architecture. Test different approaches and workflows without rebuilding from scratch, accelerating your development cycle
- Production-ready features — Deploy reliable applications with built-in support for monitoring, evaluation, and debugging through integrations like LangSmith. Scale with confidence using battle-tested patterns and best practices
- Vibrant community and ecosystem — Leverage a rich ecosystem of integrations, templates, and community-contributed components. Benefit from continuous improvements and stay up-to-date with the latest AI developments through an active open-source community
- Flexible abstraction layers — Work at the level of abstraction that suits your needs — from high-level chains for quick starts to low-level components for fine-grained control. LangChain grows with your application's complexity
Resources
- Documentation — conceptual overviews and guides
- LangChain ecosystem overview — how LangChain, LangGraph, and Deep Agents fit together
- API reference — complete reference for all public classes, functions, and types
- Discussions — community forum for technical questions, ideas, and feedback
- LangChain Academy — comprehensive, free courses on LangChain libraries and products, made by the LangChain team
- Contributing Guide — how to contribute and find good first issues
- Code of Conduct — community guidelines and standards