JevPhaseRouting selects within capacity, tool capability and quota limits. Applications can explicitly begin a stage or pin a model. A selection remains sticky within an Agent invocation; invalidation falls back to the original model.
Example: plan a change, then execute known steps
An engineering assistant first assesses risk, then uses tools to execute agreed steps. Preferstrong for planning and fast for execution, while accounting for tool support, context capacity and exhausted quotas.
The host supplies current models and capabilities. Configuration specifies candidate order per route. An explicit stage chooses its configured route; only automatic mode asks JEV to choose among eligible routes.
1. Configure routes and observation mode
Set upclient as in Client setup. Start with SHADOW to observe recommendations without changing the actual model:
plan and execute are route IDs. The application sets model order and the allowlist. Calibrate the 0.8 selection threshold; true enables reasoning-effort selection. Separate observers capture recommendations and actual model calls so recommended models are not counted as dispatched.
2. Supply the invocation’s model directory
The host providesdirectory, a BiFunction<RuntimeContext, ModelCallInput, Mono<Snapshot>> that reads capabilities, quota and token estimates for the current user and actual input. The host resolves model instances and credentials; JEV can choose only configured route IDs.
registeredModel is built and authorized by the host. Supply real estimates for estimatedInputTokens, outputReserve and consecutiveFailures rather than using example constants in production.
The immutable Snapshot includes candidates, estimated input tokens, output reserve, optional minimumEffort and pinnedModel, and consecutive failures. Failure count is a host signal, not something inferred from words in tool output. Return authorized, available models for each user/session; untrusted session fields cannot serve as a directory. Model object identity must stay stable during an invocation; rebinding triggers fallback.
Selection, reasoning effort and fallback
Choose using actual input at the first onModelCall; do not ask JEV again in the same Agent invocation. Before each dispatch reread the directory and check capacity, tools, quota, binding, pinning and minimum effort. After invalidation use the original model for the rest of the invocation, even if eligibility recovers during the same tool loop. Selection priority:- If GenerateOptions specifies modelName, baseUrl, endpointPath or apiKey, preserve the entire original request so request-specific overrides cannot leak to another model.
- Use an eligible Snapshot.pinnedModel without asking JEV.
- For an explicit stage, use the first eligible model in its configured route without asking JEV.
- In automatic mode, select only among eligible routes. The same request can choose effort; configuration still controls model order.
Explicit stages
After confirming the mode, rebuild middleware withoptions set to ENFORCE to actually switch models. messages contains the current task messages:
stages.onModelCall(...) with your downstream function. begin creates a fresh routing context; the first model call reads the directory. The goal argument exists for compatibility; decisions use user messages from the actual model input. Without phaseRouting, per-invocation model selection applies. Stages must name configured routes or fall back. Only the application initiates transitions; intermediate tool results cannot trigger them.
A new stage shares the host’s business-context references and resets only routing scope. It neither copies business state nor replays prior stages. Normal Agent execution isolates route caches per subscription. Use an explicit Phase handle for one stage execution only; do not reuse it after cancellation.
Budgets, observations and usage
The routing budget covers one model hook. Initial directory read, judgment and pre-dispatch recheck share the remaining budget; later calls perform only bounded directory rechecks. Generation time is excluded. Cancellation closes routing scope, cancels in-flight reads/judgments and stops future dispatch, without guaranteeing remote billing stops. Propagate generation failures normally; never reroute or replay the Agent or tools. OFF delegates original input without directory reads or judgments. SHADOW records suggestions while preserving the actual ModelCallInput, model and options. Observer errors do not affect the Agent. JevExecution records phase-routing version, status, added latency and judgment usage. CallRecord records each dispatched model name, requested SDK reasoningEffort, completion/failure/cancellation, elapsed time and ChatUsage from ModelCallEndEvent. CallRecord.dispatchedModel is the configured Model.getModelName; requestedEffort is what the adapter receives. Neither confirms the provider’s model snapshot or final wire parameters. Calls bypassing this hook, such as quality middleware draft revisions, are not automatically included. The host may provide Price(version,input,output,cached,creation) in USD per million tokens. Estimates treat SDK cached/cacheCreation tokens as subsets of input and price output separately. Missing prices or usage, invalid counts or overflow yield null cost. Retain the price version; unknown is not zero and synthetic prices are not real rates. Cross-session cache savings and quota probing are not inferred. Applications can read the SDK Report explicitly. Do not usepolicy.report(ctx) for per-call attribution if concurrently reusing a RuntimeContext; use call observers and distinct runtime contexts.
Runnable example
JevPhaseRoutingExample runs automatic routing, explicit planning and explicit execution as separate invocations. SetJEV_CP using the build instructions, then run: