TnsAI

Advanced Agent Features

Beyond the basic Agent lifecycle (create, chat, stop), TnsAI.Core provides specialized subsystems for cognitive support, streaming, ensemble execution, hierarchy management, and chat orchestration. These are internal components extracted from the Agent class for cohesion; most are accessed through the Agent public API rather than directly.

AgentCognitiveSupport

com.tnsai.agents.AgentCognitiveSupport holds planning, reasoning, evaluation, environment perception, and feedback collection for an Agent. It is created internally during agent construction and accessed through AgentCapabilities.

Evaluation Hooks

Eval hooks fire at lifecycle points (before/after chat, before/after tool call, on error, on agent stop) and record metrics into an EvalContext.

// Add an evaluation hook
agent.addEvalHook(myHook);

// Enable/disable evaluation
agent.setEvalEnabled(true);

// Record goal completion
agent.recordGoalCompletion("goal-1", true, Map.of("steps", 3));

Key methods on AgentCognitiveSupport:

MethodDescription
addEvalHook(EvalHook hook)Register an eval hook
removeEvalHook(EvalHook hook)Unregister an eval hook
clearEvalContext()Create a fresh EvalContext with new session ID
setEvalEnabled(boolean)Enable or disable all eval hooks
isEvalEnabled()Check if evaluation is active
recordGoalCompletion(String goalId, boolean success, Map<String, Object> details)Record a goal outcome
fireOnBeforeChat(String message)Fire pre-chat eval event
fireOnAfterChat(String result, long latencyMs)Fire post-chat eval event
fireOnBeforeToolCall(String toolName, Map<String, Object> arguments)Fire pre-tool eval event
fireOnAfterToolCall(String toolName, Object result, boolean success, long latencyMs)Fire post-tool eval event
fireOnAgentStop(String status)Fire agent stop event and complete the eval context

Planning (BDI)

Planning uses a PlannerHandle (SPI, provided by tnsai-intelligence) for GOAP/HTN planning.

// Set a planner
agent.setPlannerHandle(myPlanner);

// Plan for all goals
List<PlannerHandle.PlanStep> steps = agent.plan();

// Plan for a specific goal
List<PlannerHandle.PlanStep> steps = agent.planForGoal("deliverPackage");

// Execute a plan
PlannerHandle.PlanResult result = agent.executePlan(steps);

Key methods on AgentCognitiveSupport:

MethodSignature
planList<PlanStep> plan(List<Role> roles)
planForGoalList<PlanStep> planForGoal(String goalName, List<Role> roles)
executePlanPlanResult executePlan(List<PlanStep> steps, List<Role> roles)
extractCurrentStateMap<String, Object> extractCurrentState(List<Role> roles)
setPlannerHandlevoid setPlannerHandle(PlannerHandle handle)
getPlannerHandleOptional<PlannerHandle> getPlannerHandle()
isPlanningEnabledboolean isPlanningEnabled()

Reasoning Strategy

Reasoning strategies (ReAct, Tree-of-Thought, etc.) are pluggable via ReasoningStrategyHandle.

agent.setReasoningStrategy(reactStrategy);

// After chat, inspect reasoning
Optional<ReasoningResult> result = agent.getLastReasoningResult();

When reasoning is enabled, AgentOrchestrator.chat() routes through the strategy instead of direct LLM invocation.

Environment Perception

Agents can perceive and act on environments (BDI perception-to-belief pipeline).

agent.setEnvironment(myEnvironment);

Percept percept = agent.perceive();
ActionOutcome outcome = agent.actOnEnvironment("moveForward", Map.of("speed", 5));

Environment changes trigger onEnvironmentChangeWithRoles, which checks for unsatisfied goals if a planner is configured.

Feedback Collection

FeedbackCollector (SPI, provided by tnsai-intelligence) records tool outcomes for preference learning.

agent.setFeedbackCollector(myCollector);
FeedbackCollector collector = agent.getFeedbackCollector();

Tool outcomes are recorded automatically via recordToolOutcome(toolName, result, success, latencyMs).

AgentEnsembleExecutor

com.tnsai.agents.ensemble.AgentEnsembleExecutor provides multi-LLM ensemble operations accessed via agent.getEnsembleExecutor().

Patterns

