Skip to content
Merged
Changes from all 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
22 changes: 21 additions & 1 deletion src/agent_comms/goal_generation.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

from sqlite3 import Connection

from abc import abstractmethod
from dataclasses import dataclass
from typing import TYPE_CHECKING, ClassVar

Expand Down Expand Up @@ -87,10 +88,11 @@ def allows_resume(self, active_turn: bool) -> bool:
def stopped_permit(self, store: GoalAttemptStore, generation: Generation) -> GoalTurnPermit:
return NoLaunchPermit()

@abstractmethod
def authorize_retry(
self, store: GoalAttemptStore, generation: Generation, decision: WorkDecision
) -> None:
raise ValueError("The goal attempt is unresolved; inspect it before retrying.")
"""Authorize new work or refuse according to this generation's lifecycle."""


@dataclass(frozen=True)
Expand Down Expand Up @@ -139,6 +141,14 @@ def authorize_retry(

@dataclass(frozen=True)
class ReservedGeneration(GenerationState):
def authorize_retry(
self, store: GoalAttemptStore, generation: Generation, decision: WorkDecision
) -> None:
raise ValueError(
f"The goal generation is reserved for attempt {generation.attempt_identity.attempt_id}; "
"Retry cannot replace it. Inspect that attempt before deciding on new work."
)

def stopped_permit(self, store: GoalAttemptStore, generation: Generation) -> GoalTurnPermit:
return store.read_attempt(generation.attempt_identity.attempt_id).stopped_permit()

Expand Down Expand Up @@ -196,11 +206,21 @@ def authorize_retry(

@dataclass(frozen=True)
class CompletedGeneration(Complete, Terminal, GenerationState):
def authorize_retry(
self, store: GoalAttemptStore, generation: Generation, decision: WorkDecision
) -> None:
raise ValueError("The goal generation is completed; Retry cannot restart completed work.")

def execution(self, source: GoalExecutionSource) -> GoalExecution:
return CompletedExecution(source.goal.id)


@dataclass(frozen=True)
class CancelledGeneration(Terminal, GenerationState):
def authorize_retry(
self, store: GoalAttemptStore, generation: Generation, decision: WorkDecision
) -> None:
raise ValueError("The goal generation is cancelled; Retry cannot restart cancelled work.")

def validate_attempt(self, attempt_id: AttemptId | NoAttemptId) -> None:
"""Retirement preserves either the recorded attempt or its declared absence."""
Loading