🧭 Tools4AI

June 12, 2026 Β· View on GitHub

Table of Contents


What is Tools4AI?

Tools4AI (v1.2.1, published on Maven Central) is a pure Java agentic AI framework / ADK (Agent Development Kit).
Its core idea is simple and powerful: annotate existing Java methods with @Agent/@Action and the framework automatically maps natural-language prompts to those method calls at runtime β€” no manual parsing, no glue code.

@Agent
public class CookingAction {
    @Action(description = "what food does this person like")
    public String whatFoodDoesThisPersonLike(String name) {
        return "Paneer Butter Masala";
    }
}

// Somewhere else β€” zero plumbing:
new OpenAiActionProcessor().processSingleAction("I don't know what to cook for Vishal");
// β†’ calls whatFoodDoesThisPersonLike("Vishal") automatically

How It Works

CapabilityHow
Prompt β†’ Java method callAI reads @Action descriptions and routes prompts to the right method, extracting typed parameters (primitives, POJOs, Lists, Maps, arrays)
Prompt β†’ POJOPromptTransformer converts free-text directly into complex Java object graphs
Multi-LLMSupports Gemini (Vertex AI), OpenAI, Anthropic Claude, HuggingFace, LocalAI via LangChain4j
Multi-action typeJava methods, HTTP REST (via http_actions.json), Shell scripts (via shell_actions.yaml), Swagger/OpenAPI endpoints, extended custom loaders
Safety & trustGuardRails, HumanInLoop, ActionCallback for progress, ActionRisk (LOW/MEDIUM/HIGH) for approval gates
Response validationHallucination detection (ZeroShotHallucinationDetector), bias detection (BiasDetector), fact checking (FactDetector)
Spring integrationSpringGeminiProcessor, SpringAnthropicProcessor, SpringOpenAIProcessor β€” plug straight into Spring beans
Protocol supportA2A, MCP, A2UI, UCP protocols
Image actionsGeminiImageActionProcessor β€” image-to-text, image-to-POJO, image comparison
Script actionsScripted multi-step action chains via .action files

Tools4AI vs Spring AI

They sound similar but solve fundamentally different problems:

DimensionTools4AISpring AI
Core purposeAgentic action routing β€” maps prompts to pre-existing Java methods/REST/shellAI primitives β€” chat, embeddings, RAG, vector stores for Spring apps
Entry pointAnnotate any existing Java class/method β€” works without SpringBuilt on Spring Boot β€” Spring context is required
Action discoveryAnnotation-driven classpath scan + YAML/JSON config for REST/shellManual @Tool registration (since Spring AI 1.0), function callbacks
Parameter mappingFully automatic β€” extracts typed params from prompt and populates POJOs, Lists, Maps, arraysManual β€” you define function schemas explicitly
Non-Java actionsFirst-class shell scripts, Swagger/OpenAPI, HTTP REST β€” no code neededNot supported natively
LLM providerGemini, OpenAI, Anthropic, HuggingFace, LocalAISame set + Azure OpenAI, Amazon Bedrock, Ollama, Mistral, etc.
RAG / Vector storesNot presentCore feature (PGVector, Chroma, Pinecone, Redis, Weaviate…)
EmbeddingsNot presentCore feature
Image handlingGeminiImageActionProcessor β€” image β†’ POJO, compareMultimodal in newer versions but not POJO mapping
Safety layerGuardRails, HumanInLoop, hallucination/bias/fact detectorsNot built in
Target userEnterprise Java dev wanting to AI-enable existing apps without refactoringSpring Boot dev building new AI-native applications
Singleton/classpathSingle PredictionLoader scans the whole classpathSpring ApplicationContext β€” standard IoC
WeightLightweight, single JARFull Spring ecosystem

The one-line difference: Spring AI is a platform for building AI-first apps.
Tools4AI is a retrofit layer that makes any existing Java system AI-controllable with minimal code change.


Improvement Roadmap

The items below are forward-looking ideas. No existing code is changed β€” each represents a net-new addition or extension point.

1. πŸ—οΈ Architecture

  • PredictionLoader is a singleton with global mutable state β€” this is the root cause of all test isolation issues and would cause problems in multi-tenant apps. A proper DI-friendly ActionRegistry with scope control would fix this.
  • Classpath scanning is unbounded β€” scanning the entire classpath by default is slow and fragile. Opt-in package scanning (actionPackagesToScan) is there but not the default.
  • No async/reactive support β€” all processSingleAction calls are blocking. Modern agentic workloads need streaming and async execution.

2. πŸ€– Agent Capabilities βœ… Implemented

The following four capabilities have been added as pure extensions under the com.t4a.agent package. No existing source files were changed.

