Service Tiers (Priority & Flex)
How Nova runs background work cheaper with a priority/flex compute service-tier axis that is orthogonal to model/complexity routing — automatic by trigger source, with an optional per-agent and per-flow override.
What a service tier is
A service tier controls who gets compute priority on a request — a separate axis from which model serves it. The Auto router picks the model (cheap / mid / frontier by complexity); the service tier then chooses the serving lane:
| Tier | For | Cost / latency |
|---|---|---|
priority | Latency-sensitive, user-facing work — a Slack @mention, a web chat turn | Premium serving, fastest |
flex | Background, non-interactive work — cron-triggered reports, webhook/GitHub/Sentry-triggered flows | Cheaper, slower serving |
The two axes are independent: a frontier-complexity model can run on the flex tier (a heavy nightly report), and a cheap model can run on priority (a quick interactive lookup). Prompt caching is a third, separate optimization and is unaffected by the service tier.
How the tier is decided
serviceTier = node override ?? agent override ?? default-by-trigger-source- Default by trigger source. Interactive sources (
slack,web,email,linear,manual,sms) default topriority. Every other source —scheduled/cron,webhook,github,sentry,api,mcp_server,integration, or an unknown/absent source — defaults toflex. Background work is the cheaper default; a user-facing channel always passes a known interactive source and gets priority. - Per-agent override (
AgentDocument.serviceTier) — pins a tier for every run of one agent. - Per-flow-node override (the agent node's
serviceTierin the flow builder) — the most specific; wins over the agent and the source default.
This mirrors the human-vs-background split the HITL approval gate already uses, so background flows that auto-approve also run on the cheaper lane by default.
How the tier is applied (server-side, capability-gated)
The decision is resolved in runConversation and passed down to every model round. It is applied only when the resolved provider + key supports the matching capability, and is otherwise a graceful no-op — the request is simply served at the provider's normal rate. No configuration error, no failure.
| Provider | flex | priority | How |
|---|---|---|---|
| OpenAI | ✅ | ✅ | Responses API service_tier field |
| All others (Anthropic, Gemini, xAI, …) | no-op | no-op | Field omitted; served at the normal rate |
Capability detection is reported by each provider via supportsFeature("service-tier-flex") / supportsFeature("service-tier-priority"). To add support for another provider, report the capability in that provider's supportsFeature and map the tier onto its request in chat().
A note on Anthropic's Batch API
Anthropic offers a roughly 50%-cheaper Batch API, but it is asynchronous: you submit a job and poll for results minutes to hours later. The agent loop is synchronous (a turn must return a response inline), so the Batch API is not wired into this axis: a flex run on Anthropic is a no-op rather than silently deferring a live chat turn. Offline, batch-friendly workloads (like a corpus eval) are a separate, future integration.
Setting an override
- Per agent: set
serviceTier: "priority" | "flex"on the agent document. - Per flow node: set the agent node's
serviceTierfield. Leave it unset to inherit the agent override, then the trigger-source default.
Override precedence is node → agent → source default, so you can force a normally-background cron flow onto priority for one critical node, or push a normally-interactive agent onto flex when it is being used for bulk processing.
Where it lives
apps/admin/src/lib/agent-core/models/service-tier.ts— the decision + capability-gating logic (resolveServiceTier,applicableServiceTier,defaultServiceTierForSource).apps/admin/src/lib/agent-core/models/provider-types.ts— theServiceTiertype, theservice-tier-{flex,priority}capabilities, and theserviceTierchat param.apps/admin/src/lib/agent-core/models/providers/openai.ts— mapsserviceTier→service_tier.apps/admin/src/lib/agent-core/chat/conversation.ts— resolves and gates the tier, then threads it through the conversation loop toprovider.chat.
Model Evaluation & Optimization
How Nova routes requests across 13 LLM providers, measures quality with a replay eval harness, and proposes cost-optimal model swaps for human review.
Browser Extension — Use Cases
A living catalog of what the Nova browser extension can do — chat on any page, element pick, SDLC modes, the browser tool catalog, agent-where-you-work plays, cross-agent runtime, and the security model. Each use case carries an honest Live / In progress / Planned status.