Variants
A variant names a quality, speed and cost tier: HIGH, MEDIUM, MINI or AUTO. An agent stores a variant and can suggest one for a task. Not implemented: nothing in the framework reads the variant, so it does not change the model, tokens, tools or timeout of a call. Use it as advice when you choose a client yourself.
AgentVariant
com.tnsai.enums.AgentVariant has four values.
| Variant | Quality | Speed | Cost |
|---|---|---|---|
HIGH | MAX | SLOW | HIGH |
MEDIUM | BALANCED | NORMAL | MEDIUM |
MINI | BASIC | FAST | LOW |
AUTO | ADAPTIVE | ADAPTIVE | OPTIMAL |
isQualityFocused() is true for HIGH and MEDIUM, isSpeedFocused() for MINI, and isCostOptimized() for MINI and AUTO.
AgentVariant.forTask(description) matches keywords. It returns HIGH when the text contains refactor, architect, complex, critical, security or review; otherwise MINI for typo, fix, simple, quick, minor or small; otherwise MEDIUM. A blank description gives MEDIUM.
On an agent
| Method | Does |
|---|---|
setVariant(AgentVariant) | Stores the variant and logs the change |
getVariant() | Returns it |
setVariantSelector(VariantSelector) | Stores a selector for AUTO |
resolveVariant(task) | Returns the stored variant. For AUTO, returns the selector's choice, or AgentVariant.forTask(task) without a selector. |
package com.example.tnsai.docs;
import com.tnsai.accountability.AuthorityScope;
import com.tnsai.accountability.LiabilitySink;
import com.tnsai.agents.Agent;
import com.tnsai.agents.AgentBuilder;
import com.tnsai.agents.variant.VariantSpec;
import com.tnsai.enums.AgentVariant;
import com.tnsai.identity.AgentPrincipal;
import com.tnsai.llm.providers.OpenAIClient;
import com.tnsai.roles.Role;
import java.util.Set;
public final class VariantsAgentExample {
private VariantsAgentExample() {}
public static Agent build(Role myRole, AgentPrincipal principal,
LiabilitySink sink, AuthorityScope scope) {
Agent agent = AgentBuilder.create()
.llm(new OpenAIClient("gpt-4o"))
.role(myRole)
.principal(principal)
.liabilitySink(sink)
.authorityScope(scope)
.build();
agent.setVariant(AgentVariant.AUTO);
return agent;
}
// The variant is advice. Read it and choose the model yourself.
static String modelFor(Agent agent, String task, Set<String> availableModels) {
AgentVariant variant = agent.resolveVariant(task);
return VariantSpec.forVariant(variant).getEffectiveModel(availableModels);
}
}VariantSpec
com.tnsai.agents.variant.VariantSpec holds settings for a tier. VariantSpec.forVariant(variant) returns a built-in spec; AUTO gets the MEDIUM spec.
HIGH | MEDIUM | MINI | |
|---|---|---|---|
| Preferred model | claude-opus-4 | claude-sonnet-4 | claude-haiku-3 |
| Fallback models | gpt-4, gemini-1.5-pro | gpt-4o, gemini-1.5-flash | gpt-4o-mini, gemini-1.5-flash-8b |
| Max input tokens | 128,000 | 64,000 | 32,000 |
| Max output tokens | 16,384 | 8,192 | 4,096 |
| Tool set | ALL | STANDARD | MINIMAL |
| Timeout | 10 min | 5 min | 2 min |
| Max retries | 3 | 2 | 1 |
| Temperature | 0.7 | 0.5 | 0.3 |
| Streaming | Yes | Yes | No |
getEffectiveModel(available) returns the preferred model if it is in the set, else the first fallback in the set, else the preferred model. VariantSpec.builder() makes a custom spec, and withVariant and withModel return changed copies.
VariantSpec.ToolSet has ALL, STANDARD, MINIMAL and NONE. These are labels; no tool filtering uses them.
VariantManager
com.tnsai.agents.variant.VariantManager is a standalone helper. It holds a current variant and a spec per tier, suggests a variant from a complexity score in auto mode, notifies change listeners and records task statistics. It is not connected to any agent.
@Variant
@Variant(value, reason, recordStats, fallback) on an action method is read into the action's metadata. Not implemented: no code reads it, so the action runs with the same client as any other.
Related
- Create an agent: the builder and its required settings.
- Resilience: retries and timeouts that do apply.