TnsAI

Tools — Advanced

The function-shape POJO model deliberately keeps the tool surface small: a method, an annotation, a registry. Most "advanced" features that older docs covered (manifest generators, contract validators, security enforcers, parameter validators, retry/cache wrappers) were retired together with the legacy Tool interface in v0.6.0 / v0.7.0. Cross-cutting concerns now live one layer up — on the @ActionSpec annotation, on the agent's setToolCallFilter / setToolCallListener hooks, or on the dispatcher itself.

This page covers what's left in the advanced surface today.

Per-action LLM overrides

When an @ActionSpec(type = LLM) action needs its own system prompt or temperature without changing the agent's global LLM config, set them on the annotation:

@ActionSpec(
    type = ActionType.LLM,
    description = "Extract entities from text — must be deterministic",
    llmSystemPrompt = "You are a precise NER extractor. Output JSON only.",
    llmTemperature = 0.0f
)
public String extractEntities(String text) {
    return "Extract entities from: " + text;
}

llmSystemPrompt overrides the LLM client's default for the duration of this action; llmTemperature >= 0 overrides the chat temperature. A negative llmTemperature (the -1.0f default) means "fall back to the LLM client's default". Tool exposure stays at the agent level — every LLM action sees the agent's complete tool registry.

Inspecting the tool registry at runtime

Every agent built with AgentBuilder has a ToolMethodDispatcher whose registry() exposes the full set of registered tools. Use this when you need to introspect the catalog from inside a setToolCallListener, write tooling around tool discovery, or assert on registration in tests.

import com.tnsai.tools.method.ToolMethodDispatcher;
import com.tnsai.tools.method.ToolMethodRegistry;

ToolMethodDispatcher dispatcher = agent.getToolMethodDispatcher();
ToolMethodRegistry registry = dispatcher.registry();

for (var tool : registry.allMethods()) {
    System.out.println(tool.name() + " — " + tool.description());
}

Direct dispatch

ToolMethodDispatcher.dispatch(name, args) is the same entry point the LLM tool-call loop uses. Call it directly when you want to invoke a tool from non-LLM code (tests, batch jobs, smoke scripts) without spinning up the full chat path:

Object result = dispatcher.dispatch(
    "csv_summary",
    Map.of("path", "/data/sales.csv")
);

Argument types are coerced via Jackson — pass a Map<String, Object> whose entries match the @ToolParam parameter names.

Composio integration

ComposioClient (com.tnsai.tools.composio) provides access to 500+ managed tool integrations via the Composio platform with automatic OAuth handling. It's a separate POJO toolkit registered the same way as any other:

AgentBuilder.create()
    .llm(llm)
    .role(role)
    .toolPojos(new ComposioTools())  // wraps ComposioClient
    .build();

Operations

OperationDescription
appsList available apps/integrations
toolsGet tools for a specific app
executeExecute a tool action
connectInitiate OAuth connection
connectionsList active connections
triggersList available triggers
categoriesList app categories

App categories

PRODUCTIVITY, CRM, DEVELOPER, COMMUNICATION, MARKETING, DESIGN, FINANCE, SOCIAL, AI, STORAGE

Direct usage

ComposioClient composio = new ComposioClient();
// Requires COMPOSIO_API_KEY environment variable

String result = composio.execute("{\"operation\":\"apps\",\"category\":\"developer\"}");

String tools = composio.execute("{\"operation\":\"tools\",\"app\":\"github\"}");

String issue = composio.execute("""
    {"operation":"execute","app":"github","action":"create_issue",
     "params":{"repo":"owner/repo","title":"Bug report","body":"..."}}
    """);

Cross-References

  • Tool Catalog — the 62 shipped POJO toolkits and their methods
  • Custom Tools — write your own @Tool methods
  • Tool IntegrationsetToolCallFilter / setToolCallListener hooks
  • MCP Client — bridge MCP tools into TnsAI as DynamicToolMethod instances

On this page