Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ src/ai_company/
communication/ # Message bus, dispatcher, messenger, channels, delegation, loop prevention
config/ # YAML company config loading and validation
core/ # Shared domain models and base classes
engine/ # Agent orchestration, execution loops, parallel execution, task lifecycle, recovery, and shutdown
engine/ # Agent orchestration, execution loops, parallel execution, task decomposition, routing, task lifecycle, recovery, and shutdown
memory/ # Persistent agent memory (memory layer TBD)
observability/ # Structured logging, correlation tracking, log sinks
providers/ # LLM provider abstraction (LiteLLM adapter)
Expand Down
30 changes: 24 additions & 6 deletions DESIGN_SPEC.md
Original file line number Diff line number Diff line change
Expand Up @@ -780,7 +780,8 @@ task:
- "Unit and integration tests with >80% coverage"
- "API documentation"
estimated_complexity: "medium" # simple, medium, complex, epic
task_structure: "parallel" # sequential, parallel, mixed (M4 — see §6.9)
task_structure: "parallel" # sequential, parallel, mixed (see §6.9)
coordination_topology: "auto" # auto, sas, centralized, decentralized, context_dependent (see §6.9)
budget_limit: 2.00 # max USD for this task
deadline: null
max_retries: 1 # max reassignment attempts after failure (0 = no retry)
Expand Down Expand Up @@ -1158,13 +1159,13 @@ These are complementary systems handling different types of shared state:

### 6.9 Task Decomposability & Coordination Topology (M4+)

