AETIUS

Field reference

All types below live in agentstage.reconstruction.schema. Every example on this page reconstructs from the local fixture described in the core concepts page.

Python
from examples.fixtures import build_environment

env = build_environment()
invoice_system = env.reconstruct("invoice-agent")
pipeline_system = env.reconstruct("support-pipeline")
team_system = env.reconstruct("support-team")

ToolSpec

A reconstructed tool as a framework-neutral definition. Every field is always populated; there is no unavailable state for ToolSpec itself, only for the source system prompts and orchestration structure it sits alongside.

FieldTypeMeaning
namestrThe tool's name as observed in the traces.
descriptionstrA generated description naming how many historical calls this tool was reconstructed from. Not something the real system necessarily said about itself.
parametersdict[str, Any]JSON Schema for the tool's arguments. No field is ever marked required, since an argument being observed at all does not mean it was present on every call.
behaviorToolBehaviorProfileEverything inferable about this tool's real historical behavior. See below.
Python
lookup_invoice = invoice_system.tools["lookup_invoice"]
print(lookup_invoice.name)
print(lookup_invoice.description)
print(lookup_invoice.parameters)
Output
lookup_invoice
lookup_invoice (reconstructed from 5 observed historical call(s))
{'type': 'object', 'properties': {'invoice_id': {'type': 'string'}}, 'required': []}

ToolBehaviorProfile

FieldTypeMeaning
tool_namestrMatches the owning ToolSpec.name.
n_calls_observedintHow many historical calls to this tool were found across the reconstructed trace batch.
argument_profilesdict[str, ArgumentProfile]Per-argument observed shape. See below.
response_key_setlist[str]Union of top-level response keys seen across every observed call, sorted. Not assumed to be any particular envelope shape, just whatever this tool's real responses happened to use.
example_callslist[ObservedToolCall]The real (arguments, response) pairs this tool's replay matching draws from, capped by the extractor.
Python
profile = lookup_invoice.behavior
print(profile.tool_name)
print(profile.n_calls_observed)
print(list(profile.argument_profiles.keys()))
print(profile.response_key_set)
print(len(profile.example_calls))
Output
lookup_invoice
5
['invoice_id']
['amount', 'status']
5

ArgumentProfile

Nested under ToolBehaviorProfile.argument_profiles, one per observed argument name.

FieldTypeMeaning
observed_typeslist[str]Python type names seen for this argument's value, sorted.
distinct_value_countintCount of distinct values observed for this argument.
sample_valueslist[Any]Real observed values, capped by the extractor.
numeric_rangetuple[float, float] | None(min, max) across every observed numeric value for this argument, or None if it was never numeric.
string_length_rangetuple[int, int] | None(min, max) string length across every observed string value, or None if it was never a string.

A string-valued argument, where numeric_range is genuinely None:

Python
ap = profile.argument_profiles["invoice_id"]
print(ap.observed_types)
print(ap.distinct_value_count)
print(ap.sample_values)
print(ap.numeric_range)
print(ap.string_length_range)
Output
['str']
5
['inv_1001', 'inv_1002', 'inv_1003', 'inv_1004', 'inv_1005']
None
(8, 8)

