Download the PHP package neuron-core/router without Composer
On this page you can find all versions of the php package neuron-core/router. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download neuron-core/router
More information about neuron-core/router
Files in neuron-core/router
Package router
Short Description Route inference calls to different underlying providers based on a routing strategy you define.
License MIT
Informations about the package router
Neuron AI Router
This package provides you with a RouterProvider component. It is a proxy that implements AIProviderInterface and routes inference calls (chat, stream, structured) to different underlying providers based on a routing strategy you define.
The agent doesn't know it's talking to a router, it's a drop-in replacement for any Neuron AI provider.
At its simplest, the router is a reliability layer: define a fallback order of providers and if one fails with a transient error, the next is tried transparently. On top of that, you can add routing rules to choose which provider handles each request.
This is possible thanks to the Unified Messaging Layer that Neuron AI provides, with full support for multi-modality. Documentation here: https://docs.neuron-ai.dev/agent/messages
When to Use It
- Stay reliable when a provider hits its quota, rate-limits you, or returns a server error — define a fallback order and the next provider is tried transparently
- Route requests to the appropriate models based on the expected difficulty scored by the classifier
- Route
structured()calls to a provider with better structured output support (e.g., OpenAI) while using another provider forchat() - Use different providers depending on the content of the messages (e.g., route image-heavy requests to Gemini)
- Implement cost-based or latency-based routing logic
Installation
Install the composer package:
Quick Start
The most common use case: a fixed provider order with automatic fallback, no routing rule needed. Anthropic is the primary; if it fails with a transient error, OpenAI is tried next.
Once you need to choose providers per request, add a routing rule.
Default Provider
The router delegates messageMapper() and toolPayloadMapper() to an underlying provider. After each inference call, these delegate to whichever provider the routing rule selected. If you need the mappers available before any inference call (e.g., during agent bootstrapping), set a default:
The default is overwritten each time the routing rule resolves a provider, so it only acts as the initial fallback.
Fallback Providers
The fallback order defines which provider is tried, and in what order, when a call fails with a transient error — useful for staying reliable when a provider hits its quota, rate-limits you, or returns a server error. The Quick Start above shows the simplest case: no routing rule, just setFallbackOrder(). The first name is the primary, tried on every call; the rest are tried in order on transient failures.
Names passed to setFallbackOrder() must be registered — an unknown name throws at configuration time. Calling without either setRule() or setFallbackOrder() throws ProviderException.
Combining a rule with fallback
Add a routing rule and the fallback order works alongside it: the rule picks the provider for each request, and the fallback order takes over if that provider fails. The rule's chosen provider is always tried first and is implicitly excluded from the fallback list (it is never retried).
What triggers a fallback
The router falls back only on transient failures:
| Failure | Falls back? |
|---|---|
Network error / timeout / DNS (HttpException with no response) |
Yes |
Rate limit / quota — 429 |
Yes |
Upstream server error — 5xx |
Yes |
Client error — 400, 401, 403, 404 |
No (rethrown) |
Any non-HttpException (e.g. message-mapping bugs) |
No (rethrown) |
The last-tried provider's error is the one that surfaces to the caller.
Custom fallback strategy
If the built-in policy doesn't fit, supply a callable that inspects the thrown Throwable and returns true to fall back, false to rethrow:
The strategy takes precedence over the default policy entirely — there is no merging of the two.
Streaming
For stream(), the fallback applies only to the initial request (the one that opens the connection). If that fails with a retryable error, the next provider is tried. Once the first chunk has been emitted the stream cannot restart, so any failure from that point on propagates as-is.
Routing Rules
Routing logic is defined via the RoutingRuleInterface. The router calls resolveProvider() on the rule, passing context about the current request:
| Parameter | Type | Description |
|---|---|---|
$method |
string |
The inference method: 'chat', 'stream', or 'structured' |
$messages |
array |
The messages being sent to the provider |
$tools |
array |
The tools configured for this request |
The method must return the name of a registered provider (as a string).
Built-in Rules
MethodRule
Routes based on the inference method. Set a default provider and optionally override specific methods:
CallbackRule
Wraps a callable for maximum flexibility. Use this when you need to inspect messages or tools:
RoundRobinRule
Distributes requests evenly across providers in sequence. Each call cycles to the next provider:
DifficultyRule
Routes by the difficulty of the conversation, using the Neuron Classifier package. It classifies the first user message and then sticks to that provider for every subsequent message in the same conversation — the whole thread is served by the model the opening prompt was routed to.
The classifier is an optional dependency. Install it only if you use this rule:
Resolution order on the first user message:
- If
coverage()is below the configured threshold, the prompt is out of the classifier's domain — route to theoutOfDomainprovider. - Otherwise compare
overall()(one score in[0,1]) against theeasy/medium/hardthresholds.
The decision is cached after the first call, so the classifier runs once per conversation. Stickiness is scoped to the lifetime of the RouterProvider instance — build a fresh router per conversation to re-evaluate.
When difficulty is unknown (no tier configured for the score, or no user message present), the rule falls back to the most capable configured tier (hard → medium → easy → outOfDomain).
ContentRule
Routes based on the content blocks inside messages (images, files, audio, video). When a message contains a content type that not all providers support, you can route it to one that does:
When multiple content types are present in the same request, precedence is: video → audio → image → file → default. Content types without a configured provider are ignored and fall through to the next type in the precedence order.
Custom Rules
Implement RoutingRuleInterface to create your own routing logic:
Then use it:
Using with an Agent
Inject the router just like any other provider — either via setAiProvider() or by overriding the provider() method:
Error Handling
The router throws ProviderException with clear messages for misconfiguration:
| Scenario | Error Message |
|---|---|
| Neither a routing rule nor a fallback order set | no routing strategy configured. Call setRule() to set one, or setFallbackOrder() to route without a rule. |
| No providers registered | no providers registered. Call addProvider() to add one. |
| Rule returns unknown name | unknown provider 'name'. Available: ... |
| Unknown default provider | unknown provider 'name'. Available: ... |
| Mapper called with no default or prior call | no provider available for delegation. Call setDefaultProvider() or make an inference call first. |
Limitations
messageMapper()andtoolPayloadMapper()delegate to the last-resolved provider (or the default). These are internal to each concrete provider and are never called by the agent directly.setHttpClient()is forwarded to all registered providers.- The routing rule is called on every inference request, so keep it fast.