IntentReactor is a Spring Boot starter library that brings LLM-powered intent analysis and autonomous action planning to any Spring Boot application. It implements the ReACT (Reason + Act) paradigm and ships 18 interchangeable planning strategies — from vanilla chain-of-thought to Monte Carlo tree search — all configured with a single property.
- ReACT planning loop — iterative Thought → Action → Observation cycle driven by any Spring AI
ChatClient - 18 built-in planning strategies — ReACT, Reflexion, LATS (MCTS), CoT, Zero-Shot CoT, Step-Back, Tree-of-Thoughts, Graph-of-Thoughts, STORM, Self-Ask, Least-to-Most, Plan-and-Solve, Reflection, Self-Discover, ReTreVal, MAP, HTP, KnowAgent
- Multi-intent dispatch — automatically decomposes compound user requests into sequential, parallel, or LLM-ordered sub-plans
- Tool confirmation flow — risky tools pause execution and return
AWAITING_CONFIRMATION; resumed viaproceedAfterConfirmation() - Pluggable session stores — in-memory, filesystem, JDBC, and JPA implementations out of the box
- RAG integration —
knowledge_searchtool backed by in-memory, filesystem, JDBC, or vector sources - Dynamic JavaScript tools — define tools at runtime as JavaScript snippets running in a Rhino sandbox with class-level restrictions and execution timeouts
- MCP support — consume remote MCP servers as local tools (SSE and STDIO transports); expose IntentReactor tools and planners as an MCP server
- Context window management — sliding message window, snapshot deduplication, per-message character limits, and optional LLM-based context compression
- Spring Events —
PlanStartedEvent,PlanStepCompletedEvent,PlanFailedEvent, and more - Micrometer metrics — transparent decorator wraps any planner and records step counts and latency
| Dependency | Version |
|---|---|
| Java | 17+ |
| Spring Boot | 3.5+ |
| Spring AI | 1.1+ |
<dependency>
<groupId>com.intentreactor</groupId>
<artifactId>intent-reactor-spring-boot-starter</artifactId>
<version>0.1.16</version>
</dependency>Add a Spring AI provider (e.g., OpenAI):
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-openai</artifactId>
</dependency>spring:
ai:
openai:
api-key: ${OPENAI_API_KEY}
chat:
options:
model: gpt-4o
intent-reactor:
planning:
strategy: react # react | reflexion | lats | cot | tot | got | storm | …
max-steps: 10
autonomous: false # true = skip confirmation for risky toolsAny Spring bean implementing Tool is automatically discovered:
@Component
public class OrderLookupTool implements Tool {
@Override
public String getName() { return "order_lookup"; }
@Override
public String getDescription() {
return "Looks up an order by ID and returns its status and estimated delivery date.";
}
@Override
public Map<String, Object> getParameterSchema() {
return Map.of(
"type", "object",
"properties", Map.of(
"orderId", Map.of("type", "string", "description", "The order identifier")
),
"required", List.of("orderId")
);
}
@Override
public ToolResult execute(ToolInput input) {
String id = (String) input.getParameters().get("orderId");
// ... lookup logic ...
return ToolResult.ok(Map.of("status", "shipped", "eta", "2025-07-01"));
}
@Override
public boolean isRisky() { return false; }
}@Autowired
IntentReactorService reactor;
// One-shot (no session)
ReactorResponse r = reactor.process("What is the status of order ORD-123?", null);
System.out.println(r.getFinalText());
// Dialog mode (persistent session)
ReactorResponse r1 = reactor.process("session-42", "Look up order ORD-123");
ReactorResponse r2 = reactor.process("session-42", "Now cancel it");
// Handle confirmation for risky tools
if (r2.getStatus() == PlanStatus.AWAITING_CONFIRMATION) {
ConfirmationRequest req = r2.getConfirmationRequest();
boolean approved = ui.confirm(req.getDescription());
ReactorResponse resumed = reactor.proceedAfterConfirmation(
r2.getSessionId(),
approved ? ConfirmationResult.approve() : ConfirmationResult.reject()
);
}intent-reactor-api Pure interfaces and DTOs (no Spring dependency)
intent-reactor-core Default implementations + Spring AutoConfiguration
intent-reactor-spring-boot-starter Thin entry-point starter
Optional add-ons:
├── intent-reactor-session-jdbc JDBC-backed SessionStore
├── intent-reactor-session-jpa JPA-backed SessionStore
├── intent-reactor-tool-commons Ready-made tools (calculator, web fetch, file I/O, …)
├── intent-reactor-tool-dynamic Runtime JavaScript tools via Rhino sandbox
├── intent-reactor-rag RAG KnowledgeSource + knowledge_search tool
├── intent-reactor-mcp-client Consume remote MCP servers as local tools
├── intent-reactor-mcp-server Expose IntentReactor as an MCP server
└── intent-reactor-strategies 18 extra planning strategies (CoT, ToT, GoT, STORM, HTP, MAP, …)
Select a strategy with intent-reactor.planning.strategy:
| Strategy | Value | Description |
|---|---|---|
| ReACT (default) | react |
Iterative Reason → Act → Observe loop |
| Reflexion | reflexion |
Adds verbal self-reflection after tool failures |
| LATS | lats |
Monte Carlo Tree Search over possible action paths |
| Chain-of-Thought | cot |
Prepends a reasoning chain before acting |
| Zero-Shot CoT | zero-shot-cot |
Adds "Let's think step by step" to the prompt |
| Step-Back | step-back |
Abstracts to a higher-level question before solving |
| Reflection | reflection |
Iterative critique-and-revision of the plan |
| Self-Ask | self-ask |
Decomposes into sub-questions and answers them |
| Least-to-Most | least-to-most |
Solves easiest sub-problems first |
| Plan-and-Solve | plan-and-solve |
Explicit planning phase before execution |
| Tree of Thoughts | tot |
Explores branching reasoning paths |
| Graph of Thoughts | got |
Merges and scores thought nodes in a graph |
| Self-Discover | self-discover |
Selects and adapts reasoning modules at runtime |
| STORM | storm |
Multi-perspective research and synthesis |
| ReTreVal | retreval |
Reasoning tree with dual validation and typed-failure backtracking |
| MAP | map |
Five specialised cognitive modules: decompose, predict, evaluate, monitor, coordinate |
| HTP | htp |
Hierarchical Tree Planning: constrained subgoal decomposition with iterative refinement |
| KnowAgent | knowagent |
Builds an Action Knowledge Base (preconditions/postconditions) and filters invalid tools |
| Value | Description |
|---|---|
in-memory (default) |
Lost on restart; ideal for development |
filesystem |
Serialized to JSON files under a configurable directory |
jdbc |
Single table intent_reactor_sessions; add intent-reactor-session-jdbc |
jpa |
JPA entity; add intent-reactor-session-jpa |
intent-reactor:
session:
store: jdbc
jdbc:
table-name: intent_reactor_sessionsAdd intent-reactor-rag and configure at least one knowledge source:
intent-reactor:
rag:
enabled: true
max-results: 5
filesystem:
enabled: true
path: ./knowledge
glob: "**/*.{txt,md}"
jdbc:
enabled: false
table: knowledge_documents
content-column: contentThe knowledge_search tool is automatically registered and available to all planners.
Add intent-reactor-tool-dynamic, enable it, and register scripts via ScriptRepository:
intent-reactor:
tools:
dynamic-scripting:
enabled: true
max-execution-time: PT5S
script-repository: in-memory # in-memory | jdbc
allowed-classes:
- java.lang.Math
- java.util.List@Autowired ScriptRepository scriptRepository;
scriptRepository.save(new ScriptDefinition(
"currency_convert",
"Converts amount from one currency to another using a fixed rate.",
/* parameter schema */ Map.of(...),
/* script */ "var rate = params.from === 'USD' ? 90.0 : 1.0; rate * params.amount;"
));Add intent-reactor-mcp-client:
intent-reactor:
mcp:
client:
enabled: true
servers:
- name: my-server
transport: SSE
url: http://localhost:8090
prefix-tool-names: trueAdd intent-reactor-mcp-server together with spring-ai-starter-mcp-server. All registered Tool beans are published automatically.
| Interface | Purpose |
|---|---|
Tool |
Define a callable action; annotate with @Component |
SimulatableTool |
Tool that supports dry-run simulation (used by LATS) |
Planner |
Custom planning strategy; declare @Primary to override the default |
SessionStore |
Custom session persistence backend |
IntentPreprocessor |
Custom intent classification logic |
PromptContextProvider |
Inject extra template variables into system prompts |
ToolProvider |
Custom tool discovery and filtering per session |
intent-reactor:
llm:
provider: openai # informational label
model: gpt-4o
temperature: 0.1
prompt-resources: # override any built-in prompt template
system: classpath:prompts/default-system-ru.md
intent: classpath:prompts/default-intent-ru.md
planning:
strategy: react
autonomous: false # true = skip user confirmation for risky tools
max-steps: 10
max-retries: 3
confirmation-timeout: PT30M
parallel-timeout: PT60S
multi-intent:
strategy: sequential # sequential | parallel | llm-driven
reflexion:
max-reflection-steps: 3
lats:
max-iterations: 50
exploration-constant: 1.4
branching-factor: 3
context-window:
max-messages: 20
max-message-chars: 8000
max-snapshot-chars: 30000
compression:
enabled: false
max-tokens: 4000
trigger-ratio: 0.85
session:
store: in-memory # in-memory | filesystem | jdbc | jpa
filesystem:
path: ./sessions
jdbc:
table-name: intent_reactor_sessions
logging:
enabled: true # structured event logging via SLF4JListen to framework events with @EventListener:
@EventListener
public void onPlanCompleted(PlanCompletedEvent event) {
log.info("Session {} completed: {}", event.getSessionId(), event.getFinalText());
}
@EventListener
public void onConfirmationRequired(ConfirmationRequiredEvent event) {
// push to UI / message queue
}Available events: IntentAnalysisStartedEvent, IntentAnalysisCompletedEvent, PlanStartedEvent, PlanStepStartedEvent, PlanStepCompletedEvent, PlanCompletedEvent, PlanFailedEvent, ConfirmationRequiredEvent, ContextCompressedEvent.
Apache License 2.0