Skip to main content

Runs

A Run is a single execution of an agent. You start a run, the agent works autonomously using its configured goal and tools, and you get output when it finishes. Every run is logged with a full event timeline for debugging and observability.

Run Lifecycle​

pending  →  running  →  completed
→ failed
→ cancelled
StatusDescription
pendingQueued, waiting to start
runningAgent is actively executing -- planning, calling tools, reasoning
completedFinished successfully, output available
failedSomething went wrong -- error string available
cancelledCancelled by the user before completion

Starting a Run​

A run is started by specifying the agent ID. The agent uses the goal configured at creation time.

from flymyai import AgentClient

client = AgentClient(api_key="fly-***")

run = client.runs.create(agent_id="agent_abc123")

Run Events​

Every run emits ExecutionLog events that provide full visibility into what the agent is doing. Each event has .type, .message, .data, and .created_at.

Event TypeDescription
declared_functionsAgent declared the functions it plans to use
tool_calledAgent invoked a tool
tool_call_exceptionA tool call failed with an error
task_cancelledThe run was cancelled

Streaming Events​

client.runs.stream_events(run_id) yields ExecutionLog objects using polling-based delivery (not SSE).

for event in client.runs.stream_events(run.id):
if event.type == "declared_functions":
print(f"Functions: {event.data}")
elif event.type == "tool_called":
print(f"Tool called: {event.message}")
print(f"Details: {event.data}")
elif event.type == "tool_call_exception":
print(f"Tool error: {event.message}")
elif event.type == "task_cancelled":
print("Run was cancelled")

Example event stream:

[declared_functions]     Declared: tavily_search, browser_navigate
[tool_called] Called tavily_search with query "renewable energy trends 2026"
[tool_called] Called browser_navigate to extract page content
[tool_called] Called tavily_search with query "solar cost decline statistics"

Getting Results​

A completed run provides .status, .output, .error, .logs, .messages, and .original_prompt.

# Wait synchronously (polls until terminal status)
result = client.runs.wait(run.id, timeout=300, poll_interval=2.0)

print(f"Status: {result.status}")
print(f"Output: {result.output}")

# Or fetch the current state without waiting
result = client.runs.get(run.id)

Run Detail Fields​

FieldDescription
statusCurrent run status (see lifecycle above)
outputThe agent's result (alias for agent_result)
errorError message string (when status is failed)
logsList of ExecutionLog entries
messagesConversation messages from the run
original_promptThe prompt that was sent to the agent

Follow-up Messages​

You can append a follow-up message to a run:

client.runs.append_message(run.id, text="Can you also check competitor pricing?")

Cancelling a Run​

Cancel a run that is still in progress:

client.runs.cancel(run.id)

Listing Runs​

# All runs for an agent
runs = client.runs.list(agent_id="agent_abc123")

for run in runs:
print(f"{run.id}: {run.status} ({run.created_at})")

Error Handling​

When a run fails, run.error contains a plain error string describing what went wrong.

result = client.runs.get(run.id)

if result.status == "failed":
print(f"Error: {result.error}")
tip

Use stream_events() alongside wait() to get real-time visibility into what the agent is doing. Events of type tool_call_exception can help you diagnose tool-related failures before the run finishes.

Why Runs Matter​

  • Traceability -- full audit trail of every agent action via execution logs
  • Debugging -- pinpoint exactly where things went wrong using event types
  • Follow-ups -- continue the conversation with append_message
  • Cancellation -- stop long-running agents when you no longer need results

Next Steps​

  • Tools -- browse the catalog, configure, and attach tools
  • Agents -- configure the agent that runs execute