Core API¶
Stateless, SOLID building blocks for the ECS framework.
Overview¶
The core API provides the fundamental abstractions for entities, components, systems, and queries. These are pure, stateless functionalities that can be composed to build complex agent behaviors.
Key Principles: - Protocols over inheritance: Use runtime-checkable protocols for flexibility - Functional core: All operations are deterministic and stateless - Composability: Mix and match protocols to create rich component behaviors
Component Module¶
Define components with optional operation protocols.
Component Decorator¶
component(cls=None)
¶
Register a dataclass or Pydantic model as a component type.
Supports two forms
@component # bare decorator @component() # parenthesized, no args
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cls
|
type | None
|
The class to register, or None if called with arguments. |
None
|
Returns:
| Type | Description |
|---|---|
type | Callable[[type], type]
|
Decorated class or decorator function. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If class is neither a dataclass nor Pydantic model. |
Note
Apply @component AFTER @dataclass:
@component ... @dataclass(slots=True) ... class MyComponent: ... value: int
Source code in src/agentecs/core/component/core.py
Component Registry¶
ComponentRegistry
¶
Process-local registry mapping component types to deterministic type IDs.
Maintains bidirectional mapping between component types and their type IDs. Deterministic IDs ensure same code produces same IDs across nodes.
TODO: Figure out distributed syncing of local registries if needed.¶
Source code in src/agentecs/core/component/core.py
register(cls)
¶
Register a component type and return its metadata.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cls
|
type
|
Component class to register. |
required |
Returns:
| Type | Description |
|---|---|
ComponentTypeMeta
|
Component metadata including ID and type name. |
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If component ID collides with another registered type. |
Source code in src/agentecs/core/component/core.py
get_meta(cls)
¶
Get metadata for a registered component type.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cls
|
type
|
Component class to look up. |
required |
Returns:
| Type | Description |
|---|---|
ComponentTypeMeta | None
|
Component metadata if registered, None otherwise. |
Source code in src/agentecs/core/component/core.py
get_type(component_type_id)
¶
Get component type by its type ID.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
component_type_id
|
int
|
Component type ID to look up. |
required |
Returns:
| Type | Description |
|---|---|
type | None
|
Component class if found, None otherwise. |
Source code in src/agentecs/core/component/core.py
is_registered(cls)
¶
Check if a type is registered as a component.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cls
|
type
|
Class to check. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if class is registered as component, False otherwise. |
Source code in src/agentecs/core/component/core.py
get_registry()
¶
Access the global component registry.
Returns:
| Type | Description |
|---|---|
ComponentRegistry
|
The process-local ComponentRegistry instance. |
Operation Protocols¶
Components can optionally implement these protocols to enable advanced operations:
Combinable
¶
Bases: Protocol
Component knows how to accumulate multiple writes.
When multiple ops target the same (entity, type), the framework folds them with combine instead of overwriting.
Source code in src/agentecs/core/component/models.py
Splittable
¶
Utility Functions¶
combine_protocol_or_fallback(comp1, comp2)
¶
Combine two components, using Combinable protocol with LWW fallback.
If comp1 implements Combinable and comp2 is the same type, delegates to comp1.combine(comp2). Otherwise returns comp2 (last-writer-wins).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
comp1
|
T
|
Existing component value. |
required |
comp2
|
T
|
Incoming component value. |
required |
Returns:
| Type | Description |
|---|---|
T
|
Combined result or comp2 as fallback. |
Source code in src/agentecs/core/component/operations.py
split_protocol_or_fallback(comp)
¶
Split a component, using Splittable protocol with deepcopy fallback.
If comp implements Splittable, delegates to comp.split(). Otherwise returns two independent deep copies.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
comp
|
T
|
Component to split. |
required |
Returns:
| Type | Description |
|---|---|
tuple[T, T]
|
Tuple of two components. |
Source code in src/agentecs/core/component/operations.py
reduce_components(items)
¶
Reduce a list of components into one.
Uses sequential combines
if combine is defined, merges items using that pairwise; otherwise, takes the last item as the result.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
items
|
list[T]
|
List of components to reduce (must be same type). |
required |
Returns:
| Type | Description |
|---|---|
T
|
Single component resulting from reduction. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If items list is empty. |
Source code in src/agentecs/core/component/operations.py
Identity Module¶
Entity identification with generational indices.
EntityId
dataclass
¶
Lightweight entity identifier with generation for safe handle reuse.
Shard field enables future distributed scaling - each shard allocates indices independently within its range.
Source code in src/agentecs/core/identity/models.py
is_local()
¶
Check if this entity belongs to the local shard.
Returns:
| Type | Description |
|---|---|
bool
|
True if entity is on shard 0 (local), False otherwise. |
SystemEntity
¶
Reserved entity IDs for singletons. Always on shard 0.
Source code in src/agentecs/core/identity/models.py
Query Module¶
Query builder for filtering entities by component types.
Query
dataclass
¶
Declarative query for access pattern declarations.
Immutable - each method returns a new Query instance.
Source code in src/agentecs/core/query/models.py
AccessPattern = AllAccess | TypeAccess | QueryAccess | NoAccess
module-attribute
¶
System Module¶
Define systems with declared access patterns.
System Decorator¶
system = _SystemDecorator()
module-attribute
¶
System Metadata¶
SystemDescriptor
dataclass
¶
Metadata about a registered system.
Source code in src/agentecs/core/system/models.py
can_read_type(component_type)
¶
Check whether this system can read the given component type.
Write access implies read access.
Source code in src/agentecs/core/system/models.py
can_write_type(component_type)
¶
Check whether this system can write the given component type.
is_dev_mode()
¶
Check if system should run in isolation (dev mode).
Returns:
| Type | Description |
|---|---|
bool
|
True if system should run alone in its own execution group. |
SystemMode
¶
Bases: Enum
Execution mode controlling access capabilities.