the java framework for ai agents
Open-source and annotation-driven, on Maven Central. 12 modules, 55 declarative annotations, 31 LLM providers behind one LLMClient SPI, 62 tool kits (210 @Tool methods), six shipped chat channels, multi-agent coordination, MCP, and native Anthropic prompt caching.
three shapes of agent code
Same builder, same lifecycle — conversational, retrieval-augmented, and a multi-agent council.
conversational agent
A Role declares identity and duties; AgentBuilder wires it to an LLMClient. Streaming, tool routing, and history are built in.
read the docs// AssistantRole extends Role — identity + dutiesAgent agent = AgentBuilder.create() .role(new AssistantRole()) .llm(AnthropicClient.builder() .model("claude-sonnet-4").build()) .build(); agent.start();String reply = agent.chat("Hi!");rag over your docs
HybridRAGStrategy fuses BM25 keyword search with vector retrieval. RAGPipeline composes the full retrieve-then-generate flow.
read the docs// Hybrid = BM25 + vector storeRAGStrategy strategy = new HybridRAGStrategy( new BM25Index(corpus), vectorStore); RAGPipeline pipeline = RAGPipeline .builder(strategy).build(); String answer = pipeline.execute( "What is BDI?");multi-agent council
CouncilExecutor runs Karpathy's 3-stage llm-council — parallel deliberation and a skeptical chair, not a role-play pipeline.
read the docs// Karpathy 3-stage llm-councilCouncilExecutor council = CouncilExecutor.builder() .members(List.of(gpt4, claude, gemini)) .chairman(gemini) .anonymize(true) .build(); CouncilResult r = council.deliberate( "How should we architect auth?");declare it, don’t wire it
Retries, tracing, retrieval, guardrails and contracts are policy on the method — not plumbing inside it. The dispatcher applies them in a fixed order around your action body, which stays business logic.
@RoleSpec(name = "researcher", goals = @Goal(name = "cited", condition = "sources.size() > 0"))public class ResearchRole extends Role { @ActionSpec(type = ActionType.LOCAL) @Retrieval(strategy = Strategy.HYBRID, topK = 8) @Resilience(maxAttempts = 3, fallback = "cached") @OutputGuardrail(maxChars = 4000, maskPII = true) @Traced @Metered(name = "summarize") public Summary summarize(String topic) { return writer.compose(topic); // just the logic }}a selection — the full catalog lists each annotation with its runtime status, so you can tell a wired one from a scaffold before you depend on it.
12 modules · one version
Lockstep release. Pull tnsai-bom, depend on what you use — no per-module version juggling.
apache-2.0 · maven central · BOM-pinned · JDK 21+. each module ships as io.github.tansuasici:tnsai-*:0.13.0.
three steps
add the bom
One Maven import pins every tnsai-* module to the same version. Depend on what you use without naming versions twice.
<dependencyManagement> <dependency> <groupId>io.github.tansuasici</groupId> <artifactId>tnsai-bom</artifactId> <version>0.13.0</version> <type>pom</type><scope>import</scope> </dependency></dependencyManagement>define a role
A role extends Role and declares its identity and actions. @ActionSpec methods become tools the agent can call — parameter names and types are read straight off the method signature, so there is nothing to annotate per argument.
public class ResearcherRole extends Role { @Override public RoleIdentity getIdentity() { return new RoleIdentity("researcher", "Find academic papers", "research"); } @ActionSpec(type = ActionType.LOCAL) // param name comes from the signature (-parameters) public List<Paper> search(String query) { return arxiv.find(query); }}build, start, chat
AgentBuilder runs pre-flight validators at build() time — missing role, missing LLM, capability mismatches — so misconfigurations throw before the first message goes out.
Agent agent = AgentBuilder.create() .role(new ResearcherRole()) .llm(AnthropicClient.builder() .model("claude-sonnet-4") .withPromptCaching() // −75% input cost .build()) .build(); // throws on misconfig agent.start();String reply = agent.chat("Find papers on RAG eval.");need more depth? installation guide · agent concepts · quickstart