Handle agent results safely
The current SDK gives structure to the stream lifecycle with typed event, error, and completion frames. The final agent answer is text. Cmdop does not currently guarantee that the answer conforms to an application-defined JSON schema.
Use typed frames for control flow
Pass a machine PIN up front when required, then iterate machines.ask(...):
stream = client.machines.ask(
machine_id,
"Summarize disk usage; make no changes",
pin="1234",
)
async for frame in stream:
if frame.type == "event":
# Optional progress for a person; do not parse it as the final result.
continue
if frame.type == "error":
raise RuntimeError(f"Agent stream failed: {frame.code}")
if frame.type == "done":
# A `done` frame is not automatically a success — check the flag.
if not frame.success:
raise RuntimeError(f"Agent run failed: {frame.error}")
final_text = frame.textThe stream ends with a done frame whether the run succeeded or not. Read
frame.success before you trust frame.text; a failed run carries its reason in
frame.error. Treating every done as success is the most common bug in code
written against this loop.
See SDK streaming for the complete Python and Node frame union.
Validate at your application boundary
If your application asks the model to return JSON, treat that as a prompt request rather than a protocol guarantee:
- parse the final text with a strict local parser;
- validate required fields, types, size, and allowed values;
- reject extra or unsafe actions;
- do not execute a command merely because the model placed it in valid JSON;
- keep the original result available for diagnosis.
For machine-readable local-relay automation with a deterministic exit status, use the bounded one-shot command only when its self/loopback scope is sufficient and an AI agent is not needed.
Common questions
Does Cmdop guarantee JSON output from an agent?
No. The SDK gives typed frames for the stream lifecycle. The final agent answer is text and must be validated by your application.
How do I detect a failed agent run?
Read the done frame and check frame.success. A done frame can carry either
a successful final text or a failure reason.
Where should I validate structured agent results?
Validate at your application boundary with a strict parser, required-field checks, type checks, size limits, and allowed-value checks.