A numeric-valued argument (support-pipeline's issue_refund tool takes a refund amount), where string_length_range would instead be None:

Python
issue_refund = pipeline_system.tools["issue_refund"]
amount_profile = issue_refund.behavior.argument_profiles["amount"]
print(amount_profile.observed_types)
print(amount_profile.numeric_range)
print(amount_profile.sample_values)
Output
['float']
(19.99, 89.5)
[19.99, 45.0, 89.5]

ObservedToolCall

Nested under ToolBehaviorProfile.example_calls. This is the raw material replay matching scores against.

FieldTypeMeaning
argumentsdict[str, Any]The real arguments of one historical call.
responseAnyThe real response that call returned.
observed_atstr | NoneThe observation's timestamp in the source trace, if present.
Python
call = profile.example_calls[0]
print(call.arguments)
print(call.response)
print(call.observed_at)
Output
{'invoice_id': 'inv_1001'}
{'status': 'paid', 'amount': 129.0}
2026-01-01T09:00:02Z

OrchestrationGraph

FieldTypeMeaning
source"observed" | "unavailable"Whether any role/edge evidence exists at all.
nodeslist[OrchestrationNode]Every reconstructed role.
edgeslist[OrchestrationEdge]Every observed control-flow transition.
entry_rolestr | NoneThe role that received the initial input, most often across the batch. None only when source == "unavailable".
terminal_roleslist[str]Roles with no observed outgoing edge.
pattern"single_agent" | "pipeline" | "supervisor_delegates" | "unclassified"A classification derived purely from the graph's shape.

A real multi-role graph:

Python
o = team_system.orchestration
print(o.source)
print(o.pattern)
print(o.entry_role)
print(o.terminal_roles)
print(len(o.nodes), len(o.edges))
Output
observed
supervisor_delegates
supervisor
['researcher', 'writer']
3 4

source == "unavailable" only happens when there is no trace data to reconstruct orchestration structure from at all, for example reconstructing from an empty trace batch:

Python
from agentstage.reconstruction.build import build_reconstructed_system

empty_system = build_reconstructed_system([], label="empty", project_id="demo_project", source_agent_name=None)
print(empty_system.orchestration.source)
print(empty_system.orchestration.nodes)
print(empty_system.orchestration.edges)
print(empty_system.orchestration.pattern)
Output
unavailable
[]
[]
unclassified

nodes and edges are empty and pattern sits at its unclassified default. This is a stricter, rarer state than a real reconstructed single_agent system, which has source == "observed" with one node and zero edges, a genuine positive observation that everything happens in one flat role, not a gap.

OrchestrationNode

FieldTypeMeaning
rolestrThe role identifier, lowercased, used to key edges, entry_role, terminal_roles, and ReconstructedSystem.role(...).
namestrThe role's display name as first seen in the traces.
Python
node = o.nodes[0]
print(node.role, node.name)
Output
researcher researcher

OrchestrationEdge

FieldTypeMeaning
from_rolestrThe role the transition was observed from.
to_rolestrThe role the transition was observed into.
triggerstr | NoneWhat was observed to cause the handoff, for example "handoff" (an explicit transfer_to_x-style observation name) or "nested_span" (a role change inferred from a nested observation's own metadata). Descriptive, not a guarantee of the real system's internal mechanism, since traces only show what was instrumented.
n_observedintHow many times this exact (from_role, to_role, trigger) transition was seen across the batch.
Python
edge = o.edges[0]
print(edge.from_role, edge.to_role, edge.trigger, edge.n_observed)
Output
supervisor researcher handoff 3

RoleSpec

FieldTypeMeaning
rolestrMatches the corresponding OrchestrationNode.role.
namestrDisplay name.
system_promptstrThe real observed system prompt text, or the fixed placeholder string "[unavailable — no system prompt observed in source traces]" when none was captured.
system_prompt_source"observed" | "unavailable"Which of the two system_prompt actually is.
toolslist[str]Tool names attributed to this specific role.

A role with an observed prompt:

Python
researcher = team_system.role("researcher")
print(researcher.role)
print(researcher.name)
print(researcher.system_prompt_source)
print(researcher.system_prompt)
print(researcher.tools)
Output
researcher
researcher
observed
You research internal documentation to answer support questions accurately.
['search_docs']

The same system's writer role, where the fixture deliberately never captured a system prompt:

Python
writer = team_system.role("writer")
print(writer.system_prompt_source)
print(writer.system_prompt)
Output
unavailable
[unavailable — no system prompt observed in source traces]

ReconstructedSystem itself (label, roles, tools, orchestration, provenance) and ReconstructionProvenance (trace_count, source_agent_name, other_groups_found, warnings, extraction_date) are covered with real examples in the core concepts page rather than repeated here.