MethodSignatureDescription
parallelChatParallelResults parallelChat(String message, List<LLMClient> llms)Fan out to all LLMs, collect all responses
raceChatOptional<LLMResult> raceChat(String message, List<LLMClient> llms, long timeoutSeconds)First successful response wins
consensusChatOptional<LLMResult> consensusChat(String message, List<LLMClient> llms, Function<String, Double> scorer)Score responses, pick highest
majorityVoteChatOptional<LLMResult> majorityVoteChat(String message, List<LLMClient> llms)Most common response pattern
ensembleChatOptional<String> ensembleChat(String message, List<LLMClient> llms, LLMClient aggregator)Synthesize responses with aggregator LLM
// Fan-out to multiple LLMs
ParallelLLM.ParallelResults results = agent.getEnsembleExecutor()
    .parallelChat("Explain quantum computing", List.of(gpt4, claude, gemini));

// Race: first response wins
Optional<ParallelLLM.LLMResult> fastest = agent.getEnsembleExecutor()
    .raceChat("Quick question", List.of(gpt4, claude), 10);

// Consensus with scoring
Optional<ParallelLLM.LLMResult> best = agent.getEnsembleExecutor()
    .consensusChat("Review this code", llms, response -> scoreQuality(response));

// Ensemble synthesis
Optional<String> synthesized = agent.getEnsembleExecutor()
    .ensembleChat("Complex analysis", List.of(gpt4, claude), aggregatorLLM);

AgentHierarchyManager

com.tnsai.agents.hierarchy.AgentHierarchyManager manages parent-child relationships between agents, including bidirectional consistency and task delegation/escalation.

Hierarchy Setup

Agent supervisor = new SupervisorAgent();
Agent developer = new DeveloperAgent();
Agent tester = new TesterAgent();

// Bidirectional parent-child links
supervisor.addChild(developer);
supervisor.addChild(tester);

// developer.getParent() == supervisor
// supervisor.getChildren() contains both

// Add multiple at once
supervisor.addChildren(developer, tester, designer);

Task Delegation and Escalation

// Supervisor delegates to child
supervisor.delegateToChild(developer.id(), "writeCode", Map.of(
    "task", "Implement authentication",
    "language", "Java"
));

// Developer escalates to supervisor
developer.escalateToParent("requestApproval", Map.of(
    "reason", "Production deployment requires sign-off"
));

Both methods use AgentCommunicationManager to send TaskMessageType.REQUEST messages. delegateToChild throws NoSuchElementException if the child is not found; escalateToParent throws IllegalStateException if no parent is set.

HierarchyContext Interface

The manager uses a HierarchyContext interface (implemented by Agent) to access internals:

public interface HierarchyContext {
    String getAgentId();
    Agent getAgentRef();
    Agent getParentRef();
    void setParentRef(Agent parent);
    List<Agent> getChildrenSnapshot();
    boolean hasChild(Agent child);
    boolean addChildDirect(Agent child);
    boolean removeChildDirect(Agent child);
    Agent findChildById(String childId);
    AgentCommunicationManager getCommunicationManager();
}

AgentStreamingSupport

com.tnsai.agents.streaming.AgentStreamingSupport handles streaming and event-based chat operations.

Token Streaming

// Stream tokens as a Java Stream
Stream<String> tokens = agent.streamChat("Tell me about Java");
tokens.forEach(System.out::print);

Streaming with Tool Calls

The streamChatWithTools method combines streaming with multi-turn tool execution (up to 10 iterations):

agent.streamChatWithTools("Search for TnsAI docs", chunk -> {
    if (chunk.isContent()) {
        System.out.print(chunk.getContent());
    } else if (chunk.isToolCall()) {
        System.out.println("Tool: " + chunk.getToolCall().get().getName());
    }
});

Flow: stream LLM response -\> if tool calls received, execute them -\> send results back to LLM -\> repeat until final text or max iterations (10).

Event-Based Chat (AG-UI)

// With direct event consumer
agent.chatWithEvents("Hello", event -> {
    if (event instanceof TextDeltaEvent delta) {
        System.out.print(delta.getText());
    } else if (event instanceof ToolCallStartEvent tc) {
        System.out.println("Calling: " + tc.getToolName());
    }
});

// With session-based publisher
agent.chatWithEvents("Hello", sessionId);

