File size: 5,557 Bytes
7e96f34
 
 
 
 
 
 
 
 
63c75d5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
---
license: mit
tags:
  - openclaw
  - sidecar
  - session-review
  - fastapi
---

# Session Amplifier

Lightweight OpenClaw sidecar for transcript spooling and session review.

## What it does

- **Spooler** β€” walks `~/.openclaw/agents/<agent>/sessions/*.jsonl`, cleans/redacts tool results, stores summaries to SQLite
- **Reviewer** β€” scores sessions for quality/failure patterns, detects unused tools/skills, surfaces recommendations
- **Snapshot adapter** β€” exposes canonical `openclaw.session.v1` session snapshots for dashboards/reviewers without gateway core patches
- **API** β€” FastAPI server on port 8477 with 4 endpoints

## Quick start

```bash
# Install deps
pip install -r requirements.txt

# Init DB
python main.py init

# Run once (spool or review)
python main.py spool
python main.py review

# Start API server
python main.py serve

# Watch transcript files and spool on changes
python main.py watch --interval 5
```

## Running Tests

The application uses `pytest` for testing. The tests use an in-memory SQLite database and do not require filesystem access.

```bash
# Run all tests
pytest tests/
```

## Docker / container run path

```bash
cd sidecar/session-amplifier
docker compose up -d --build
```

Manual equivalent:

```bash
docker build -t session-amplifier sidecar/session-amplifier/
docker run -p 8477:8477 \
  -v ~/.openclaw:/openclaw:ro \
  -v session_amplifier_state:/data/session-amplifier \
  -e OPENCLAW_AGENTS_ROOT=/openclaw/agents \
  -e OPENCLAW_STATE_DIR=/data/session-amplifier \
  session-amplifier serve
```

Host note: the bare host Python environment may not have `uvicorn` / `fastapi` installed. The intended live-service path is the container.

Gateway integration note: when OpenClaw runs in Docker, gateway-side scripts should target the sidecar by container hostname, not `localhost`. Default wrapper target is `SESSION_AMPLIFIER_BASE_URL=http://session-amplifier:8477`. The sidecar compose file joins the external `librechat_default` network so the gateway container can resolve it.

## API endpoints

| Method | Path | Description |
|--------|------|-------------|
| GET | `/health` | Container health + version |
| POST | `/spool` | Trigger incremental spooling |
| GET | `/review/report` | Fetch latest review report |
| GET | `/review/skills` | Fetch skill/MCP coverage report |
| GET | `/sessions/recent` | Recent sessions with activity/error counts |
| GET | `/sessions/snapshots` | Recent sessions as canonical `openclaw.session.v1` snapshots |
| GET | `/session/{id}/snapshot` | One canonical `openclaw.session.v1` snapshot |
| GET | `/session/{id}/activity` | Normalized per-session activity feed |

## Config (env)

| Var | Default | Description |
|-----|---------|-------------|
| `OPENCLAW_AGENTS_ROOT` | `~/.openclaw/agents` | Transcript source |
| `OPENCLAW_STATE_DIR` | `~/.openclaw/workspace/ops/state` | SQLite + artifacts output |
| `MAX_TOOLRESULT_CHARS` | `2000` | Truncate threshold |
| `SPOOLER_BATCH_SIZE` | `100` | DB insert batch size |
| `REVIEW_CONFIDENCE_THRESHOLD` | `0.5` | Min confidence for recommendations |
| `API_PORT` | `8477` | HTTP server port |

## Package layout

```
session-amplifier/
β”œβ”€β”€ config.py            # Env/config loading
β”œβ”€β”€ main.py              # CLI entrypoint (init/serve/serve-watch/spool/review/watch)
β”œβ”€β”€ requirements.txt
β”œβ”€β”€ Dockerfile
β”œβ”€β”€ spooler/
β”‚   β”œβ”€β”€ processor.py     # JSONL β†’ spooled rows
β”‚   β”œβ”€β”€ redaction.py     # API key / path / base64 redaction
β”‚   β”œβ”€β”€ noise_filter.py  # Drop known-noise tool output
β”‚   └── store.py         # SQLite read/write
β”œβ”€β”€ reviewer/
β”‚   β”œβ”€β”€ scorer.py        # Session quality scoring
β”‚   β”œβ”€β”€ pattern_detector.py  # Recurring failure detection
β”‚   β”œβ”€β”€ skill_analyzer.py    # MCP/skill coverage
β”‚   └── report.py        # Report generation + persistence
β”œβ”€β”€ api/
β”‚   └── routes.py        # FastAPI route handlers
└── tests/
    └── ...              # pytest suite
```

## Architecture notes

- Reads-only from `OPENCLAW_AGENTS_ROOT`; never modifies transcripts
- Idempotent spooling via `UNIQUE(session_id, entry_idx)` constraint
- **Incremental spooling**: Uses tracked `last_entry_idx` file state to only parse lines appending to existing files, drastically reducing processing time overhead.
- Reviewer is deterministic (no LLM required in v1); recommendations scored by confidence threshold
- Watch mode is polling-based in v1 for simplicity; `python main.py watch --interval 5` or `serve-watch`
- By default `serve-watch` / `watch` only triggers spooling. To optionally trigger the reviewer append `--review-every <N>`.
- Manual trigger remains available for cron/recovery: `POST /spool` β†’ wait β†’ `GET /review/report`
- A simple CLI-style live monitor is available at `/home/node/.openclaw/workspace/ops/scripts/session_amplifier_live_monitor.py`
- Snapshot endpoints are read-only and sidecar-local. Rollback is removing `reviewer/session_snapshot.py`, the two route handlers/imports in `api/routes.py`, and the snapshot smoke test; no gateway config change is required unless the service was rebuilt/redeployed.

## Troubleshooting

- **API keys exposed in tool outputs?** Check `SPOOLER_REDACT_PATTERNS`.
- **Database lock errors?** Multiple cron instances might be racing. Restart with a clean volume or disable concurrent spool calls.
- **Reporting "No data"?** Ensure `OPENCLAW_AGENTS_ROOT` path exists inside the container and matches host volume bindings.