Skip to content

Models

Core data models and enums used throughout Agent Queue.

Shared data model types for the agent-queue system.

This module is the shared vocabulary of the entire system. Every component — orchestrator, scheduler, database, Discord bot, agent adapters — communicates through the enums and dataclasses defined here. Keeping them in one place prevents circular imports and ensures a single source of truth for the structure of tasks, agents, projects, and hooks.

See specs/models-and-state-machine.md for the full behavioral specification.

Classes

TaskStatus

Bases: Enum

The states a task can occupy in the orchestrator's state machine.

These map directly to the state machine defined in VALID_TASK_TRANSITIONS (see src/state_machine.py). The orchestrator's main loop drives tasks through these states based on events like dependency resolution, agent completion, rate limiting, and human approval.

Note: transitions are not enforced by the state machine in production — the orchestrator writes directly via db.update_task(). The state machine module is used only for validation logging. See specs/models-and-state-machine.md.

TaskEvent

Bases: Enum

Events that trigger transitions between TaskStatus states.

These are grouped into: core lifecycle events (DEPS_MET through PR_MERGED), retry/failure events (RETRY, MAX_RETRIES), administrative overrides (ADMIN_SKIP, ADMIN_STOP, ADMIN_RESTART), and error recovery events (PR_CLOSED, TIMEOUT, EXECUTION_ERROR, RECOVERY). Each (TaskStatus, TaskEvent) pair maps to exactly one target TaskStatus in the transitions table.

TaskType

Bases: Enum

Categorizes the kind of work a task represents.

Used by the Discord UI to display type-specific emoji tags and by the chat agent to help the LLM understand the nature of each task at a glance. The plan parser can auto-assign a type when creating subtasks from a plan file.

Values are lowercase strings stored directly in the task_type column.

AgentState

Bases: Enum

Tracks the runtime state of an agent process from the orchestrator's perspective.

The orchestrator uses this to decide which agents are available for task assignment (IDLE) and to detect dead agents via heartbeat checks (BUSY agents that stop heartbeating are presumed crashed).

AgentResult

Bases: Enum

The outcome reported by an agent adapter when a task execution finishes.

The orchestrator maps these to TaskEvents: COMPLETED and FAILED are straightforward; PAUSED_TOKENS and PAUSED_RATE_LIMIT cause the task to enter PAUSED with a resume_after timestamp, allowing the orchestrator to automatically retry once the rate limit window or token budget resets. WAITING_INPUT indicates the agent is blocked on a human question — the task transitions to WAITING_INPUT and a notification is sent.

ProjectStatus

Bases: Enum

Lifecycle state of a project. PAUSED projects are skipped by the scheduler.

VerificationType

Bases: Enum

How a task's output should be verified before it can move to COMPLETED.

AUTO_TEST runs test commands from TaskContext; QA_AGENT spawns a separate verification agent; HUMAN requires manual approval via Discord.

RepoSourceType

Bases: Enum

How a project's repository was set up — cloned from a URL, linked to an existing local path, or initialized as a new git repo.

RepoConfig dataclass

RepoConfig(id: str, project_id: str, source_type: RepoSourceType, url: str = '', source_path: str = '', checkout_base_path: str = '', default_branch: str = 'main')

Describes a git repository associated with a project.

The GitManager uses this to clone, link, or initialize the repo and to create per-task worktrees branching from default_branch.

Repos are purely git config (URL, default branch, source type) — they no longer determine filesystem layout. Workspace paths are managed by the agent_workspaces table instead.

Project dataclass

Project(id: str, name: str, credit_weight: float = 1.0, max_concurrent_agents: int = 2, status: ProjectStatus = ProjectStatus.ACTIVE, total_tokens_used: int = 0, budget_limit: int | None = None, discord_channel_id: str | None = None, repo_url: str = '', repo_default_branch: str = 'main', default_profile_id: str | None = None)

A project is the unit of scheduling and resource allocation.

The scheduler distributes agent capacity across projects proportionally to their credit_weight. Each project may have its own Discord channel and token budget. max_concurrent_agents caps how many agents can work on this project simultaneously.

Repo configuration (repo_url, repo_default_branch) is embedded directly on the project — one repo per project. Multiple workspaces per project are managed via the Workspace model (see workspaces table).

Task dataclass

Task(id: str, project_id: str, title: str, description: str, priority: int = 100, status: TaskStatus = TaskStatus.DEFINED, verification_type: VerificationType = VerificationType.AUTO_TEST, retry_count: int = 0, max_retries: int = 3, parent_task_id: str | None = None, repo_id: str | None = None, assigned_agent_id: str | None = None, branch_name: str | None = None, resume_after: float | None = None, requires_approval: bool = False, pr_url: str | None = None, plan_source: str | None = None, is_plan_subtask: bool = False, task_type: TaskType | None = None, profile_id: str | None = None, preferred_workspace_id: str | None = None)

