Skip to content

Commit ac68378

Browse files
feat(timeline): structured session timeline view (#81)
- timeline.py: build_timeline, format_timeline, format_timeline_json, cmd_timeline - Groups events into phases (reuses explain.py phase detection) - Shows tool calls, file ops, LLM requests, errors, retries per phase - Cost estimates per phase and session (reuses cost.py pricing) - Wasted-spend callout for failed phases - Retry detection: same tool+args called more than once - --format json for machine-readable output - --model flag for cost estimate pricing (sonnet/opus/haiku/gpt4/gpt4o) - 66 tests in tests/test_timeline.py - README: new timeline section and command reference entries - Version bump 0.50.0 → 0.51.0 Closes #81 Co-authored-by: Ona <no-reply@ona.com>
1 parent 77b0038 commit ac68378

5 files changed

Lines changed: 1090 additions & 1 deletion

File tree

README.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ print(f"Replay with: agent-strace replay {meta.session_id}")
186186
| `curve` | Personal cost-efficiency curve |
187187
| `a2a-tree` | Cross-agent trace correlation (A2A protocol) |
188188
| `mcp` | MCP server: expose traces as queryable tools for a debugging agent |
189+
| `timeline` | Structured phase-by-phase view of a session with costs, retries, and wasted spend |
189190
| `config-watch` | Snapshot and diff AGENTS.md and other config files; find affected sessions |
190191

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

452+
### Session timeline
453+
454+
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.
455+
456+
```bash
457+
# Timeline for the latest session
458+
agent-strace timeline
459+
460+
# Timeline for a specific session
461+
agent-strace timeline <session-id>
462+
463+
# Machine-readable output
464+
agent-strace timeline <session-id> --format json
465+
466+
# Use a different model for cost estimates
467+
agent-strace timeline <session-id> --model opus
468+
```
469+
470+
Example output:
471+
472+
```
473+
Session: abc123def456 | 2026-05-19 14:32 | 4m 12s | $0.0043 | 3 errors
474+
475+
Phase 1: Setup (0:00–0:45) $0.0008
476+
✓ Read src/auth/handler.go
477+
✓ Read src/auth/middleware.go
478+
479+
Phase 2: Implementation (0:45–2:10) $0.0031
480+
· Run Bash (1.2s)
481+
pytest tests/test_auth.py
482+
✗ Error: Bash
483+
FAILED tests/test_auth.py::TestAuthHandler
484+
· Run Bash (attempt 2) (1.1s)
485+
pytest tests/test_auth.py
486+
✗ Error: Bash
487+
FAILED tests/test_auth.py::TestAuthHandler
488+
✓ Write src/auth/handler.go +3 lines
489+
✓ Run Bash (0.9s)
490+
491+
⚠ 2 retries in this phase
492+
493+
⚠ Wasted spend: 2 retries on failed phases = ~$0.0008 (19% of session cost)
494+
```
495+
496+
| Flag | Default | Description |
497+
|---|---|---|
498+
| `--format` | `text` | `text` or `json` |
499+
| `--model` | `sonnet` | Pricing model for cost estimates: `sonnet`, `opus`, `haiku`, `gpt4`, `gpt4o` |
500+
449501
### Config change detector
450502

451503
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.

src/agent_trace/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
"""agent-trace: strace for AI agents."""
22

3-
__version__ = "0.50.0"
3+
__version__ = "0.51.0"

src/agent_trace/cli.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
from .integrations import detect_and_instrument, _INTEGRATIONS
5050
from .budget_report import cmd_budget_report
5151
from .compare import cmd_compare
52+
from .timeline import cmd_timeline
5253
from .config_watch import cmd_config_watch
5354
from .lint import cmd_lint
5455
from .retention import cmd_retention
@@ -572,6 +573,17 @@ def build_parser() -> argparse.ArgumentParser:
572573
p_explain = sub.add_parser("explain", help="explain a session in plain English")
573574
p_explain.add_argument("session_id", nargs="?", help="session ID or prefix (default: latest)")
574575

576+
# timeline
577+
p_timeline = sub.add_parser("timeline",
578+
help="structured chronological view of a session by phase")
579+
p_timeline.add_argument("session_id", nargs="?",
580+
help="session ID or prefix (default: latest)")
581+
p_timeline.add_argument("--model", default="sonnet",
582+
choices=["sonnet", "opus", "haiku", "gpt4", "gpt4o"],
583+
help="model pricing for cost estimates (default: sonnet)")
584+
p_timeline.add_argument("--format", choices=["text", "json"], default="text",
585+
help="output format (default: text)")
586+
575587
# diff
576588
p_diff = sub.add_parser("diff", help="compare two sessions structurally")
577589
p_diff.add_argument("session_a", help="first session ID or prefix")
@@ -1055,6 +1067,7 @@ def main() -> None:
10551067
"stats": cmd_stats,
10561068
"import": cmd_import,
10571069
"explain": cmd_explain,
1070+
"timeline": cmd_timeline,
10581071
"cost": cmd_cost,
10591072
"diff": cmd_diff,
10601073
"why": cmd_why,

0 commit comments

Comments
 (0)