TnsAI

Architecture Overview

Module Dependency Graph

Twelve modules on one lockstep version. Dependencies form four layers plus a meta artifact (BOM) that pins them all.

Module Dependency Graph — TnsAI 12 modules across Foundation / Capabilities / Composed / Application + BOM meta layer

ASCII fallback (for terminal / plain-text readers)
FOUNDATION
  tnsai-core            Agent · Role · Action · Events · SPI · ToolMethodRegistry
                        (no inter-module dependencies)


CAPABILITIES — depend on tnsai-core
  tnsai-llm             LLMClient impls for 20+ providers · prompt caching
  tnsai-coordination    Group topologies · council · voting
  tnsai-tools           POJO toolkits across web · file · DB · code · media · fintech · …
  tnsai-mcp             Model Context Protocol client + server
  tnsai-quality         Observability + security enforcement


COMPOSED — depend on core + 1+ capability
  tnsai-intelligence    → core, coordination
                          RAG · planning · reasoning · context
  tnsai-channels        → core, coordination
                          Telegram · CLI · Email · Slack · Discord · WhatsApp
                          adapters via SPI
  tnsai-evaluation      → core, intelligence, quality
                          Benchmarks · quality gates · evaluators
  tnsai-integration     → core, coordination, evaluation
                          SCOPBridge + framework adapters


APPLICATION
  tnsai-server          → core, llm, coordination, quality
                          WebSocket backend · RAG service · tool execution

META
  tnsai-bom             Bill of Materials — pins all 12 modules to one version

Core Concepts

Agent Lifecycle

Agent lifecycle: a user message flows through agent.chat into Memory, System Prompt, and LLM call. The LLM response branches into either a text reply (returned to the user) or a tool call routed to ActionExecutor. ActionExecutor dispatches one of four ActionType handlers (LOCAL, WEB_SERVICE, LLM, MCP_TOOL), and the tool result loops back to the LLM for multi-turn execution.

ASCII fallback (for terminal / plain-text readers)
User Message


agent.chat(message)

    ├──  Memory         append to conversation history
    ├──  System Prompt  identity + roles + invariants + state
    └──  LLM call       request with tool definitions


                        LLM Response

                ┌───────────────┴───────────────┐
                │                               │
                ▼                               ▼
            Text reply                      Tool Call
                │                               │
                │                               ▼
                │                         ActionExecutor
                │                               │
                │                               │   ActionType:
                │                               ├──  LOCAL        Java method on Role
                │                               ├──  WEB_SERVICE  HTTP / REST endpoint
                │                               ├──  LLM          LLM dispatch via ToolMethodDispatcher
                │                               └──  MCP_TOOL     Model Context Protocol tool
                │                               │
                │                               ▼
                │                         Tool Result
                │                               │
                │                               ▼
                │                     back to LLM (multi-turn loop)


          return to user

Action Routing

Actions are discovered from Roles via @ActionSpec annotations. The ActionExecutor routes each action to the correct executor based on ActionType:

TypeSourceExample
LOCALJava method on Role@ActionSpec(type = ActionType.LOCAL) String greet(String name)
WEB_SERVICEHTTP / REST endpoint@ActionSpec(type = ActionType.WEB_SERVICE) + @WebService(...)
LLMLLM dispatch using the agent's ToolMethodDispatcher@ActionSpec(type = ActionType.LLM) + agent-level .builtInTools(...) / .toolPojos(...)
MCP_TOOLModel Context Protocol server tool@ActionSpec(type = ActionType.MCP_TOOL) + @MCPTool(serverUrl = "...")

Extension Points (SPI)

TnsAI uses Java's ServiceLoader pattern for modular extensibility:

SPI InterfaceModulePurpose
LLMClientProviderCoreRegister LLM providers
CheckpointerProviderCoreState persistence
PlannerHandle.FactoryIntelligencePlanning algorithms
ReasoningStrategyHandle.FactoryIntelligenceReasoning patterns
ContextManagerHandle.FactoryIntelligenceDecision tracing
EvalHandle.FactoryQualityEvaluation hooks
SecurityEnforcerHandle.FactoryQualitySecurity policies

Register implementations in META-INF/services/<interface-name>.

Agent Internal Architecture

The Agent facade composes a small set of focused collaborators — each owns one slice of behavior, so extending or replacing one piece doesn't ripple through the whole class. If you're subclassing Agent or swapping out one of these collaborators via SPI, this is the map.

Agent internal architecture: the Agent facade composes focused collaborators — AgentOrchestrator (chat loop, tool-call routing, KB integration), AgentStreamingSupport (streaming chat + ChatChunk events), AgentCapabilities (planning, reasoning, eval, feedback, environment, variant, resilience), AgentCognitiveSupport, AgentHierarchyManager (parent/child relationships), AgentMessagingHandler (inter-agent messaging via communication SPI), AgentGroupManager (group membership).

ASCII fallback (for terminal / plain-text readers)
Agent                       identity · lifecycle · template methods · facade

   ├── AgentOrchestrator    chat · streaming hooks · tool-call loop · KB

   ├── AgentCapabilities    planning · reasoning · eval · feedback ·
   │                        environment · variant · resilience

   ├── AgentCognitiveSupport
   │                        internal cognitive support (public for visibility)

   ├── AgentHierarchyManager
   │                        parent / child relationships

   ├── AgentStreamingSupport
   │                        streaming chat + ChatChunk events

   ├── AgentMessagingHandler
   │                        inter-agent messaging via communication SPI

   └── AgentGroupManager    group membership

Design Principles

  1. Annotation-first@ActionSpec, @AgentSpec, @ChannelSpec over programmatic config
  2. SPI for extensibility — modules register via META-INF/services/
  3. Composition over inheritance — Agent delegates to focused managers
  4. Immutability — records for data, List.of(), Map.of()
  5. Thread safetyConcurrentHashMap, CopyOnWriteArrayList, virtual threads

On this page