Events emitted: RunStartEvent, StatusEvent, TextDeltaEvent, ToolCallStartEvent, ToolCallEndEvent, ErrorEvent, RunEndEvent.

AgentChatOrchestrator

com.tnsai.agents.chat.AgentChatOrchestrator handles LLM invocation, response processing, structured output, and RAG augmentation.

LLM Invocation

// Full control
Object response = chatOrchestrator.invokeLLM(message, useHistory, useTools, trace);

// Process response (handles text and tool calls)
String result = chatOrchestrator.processLLMResponse(response, useHistory);

Structured Output (Guardrails Pattern)

// With custom parser
MyOutput output = agent.chatWithStructure(
    "Extract the key points",
    new MyOutputParser(),
    3  // maxRetries for correction
);

// With format detection (JSON, YAML, TOML)
MyRecord record = agent.chatWithFormat("Generate config", MyRecord.class, 2);

// With explicit format
MyRecord record = agent.chatWithFormat("Generate config", MyRecord.class, OutputFormat.YAML, 2);

The orchestrator detects output format from @OutputFormatSpec on the target class or agent class, defaulting to JSON.

RAG (Knowledge Base Augmentation)

When a KnowledgeBase is set on the agent, the orchestrator automatically augments user messages with relevant knowledge results before sending to the LLM:

agent.setKnowledgeBase(myKnowledgeBase);
agent.setKnowledgeBaseTopK(5);

// Messages are now automatically augmented with knowledge context
agent.chat("What is our refund policy?");

AgentOrchestrator

com.tnsai.agents.orchestration.AgentOrchestrator is the top-level coordinator that wires together AgentToolExecutor, AgentChatOrchestrator, AgentStreamingSupport, and AgentEnsembleExecutor. It implements the context interfaces for all three sub-delegates so they can access agent internals without circular dependencies.

Key Public Methods

MethodDescription
chat(String message, boolean useHistory, boolean useTools)Main chat entry point with eval hooks and context graph tracing
streamChat(String message)Token-by-token streaming
streamChatWithTools(String message, Consumer<ChatChunk> handler)Streaming with tool calling loop
chatWithEvents(String message, Consumer<TnsAIEvent> consumer)Event-based chat
chatWithEvents(String message, String sessionId)Event-based chat with session publisher
executeActionPublic(String name, Map<String, Object> params)Execute a named action
executeActionTyped(ActionRequest request)Execute with typed request/response
executeActionOnRole(String roleId, String name, Map<String, Object> params)Execute on a specific role
setToolCallFilter(ToolCallFilter filter)Set permission control for tool calls
setToolCallListener(ToolCallListener listener)Set progress callbacks
setKnowledgeBase(KnowledgeBase kb)Set RAG knowledge base
shutdown()End context conversations

Context Graph Integration

When context graph is enabled, the orchestrator automatically:

  • Starts/ends context conversations around chat sessions
  • Creates snapshots at conversation boundaries
  • Records DecisionTrace entries for each chat (success or failure)

AgentCapabilities

com.tnsai.agents.capabilities.AgentCapabilities is the capability facade that bridges cognitive support, resilience, variants, and context graphs. Agent delegates to this class for all capability operations.

Variant Selection

agent.setVariant(AgentVariant.HIGH);
AgentVariant current = agent.getVariant();

// Auto-resolve based on task
AgentVariant resolved = agent.resolveVariant("Complex refactoring task");

// Custom selector
agent.setVariantSelector(mySelector);

Context Graph

agent.enableContextGraph(snapshotStore, decisionTraceStore);

Optional<ContextManagerHandle> cm = agent.getContextManager();
boolean enabled = agent.isContextGraphEnabled();

Resilience

AgentHealthState health = agent.getHealthState();
ResilienceExecutor executor = agent.getResilienceExecutor();
RetryPolicy policy = agent.getDefaultRetryPolicy();
DeadLetterQueue dlq = agent.getDeadLetterQueue();
agent.clearRecoveryState();
  • Streaming -- streaming basics and ChatChunk
  • Tools -- tool registration and the Tool interface
  • Roles -- role-based action discovery
  • Events -- TnsAI event system
  • Resilience -- retry, circuit breaker, recovery
  • Variants -- AgentVariant cost/quality tiers

On this page