The fundamental unit of work in the system.

A task moves through the TaskStatus state machine from DEFINED to COMPLETED (or BLOCKED). It carries everything the orchestrator needs: scheduling metadata (priority, project_id), execution context (repo_id, branch_name, assigned_agent_id), lifecycle tracking (retry_count, resume_after), and plan-generation lineage (parent_task_id, plan_source, is_plan_subtask).

Agent dataclass

Agent(id: str, name: str, agent_type: str, state: AgentState = AgentState.IDLE, current_task_id: str | None = None, pid: int | None = None, last_heartbeat: float | None = None, total_tokens_used: int = 0, session_tokens_used: int = 0)

Represents a registered agent process (e.g., a Claude Code instance).

The orchestrator tracks agent state, heartbeats, and token usage. When an agent is IDLE, the scheduler may assign it a task. Per-project workspace paths are managed via project-scoped Workspaces with dynamic locking.

Workspace dataclass

Workspace(id: str, project_id: str, workspace_path: str, source_type: RepoSourceType, name: str | None = None, locked_by_agent_id: str | None = None, locked_by_task_id: str | None = None, locked_at: float | None = None)

A project-scoped workspace directory where agents execute tasks.

Each project can have multiple workspaces (e.g. separate clones or linked directories). Agents dynamically acquire a workspace lock when assigned a task and release it on completion — no manual agent-to-workspace mapping.

AgentProfile dataclass

AgentProfile(id: str, name: str, description: str = '', model: str = '', permission_mode: str = '', allowed_tools: list[str] = list(), mcp_servers: dict[str, dict] = dict(), system_prompt_suffix: str = '', install: dict = dict())

A capability bundle that configures agents for specific task types.

Profiles define what tools, MCP servers, model overrides, and system prompt additions an agent should receive when executing a task. They are resolved at task execution time (not during scheduling) to keep the scheduler deterministic and profile-unaware.

Resolution cascade: task.profile_id → project.default_profile_id → None (system default). See specs/agent-profiles.md.

TaskContext dataclass

TaskContext(description: str, task_id: str = '', acceptance_criteria: list[str] = list(), test_commands: list[str] = list(), checkout_path: str = '', branch_name: str = '', attached_context: list[str] = list(), mcp_servers: dict[str, dict] = dict())

The input bundle passed to an agent adapter when executing a task.

This is the adapter's entire view of the work to be done: what to build (description, acceptance_criteria), how to verify it (test_commands), where to work (checkout_path, branch_name), and what tools/context are available. The orchestrator constructs this from the Task, its criteria, context entries, and tool permissions stored in the database.

AgentOutput dataclass

AgentOutput(result: AgentResult, summary: str = '', files_changed: list[str] = list(), tokens_used: int = 0, error_message: str | None = None, question: str | None = None)

The result returned by an agent adapter after task execution.

The orchestrator uses result to determine the next state transition, summary for Discord notifications, files_changed for commit/PR decisions, and tokens_used for budget tracking. On failure, error_message provides context for retry logic. When result is WAITING_INPUT, question contains the agent's question for human review.

Hook dataclass

Hook(id: str, project_id: str, name: str, enabled: bool = True, trigger: str = '{}', context_steps: str = '[]', prompt_template: str = '', llm_config: str | None = None, cooldown_seconds: int = 3600, max_tokens_per_run: int | None = None, created_at: float = 0.0, updated_at: float = 0.0)

Definition of an automated hook that runs in response to events or on a schedule.

Hooks allow project-level automation without manual intervention: they can be triggered periodically, by cron, or by task lifecycle events (via the EventBus). Each hook defines context-gathering steps, an LLM prompt template, and cooldown/budget limits to prevent runaway costs. See specs/hooks.md.

HookRun dataclass

HookRun(id: str, hook_id: str, project_id: str, trigger_reason: str, status: str = 'running', event_data: str | None = None, context_results: str | None = None, prompt_sent: str | None = None, llm_response: str | None = None, actions_taken: str | None = None, skipped_reason: str | None = None, tokens_used: int = 0, started_at: float = 0.0, completed_at: float | None = None)

A single execution record of a Hook.

Captures the full lifecycle of one hook invocation: why it fired (trigger_reason), what context was gathered, what prompt was sent to the LLM, and what actions resulted. Used for auditing and debugging hook behavior.

PhaseResult

Bases: Enum

Outcome of a single completion pipeline phase.

CompletionPhase dataclass

CompletionPhase(name: str, builtin: bool = True, blocking: bool = True)

Descriptor for one phase in the completion pipeline.

PipelineContext dataclass

PipelineContext(task: Task, agent: Agent, output: AgentOutput, workspace_path: str | None, workspace_id: str | None, repo: RepoConfig | None, default_branch: str = 'main', project: Project | None = None, pr_url: str | None = None)

Passed through each phase of the completion pipeline.