> **MVP: Not applicable.** M3 is single-agent. This section defines M4+ concepts for multi-agent task routing.
> **Current state:** Task structure classification (`TaskStructureClassifier`), DAG-based decomposition (`DecompositionService`, `DependencyGraph`, `ManualDecompositionStrategy`), status rollup (`StatusRollup`), agent-task scoring (`AgentTaskScorer`), routing (`TaskRoutingService`), and auto topology selection (`TopologySelector`) are implemented in `engine/decomposition/` and `engine/routing/`. LLM-based decomposition strategies and runtime multi-agent coordination are M4+ (see #168).

Empirical research on agent scaling ([Kim et al., 2025](https://arxiv.org/abs/2512.08296) — 180 controlled experiments across 3 LLM families and 4 benchmarks) demonstrates that **task decomposability is the strongest predictor of multi-agent effectiveness** — stronger than team size, model capability, or coordination architecture.

#### Task Structure Classification

Each task will carry a `task_structure` field (to be added to §6.2 Task Definition at M4) classifying its decomposability:
Each task carries a `task_structure` field (see §6.2 Task Definition) classifying its decomposability:

| Structure | Description | MAS Effect | Example |
|-----------|-------------|------------|---------|
Expand All @@ -1182,7 +1183,7 @@ The communication pattern (§5.1) is configured at the company level, but **coor

| Task Properties | Recommended Topology | Rationale |
|----------------|---------------------|-----------|
| `sequential` + few tools (≤4) | **Single-agent (SAS)** | Coordination overhead fragments reasoning capacity on sequential tasks |
| `sequential` + few artifacts (≤4) | **Single-agent (SAS)** | Coordination overhead fragments reasoning capacity on sequential tasks |
| `parallel` + structured domain | **Centralized** | Orchestrator decomposes, sub-agents execute in parallel, orchestrator synthesizes. Lowest error amplification (4.4×) |
| `parallel` + exploratory/open-ended | **Decentralized** | Peer debate enables diverse exploration of high-entropy search spaces |
| `mixed` | **Context-dependent** | Sequential backbone handled by single agent; parallel sub-tasks delegated to sub-agents |
Expand All @@ -1203,7 +1204,7 @@ coordination:
mixed_default: "context_dependent" # hybrid: not a single topology — engine selects per-phase
```

The auto-selector uses task structure, tool count, and (when available from M5 memory) historical single-agent success rate as inputs. The exact selection logic is an M4 implementation detail — the spec defines the interface and the empirically-grounded heuristics above.
The auto-selector uses task structure, artifact count, and (when available from M5 memory) historical single-agent success rate as inputs. The exact selection logic is an M4 implementation detail — the spec defines the interface and the empirically-grounded heuristics above.

> **Reference:** These heuristics are derived from Kim et al. (2025), which achieved 87% accuracy predicting optimal architecture from task properties across held-out configurations. Our context differs (role-differentiated agents vs. identical agents), so thresholds should be validated empirically once multi-agent execution is implemented.

Expand Down Expand Up @@ -2364,7 +2365,7 @@ ai-company/
│ │ ├── role.py # Role model
│ │ ├── role_catalog.py # Role catalog
│ │ └── personality.py # Personality compatibility scoring
│ ├── engine/ # Agent orchestration, execution loops, and task lifecycle
│ ├── engine/ # Agent orchestration, execution loops, parallel execution, task decomposition, routing, task lifecycle, recovery, and shutdown
│ │ ├── errors.py # Engine error hierarchy
│ │ ├── prompt.py # System prompt builder
│ │ ├── prompt_template.py # System prompt Jinja2 templates
Expand All @@ -2385,6 +2386,21 @@ ai-company/
│ │ ├── parallel_models.py # AgentAssignment, ParallelExecutionGroup, AgentOutcome, ParallelExecutionResult, ParallelProgress
│ │ ├── resource_lock.py # ResourceLock protocol + InMemoryResourceLock
│ │ ├── shutdown.py # Graceful shutdown strategy & manager
│ │ ├── decomposition/ # Task decomposition subsystem
│ │ │ ├── __init__.py # Package exports
│ │ │ ├── classifier.py # TaskStructureClassifier (sequential/parallel/mixed)
│ │ │ ├── dag.py # DependencyGraph (validation, topo sort, parallel groups)
│ │ │ ├── manual.py # ManualDecompositionStrategy
│ │ │ ├── models.py # SubtaskDefinition, DecompositionPlan, DecompositionResult, SubtaskStatusRollup, DecompositionContext
│ │ │ ├── protocol.py # DecompositionStrategy protocol
│ │ │ ├── rollup.py # StatusRollup (compute subtask status aggregation)
│ │ │ └── service.py # DecompositionService (orchestrates strategy + classifier + DAG)
│ │ ├── routing/ # Task routing subsystem
│ │ │ ├── __init__.py # Package exports
│ │ │ ├── models.py # RoutingCandidate, RoutingDecision, RoutingResult, AutoTopologyConfig
│ │ │ ├── scorer.py # AgentTaskScorer (skill/role/seniority matching)
│ │ │ ├── service.py # TaskRoutingService (routes subtasks to agents)
│ │ │ └── topology_selector.py # TopologySelector (auto coordination topology)
│ │ ├── task_engine.py # Task routing & scheduling (M4)
│ │ ├── workflow_engine.py # Workflow orchestration (M4)
│ │ ├── meeting_engine.py # Meeting coordination (M4)
Expand Down Expand Up @@ -2436,6 +2452,7 @@ ai-company/
│ │ │ ├── config.py # CONFIG_* constants
│ │ │ ├── delegation.py # DELEGATION_* constants
│ │ │ ├── correlation.py # CORRELATION_* constants
│ │ │ ├── decomposition.py # DECOMPOSITION_* constants
│ │ │ ├── execution.py # EXECUTION_* constants
│ │ │ ├── git.py # GIT_* constants
│ │ │ ├── parallel.py # PARALLEL_* constants
Expand All @@ -2446,6 +2463,7 @@ ai-company/
│ │ │ ├── routing.py # ROUTING_* constants
│ │ │ ├── sandbox.py # SANDBOX_* constants
│ │ │ ├── task.py # TASK_* constants
│ │ │ ├── task_routing.py # TASK_ROUTING_* constants
│ │ │ ├── template.py # TEMPLATE_* constants
│ │ │ └── tool.py # TOOL_* constants
│ │ ├── processors.py # Log processors
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ AI Company lets you spin up a virtual organization staffed entirely by AI agents
- **Multi-Provider** - Any LLM via LiteLLM — cloud APIs, OpenRouter (400+ models), local Ollama, and more
- **Smart Cost Management** - Per-agent budget tracking, auto model routing, CFO agent optimization
- **Hierarchical Delegation** - Chain-of-command task delegation with five-mechanism loop prevention
- **Task Decomposition & Routing** - DAG-based subtask decomposition, structure classification, and agent-task scoring
- **Configurable Autonomy** - From fully autonomous to human-approves-everything, with a Security Ops agent in between
- **Persistent Memory** - Agents remember past decisions, code, relationships (memory layer TBD)
- **HR System** - Hire, fire, promote agents. HR agent analyzes skill gaps and proposes candidates
Expand Down
4 changes: 4 additions & 0 deletions src/ai_company/core/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
CompanyType,
Complexity,
ConflictApproach,
CoordinationTopology,
CostTier,
CreativityLevel,
DecisionMakingStyle,
Expand All @@ -43,6 +44,7 @@
SeniorityLevel,
SkillCategory,
TaskStatus,
TaskStructure,
TaskType,
ToolAccessLevel,
ToolCategory,
Expand Down Expand Up @@ -84,6 +86,7 @@
"CompanyType",
"Complexity",
"ConflictApproach",
"CoordinationTopology",
"CostTier",
"CreativityLevel",
"CustomRole",
Expand Down Expand Up @@ -114,6 +117,7 @@
"SkillSet",
"Task",
"TaskStatus",
"TaskStructure",
"TaskType",
"Team",
"ToolAccessLevel",
Expand Down
26 changes: 26 additions & 0 deletions src/ai_company/core/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,32 @@ class ConflictApproach(StrEnum):
COLLABORATE = "collaborate"


class TaskStructure(StrEnum):
"""Classification of how a task's subtasks relate to each other.

Used by the decomposition engine to determine coordination topology
and execution ordering. See DESIGN_SPEC Section 6.9.
"""

SEQUENTIAL = "sequential"
PARALLEL = "parallel"
MIXED = "mixed"


class CoordinationTopology(StrEnum):
"""Coordination topology for multi-agent task execution.

Determines how agents coordinate when executing decomposed subtasks.
See DESIGN_SPEC Section 6.9.
"""

SAS = "sas"
CENTRALIZED = "centralized"
DECENTRALIZED = "decentralized"
CONTEXT_DEPENDENT = "context_dependent"
AUTO = "auto"


class ActionType(StrEnum):
"""Convenience constants for common approval action types.

Expand Down
17 changes: 16 additions & 1 deletion src/ai_company/core/task.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,14 @@
from pydantic import BaseModel, ConfigDict, Field, model_validator

from ai_company.core.artifact import ExpectedArtifact # noqa: TC001
from ai_company.core.enums import Complexity, Priority, TaskStatus, TaskType
from ai_company.core.enums import (
Complexity,
CoordinationTopology,
Priority,
TaskStatus,
TaskStructure,
TaskType,
)
from ai_company.core.task_transitions import validate_transition
from ai_company.core.types import NotBlankStr # noqa: TC001
from ai_company.observability import get_logger
Expand Down Expand Up @@ -133,6 +140,14 @@ class Task(BaseModel):
default=(),
description="Ordered agent IDs of delegators (root first)",
)
task_structure: TaskStructure | None = Field(
default=None,
description="Classification of subtask relationships (None = not classified)",
)
coordination_topology: CoordinationTopology = Field(
default=CoordinationTopology.AUTO,
description="Coordination topology for multi-agent execution",
)
Comment on lines +143 to +150

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Update class docstring to document new fields.

The Task class docstring (lines 52-73) lists all attributes but doesn't include the newly added task_structure and coordination_topology fields. Add them for consistency.

📝 Proposed docstring addition

Add these entries to the Attributes section in the class docstring:

         delegation_chain: Ordered agent IDs of delegators (root first).
+        task_structure: Classification of subtask relationships
+            (``None`` if not classified).
+        coordination_topology: Coordination topology for multi-agent
+            execution (default ``AUTO``).
     """
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/ai_company/core/task.py` around lines 143 - 150, The Task class docstring
is missing documentation for the two new fields; update the Attributes section
of the Task class docstring to include brief descriptions for task_structure
(TaskStructure | None — classification of subtask relationships; None means not
classified) and coordination_topology (CoordinationTopology — coordination
topology for multi-agent execution, default AUTO). Edit the Task class docstring
near the existing attribute list so the entries match the style/format of the
other attributes and reference the exact field names task_structure and
coordination_topology.


@model_validator(mode="after")
def _validate_deadline_format(self) -> Self:
Expand Down
48 changes: 48 additions & 0 deletions src/ai_company/engine/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,32 @@
AgentContext,
AgentContextSnapshot,
)
from ai_company.engine.decomposition import (
DecompositionContext,
DecompositionPlan,
DecompositionResult,
DecompositionService,
DecompositionStrategy,
DependencyGraph,
ManualDecompositionStrategy,
StatusRollup,
SubtaskDefinition,
SubtaskStatusRollup,
TaskStructureClassifier,
)
from ai_company.engine.errors import (
BudgetExhaustedError,
DecompositionCycleError,
DecompositionDepthError,
DecompositionError,
EngineError,
ExecutionStateError,
LoopExecutionError,
MaxTurnsExceededError,
ParallelExecutionError,
PromptBuildError,
ResourceConflictError,
TaskRoutingError,
)
from ai_company.engine.loop_protocol import (
BudgetChecker,
Expand Down Expand Up @@ -58,6 +75,15 @@
RecoveryStrategy,
)
from ai_company.engine.resource_lock import InMemoryResourceLock, ResourceLock
from ai_company.engine.routing import (
AgentTaskScorer,
AutoTopologyConfig,
RoutingCandidate,
RoutingDecision,
RoutingResult,
TaskRoutingService,
TopologySelector,
)
from ai_company.engine.run_result import AgentRunResult
from ai_company.engine.shutdown import (
CleanupCallback,
Expand All @@ -78,11 +104,22 @@
"AgentEngine",
"AgentOutcome",
"AgentRunResult",
"AgentTaskScorer",
"AutoTopologyConfig",
"BudgetChecker",
"BudgetExhaustedError",
"CleanupCallback",
"CooperativeTimeoutStrategy",
"DecompositionContext",
"DecompositionCycleError",
"DecompositionDepthError",
"DecompositionError",
"DecompositionPlan",
"DecompositionResult",
"DecompositionService",
"DecompositionStrategy",
"DefaultTokenEstimator",
"DependencyGraph",
"EngineError",
"ExecutionLoop",
"ExecutionPlan",
Expand All @@ -91,6 +128,7 @@
"FailAndReassignStrategy",
"InMemoryResourceLock",
"LoopExecutionError",
"ManualDecompositionStrategy",
"MaxTurnsExceededError",
"ParallelExecutionError",
"ParallelExecutionGroup",
Expand All @@ -108,16 +146,26 @@
"RecoveryStrategy",
"ResourceConflictError",
"ResourceLock",
"RoutingCandidate",
"RoutingDecision",
"RoutingResult",
"ShutdownChecker",
"ShutdownManager",
"ShutdownResult",
"ShutdownStrategy",
"StatusRollup",
"StatusTransition",
"StepStatus",
"SubtaskDefinition",
"SubtaskStatusRollup",
"SystemPrompt",
"TaskCompletionMetrics",
"TaskExecution",
"TaskRoutingError",
"TaskRoutingService",
"TaskStructureClassifier",
"TerminationReason",
"TopologySelector",
"TurnRecord",
"add_token_usage",
"build_system_prompt",
Expand Down
33 changes: 33 additions & 0 deletions src/ai_company/engine/decomposition/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
"""Task decomposition engine.

Breaks complex tasks into subtasks with dependency tracking,
classifies task structure, and manages status rollup.
"""

from ai_company.engine.decomposition.classifier import TaskStructureClassifier
from ai_company.engine.decomposition.dag import DependencyGraph
from ai_company.engine.decomposition.manual import ManualDecompositionStrategy
from ai_company.engine.decomposition.models import (
DecompositionContext,
DecompositionPlan,
DecompositionResult,
SubtaskDefinition,
SubtaskStatusRollup,
)
from ai_company.engine.decomposition.protocol import DecompositionStrategy
from ai_company.engine.decomposition.rollup import StatusRollup
from ai_company.engine.decomposition.service import DecompositionService

__all__ = [
"DecompositionContext",
"DecompositionPlan",
"DecompositionResult",
"DecompositionService",
"DecompositionStrategy",
"DependencyGraph",
"ManualDecompositionStrategy",
"StatusRollup",
"SubtaskDefinition",
"SubtaskStatusRollup",
"TaskStructureClassifier",
]
Loading