Quickstart
Build your first TnsAI agent in 5 minutes. Prerequisites: Installation.
Your First Agent
Option 1: AgentBuilder (no subclassing)
package com.example.tnsai.docs;
import com.tnsai.accountability.AuthorityScope;
import com.tnsai.accountability.RecordingLiabilitySink;
import com.tnsai.actions.ActionDiscovery;
import com.tnsai.agents.Agent;
import com.tnsai.agents.AgentBuilder;
import com.tnsai.annotations.ActionSpec;
import com.tnsai.enums.ActionType;
import com.tnsai.identity.AgentDescriptor;
import com.tnsai.identity.LocalIdentityProvider;
import com.tnsai.llm.providers.AnthropicClient;
import com.tnsai.models.role.RoleIdentity;
import com.tnsai.roles.Role;
import java.time.Duration;
import java.util.List;
public final class QuickstartBuilderExample {
private QuickstartBuilderExample() {
}
public static final class AssistantRole extends Role {
@Override
public RoleIdentity getIdentity() {
return new RoleIdentity(
"assistant",
"Friendly conversational agent",
"support");
}
@ActionSpec(
type = ActionType.LOCAL,
description = "Greet the user by name")
public String greet(String name) {
return "Hello, " + name + "!";
}
}
public static Agent buildAgent() {
String model = "claude-sonnet-4-20250514";
var role = Role.create(AssistantRole.class);
var actionNames = ActionDiscovery.discoverActions(role).getActions().stream()
.map(action -> action.getName())
.toList();
var principal = new LocalIdentityProvider().issue(
AgentDescriptor.builder()
.agentClass(AssistantRole.class.getName())
.systemPrompt("You are a friendly assistant.")
.toolNames(actionNames)
.model("anthropic:" + model)
.build());
return AgentBuilder.create()
.llm(new AnthropicClient(model))
.role(role)
.principal(principal)
.liabilitySink(new RecordingLiabilitySink())
.authorityScope(AuthorityScope.unrestricted(Duration.ofHours(1)))
.build();
}
public static void main(String[] args) {
Agent agent = buildAgent();
agent.start();
String response = agent.chat("Hi, my name is Alice");
System.out.println(response);
}
}Required. The
AgentBuilderpath needs the accountability trio —principal,liabilitySink, andauthorityScope. Without all three,build()throwsIllegalStateException(TNS-298); the framework ships no silent no-op default.RecordingLiabilitySinkis in-memory — useFilesystemLiabilitySinkfor production audit trails. See Accountability for the full identity / liability / scope model.
Option 2: Annotated Agent (subclass)
package com.example.tnsai.docs;
import com.tnsai.agents.Agent;
import com.tnsai.annotations.AgentSpec;
import com.tnsai.llm.LLMClient;
import com.tnsai.llm.providers.AnthropicClient;
import com.tnsai.roles.Role;
import java.util.List;
@AgentSpec(description = "A helpful research assistant")
public final class AnnotatedAgentExample extends Agent {
@Override
protected LLMClient getLLM() {
return new AnthropicClient("claude-sonnet-4-20250514");
}
@Override
protected List<Role> getRoles() {
return List.of(Role.create(QuickstartBuilderExample.AssistantRole.class));
}
public static void main(String[] args) {
var agent = new AnnotatedAgentExample();
agent.start();
String answer = agent.chat("What is quantum computing?");
System.out.println(answer);
}
}Adding Tools
For brevity the examples below omit the
.principal(...),.liabilitySink(...), and.authorityScope(...)calls — assume theprincipal,sink, andscopefrom Option 1. EveryAgentBuilder.build()still requires them.
Register shipped POJO toolkits by enum constant — compile-safe:
import com.tnsai.enums.BuiltInTool;
var agent = AgentBuilder.create()
.llm(new AnthropicClient("claude-sonnet-4-20250514"))
.role(new AssistantRole())
.builtInTools(
BuiltInTool.WEB_SEARCH_TOOLS, // brave_search, duckduckgo, wikipedia, …
BuiltInTool.PDF_TOOLS, // pdf_extract_text, pdf_metadata, …
BuiltInTool.MARKDOWN_TOOLS // markitdown
)
.build();Each enum entry registers every @Tool-annotated method on the backing POJO. The LLM sees them all (e.g. brave_search, pdf_extract_text, markitdown) and picks one per call.
For your own toolkits, register the POJO instances directly:
var agent = AgentBuilder.create()
.llm(llm)
.role(role)
.toolPojos(new MyDomainTools(), new MyAnalyticsTools())
.build();See Tools / Catalog for the full shipped catalog and Custom Tools for the @Tool annotation pattern.
Streaming
agent.streamChatWithTools("Summarize this paper", chunk -> {
if (chunk.isContent()) {
System.out.print(chunk.getContent());
}
});Structured Output
record WeatherInfo(String city, double temperature, String condition) {}
WeatherInfo weather = agent.chatWithFormat(
"What's the weather in Istanbul?",
WeatherInfo.class,
3 // max retries
);Next Steps
- Architecture Overview — How the modules fit together.
- Module Overview — What each module provides.
- Agents — Deep dive into a single agent's lifecycle and behavior.
- Capabilities: Tools — Using and creating tools.
- Production: Evaluation — Testing agent quality.