Skip to content
tnsaijava agent framework

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.mcp.composio) provides direct access to the Composio REST API for discovering and executing managed integrations. It lives in tnsai-mcp; it is not one of the POJO toolkits in tnsai-tools.

import com.tnsai.mcp.composio.ComposioClient;

ComposioClient composio = new ComposioClient(System.getenv("COMPOSIO_API_KEY"));

Operations

OperationDescription
listApps()List available apps/integrations
listTools(appName)List actions for one app
executeTool(toolName, params)Execute an action
getConnectionStatus(appName)Inspect an app's connection status

Direct usage

List<ComposioClient.ComposioApp> apps = composio.listApps();
List<ComposioClient.ComposioTool> tools = composio.listTools("github");
JsonNode issue = composio.executeTool(
    "github_create_issue",
    Map.of("repo", "owner/repo", "title", "Bug report", "body", "...")
);

Cross-References

  • Tool Catalog — the 63 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