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