Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ print(f"Replay with: agent-strace replay {meta.session_id}")
| `curve` | Personal cost-efficiency curve |
| `a2a-tree` | Cross-agent trace correlation (A2A protocol) |
| `mcp` | MCP server: expose traces as queryable tools for a debugging agent |
| `timeline` | Structured phase-by-phase view of a session with costs, retries, and wasted spend |
| `config-watch` | Snapshot and diff AGENTS.md and other config files; find affected sessions |

```
Expand Down Expand Up @@ -238,6 +239,8 @@ agent-strace oncall --rotation-start DATE On-call readiness for agent-modi
agent-strace curve [--export csv] Personal agent cost-efficiency curve
agent-strace inflation [--compare m1,m2] Token inflation calculator across model versions
agent-strace a2a-tree [session-id] Visualise A2A agent call graph
agent-strace timeline [session-id] [--format text|json] [--model MODEL]
Structured phase-by-phase session view with costs and retries
agent-strace config-watch snapshot [--label TEXT] [--watch PATH]
Snapshot current config file state
agent-strace config-watch check [--format text|json] [--watch PATH]
Expand Down Expand Up @@ -446,6 +449,55 @@ Rules are configurable via `.agent-strace-lint.json`:
| `error-retry-loop` | WARN | Same tool errored and was retried 3+ times |
| `no-output` | WARN | Session completed with no write or file-modifying tool calls |

### Session timeline

A structured, phase-by-phase view of what happened in a session — tool calls, file operations, LLM requests, errors, retries, and a wasted-spend callout for failed phases.

```bash
# Timeline for the latest session
agent-strace timeline

# Timeline for a specific session
agent-strace timeline <session-id>

# Machine-readable output
agent-strace timeline <session-id> --format json

# Use a different model for cost estimates
agent-strace timeline <session-id> --model opus
```

Example output:

```
Session: abc123def456 | 2026-05-19 14:32 | 4m 12s | $0.0043 | 3 errors

Phase 1: Setup (0:00–0:45) $0.0008
✓ Read src/auth/handler.go
✓ Read src/auth/middleware.go

Phase 2: Implementation (0:45–2:10) $0.0031
· Run Bash (1.2s)
pytest tests/test_auth.py
✗ Error: Bash
FAILED tests/test_auth.py::TestAuthHandler
· Run Bash (attempt 2) (1.1s)
pytest tests/test_auth.py
✗ Error: Bash
FAILED tests/test_auth.py::TestAuthHandler
✓ Write src/auth/handler.go +3 lines
✓ Run Bash (0.9s)

⚠ 2 retries in this phase

⚠ Wasted spend: 2 retries on failed phases = ~$0.0008 (19% of session cost)
```

| Flag | Default | Description |
|---|---|---|
| `--format` | `text` | `text` or `json` |
| `--model` | `sonnet` | Pricing model for cost estimates: `sonnet`, `opus`, `haiku`, `gpt4`, `gpt4o` |

### Config change detector

Track changes to AGENTS.md and other agent configuration files. Snapshot the current state before a change, then check what drifted and which sessions ran after it.
Expand Down
2 changes: 1 addition & 1 deletion src/agent_trace/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
"""agent-trace: strace for AI agents."""

__version__ = "0.50.0"
__version__ = "0.51.0"
13 changes: 13 additions & 0 deletions src/agent_trace/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
from .integrations import detect_and_instrument, _INTEGRATIONS
from .budget_report import cmd_budget_report
from .compare import cmd_compare
from .timeline import cmd_timeline
from .config_watch import cmd_config_watch
from .lint import cmd_lint
from .retention import cmd_retention
Expand Down Expand Up @@ -572,6 +573,17 @@ def build_parser() -> argparse.ArgumentParser:
p_explain = sub.add_parser("explain", help="explain a session in plain English")
p_explain.add_argument("session_id", nargs="?", help="session ID or prefix (default: latest)")

# timeline
p_timeline = sub.add_parser("timeline",
help="structured chronological view of a session by phase")
p_timeline.add_argument("session_id", nargs="?",
help="session ID or prefix (default: latest)")
p_timeline.add_argument("--model", default="sonnet",
choices=["sonnet", "opus", "haiku", "gpt4", "gpt4o"],
help="model pricing for cost estimates (default: sonnet)")
p_timeline.add_argument("--format", choices=["text", "json"], default="text",
help="output format (default: text)")

# diff
p_diff = sub.add_parser("diff", help="compare two sessions structurally")
p_diff.add_argument("session_a", help="first session ID or prefix")
Expand Down Expand Up @@ -1055,6 +1067,7 @@ def main() -> None:
"stats": cmd_stats,
"import": cmd_import,
"explain": cmd_explain,
"timeline": cmd_timeline,
"cost": cmd_cost,
"diff": cmd_diff,
"why": cmd_why,
Expand Down
Loading
Loading