Format
All events are JSON objects emitted one per line (NDJSON). Every event has:| Field | Type | Description |
|---|---|---|
event | string | Event type identifier (see below) |
ts | integer | Unix timestamp in milliseconds |
ExecutionStarted
Emitted immediately before the child process is spawned. Always the first event in any log.| Field | Type | Description |
|---|---|---|
limits_set | string | The active limit set name. "[limits]" = base defaults. |
command | string | The full command string as passed to nanny run. |
limits.steps | integer | Active step limit. |
limits.cost | integer | Active cost limit. |
limits.timeout | integer | Active timeout in milliseconds. |
ExecutionStopped
Emitted on every exit path — clean completion, limit breach, spawn failure, or internal error. Always the last event in any log.| Field | Type | Description |
|---|---|---|
reason | string | Why execution stopped. See reasons below. |
steps | integer | Total steps completed. |
cost_spent | integer | Total cost units spent. |
elapsed_ms | integer | Total wall-clock time in milliseconds. |
Stop reasons
| Reason | Description |
|---|---|
AgentCompleted | Process exited cleanly on its own. |
TimeoutExpired | Wall-clock timeout was reached. Process was killed. |
MaxStepsReached | Step limit was reached. Process was killed. |
BudgetExhausted | Cost budget was exhausted. Process was killed. |
ToolDenied | A tool call was blocked by the allowlist or a rule. |
RuleDenied | A custom rule returned a denial. |
ManualStop | Execution was stopped programmatically. |
ProcessCrashed | The child process exited with a non-zero code unexpectedly. |
AgentScopeEntered
Emitted when a function annotated with#[nanny::agent("name")] is entered. Records the limits active for that scope.
| Field | Type | Description |
|---|---|---|
name | string | The name of the agent scope (matches [limits.<name>] in nanny.toml). |
limits.steps | integer | Step limit active for this scope. |
limits.cost | integer | Cost limit active for this scope. |
limits.timeout | integer | Timeout active for this scope in milliseconds. |
AgentScopeExited
Emitted when a function annotated with#[nanny::agent("name")] returns. Records usage during that scope.
| Field | Type | Description |
|---|---|---|
name | string | The name of the agent scope. |
steps_used | integer | Steps consumed during this scope. |
cost_used | integer | Cost units consumed during this scope. |
StepCompleted
Emitted after each agent step when using the Rust SDK or Python SDK.| Field | Type | Description |
|---|---|---|
step | integer | The step number, starting from 1. |
ToolAllowed
Emitted when Nanny permits a tool call to proceed.| Field | Type | Description |
|---|---|---|
tool | string | The name of the tool that was allowed. |
ToolDenied
Emitted when Nanny blocks a tool call — either the tool is not in the allowlist, or a rule returned a denial.| Field | Type | Description |
|---|---|---|
tool | string | The name of the tool that was blocked. |
reason | string | The stop reason that triggered the denial. |
ToolFailed
Emitted when a permitted tool fails at runtime. Distinct fromToolDenied — the tool was allowed but encountered an error (network failure, bad arguments, timeout). No cost is charged on failure.
| Field | Type | Description |
|---|---|---|
tool | string | The name of the tool that failed. |
error | string | A description of the error. |