Ordo
Add Hugging Face repo card metadata
7e96f34
---
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.