Iterate toward a goal#

A goal_mode external event selects one future request. A private evaluator then reports incomplete and finally achieved. This demonstrates control flow, not real-model evaluation quality.

Run it#

From the repository root:

uv run python docs/_examples/goal.py

The output includes:

Implementation and tests are complete.

This program uses deterministic offline models and temporary storage where needed. It requires no API key and is executed by the documentation test suite.

Separate the worker from the reviewer#

The application selects goal mode for a specific upcoming request. A reviewer checks the worker’s result and can request another attempt:

async def main() -> None:
    reviewer = ReviewModel()
    definition = SubAgentDefinition(
        name="review",
        description="verify goal completion",
        system_prompt="Inspect evidence and call report_goal_evaluation.",
        model=reviewer,
    )
    config = AgentRunConfig(session_id="goal-example", request_id="request-1")
    client = await create_agent(
        DraftModel(),
        config=config,
        extensions=[GoalExtension(definition, max_iterations=2)],
        event_dispatcher=GoalEvents(),
    )
    accepted = client.agent.emit_external_event(ExternalEvent(GOAL_MODE_EVENT_NAME, {}), config=config)
    assert accepted == ["GoalExtension"]
    result = await client.run("Implement the change with tests", config=config)
    assert reviewer.reviews == 2
    print(result.content)

Here the reviewer deliberately reports missing tests once, then accepts the second answer. In a real workflow, have it inspect concrete evidence rather than accepting the worker’s claims. Bound continuation with an iteration limit and give the user a way to cancel; an evaluator is not a guarantee of correctness.

Complete source#

Download goal.py.

  1"""Run a bounded goal review using the normal Agent as a private evaluator."""
  2
  3import asyncio
  4from collections.abc import AsyncIterator
  5
  6from zett_agent.agent import AgentRunConfig
  7from zett_agent.client import create_agent
  8from zett_agent.dispatcher import AgentEventDispatcher
  9from zett_agent.events import AgentEvent
 10from zett_agent.extensions.external import ExternalEvent
 11from zett_agent.extensions.goal import (
 12    GOAL_MODE_EVENT_NAME,
 13    GoalExtension,
 14)
 15from zett_agent.extensions.subagent import SubAgentDefinition
 16from zett_agent.messages import (
 17    AssistantMessage,
 18    ToolCall,
 19    ToolMessage,
 20)
 21from zett_agent.model import (
 22    ModelEvent,
 23    ModelRequest,
 24    ModelResponse,
 25    RetryOptions,
 26)
 27
 28
 29class DraftModel:
 30    retry = RetryOptions(max_retries=0)
 31
 32    def __init__(self) -> None:
 33        self.attempt = 0
 34
 35    async def stream(self, request: ModelRequest) -> AsyncIterator[ModelEvent]:
 36        self.attempt += 1
 37        answer = "A draft without tests." if self.attempt == 1 else "Implementation and tests are complete."
 38        yield ModelEvent.text(answer)
 39        yield ModelEvent.completed(ModelResponse(AssistantMessage(content=answer)))
 40
 41
 42class ReviewModel:
 43    """Script review decisions; real evaluators must inspect actual evidence."""
 44
 45    retry = RetryOptions(max_retries=0)
 46
 47    def __init__(self) -> None:
 48        self.reviews = 0
 49
 50    async def stream(self, request: ModelRequest) -> AsyncIterator[ModelEvent]:
 51        if isinstance(request.messages[-1], ToolMessage):
 52            message = AssistantMessage(content="Decision submitted.")
 53        else:
 54            self.reviews += 1
 55            achieved = self.reviews > 1
 56            message = AssistantMessage(
 57                tool_calls=(
 58                    ToolCall(
 59                        "review-1",
 60                        "report_goal_evaluation",
 61                        {
 62                            "achieved": achieved,
 63                            "summary": "Verified" if achieved else "Tests missing",
 64                            "remaining_work": [] if achieved else ["Add tests"],
 65                            "next_instruction": None if achieved else "Add and run the tests.",
 66                        },
 67                    ),
 68                )
 69            )
 70        yield ModelEvent.completed(ModelResponse(message))
 71
 72
 73class GoalEvents(AgentEventDispatcher):
 74    async def on_internal_message_started_event(self, event: AgentEvent) -> None:
 75        print("Continuing after private review")
 76
 77
 78async def main() -> None:
 79    reviewer = ReviewModel()
 80    definition = SubAgentDefinition(
 81        name="review",
 82        description="verify goal completion",
 83        system_prompt="Inspect evidence and call report_goal_evaluation.",
 84        model=reviewer,
 85    )
 86    config = AgentRunConfig(session_id="goal-example", request_id="request-1")
 87    client = await create_agent(
 88        DraftModel(),
 89        config=config,
 90        extensions=[GoalExtension(definition, max_iterations=2)],
 91        event_dispatcher=GoalEvents(),
 92    )
 93    accepted = client.agent.emit_external_event(ExternalEvent(GOAL_MODE_EVENT_NAME, {}), config=config)
 94    assert accepted == ["GoalExtension"]
 95    result = await client.run("Implement the change with tests", config=config)
 96    assert reviewer.reviews == 2
 97    print(result.content)
 98
 99
100if __name__ == "__main__":
101    asyncio.run(main())

Next: Run an isolated child agent for ordinary delegation, or GoalExtension for selection and limits.