A cost-aware LLM router should estimate input and output charges separately, rule out models that fail the request’s requirements, and record the provider’s actual usage afterward. Claude Opus 5.5 has a documented API model ID and published rates; GPT-6 Sol’s availability and API details are not settled by the current official references, so verify it in your OpenAI account before enabling it. The implementation below keeps routing policy separate from provider adapters and treats prices and model access as versioned configuration—not hard-coded assumptions.
What the router should decide
Routing is a policy decision, not a claim that one provider is universally better. For each request, the router needs enough metadata to decide whether a model is eligible, estimate its cost, and choose among the eligible options.
As an Amazon Associate I earn from qualifying purchases.
- Task class: for example, code generation, extraction, or summarization.
- Hard requirements: supported input types, tools, structured output, context limits, and data-handling constraints.
- Quality and latency requirements: thresholds configured from evaluations and measurements for your workload, not inferred from a vendor’s model description.
- Budget ceiling: the maximum estimated charge allowed for this request.
- Availability: whether the model is enabled and callable in the target account and deployment.
A practical policy is to filter out candidates that fail a hard requirement, then select the lowest estimated-cost candidate among those that meet the configured quality and latency thresholds. If you have not evaluated a candidate on your own workload, mark its quality eligibility as unvalidated rather than assigning it a made-up score.
Check the model names, access, and rates first
Anthropic lists the Claude API model ID as claude-opus-5-5. Its official model overview, current in October 2026, lists a 1-million-token context window, a maximum output of 128,000 tokens, and standard rates of $4 per million input tokens and $20 per million output tokens. Anthropic lists the model as released September 22, 2026, and says retirement will be no sooner than September 22, 2027. Confirm current limits and pricing before deployment.
#1 Best Overall
GPT-6 Sol needs a more cautious treatment. An OpenAI pricing-page search result lists rates, but the model documentation result identifies GPT-5.6 Sol instead. That conflict does not establish that GPT-6 Sol is callable from your account, what model identifier to send, or which request schema and features it supports. Check the current OpenAI model reference and verify access in the account where the router will run. Do not silently substitute GPT-5.6 Sol or enable GPT-6 Sol based on a pricing result alone.
| Candidate | What is established | What to verify before routing |
|---|---|---|
| Claude Opus 5.5 | Anthropic’s official overview lists API model ID claude-opus-5-5, a 1-million-token context window, and 128,000-token maximum output. |
Current account access, supported request features, applicable pricing modifiers, and operational limits. |
| GPT-6 Sol | An OpenAI pricing-page result lists $2 per million input and $10 per million output tokens for short context, and $4/$15 for long context. Treat these as a pricing lead, not proof of access. | Whether the model is available in the target account; its exact model ID, endpoint/request schema, context definition, supported features, and applicable rates. The retrieved model-document result instead names GPT-5.6 Sol. |
Keep each verified model ID in deployment configuration. Validate it at startup or in deployment checks by using the provider’s current account/model discovery or validation mechanism. Since the current material does not establish the OpenAI request schema or a specific Node.js SDK version, the adapter below deliberately leaves provider-specific calls to an implementation that you verify against current provider documentation.
Estimate cost from both sides of the response
A flat price per request is misleading when input, output, cache, batch, context length, or geography can change the rate. For a simple standard-rate estimate, calculate:
Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallRank #2
estimatedCostUsd = (estimatedInputTokens / 1_000_000 * inputUsdPerMillion)
+ (estimatedOutputTokens / 1_000_000 * outputUsdPerMillion);
For Claude Opus 5.5 at Anthropic’s listed standard rates, a request estimated at 10,000 input tokens and 2,000 output tokens costs $0.08 before any other pricing dimension: $0.04 for input plus $0.04 for output. That is an estimate, not a guaranteed charge; use the provider-reported usage and applicable rates to reconcile it.
Anthropic’s October 2026 model overview also lists five-minute cache writes at $5 per million tokens, one-hour cache writes at $8 per million, and cache reads at $0.20 per million. It lists a 50% reduction to input and output token prices for Batch API processing. Anthropic’s pricing details list Fast mode at $8 per million input and $40 per million output tokens; Fast mode is a research preview available on the first-party Claude API. For Claude 4.6 and later on the Claude API and Claude Platform on AWS, US-only inference carries a 1.1× multiplier; global routing is the default at standard rates. Partner-operated cloud pricing is independent. Do not apply the base-rate calculation to these cases without accounting for the applicable modifier.
The OpenAI figures above likewise cannot be used for live routing until the model, account access, context category, and applicable rates are confirmed. Store rates with an effective date and source in configuration, and increment a pricing-configuration version whenever you change them.
Rank #3
Keep policy separate from provider adapters
The policy function should choose a candidate using normalized request metadata and configuration. Adapters should handle provider-specific authentication, request construction, response parsing, usage fields, and errors. This separation lets you change a provider integration without quietly changing the selection policy.
Define a small candidate contract
The following JavaScript is the router core, not a provider SDK integration. Supply token estimates from the selected model’s tokenizer or provider metadata, and set quality and latency eligibility from your own evaluations. Leave GPT-6 Sol disabled until its account access, model ID, schema, and rates are verified.
const pricing = {
version: "2026-10-07-a",
candidates: [
{
key: "claude-opus-5-5",
provider: "anthropic",
modelId: process.env.CLAUDE_OPUS_MODEL ?? "claude-opus-5-5",
enabled: true,
inputUsdPerMillion: 4,
outputUsdPerMillion: 20,
supports: { tools: true, structuredOutput: true },
},
{
key: "gpt-6-sol",
provider: "openai",
modelId: process.env.OPENAI_GPT6_SOL_MODEL,
enabled: false, // Enable only after verifying access and current rates.
inputUsdPerMillion: null,
outputUsdPerMillion: null,
supports: { tools: false, structuredOutput: false },
},
],
};
function estimateUsd(candidate, inputTokens, outputTokens) {
if (!Number.isFinite(candidate.inputUsdPerMillion) ||
!Number.isFinite(candidate.outputUsdPerMillion)) return Infinity;
return inputTokens / 1_000_000 * candidate.inputUsdPerMillion +
outputTokens / 1_000_000 * candidate.outputUsdPerMillion;
}
function chooseCandidate(request, candidates) {
const eligible = candidates
.filter(c => c.enabled && c.modelId)
.filter(c => request.needsTools !== true || c.supports.tools)
.filter(c => request.needsStructuredOutput !== true || c.supports.structuredOutput)
.filter(c => request.qualityEligibleByCandidate[c.key] === true)
.filter(c => request.latencyEligibleByCandidate[c.key] === true)
.map(c => ({
candidate: c,
estimatedUsd: estimateUsd(c, request.estimatedInputTokens,
request.estimatedOutputTokens),
}))
.filter(x => Number.isFinite(x.estimatedUsd) &&
x.estimatedUsd <= request.maxEstimatedUsd);
eligible.sort((a, b) => a.estimatedUsd - b.estimatedUsd);
if (eligible.length === 0) throw new Error("No candidate meets request policy");
return eligible[0];
}
Before using this policy in production, validate request values as finite non-negative numbers, make capability declarations match the current API contract, and ensure estimates use the right rate tier. The Boolean eligibility maps are intentionally inputs: populate them from task-specific evaluations and latency measurements rather than treating model names or vendor descriptions as evidence.
Inject adapters instead of mixing API details into policy
Each adapter can expose a shared method such as generate(request, candidate) and return a normalized result while retaining the original provider response metadata. Keep the policy unaware of vendor-specific field names.
async function route(request, { pricing, adapters, log }) {
const choice = chooseCandidate(request, pricing.candidates);
const startedAt = Date.now();
const adapter = adapters[choice.candidate.provider];
if (!adapter) throw new Error("No adapter for selected provider");
const result = await adapter.generate(request, choice.candidate);
const elapsedMs = Date.now() - startedAt;
const actual = result.usage
? estimateUsd(choice.candidate,
result.usage.inputTokens, result.usage.outputTokens)
: null;
log({
requestId: result.providerRequestId ?? null,
provider: choice.candidate.provider,
modelId: choice.candidate.modelId,
pricingVersion: pricing.version,
estimatedUsd: choice.estimatedUsd,
actualUsd: actual,
usage: result.usage ?? null,
elapsedMs,
finishReason: result.finishReason ?? null,
refusal: result.refusal ?? null,
fallbackReason: null,
});
return result;
}
The sample’s actual-cost calculation uses the same simple two-rate formula as the estimate. Extend the normalized usage and pricing calculation for cache reads and writes, batch requests, long-context tiers, geography, or other applicable billing dimensions. If the provider does not return enough usage detail to calculate the charge, record actual cost as unknown rather than presenting an estimate as actual.
The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Handle refusals, partial results, and retries explicitly
An HTTP success response is not necessarily a completed answer. Anthropic documents that Claude Opus 5.5 can return HTTP 200 with stop_reason: "refusal" and a stop_details object naming a policy area. The Anthropic adapter should preserve this signal in the normalized result; application policy can then display the refusal, stop, or consider a permitted fallback. A fallback is an option, not a guarantee that the next provider will accept or complete the request.
Best Value
Claude Opus 5.5 also has compatibility details that affect adapters: thinking cannot be disabled, forced tool use returns an error, thinking blocks are tied to the model and conversation, and the earlier computer_20251124 computer-use tool is not accepted on the Claude API and Google Cloud. Its default display behavior can place text between tool calls in thinking blocks whose text is empty. If your application streams progress text, parse the documented response behavior rather than assuming every text segment is user-visible prose.
- Preserve provider status, finish/stop reason, refusal details, tool calls, and provider request ID when normalizing a response.
- Retry only failures classified as retryable, and only when repeating the operation is safe.
- Bound retries and add backoff so transient failures do not create retry storms.
- Make fallback policy explicit. Record the selected model, reason for fallback, and pricing configuration version because changing providers can change cost, quality, latency, and data handling.
- Avoid logging API secrets or retaining prompt contents unnecessarily. Log usage and decision metadata needed for accounting and debugging.
Validate the router against your workload
Before trusting a cost-aware policy, compare candidates using the same representative tasks and the same scoring rubric. A price table alone cannot tell you which model meets a quality threshold, and a vendor’s latency descriptor is not a measured service-level guarantee for your deployment.
- Verify access and contracts. Confirm each model identifier, account access, supported request features, limits, and current endpoint schema in the target environment.
- Build a task-specific evaluation set. Include normal cases and failure cases, and score quality using criteria relevant to the task.
- Measure latency and reliability. Measure end-to-end latency, errors, and retry/fallback behavior in the target region and service tier.
- Test cost estimates. Compare estimated input/output usage with provider-reported usage, then reconcile sampled results against invoices. Include cache, batch, context, and region modifiers where applicable.
- Review policy decisions. Confirm that only candidates meeting hard constraints and validated thresholds are eligible, and inspect why the router selected or rejected each candidate.
- Version changes. Keep model IDs, rates, capabilities, and policy settings in versioned configuration so a decision can be reconstructed later.
Report any evaluation with its date, workload, sample size, scoring method, deployment region, and failure cases. Until those measurements exist, describe the router as a configurable cost policy—not as proof of cost savings, model superiority, or lower latency.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




