This page documents all 24 core component dataclasses used in the ECS agent architecture. All components use @dataclass(slots=True) for memory efficiency and can be imported from ecs_agent.components.
Links an agent to an LLM provider for reasoning and planning.
| Name | Type | Default | Description |
|---|---|---|---|
provider |
LLMProvider |
(none) | The LLM provider instance |
model |
str |
(none) | The specific model identifier |
system_prompt |
str |
"" |
Optional system prompt override |
pending_provider |
`LLMProvider | None` | None |
pending_model |
`str | None` | None |
Used by: ReasoningSystem, PlanningSystem, ReplanningSystem
Usage:
from ecs_agent.components import LLMComponent
from ecs_agent.providers.openai_provider import OpenAIProvider
llm = LLMComponent(
provider=OpenAIProvider(api_key="..."),
model="gpt-4o",
system_prompt="You are a helpful assistant."
)
world.add_component(agent, llm)
# Queue model switch (takes effect at next LLM request)
llm.pending_model = "gpt-3.5-turbo"Maintains the full history of messages for an agent's conversation.
| Name | Type | Default | Description |
|---|---|---|---|
messages |
list[Message] |
(none) | History of conversation messages |
max_messages |
int |
100 |
Maximum number of messages to retain |
Used by: ReasoningSystem, PlanningSystem, MemorySystem, MessageBusSystem, ToolExecutionSystem, ReplanningSystem
Usage:
from ecs_agent.components import ConversationComponent
world.add_component(agent, ConversationComponent(messages=[]))Legacy component that stores the system prompt template and rendered content. For new agents, prefer SystemPromptConfigSpec with SystemPromptRenderSystem.
| Name | Type | Default | Description |
|---|---|---|---|
template |
str |
"" |
Base system prompt template with placeholders |
sections |
list[PromptSectionSpec] |
[] |
List of prompt sections to inject into placeholders |
content |
str |
"" |
Rendered system prompt output |
Used by: ReasoningSystem, PlanningSystem, ReplanningSystem (legacy path)
New-style prompt spec using ${name} placeholder templates. Processed by SystemPromptRenderSystem.
| Name | Type | Default | Description |
|---|---|---|---|
template_source |
PromptTemplateSource |
required | Inline string or file path for the template |
placeholder_specs |
dict[str, PlaceholderSpec] |
{} |
Per-placeholder resolver specs (static, callable, or file) |
Produces: RenderedSystemPromptComponent (via SystemPromptRenderSystem)
Usage:
from ecs_agent.prompts.contracts import SystemPromptConfigSpec, PromptTemplateSource
world.add_component(entity, SystemPromptConfigSpec(
template_source=PromptTemplateSource(
inline="You are a helpful assistant. Tools: ${_installed_tools}"
)
))cached/frozen rendered system prompt produced by SystemPromptRenderSystem on the first successful render-system pass. Reused on subsequent ticks; consumed by ReasoningSystem, PlanningSystem, ReplanningSystem.
| Name | Type | Description |
|---|---|---|
text |
str |
Fully rendered system prompt with all ${name} placeholders resolved |
Output component written by UserPromptNormalizationSystem containing the normalized user message for the current tick. Stored conversation history is never mutated.
| Name | Type | Description |
|---|---|---|
text |
str |
Normalized user message with trigger injections prepended |
Internal registry for named entity resolution and tagging. Usually managed by World via register_entity(), not directly attached to entities.
Fields:
entity_id: EntityId— Entity being registeredname: str— Unique name for lookuptags: set[str]— Tag set (default: empty set)metadata: dict[str, Any]— Additional metadata (default: empty dict)
Example:
from ecs_agent.components import EntityRegistryComponent
# Usually created via world.register_entity(), not directly
agent = world.create_entity()
world.register_entity(agent, "coordinator", tags={"manager", "primary"})Stores the definitions and execution handlers for all tools available to the agent.
| Name | Type | Default | Description |
|---|---|---|---|
tools |
dict[str, ToolSchema] |
(none) | Mapping of tool names to their schemas |
handlers |
dict[str, Callable[..., Awaitable[str]]] |
(none) | Async handlers for tool execution |
Used by: ReasoningSystem, PlanningSystem, ToolExecutionSystem
Usage:
from ecs_agent.components import ToolRegistryComponent
world.add_component(agent, ToolRegistryComponent(tools=tools, handlers=handlers))Captures tool calls generated by reasoning or planning that are waiting for execution.
| Name | Type | Default | Description |
|---|---|---|---|
tool_calls |
list[ToolCall] |
(none) | List of requested tool calls |
Added by: ReasoningSystem, PlanningSystem
Consumed by: ToolExecutionSystem (removes the component after processing)
Usage:
from ecs_agent.components import PendingToolCallsComponent
world.add_component(agent, PendingToolCallsComponent(tool_calls=requested_calls))Holds the output results of executed tool calls before they are returned to the conversation.
| Name | Type | Default | Description |
|---|---|---|---|
results |
dict[str, str] |
(none) | Mapping of call ID to result string |
Added by: ToolExecutionSystem
Usage:
from ecs_agent.components import ToolResultsComponent
world.add_component(agent, ToolResultsComponent(results={"call_1": "Success output"}))Maintains a ReAct plan, tracking individual steps and completion status.
| Name | Type | Default | Description |
|---|---|---|---|
steps |
list[str] |
(none) | Sequential list of plan steps |
current_step |
int |
0 |
Current active step index |
completed |
bool |
False |
Completion flag for the plan |
Used by: PlanningSystem, ReplanningSystem
Usage:
from ecs_agent.components import PlanComponent
world.add_component(agent, PlanComponent(steps=["Analyze", "Execute", "Verify"]))Configures the behavior and limits for the message bus.
| Name | Type | Default | Description |
|---|---|---|---|
max_queue_size |
int |
1000 |
Maximum number of buffered messages per subscriber |
publish_timeout |
float |
2.0 |
Timeout in seconds for blocking publishes (backpressure) |
request_timeout |
float |
30.0 |
Default timeout for request-response conversations |
cleanup_interval |
float |
10.0 |
Seconds between cleanup of stale request states |
Used by: MessageBusSystem
Usage:
from ecs_agent.components import MessageBusConfigComponent
world.add_component(agent, MessageBusConfigComponent(request_timeout=60.0))Tracks an entity's topic subscriptions and message queues.
| Name | Type | Default | Description |
|---|---|---|---|
subscriptions |
set[str] |
set() |
Set of topics the entity is subscribed to |
inbox |
deque[MessageBusEnvelope] |
deque() |
Incoming message queue for the subscriber |
Used by: MessageBusSystem
Usage:
from ecs_agent.components import MessageBusSubscriptionComponent
world.add_component(agent, MessageBusSubscriptionComponent(subscriptions={"agent.updates", "system.alerts"}))Manages active request-response conversations for an entity.
| Name | Type | Default | Description |
|---|---|---|---|
active_requests |
dict[str, float] |
{} |
Mapping of correlation IDs to request expiration timestamps |
Used by: MessageBusSystem
Usage:
from ecs_agent.components import MessageBusConversationComponent
world.add_component(agent, MessageBusConversationComponent())Captures diagnostic information when a system encounters an exception.
| Name | Type | Default | Description |
|---|---|---|---|
error |
str |
(none) | The error message or traceback |
system_name |
str |
(none) | System that triggered the error |
timestamp |
float |
(none) | Unix timestamp of occurrence |
Added by: ReasoningSystem, PlanningSystem on failure
Consumed by: ErrorHandlingSystem (processed and then removed)
Usage:
import time
from ecs_agent.components import ErrorComponent
world.add_component(agent, ErrorComponent(
error="API key expired",
system_name="ReasoningSystem",
timestamp=time.time()
))Signals agent should stop gracefully with partial content preservation.
| Name | Type | Default | Description |
|---|---|---|---|
reason |
InterruptionReason |
(none) | Enum: USER_REQUESTED, SYSTEM_PAUSE, ERROR, COMPLETION |
message |
str |
"" |
Human-readable reason string |
metadata |
dict[str, Any] |
{} |
Structured context (default: empty dict) |
timestamp |
float |
(auto) | Auto-generated via time.time() |
Added by: External code (user interruption), systems (error conditions)
Consumed by: Runner (detects and halts execution)
Usage:
from ecs_agent.components import InterruptionComponent
from ecs_agent.types import InterruptionReason
world.add_component(agent, InterruptionComponent(
reason=InterruptionReason.USER_REQUESTED,
message="User clicked stop",
metadata={"source": "web_ui"}
))A marker component that signifies the agent has finished its task.
| Name | Type | Default | Description |
|---|---|---|---|
reason |
str |
(none) | Final completion status or reason |
Checked by: Runner loop to determine when to stop execution.
In interactive flows, a TerminalComponent can also be handled by the opt-in TerminalCleanupSystem, which clears selected reasons after terminal-producing systems run. By default, that helper only clears reasoning_complete and leaves other terminal reasons intact.
Usage:
from ecs_agent.components import TerminalComponent
world.add_component(agent, TerminalComponent(reason="Task goal reached."))Establishes a hierarchical relationship between entities.
| Name | Type | Default | Description |
|---|---|---|---|
owner_id |
EntityId |
(none) | ID of the parent/owner entity |
Usage:
from ecs_agent.components import OwnerComponent
world.add_component(child, OwnerComponent(owner_id=root_agent_id))Provides a generic key-value store for custom system memory.
| Name | Type | Default | Description |
|---|---|---|---|
store |
dict[str, Any] |
(none) | Backing dictionary for storage |
Used by: Available for custom implementations and extensions.
Usage:
from ecs_agent.components import KVStoreComponent
world.add_component(agent, KVStoreComponent(store={"count": 5}))Configures how tool calls are approved or denied before execution.
| Name | Type | Default | Description |
|---|---|---|---|
policy |
ApprovalPolicy |
(none) | ALWAYS_APPROVE, ALWAYS_DENY, or REQUIRE_APPROVAL |
timeout |
`float | None` | 30.0 |
approved_calls |
list[str] |
[] |
History of approved tool call IDs |
denied_calls |
list[str] |
[] |
History of denied tool call IDs |
| , | |||
Used by: ToolApprovalSystem |
Usage:
from ecs_agent.components import ToolApprovalComponent
from ecs_agent.types import ApprovalPolicy
world.add_component(agent, ToolApprovalComponent(policy=ApprovalPolicy.REQUIRE_APPROVAL, timeout=60.0))Defines execution limits for code-running tools or sandboxed environments.
| Name | Type | Default | Description |
|---|---|---|---|
timeout |
float |
30.0 |
Maximum execution time in seconds |
max_output_size |
int |
10000 |
Maximum allowed size of execution output in bytes |
Used by: Tools using Sandbox logic. |
Usage:
from ecs_agent.components import SandboxConfigComponent
world.add_component(agent, SandboxConfigComponent(timeout=10.0, max_output_size=5000))Configures Monte Carlo Tree Search (MCTS) for finding the optimal plan path.
| Name | Type | Default | Description |
|---|---|---|---|
max_depth |
int |
5 |
Maximum search depth in the MCTS tree |
max_branching |
int |
3 |
Maximum number of child nodes to expand per parent |
exploration_weight |
float |
1.414 |
UCB1 exploration constant |
best_plan |
list[str] |
[] |
The best plan path found after search completes |
search_active |
bool |
False |
Internal flag indicating search is in progress |
Used by: TreeSearchSystem (mutually exclusive with PlanComponent) |
Usage:
from ecs_agent.components import PlanSearchComponent
world.add_component(agent, PlanSearchComponent(max_depth=10, max_branching=5))Triggers a vector search and stores the retrieved document snippets.
| Name | Type | Default | Description |
|---|---|---|---|
query |
str |
"" |
The search query string; cleared after retrieval |
top_k |
int |
5 |
Number of documents to retrieve |
retrieved_docs |
list[str] |
[] |
Snippets of retrieved text |
| , | |||
Used by: RAGSystem |
Usage:
from ecs_agent.components import RAGTriggerComponent
world.add_component(agent, RAGTriggerComponent(query="How to use ECS?", top_k=3))Provides an entity with access to an embedding provider. ,
| Name | Type | Default | Description |
|---|---|---|---|
provider |
EmbeddingProvider |
(none) | The embedding provider instance |
dimension |
int |
0 |
Expected vector dimension |
| , | |||
Used by: RAGSystem |
Usage:
from ecs_agent.components import EmbeddingComponent
from ecs_agent.providers.fake_embedding_provider import FakeEmbeddingProvider
world.add_component(agent, EmbeddingComponent(provider=FakeEmbeddingProvider(), dimension=384))Links an entity to a vector store for storage and retrieval. ,
| Name | Type | Default | Description |
|---|---|---|---|
store |
VectorStore |
(none) | The vector store instance |
| , | |||
Used by: RAGSystem |
|||
| , | |||
| Usage: |
from ecs_agent.components import VectorStoreComponent
from ecs_agent.providers.vector_store import InMemoryVectorStore
world.add_component(agent, VectorStoreComponent(store=InMemoryVectorStore(dimension=384)))Enables system-level streaming output for an entity's LLM responses.
| Name | Type | Default | Description |
|---|---|---|---|
enabled |
bool |
False |
Whether streaming is active for this entity |
Used by: ReasoningSystem (checks this to decide streaming vs batch mode)
Usage:
from ecs_agent.components import StreamingComponent
world.add_component(agent, StreamingComponent(enabled=True))Stores snapshots of world state for undo/restore operations.
| Name | Type | Default | Description |
|---|---|---|---|
snapshots |
list[dict[str, Any]] |
[] |
Stack of serialized world state snapshots |
max_snapshots |
int |
10 |
Maximum number of snapshots to retain |
Used by: CheckpointSystem
Usage:
from ecs_agent.components import CheckpointComponent
world.add_component(agent, CheckpointComponent(max_snapshots=5))Configures when and how conversation compaction occurs.
| Name | Type | Default | Description |
|---|---|---|---|
threshold_tokens |
int |
(none) | Token count threshold triggering compaction |
summary_model |
str |
(none) | Model to use for generating summaries |
Used by: CompactionSystem
Usage:
from ecs_agent.components import CompactionConfigComponent
world.add_component(agent, CompactionConfigComponent(threshold_tokens=4000, summary_model="qwen-plus"))Stores archived conversation summaries created by compaction.
| Name | Type | Default | Description |
|---|---|---|---|
archived_summaries |
list[str] |
[] |
List of past conversation summaries |
Used by: CompactionSystem
Usage:
from ecs_agent.components import ConversationArchiveComponent
world.add_component(agent, ConversationArchiveComponent())Tracks the current state of the runner execution on an entity.
| Name | Type | Default | Description |
|---|---|---|---|
current_tick |
int |
(none) | Current tick number in the runner loop |
is_paused |
bool |
False |
Whether the runner is paused |
checkpoint_path |
`str | None` | None |
Used by: Runner.save_checkpoint(), Runner.load_checkpoint()
Usage:
from ecs_agent.components import RunnerStateComponent
# Usually added automatically by Runner, but can be pre-configured
world.add_component(agent, RunnerStateComponent(current_tick=0))Enables an entity to request and receive async user input.
| Name | Type | Default | Description |
|---|---|---|---|
prompt |
str |
"" |
The prompt to display to the user |
future |
`asyncio.Future[str] | None` | None |
timeout |
`float | None` | None |
result |
`str | None` | None |
Used by: UserInputSystem
Usage:
from ecs_agent.components import UserInputComponent
world.add_component(agent, UserInputComponent(prompt="Enter your name: ", timeout=None))Tree-structured conversation with branching and linearization.
| Name | Type | Default | Description |
|---|---|---|---|
messages |
dict[str, ConversationMessage] |
{} |
All messages indexed by ID |
current_branch_id |
`str | None` | None |
branches |
dict[str, ConversationBranch] |
{} |
All branches indexed by ID |
Used by: conversation_tree module, ReasoningSystem (auto-linearizes current branch)
Usage:
from ecs_agent.components import ConversationTreeComponent
from ecs_agent.types import ConversationMessage, ConversationBranch
root_msg = ConversationMessage(
id="msg_0",
parent_message_id=None,
role="user",
content="Hello",
)
branch = ConversationBranch(branch_id="main", leaf_message_id="msg_0")
world.add_component(
agent,
ConversationTreeComponent(
messages={"msg_0": root_msg},
current_branch_id="main",
branches={"main": branch},
),
)Tracks OpenAI Responses API state for multi-turn conversations.
| Name | Type | Default | Description |
|---|---|---|---|
previous_response_id |
`str | None` | None |
Used by: OpenAIProvider (when use_responses_api=True)
Usage:
from ecs_agent.components import ResponsesAPIStateComponent
world.add_component(
agent,
ResponsesAPIStateComponent(previous_response_id=None),
)
# System automatically updates previous_response_id after each LLM callRegistry of named subagent configurations for delegation.
| Name | Type | Default | Description |
|---|---|---|---|
subagents |
dict[str, SubagentConfig] |
{} |
Subagent configurations by name |
Used by: SubagentSystem, delegate tool
Usage:
from ecs_agent.components import SubagentRegistryComponent
from ecs_agent.types import SubagentConfig
researcher = SubagentConfig(
name="researcher",
provider=your_provider,
model="gpt-4o",
system_prompt="You are a research assistant.",
max_ticks=10,
skills=[],
)
world.add_component(
agent,
SubagentRegistryComponent(subagents={"researcher": researcher}),
)The primary component for task definition and tracking in the Task Orchestration System.
| Name | Type | Default | Description |
|---|---|---|---|
task_id |
str |
(none) | Stable identifier for the task |
description |
str |
(none) | What the task does (supports placeholder rendering) |
expected_output |
str |
(none) | What success looks like |
assigned_agent |
EntityId | str | None |
(none) | EntityId (local), str (subagent name), or None |
tools |
list[str] |
(none) | List of tool names available for the task |
context_dependencies |
list[str] |
(none) | List of scratchbook refs needed for execution |
status |
TaskStatus |
(none) | Current state machine status |
priority |
int |
0 |
Execution priority (higher = earlier) |
output_schema |
dict[str, Any] | None |
None |
Optional Pydantic-style schema for output validation |
max_retries |
int |
0 |
Maximum number of automatic retry attempts |
Used by: TaskFetchingUnit, TaskExecutor, WavePlanner, DependencyAnalyzer
Usage:
from ecs_agent.components import TaskComponent
from ecs_agent.types import TaskStatus
task = TaskComponent(
task_id="analyze_report",
description="Analyze the report at {{tool_results/report_id}}",
expected_output="Summary of the report",
assigned_agent="analyst_agent",
tools=["read_file", "write_file"],
context_dependencies=["tool_results/report_id"],
status=TaskStatus.PENDING,
priority=10
)
world.add_component(agent, task)Stores a reference to a specific scratchbook artifact.
| Name | Type | Default | Description |
|---|---|---|---|
artifact_id |
str |
(none) | Unique identifier for the artifact file |
category |
str |
(none) | Category subfolder path |
content_hash |
str |
(none) | SHA256 hash of the artifact content |
timestamp |
str |
(none) | Creation timestamp |
Used by: TaskPersistenceService, ContextResolver, ScratchbookIndexer
Usage:
from ecs_agent.components import ScratchbookRefComponent
ref = ScratchbookRefComponent(
artifact_id="report_001",
category="tool_results",
content_hash="abc123...",
timestamp="1709827200.0"
)
world.add_component(agent, ref)Maintains an index of available artifacts for an agent.
| Name | Type | Default | Description |
|---|---|---|---|
artifacts |
dict[str, ScratchbookRef] |
{} |
Mapping of artifact IDs to their metadata references |
Used by: ScratchbookIndexer
Usage:
from ecs_agent.components import ScratchbookIndexComponent
world.add_component(agent, ScratchbookIndexComponent(artifacts={}))Configures opt-in prompt normalization and keyword injection.
| Name | Type | Default | Description |
|---|---|---|---|
triggers |
dict[str, str] |
{} |
Mapping of @keyword or event:<name> to template content |
enable_context_pool |
bool |
False |
Enable one-shot context collection |
context_pool_max_chars |
int |
8192 |
Maximum characters for context block |
Queue-backed storage for context items (tool results, subagent outputs) to be injected into outbound user messages.
| Name | Type | Default | Description |
|---|---|---|---|
entries |
list[ContextEntry] |
[] |
Collected context entries |
Tracks an active reservation snapshot for deterministic prompt context injection.
| Name | Type | Default | Description |
|---|---|---|---|
reservation_id |
str |
(required) | Unique reservation identifier |
created_at_tick |
int |
(required) | Tick when reservation was created |
reserved_entries |
list[ContextEntry] |
(required) | Snapshot of reserved context entries |