OptionalcontrolControl-flow tool name → what calling it decides. Absent when no control tools were declared.
OptionalprotocolWhich protocol the turn was produced under. 'implicit' reads plain text with no call as
task completion; the other two keep the envelope rules. Absent = 'envelope'.
OptionaltextThe model's text output, if any.
OptionaltoolNative tool calls on the assistant turn, if the driver requested tools.
OptionaltoolSanitized tool name → the Action name the framework dispatches for it.
Provider tool names are constrained (^[a-zA-Z0-9_-]+$ and friends), so MJ's Action names
are sanitized on the way out: Execute Code is declared as execute_code. A corpus case
names the ACTION, per §1.2 — comparing the raw wire name against it would score every
correct native call as the wrong action, measuring the sanitizer rather than the model.
The driver supplies the framework's own reverse map, the same one LoopAgentType dispatches
from. An unmapped name passes through unchanged: a model that invented a tool should be
reported under the name it invented, not silently dropped.
What the harness observed on the wire, before normalization.