Documentation Index
Fetch the complete documentation index at: https://docs.plato.so/llms.txt
Use this file to discover all available pages before exploring further.
Spans
Spans track timed operations with automatic parent-child relationships. They’re the primary way to structure logs.
Basic Usage
from plato.agents import span
async with span("my_operation") as s:
s.log("Starting work...")
# Do work
s.log("Work complete")
Parameters
| Parameter | Type | Default | Description |
|---|
name | str | Required | Operation name |
span_type | str | "span" | Event type (span, agent, step, etc.) |
source | str | "agent" | Source (agent, world, system) |
extra | dict | None | Additional metadata |
Span Methods
log()
Add log messages to the span:
async with span("process") as s:
s.log("Step 1 complete")
s.log("Step 2 complete")
# Logs are included in the span's extra data
Add metadata to the span:
async with span("fetch_data") as s:
data = await fetch()
s.set_extra({
"count": len(data),
"source": "api",
})
event_id
Get the span’s unique ID:
async with span("operation") as s:
print(f"Span ID: {s.event_id}")
Automatic Nesting
Spans automatically track parent-child relationships:
async with span("parent") as parent:
# This span's parent is "parent"
async with span("child") as child:
# This span's parent is "child"
async with span("grandchild"):
pass
Results in hierarchy:
parent
├── child
│ └── grandchild
Span Lifecycle
- Enter: Logs
"{name} started" with started_at timestamp
- Exit (success): Logs
"{name} completed" with ended_at timestamp
- Exit (error): Logs
"{name} failed" with error details
async with span("risky_operation") as s:
try:
await risky_task()
except Exception as e:
# Span automatically logs failure with error info
raise
Event Structure
Each span generates events with this structure:
{
"session_id": "session-123",
"span_type": "span",
"content": "my_operation completed",
"source": "agent",
"event_id": "uuid-...",
"parent_id": "parent-uuid-...",
"started_at": "2024-01-15T10:00:00Z",
"ended_at": "2024-01-15T10:00:05Z",
"extra": {
"logs": ["Step 1", "Step 2"],
"custom_key": "value"
}
}
No-Op Mode
When logging isn’t initialized, spans become no-ops:
from plato.agents import span, reset_logging
reset_logging() # Clear logging
async with span("operation") as s:
s.log("This goes to debug logger only")
# No HTTP calls are made
Example: Agent Execution
from plato.agents import span
async def run_agent(instruction: str):
async with span("agent_execution", span_type="agent") as agent_span:
agent_span.log(f"Starting with: {instruction}")
async with span("setup", span_type="step"):
await setup_environment()
async with span("execute", span_type="step") as exec_span:
result = await execute_task(instruction)
exec_span.set_extra({"result": result})
async with span("cleanup", span_type="step"):
await cleanup()
agent_span.set_extra({"success": True})