LangChain connector
langchain-nuroute is the official
LangChain chat model for NuRoute. It plugs a NuRoute-routed
model into any LangChain chain, agent, or RunnableSequence as ChatNuRoute — a normal
BaseChatModel, so it composes with everything else LangChain has (prompts, output parsers,
tools, LCEL pipes) exactly like ChatOpenAI or ChatAnthropic would.
How it works
ChatNuRoute calls your NuRoute gateway through the nuroute
Python SDK client, not through an OpenAI-compatibility shim. Pointing LangChain's own
ChatOpenAI at the gateway's OpenAI-compatible /v1/chat/completions endpoint also works — the
gateway accepts OpenAI-shaped requests directly — but it flattens NuRoute-specific behavior into
OpenAI's response and error shapes. Going through ChatNuRoute instead keeps that behavior
intact: the "auto" routing model, provider overrides to pin a specific upstream provider, and
gateway errors surfacing as NuRouteError rather than an OpenAI-shaped exception.
Install
pip install langchain-nuroute
Requires Python 3.9+.
Quick start
from langchain_nuroute import ChatNuRoute
from langchain_core.messages import HumanMessage
llm = ChatNuRoute(
nuroute_api_key="aicp-...",
nuroute_base_url="https://your-nuroute-gateway",
model="auto", # NuRoute's routing engine picks the best model — see Concepts > Routing
)
response = llm.invoke([HumanMessage(content="Hello!")])
print(response.content)
With model="auto", Artemis Task picks the model for each request.
ChatNuRoute is a normal BaseChatModel, so it works in a chain the same way any other
LangChain chat model would:
from langchain_core.prompts import ChatPromptTemplate
prompt = ChatPromptTemplate.from_template("Summarize this in one sentence:\n\n{text}")
chain = prompt | llm
print(chain.invoke({"text": "..."}).content)
Streaming
for chunk in llm.stream([HumanMessage(content="Tell me a short story")]):
print(chunk.content, end="", flush=True)
Forcing a provider or model
Combine a specific model with provider to pin both. With model="auto" and a provider, no
router runs: the provider serves the first model it lists.
llm = ChatNuRoute(
nuroute_api_key="aicp-...",
nuroute_base_url="https://your-nuroute-gateway",
model="claude-sonnet-4-6",
provider="anthropic",
temperature=0.2,
max_tokens=1024,
)
Reading routing metadata
Every response carries which model NuRoute actually routed to and the token usage for the
call, available on llm_output when calling generate directly:
result = llm.generate([[HumanMessage(content="Hello!")]])
print(result.llm_output["model"]) # e.g. "gpt-4o-mini"
print(result.llm_output["usage"]) # {"prompt_tokens": ..., "completion_tokens": ..., "total_tokens": ...}
Error handling
Gateway errors raise nuroute.NuRouteError (the same exception the SDK itself raises), with
status, error_type, and code fields — not an OpenAI-shaped exception:
from nuroute import NuRouteError
try:
llm.invoke([HumanMessage(content="Hello!")])
except NuRouteError as e:
print(e.status, e.error_type, e.message)
What's not supported
ChatNuRoute doesn't accept a stop parameter — the gateway's /v1/chat/completions endpoint
has no stop-sequence support today, so passing one raises NotImplementedError rather than
silently ignoring it.