Skip to content
tnsaiDocs
GitHub

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.

VariantQualitySpeedCost
HIGHMAXSLOWHIGH
MEDIUMBALANCEDNORMALMEDIUM
MINIBASICFASTLOW
AUTOADAPTIVEADAPTIVEOPTIMAL

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

MethodDoes
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.

HIGHMEDIUMMINI
Preferred modelclaude-opus-4claude-sonnet-4claude-haiku-3
Fallback modelsgpt-4, gemini-1.5-progpt-4o, gemini-1.5-flashgpt-4o-mini, gemini-1.5-flash-8b
Max input tokens128,00064,00032,000
Max output tokens16,3848,1924,096
Tool setALLSTANDARDMINIMAL
Timeout10 min5 min2 min
Max retries321
Temperature0.70.50.3
StreamingYesYesNo

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.