CapabilityPackageKey classes
Memory / conversation historycom.t4a.agent.memoryAgentMemory, InMemoryAgentMemory (bounded sliding window), PersistentFileAgentMemory (JSON file, survives restarts)
Multi-agent orchestrationcom.t4a.agent.orchestrationAgentOrchestrator (LLM-driven routing + result aggregation), AgentDefinition, OrchestrationResult
ReAct planning loopcom.t4a.agent.planningReActPlanner (Reason→Act→Observe loop, configurable max iterations), ExecutionPlan, PlanStep
Tool result feedbackcom.t4a.agent.feedbackToolResultFeedbackProcessor (decorator β€” feeds raw tool result back to LLM for natural-language synthesis)
Retry / fallbackcom.t4a.agent.resilienceRetryActionProcessor (decorator β€” exponential backoff retries, optional fallback processor e.g. a different LLM provider)
Audit trailcom.t4a.agent.auditAuditedActionProcessor (decorator β€” records every execution), AuditTrail, InMemoryAuditTrail (bounded), JsonFileAuditTrail (append-only JSON-lines)

Memory β€” quick start

AgentMemory memory = new InMemoryAgentMemory(20);          // short-term, 20-turn window
AgentMemory memory = new PersistentFileAgentMemory("/var/agent/session.json"); // long-term

memory.addTurn("What is the weather?", "25Β°C");
String prompt = memory.getHistoryAsContext() + "\nNow: what should I wear?";

Multi-agent orchestration β€” quick start

AgentOrchestrator orch = new AgentOrchestrator(new OpenAiActionProcessor());
orch.register(new AgentDefinition("flights", "handles flight booking", flightProcessor));
orch.register(new AgentDefinition("hotels",  "handles hotel reservations", hotelProcessor));

OrchestrationResult result = orch.execute(
    "Book a flight to Bangalore on Aug 15 and a hotel for 3 nights");
System.out.println(result.getSummary()); // LLM-synthesised answer

ReAct planning loop β€” quick start

ReActPlanner planner = new ReActPlanner(new OpenAiActionProcessor()); // default 10 iterations
ExecutionPlan plan = planner.plan("Research the best route and book the cheapest flight to Tokyo");
plan.getSteps().forEach(step ->
    System.out.printf("Step %d | %s β†’ %s%n",
        step.getStepNumber(), step.getThought(), step.getObservation()));
System.out.println(plan.getFinalAnswer());

Tool result feedback β€” quick start

// Without decorator:  processSingleAction returns the raw Java return value ("25")
// With decorator:     processSingleAction returns "The temperature in Toronto is 25Β°C today."
AIProcessor enriched = new ToolResultFeedbackProcessor(new OpenAiActionProcessor());
String answer = (String) enriched.processSingleAction("What is the temperature in Toronto?");

Retry & fallback β€” quick start

AIProcessor resilient = new RetryActionProcessor(
        new OpenAiActionProcessor(),
        3,                               // max attempts (including the first)
        500,                             // initial backoff ms, doubles each retry
        new GeminiV2ActionProcessor());  // optional fallback after retries exhaust (may be null)
Object result = resilient.processSingleAction("Book a flight to Bangalore");

Audit trail β€” quick start

AuditTrail trail = new JsonFileAuditTrail("/var/agent/audit.jsonl"); // or new InMemoryAuditTrail(100)
AIProcessor audited = new AuditedActionProcessor(new OpenAiActionProcessor(), trail);

audited.processSingleAction("Restart the payment server");
// audit.jsonl: {"timestampMs":...,"prompt":"Restart the payment server","success":true,"durationMs":...}
// Failures are recorded too (success=false, errorMessage) and rethrown unchanged.

3. πŸ”’ Safety & Observability

  • HumanInLoop is an interface with no built-in UI β€” there is no out-of-box approval UI/webhook, just the interface contract.
  • ActionRisk gates are not enforced by the framework β€” MEDIUM/HIGH risk actions do not automatically pause for approval unless the caller explicitly checks.
  • Audit trail / action log βœ… Implemented β€” com.t4a.agent.audit (AuditedActionProcessor + JsonFileAuditTrail) gives a persistent record of every execution: prompt, result, success/failure, duration.
  • GuardRails is Gemini-only (GeminiGuardRails) β€” OpenAI/Anthropic actions have no guard-rail implementation.

4. πŸ§ͺ Testing & Quality

  • PredictionLoader singleton makes unit tests fragile β€” 5 tests are permanently disabled because of singleton state bleed between tests. Proper scoping or a clean reset mechanism would fix them all.
  • No integration test harness β€” the regression tests in com.t4a.regression all require live API keys. A contract-test / mock-LLM layer would enable true CI with no credentials.

5. πŸ”Œ Extensibility

  • ExtendedPredictionLoader + @ActivateLoader are very powerful but underdocumented β€” custom action loaders auto-discovered by annotation is a great pattern that needs more examples.
  • Retry / fallback βœ… Implemented β€” com.t4a.agent.resilience.RetryActionProcessor retries transient AIProcessingException failures with exponential backoff and optionally falls back to a second processor (e.g. another LLM provider).
  • SwaggerPredictionLoader silently swallows parse errors β€” many catch (Exception e) { log.warn(...) } blocks do not surface which endpoints failed to load.

6. 🌐 Ecosystem

  • No Spring Boot auto-configuration (spring.factories / @AutoConfiguration) β€” Spring users have to wire it manually. A tools4ai-spring-boot-starter artifact would significantly drive adoption.
  • No MCP server implementation β€” the README mentions MCP protocol support but there is no MCP server/client in the codebase yet.
  • No metrics β€” no Micrometer integration for action execution latency, error rates, or LLM token usage per action.