Desktop app for LLM safe routing, agent observability & reflection.
- Lightweight local model proxy/router compatible with OpenAI and Anthropic client protocols; on API failure, exhausted quota/token limits, or rate limits, automatic fallback with no interruption.
- Built-in safeguards: data-leak prevention, redaction, operation blocking, and file-path protection.
- Reconstructs agent goals, decisions, and actions from LLM proxy traffic; provides causal trajectory maps, action reflection reports, and agent daily digests—addressing observability for multi-agent and long-running agents, and helping improve Agent Orchestration Loop (outer orchestration loop) reliability and task success rates.
- macOS and Windows desktop apps with one-click install.
中文文档: README.zh-CN.md
Admin UI screenshots — click a title to flip · 1–5
| Dimension | Description |
|---|---|
| Route | high / medium / low ordered fallback groups; auto-switch on upstream failure, malformed JSON, or missing first stream token; built-in OpenAI ↔ Anthropic conversion |
| Fast | Rust core, local forwarding, native streaming; single config file, hot reload; AgentMirror tray app stays out of your way |
| Safe | Content/file DLP, tool operation rules, path protection; master switch to enable or disable all security features |
| Mirror | Reconstruct agent goals, decisions, and actions from LLM proxy traffic; causal trajectory maps, reflection reports, and agent daily digests |
Change one line in your client. Run AgentMirror. A faster, more reliable path to models—with built-in safety and agent observability.
chmod +x scripts/install.sh
./scripts/install.sh --all # CLI + tray app + login autostart
securemodelroute # start AgentMirror and open admin UIWindows: run AgentMirror_*_x64-setup.exe (recommended), or .\install.ps1 -All, then securemodelroute
Client config (provider mode — recommended, one universal base URL):
from openai import OpenAI
client = OpenAI(base_url="http://127.0.0.1:8080/v1", api_key="dummy")
# Pick a tier by model id (same provider, one base URL):
client.chat.completions.create(model="saferoute-high", messages=[...])# Anthropic SDK — same base URL; POST /messages (or /v1/messages)
import anthropic
client = anthropic.Anthropic(base_url="http://127.0.0.1:8080/v1", api_key="dummy")
client.messages.create(model="saferoute-high", max_tokens=1024, messages=[...])AgentMirror detects the client protocol from headers and JSON body, then converts to each upstream model’s OpenAI or Anthropic API inside the selected fallback group.
Works like OpenClaw / Cursor provider mode: AgentMirror is one provider; high / medium / low fallback groups appear as three models. GET /models or GET /v1/models lists them.
| Item | Value |
|---|---|
| Universal API base URL | http://127.0.0.1:8080/v1 |
| OpenAI-style path | POST /chat/completions (alias of /v1/chat/completions) |
| Anthropic-style path | POST /messages (alias of /v1/messages) |
| Models | saferoute-high, saferoute-medium, saferoute-lite |
| Admin UI | http://127.0.0.1:8080/ui |
| Health | http://127.0.0.1:8080/health |
Legacy tier path prefixes (/high/messages, /medium/chat/completions, …) and header X-SMR-Fallback-Group still work. Path/header override the model field when both are set. Session id: X-SMR-Session-Id.
Pre-built packages are on GitHub Releases.
| Platform | Package | Install |
|---|---|---|
| macOS (Apple Silicon) | AgentMirror_*_arm64.dmg |
Open the DMG, drag AgentMirror.app to Applications, launch from the menu bar tray |
| macOS (Apple Silicon) | smr-*-darwin-arm64-app.tar.gz |
Extract AgentMirror.app to /Applications |
| macOS (Intel) | AgentMirror_*_x86_64.dmg |
Same as arm64 DMG (cross-built on Apple Silicon hosts) |
| macOS (Intel) | smr-*-darwin-x86_64-app.tar.gz |
Extract AgentMirror.app to /Applications |
| macOS (Intel) | smr-*-darwin-x86_64.tar.gz |
CLI only |
| Windows x86_64 | AgentMirror_*_x64-setup.exe |
Recommended: run the NSIS installer — registers in Settings → Apps, installs tray GUI + smr.exe CLI, includes uninstaller |
| Windows x86_64 | smr-*-windows-x86_64-app.zip |
Portable GUI + optional *-setup.exe; or extract and run install.ps1 -All |
| Windows x86_64 | smr-*-windows-x86_64.zip |
CLI only: extract, run install.ps1, then securemodelroute |
Uninstall on Windows: Settings → Apps → AgentMirror (NSIS), or run .\uninstall.ps1 to remove the NSIS app and CLI companion files.
Build the NSIS installer on Windows: .\scripts\package.ps1 (requires Node.js + Rust). From macOS with UTM: ./scripts/vm/package-windows-gui.sh.
From source: on macOS run ./scripts/install.sh --all; on Windows use AgentMirror_*_x64-setup.exe (NSIS) or .\install.ps1 -All inside the zip.
Config after install: ~/.local/etc/securemodelroute/smr.yaml (macOS/Linux/Windows NSIS or install.ps1). Add upstream API keys in the admin UI or YAML—never commit secrets.
OpenClaw is an OpenAI-compatible agent gateway. Point it at AgentMirror for local fallback routing with unified DLP, operation blocking, and path protection.
Prerequisites: AgentMirror running (securemodelroute or the tray app). Configure upstream models and API keys in AgentMirror only (admin UI → Routing or smr.yaml). OpenClaw never needs real vendor keys.
Provider mode (recommended): AgentMirror exposes one OpenAI-compatible provider with three public tier models — saferoute-high, saferoute-medium, saferoute-lite — not upstream names like gpt-4o-mini. Each id selects a fallback group; AgentMirror walks that group’s chain and handles OpenAI ↔ Anthropic conversion internally.
Edit ~/.openclaw/openclaw.json (JSON5):
{
models: {
mode: "merge",
providers: {
saferoute: {
baseUrl: "http://127.0.0.1:8080/v1",
apiKey: "dummy",
api: "openai-completions",
models: [
{
id: "saferoute-high",
name: "AgentMirror High",
reasoning: false,
input: ["text"],
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
contextWindow: 128000,
maxTokens: 8192,
},
{
id: "saferoute-medium",
name: "AgentMirror Medium",
reasoning: false,
input: ["text"],
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
contextWindow: 128000,
maxTokens: 8192,
},
{
id: "saferoute-lite",
name: "AgentMirror Lite",
reasoning: false,
input: ["text"],
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
contextWindow: 128000,
maxTokens: 8192,
},
],
},
},
},
agents: {
defaults: {
model: { primary: "saferoute/saferoute-high" },
models: {
"saferoute/saferoute-high": { alias: "high" },
"saferoute/saferoute-medium": { alias: "medium" },
"saferoute/saferoute-lite": { alias: "lite" },
},
},
},
}Steps:
- In AgentMirror admin UI → Routing, configure each tier’s upstream chain (OpenAI, Anthropic, DeepSeek, etc.).
- In OpenClaw, register the three public ids above (
saferoute-high/medium/lite) undermodels.providers.saferoute.models. - Add every
saferoute/<public-id>you use toagents.defaults.models(OpenClaw allowlist). Switch tiers withopenclaw models set saferoute/saferoute-mediumor setagents.defaults.model.primary. - Restart the gateway:
openclaw gateway restart(or restart the OpenClaw app).
Tip: admin UI → Overview → OpenClaw configuration example lists the same base URL and model ids; use Copy there.
Legacy alternatives (when a client cannot set model to saferoute-*):
- Tier path prefix:
baseUrl: "http://127.0.0.1:8080/high/v1"(also/medium/v1,/lite/v1) - Header override:
headers: { "X-SMR-Fallback-Group": "high" }onhttp://127.0.0.1:8080/v1
AgentMirror applies DLP, operation rules, and path protection to OpenClaw traffic the same as any other client.
Reconstruct what agents did, why, and how to improve — from LLM proxy traffic alone (no extra agent instrumentation).
- Traffic-based reconstruction — infer goals, decisions, and tool actions from proxied requests and responses
- Causal trajectory — Goal → Decision → Action → Observation per run; directed graph, mind map, or timeline views
- Reflection reports — LLM-first by default (
insight.llm_critic: true): every 10 turns while a run is active, plus on run completion or after 10+ minutes idle. Five-dimension critique with original/current goal tracking. Rule baseline only when the upstream LLM is unavailable (llm_critic: falsefor legacy rule-only mode) - Daily digests — LLM-first by default (
insight.llm_daily: true), summarizing per-agent tasks, issues, and recommendations from reflection reports; UI shows generating / no runs / unchanged states - Multi-agent — separate runs by
X-SMR-Agent-Id, system-prompt fingerprint, or idle/run boundaries - Agent profile & patterns — capability profile from tools/stats; action-pattern mining in reflection reports
- Run management — merge/split runs; DLP and operation-safety highlights on run cards
- Daily export — browser print / HTML view (
GET /api/insight/daily/{date}/print)
Enable traffic snapshots on the Logs tab (insight.require_traffic_bodies auto-enables logging.save_traffic_bodies). Blocked/failed proxy requests are excluded by default; set insight.include_failed_requests: true to trace them (request body only).
Retention: insight data defaults to 30 days (insight.retention_days); traffic snapshots default to 7 days (logging.traffic_retention_days). Increase traffic retention if you need long-session replay via POST /api/insight/reset with replay_from_traffic: true.
See AgentMirror design for the full API reference.
- Three fallback tiers with drag-and-drop ordering in the admin UI
- Per-request group via URL path (
/high/v1,/medium/v1,/lite/v1) or header override - Streaming-aware fallback until the first content token
- Protocol detection and cross-vendor request/response mapping
Automatically redact sensitive data before the model accesses or retrieves it, preventing leakage through LLM calls.
- Content rules — full-text or fragment match for secrets, phrases, extensionless sensitive strings
- Reversible tokens — with
pipeline.dlp_reversible: true(default), secrets are replaced by session tokens ([[smr:…]]) before they reach the model. Only tool-call / tool-result fields are restored on the response path; ordinary assistant text is not auto-restored. Per-session vault is capped at 4096 unique secrets (overflow falls back to irreversible redaction). - File rules — disk-backed index (Bloom + SQLite + byte verify) for large corpora; incremental rebuild on file changes
- SessionGuard — when a tool mentions a protected file, redaction continues for the next N requests (
trigger_window). Supports absolute paths, shellcd <dir> && … "relative", and JSONcwd/pathpatterns common in agents - Built-in credential presets (
sk-,AKIA,ghp_, …) optional
- Inspect tool-related fields on requests and responses
observe(log only) orenforce(block)- Rules by
command_exec,api_call,network_access+ keywords
deny_delete/deny_modify/deny_accesson paths; directories cover descendants
- Web admin at
/ui(English / 中文) - AgentMirror tray app (macOS / Windows)
- SQLite audit log and live security events
- Traffic body snapshots for debugging (optional, up to 20 MiB per file). Default saves after DLP; UI can switch to raw pre-DLP capture (may write secrets to disk).
Master switch: pipeline.security_enabled (also in the UI header).
Example: [config/smr.example.yaml](config/smr.example.yaml)
server:
listen: "127.0.0.1:8080"
default_fallback_group: high
pipeline:
security_enabled: true
dlp_enabled: true
dlp_reversible: true
operation_security_mode: enforce
insight:
enabled: true
require_traffic_bodies: true
llm_critic: true # LLM-only reflection reports (default)
llm_daily: true # LLM-only daily digests (default)
critic_model_group: high
retention_days: 30
include_failed_requests: false
fallback_groups:
high:
- id: primary
base_url: "https://api.openai.com/v1"
model: "gpt-4o-mini"
api_key_env: OPENAI_API_KEY
- id: fallback
base_url: "https://api.anthropic.com/v1"
model: "claude-sonnet-4-20250514"
protocol: anthropic
api_key_env: ANTHROPIC_API_KEYConfig paths
| Platform | Typical location |
|---|---|
| macOS / Linux (install script) | ~/.local/etc/securemodelroute/smr.yaml |
macOS / Linux (direct smr) |
~/.config/securemodelroute/smr.yaml |
| Windows | %USERPROFILE%\.local\etc\securemodelroute\smr.yaml |
Override with SMR_CONFIG. Prefer api_key_env over inline keys—never commit secrets.
File DLP index: {config_dir}/file-index/{rule_id}/
Traffic snapshots (debug only):
logging:
save_traffic_bodies: true
traffic_retention_days: 7 # insight replay needs snapshots within this window
traffic_request_capture: after_dlp # after_dlp (default) | before_dlp (raw, may contain secrets)
traffic_max_body_bytes: 20971520 # 20 MiB capFiles: {config_dir}/traffic/*.body
Open http://127.0.0.1:8080/ui — overview, routing, DLP, path rules, operation rules, agent reflection, logs, full YAML editor. Screenshots: see Admin UI preview above.
| API | Description |
|---|---|
GET /api/status |
Listen address, security flags, index readiness |
GET/PUT /api/config |
Read/write config; PUT hot-reloads |
GET /api/traffic |
Traffic snapshot list |
GET /api/traffic/{id} |
Full snapshot body |
GET /api/events, /api/audits |
Events and audit rows |
GET /api/insight/agents, /runs, /runs/{id}/graph, /runs/{id}/report |
AgentMirror runs, graphs, reflection reports |
GET /api/insight/daily/{date}, POST /api/insight/daily/generate |
Daily digests |
GET /api/insight/agents/{id}/profile |
Agent capability profile |
POST /api/insight/reset |
Clear insight data; optional traffic replay |
Full insight API: docs/AgentMirror-Design.md.
cargo test && ./scripts/verify.sh
cp config/test.env.example config/test.env # gitignored; set SMR_GLM_API_KEY / SMR_DEEPSEEK_API_KEY
./scripts/run_all_tests.shFurther design details: docs/AgentMirror-Design.md.
MIT




