02 - Architecture¶
Module Structure¶
agentensemble/ # Root project
agentensemble-core/ # Core library (the framework)
agentensemble-examples/ # Example applications
Dependency Graph¶
agentensemble-core
+-- langchain4j-core (LLM abstractions, tool specs, message types)
+-- lombok (compile-only: builders, value objects)
+-- jackson-databind (JSON serialization for tool I/O)
+-- slf4j-api (logging facade)
agentensemble-examples
+-- agentensemble-core
+-- langchain4j-open-ai (OpenAI model provider -- example only)
+-- logback-classic (SLF4J implementation for examples)
Users add their own LangChain4j model provider as a runtime dependency (e.g., langchain4j-open-ai, langchain4j-ollama, langchain4j-anthropic).
Package Structure¶
net.agentensemble
Agent.java # Top-level user-facing domain objects
Task.java
Ensemble.java
net.agentensemble.agent
AgentExecutor.java # Runs one agent on one task
AgentPromptBuilder.java # Constructs system/user prompts
net.agentensemble.task
TaskOutput.java # Task result value object
net.agentensemble.ensemble
EnsembleOutput.java # Ensemble result value object
net.agentensemble.workflow
Workflow.java # Enum: SEQUENTIAL, HIERARCHICAL
WorkflowExecutor.java # Strategy interface
SequentialWorkflowExecutor.java # Runs tasks one-by-one
HierarchicalConstraints.java # Constraints for hierarchical workflow
HierarchicalConstraintEnforcer.java # Enforces hierarchical constraints (package-private)
net.agentensemble.tool
AgentTool.java # Framework tool interface
ToolResult.java # Tool execution result
LangChain4jToolAdapter.java # Adapts AgentTool to LC4j
net.agentensemble.config
TemplateResolver.java # {variable} substitution
net.agentensemble.exception
AgentEnsembleException.java # Base exception
ValidationException.java # Invalid configuration
TaskExecutionException.java # Task-level failure
AgentExecutionException.java # Agent-level failure
ToolExecutionException.java # Tool execution failure
MaxIterationsExceededException.java # Agent hit iteration limit
PromptTemplateException.java # Template variable error
ConstraintViolationException.java # Hierarchical constraint violated
net.agentensemble.metrics # Execution metrics (issue #42)
TaskMetrics.java # Per-task token counts, timing, costs
ExecutionMetrics.java # Aggregated per-run metrics
CostConfiguration.java # Per-token cost rates for estimation
CostEstimate.java # Monetary cost estimate value object
MemoryOperationCounts.java # STM/LTM/entity operation counters
net.agentensemble.trace # Execution trace (issues #42, #89)
ExecutionTrace.java # Top-level immutable run trace
TaskTrace.java # Per-task trace
LlmInteraction.java # Single LLM chat() call record
ToolCallTrace.java # Single tool invocation record
DelegationTrace.java # Peer delegation record
TaskPrompts.java # System/user prompt snapshot
AgentSummary.java # Agent configuration snapshot
ErrorTrace.java # Error record
LlmResponseType.java # FINAL_ANSWER / TOOL_CALLS enum
ToolCallOutcome.java # SUCCESS / FAILURE / ERROR / SKIPPED enum
CaptureMode.java # OFF / STANDARD / FULL capture depth (issue #89)
CapturedMessage.java # Serializable LLM message snapshot (issue #89)
net.agentensemble.trace.export # Trace export (issue #42)
ExecutionTraceExporter.java # Strategy interface for exporting traces
JsonTraceExporter.java # File-based JSON exporter
net.agentensemble.trace.internal # Internal accumulator (package-private API)
TaskTraceAccumulator.java # Mutable collector, frozen at task end
net.agentensemble.memory # Memory subsystem
MemoryContext.java # Runtime memory state for one run
MemoryOperationListener.java # Callback interface for memory events (issue #89)
EnsembleMemory.java # Memory configuration
ShortTermMemory.java # In-run task output accumulator
LongTermMemory.java # Pluggable persistent store interface
EntityMemory.java # Key-value fact store interface
MemoryEntry.java # Memory entry value object
Design Principles¶
-
Immutability:
Agent,Task,TaskOutput,EnsembleOutputare immutable value objects (@Value). Once built, they cannot be modified. -
Builder pattern: All domain objects use Lombok
@Builderfor construction with validation in custom builder methods. -
Strategy pattern:
WorkflowExecutoris a strategy interface withSequentialWorkflowExecutor,HierarchicalWorkflowExecutor, andParallelWorkflowExecutorimplementations.ManagerPromptStrategyis a secondary strategy interface that controls how the Manager agent's system and user prompts are generated in hierarchical workflow --DefaultManagerPromptStrategyprovides the built-in behaviour while callers can substitute a custom implementation viaEnsemble.Builder.managerPromptStrategy(). -
Composition over inheritance:
AgentExecutorcomposes LangChain4j services rather than extending them. No deep inheritance hierarchies. -
Fail-fast: Validation happens at construction time (
build()) and atrun()time, not deep in execution. Users get clear error messages early. -
No singletons or statics: All components are instantiated, making testing straightforward.
TemplateResolveruses static methods but is stateless and pure. -
Separation of concerns: Prompt construction (AgentPromptBuilder), execution (AgentExecutor), orchestration (WorkflowExecutor), and domain model are separate classes with single responsibilities.
Build System¶
- Gradle with Kotlin DSL (
.gradle.kts) - Version catalog (
gradle/libs.versions.toml) for centralized dependency management java-libraryplugin foragentensemble-core(properapivsimplementationseparation)applicationplugin foragentensemble-examples- Java 21 target
- Lombok annotation processor configured via Gradle