Canonical reference for data flow boundaries, execution lifecycle, failure taxonomy, and observability correlation in pagantic.
All data entering or leaving pagantic flows through two types: SystemRequest (inbound) and SystemResponse (outbound). These types define the system boundary. No internal layer is accessible without passing through them first.
Input from adapters into the system. Adapters construct this from external input - HTTP requests, CLI arguments, TUI interactions - and pass it to the orchestration facade.
SystemRequest {
// Correlation
RequestID string // Unique per request, generated by adapter if not provided
SessionID string // Stable per conversation (AgentLoop sessions)
TraceID string // Distributed tracing root
// Intent
Messages []core.Message // Conversation messages
Mode Mode // chat | structured | plan | redundant
// Execution Hints
Hints ExecutionHints // Optional tuning knobs
// Output Contract
Output OutputContract // Schema/grammar expectations
// Capabilities
Tools []string // Allowed tool names (empty = all registered)
}
core.Message carries a role (system, user, assistant, tool) and content. The orchestration layer reads these to build inference prompts.chat routes to AgentLoop, structured to SpecializedLoop, plan to PlanExecutor, redundant to RedundantLoop.Returned by the orchestration facade after execution completes (or fails). Adapters map this back to whatever format the external caller expects.
SystemResponse {
// Correlation (echo)
RequestID string
SessionID string
// Output
Content string // Text response
StructuredOutput any // Parsed output when schema provided
ToolCallsMade []core.ToolCall // Log of tool invocations during execution
// Quality
Confidence *float64 // Optional [0..1] confidence score
ConfidenceSource string // "voting" | "validation" | "retrieval"
// Usage
TokenUsage core.TokenUsage
// Error
Error *SystemError // Non-nil on failure
}
any because the shape depends on the caller's schema. Nil when no schema was provided."voting", "validation", or "retrieval".Structured error type returned in SystemResponse.Error. Designed for programmatic handling - callers inspect Category and Retryable rather than parsing message strings.
SystemError {
Code string // Stable error code, e.g. "TOOL_EXECUTION_FAILED"
Category FailureCategory // From failure taxonomy
Retryable bool // Whether caller should retry
Message string // Human-readable description
Details map[string]any // Structured diagnostic data
CausedBy error // Optional wrapped cause
}
CATEGORY_SPECIFIC_ERROR (e.g., TOOL_EXECUTION_FAILED, CONSTRAINT_SCHEMA_INVALID). Callers switch on this for programmatic handling.Optional tuning knobs passed through SystemRequest.Hints. Adapters forward these without interpretation. The orchestration layer applies them during PREPARE and EXECUTE phases.
ExecutionHints {
MaxTokens int // Token limit for inference response
Timeout time.Duration // Deadline for entire execution
Temperature float64 // Model temperature (0.0 = deterministic)
TopP float64 // Nucleus sampling parameter
Options map[string]any // Vendor-specific pass-through
}
Defines the expected shape of model output. When populated, the system enforces conformance using constraint and validation layers.
OutputContract {
Schema *core.Schema // JSON schema for structured output
Grammar *string // GBNF grammar for decoder constraint
RepairAllowed bool // Whether JSON repair is permitted
StrictValidation bool // Fail on any validation error (no partial)
}
Each Mode selects an orchestration pattern. The pattern determines which SystemResponse fields are populated:
| Pattern | Mode | SystemResponse fields produced |
|---|---|---|
| AgentLoop | chat |
Content, ToolCallsMade, TokenUsage |
| SpecializedLoop | structured |
Content, StructuredOutput, ValidationResult, TokenUsage |
| PlanExecutor | plan |
Content, StructuredOutput (per step), ToolCallsMade, TokenUsage |
| RedundantLoop | redundant |
Content, StructuredOutput, Confidence, ConfidenceSource, TokenUsage |
Every SystemRequest passes through a state machine from receipt to response. The states are fixed; which states are visited depends on the orchestration pattern selected by Mode.
Tracks the current position in the lifecycle state machine. Updated on every state transition.
ExecutionState {
Current LifecycleState // Current state in the machine
EnteredAt time.Time // When current state was entered
Attempt int // Current attempt number (incremented on retry)
TotalSteps int // Steps completed (PlanExecutor)
LastError *SystemError // Most recent error (may be recovered from)
LastStep string // Name of last completed step
}
Carries all state for a single request execution. Immutable fields are set at INIT. Mutable fields are updated as execution progresses through states.
ExecutionContext {
// Immutable (set at INIT)
RequestID string
SessionID string
TraceID string
Mode Mode
StartedAt time.Time
// Mutable (updated during execution)
State ExecutionState
SelectedTools []string // Tools resolved during PREPARE
Candidates []CandidateIR // Current candidate set (rerank/voting)
Metadata map[string]any // Extension point
}
| Pattern | States Traversed | Retry Path | Tool Loop | Notes |
|---|---|---|---|---|
| AgentLoop | INIT -> PREPARE -> EXECUTE -> COMPLETE | EXECUTE -> VALIDATE -> EXECUTE (per turn) | Yes, within EXECUTE | Multi-turn: EXECUTE/VALIDATE cycle repeats per user turn |
| SpecializedLoop | INIT -> PREPARE -> EXECUTE -> VALIDATE -> COMPLETE | VALIDATE -> EXECUTE | No | Single-shot with validation |
| PlanExecutor | INIT -> PLAN -> PREPARE -> EXECUTE -> VALIDATE -> COMPLETE | Per-step: EXECUTE -> VALIDATE -> EXECUTE | Per step | EXECUTE contains sub-cycles for each Step |
| RedundantLoop | INIT -> PREPARE -> EXECUTE -> VALIDATE -> COMPLETE | N/A (voting replaces retry) | No | EXECUTE runs N parallel inferences |
Every error in pagantic belongs to exactly one FailureCategory. Categories determine retry eligibility, recovery path, and which layer emitted the error.
| Category | Error Code Pattern | Retryable | Recovery Path | Emitting Layer |
|---|---|---|---|---|
| InferenceFailure | INFERENCE_* |
Sometimes | Retry with backoff | inference (L01) |
| ToolFailure | TOOL_* |
If idempotent | Retry tool or skip | tool (L04) |
| ConstraintFailure | CONSTRAINT_* |
Yes | JSON repair, re-infer | constraint (L05) |
| ValidationFailure | VALIDATION_* |
Yes | Repair + re-infer, or prompt adjustment | validate (L07) |
| OrchestrationFailure | ORCHESTRATION_* |
No | Manual intervention | orchestrate (L02) |
| ConfigurationFailure | CONFIG_* |
No | Fix configuration | Any layer at init |
| Cancellation | CANCELLED |
No | Re-submit request | Any layer |
Engine returned error, model unavailable, context window exceeded, or malformed response from the model.
INFERENCE_ENGINE_ERRORINFERENCE_MODEL_UNAVAILABLEINFERENCE_CONTEXT_EXCEEDEDINFERENCE_MALFORMED_RESPONSETool not found in registry, execution returned error, timed out, or became unavailable mid-loop.
TOOL_NOT_FOUNDTOOL_EXECUTION_FAILEDTOOL_TIMEOUTTOOL_UNAVAILABLEGrammar rejected output, schema validation failed, JSON is not valid, or enum value not recognized.
CONSTRAINT_GRAMMAR_REJECTEDCONSTRAINT_SCHEMA_INVALIDCONSTRAINT_JSON_INVALIDCONSTRAINT_ENUM_UNRECOGNIZEDRule check failed or semantic validation detected issues (hallucination, nonsensical output).
VALIDATION_RULE_FAILEDVALIDATION_SEMANTIC_FAILEDPlan step received unexpected input type, iteration limit exceeded, or no voting consensus reached.
ORCHESTRATION_STEP_MISMATCHORCHESTRATION_ITERATION_LIMITORCHESTRATION_NO_CONSENSUSMissing or invalid configuration detected at initialization time.
CONFIG_NO_ENGINECONFIG_SCHEMA_REQUIREDCONFIG_GRAMMAR_NOT_FOUNDRequest was cancelled externally or exceeded its deadline.
CANCELLED_TIMEOUTCANCELLED_SIGNAL| Pattern | Can Emit | Can Recover From |
|---|---|---|
| AgentLoop | InferenceFailure, ToolFailure, Cancellation | ToolFailure (retry tool call) |
| SpecializedLoop | InferenceFailure, ConstraintFailure, ValidationFailure, Cancellation | ConstraintFailure (repair), ValidationFailure (retry) |
| PlanExecutor | All categories | ConstraintFailure, ValidationFailure (per step), ToolFailure (if step uses tools) |
| RedundantLoop | InferenceFailure, ConstraintFailure, OrchestrationFailure, Cancellation | InferenceFailure (other replicas succeed), ConstraintFailure (repair per replica) |
All observability events - logs, traces, metrics - carry correlation identifiers that link them back to the originating SystemRequest and execution context.
CorrelationContext {
RequestID string // Stable per SystemRequest
SessionID string // Stable per conversation (AgentLoop)
TraceID string // Distributed tracing root
SpanID string // Current execution unit
ParentSpanID string // Parent in span hierarchy
CausedBy string // Causal link: tool_call_id, step_name, etc.
}
All observability events must include these fields (when applicable):
| Field | Always | Condition |
|---|---|---|
request_id |
Yes | Every event |
session_id |
No | When in AgentLoop (multi-turn) |
step_name |
No | When inside PlanExecutor |
tool_call_id |
No | When tool-related |
InferenceStartEvent {
CorrelationContext
MessageCount int
ToolDefsCount int
SchemaPresent bool
GrammarPresent bool
Temperature float64
}
InferenceEndEvent {
CorrelationContext
DurationMs int64
TokensIn int
TokensOut int
FinishReason string // "stop" | "tool" | "error"
ToolCallCount int
}
ToolStartEvent {
CorrelationContext
ToolName string
ToolCallID string // Links to inference ToolCall.ID
ArgsHash string // Deterministic hash for dedup
}
ToolEndEvent {
CorrelationContext
ToolName string
ToolCallID string
DurationMs int64
Success bool
ErrorCode string // From failure taxonomy if failed
}
LifecycleTransitionEvent {
CorrelationContext
FromState string
ToState string
Attempt int
Reason string // Why this transition happened
}
PlanExecutor is the executor of a plan, not the creator. Plans are produced by a Planner (or manually authored) and handed to PlanExecutor for execution.
// Planner creates an ExecutionPlan from a SystemRequest.
// Implementations range from static plan builders to LLM-based planners.
Planner {
CreatePlan(ctx context.Context, req SystemRequest) (ExecutionPlan, error)
}
Planner is a single-method interface. Implementations decide how to decompose a request into steps. A static planner might use a lookup table; an LLM-based planner makes an inference call to generate the plan.
Constraints on plan shape and execution. Applied by PlanExecutor before running any steps.
PlanPolicy {
MaxSteps int // Upper bound on plan length
AllowedStepTypes []string // Which step types this mode permits
RequireLinear bool // If true, no branching/parallel steps
TimeoutPerStep time.Duration // Per-step deadline
}
Metadata about plan creation. Attached to the ExecutionPlan for observability and debugging.
PlanTrace {
PlannerID string // Which planner created this plan
Rationale string // Why these steps were chosen
CreatedAt time.Time
StepCount int
}