Pipelines

Multi-stage flows where one stage can reject the next.

A staged pipeline runs one agent through a sequence of stages. Each stage has its own prompt, its own tool set, and optionally a verdict tool it must call before the pipeline moves on. A shared fact store carries structured data between stages, so nothing depends on the agent summarising its own work into text and reading it back.

from agentino.pipeline.staged import FactStore, StageDef, StagedPipeline


class TriageFacts(FactStore):
    task_type: str = ""

    def to_context(self) -> str:
        return f"task_type={self.task_type}"


stages = [
    StageDef(name="classify", prompt="Decide what kind of task this is.",
             tools=["read_file"], verdict_tool="classify_verdict"),
    StageDef(name="execute", prompt="Carry it out.",
             tools=["read_file", "write_file"]),
    StageDef(name="report", prompt="Summarise what changed.",
             tools=["report"], verdict_tool="report"),
]

pipeline = StagedPipeline(stages=stages, facts=TriageFacts())
result = await pipeline.run(agent_template, task_text)

Every stage field

Default
nameStage identifier, used in results and logs
prompt""Instructions for this stage alone
toolsallTool names this stage may call. A stage that should not write does not get the write tool
verdict_toolA tool the stage must call to finish. Without it a stage ends when the agent stops talking
gateA gate that must be marked before this stage runs
max_turns10Cap on this stage's tool-calling loop
skip_conditionf(facts) -> bool; true skips the stage
repeatablefalseWhether the stage may run more than once
max_cycles3How many times, when it is repeatable
on_fail"retry"What to do when the stage fails
number0Ordering, when it is not the list order

Pipeline options

Default
stagesThe stages, in order
factsA FactStore carried between them
max_reprompts3Retries when a stage does not produce its verdict
global_max_cycles20Ceiling across the whole run, so a repeatable stage cannot loop forever
failure_checkf(result, facts) -> bool; your own definition of a failed stage

Why the tool set is per stage

Restricting tools per stage is the part that carries weight. A classify stage with only read_file cannot write, whatever the prompt says and whatever the model decides — the tool is not there to call. That is a structural guarantee rather than an instruction, which is the difference between a pipeline and a long prompt.

verdict_tool is the other half: a stage that must call a named tool to finish cannot end by producing prose that merely looks like a decision.

The fact store

Stages share a FactStore — any object with a to_context() method. Its output is injected into the next stage's prompt.

The alternative is asking the agent to summarise its own work as text and parse it back, which loses structure and fails quietly when the wording drifts. A field on an object does not.