Result shape
interface RunnerResultV2<TOutput = unknown> {
output: TOutput;
assistantText: string | null;
finalizedPayload?: unknown;
operatorAffordance?: unknown;
}| Field | Required | Meaning |
|---|---|---|
output | Yes | Normalized runtime and application result data |
assistantText | Yes | Human-facing assistant response, or null when none exists |
finalizedPayload | No | Structured finalized data owned by the application contract |
operatorAffordance | No | Control information for waiting or operator-managed work |
An empty string is not valid assistantText. Structured data must never be converted into an invented assistant message.
Assistant text and structured data
Only assistantText owns the committed reader-facing answer. output and finalizedPayload are validated application/runtime data; visible progress, tool results, and provider reasoning remain separate.
Terminal outcome taxonomy
Completed, failed, cancelled, and waiting outcomes are mutually distinguishable. A disconnect is a transport observation and cannot synthesize a terminal outcome.
Waiting, cancellation, and recovery
Waiting names the exact pending request and allowed continuation. Recovery may add a stable option identifier. Cancellation records the accepted request and terminal result for the exact run.
Outcome handling
| Outcome | Event or status | Consumer behavior |
|---|---|---|
| Completed | run.completed | Store the result and render non-null assistantText |
| Failed | run.failed | Preserve safe failure details and any validated result data |
| Cancelled | run.cancelled | Record cancellation for the exact run |
| Waiting | Normalized waiting status | Show the expected continuation and resume or cancel the same run |
const result = terminal.payload.result;
if (result.assistantText !== null) {
renderAssistant(result.assistantText);
}
storeStructuredResult(result.output, result.finalizedPayload);Persistence and replay
Persist the canonical terminal event once with its session/run correlation and last accepted cursor. Replay may render that record again but cannot replace or reinterpret it.
Consumer invariants
- Parse before use.
- Render committed text only from
assistantText. - Require one terminal outcome per accepted run.
- Bind resume/recovery to the exact pending request.
- Preserve structured data, evidence, and cancellation independently.