Skip to content

Sidecar Protocol

All communication between the Tauri Rust core and the Python sidecar is newline-delimited JSON (NDJSON) over the process’s stdin/stdout pipe. Each message is a single JSON object on one line.

{"type": "input", "text": "refactor this function to use async/await"}
{"type": "cd", "path": "/Users/alice/projects/myapp"}
{"type": "reset"}
{"type": "interrupt"}
{"type": "load_model", "model_path": "~/CyberPaw/models/gemma-4-E4B-it-Q4_K_M.gguf", "backend": "llamacpp"}
{"type": "config", "patch": {"permission_mode": "auto_read", "max_new_tokens": 2048}}
{"type": "tool_ack", "id": "perm_a1b2c3d4", "decision": "allow"}
{"type": "download_start", "model_id": "gemma-4-e2b-q4km", "dest_dir": "~/CyberPaw/models"}
{"type": "status_request"}

{"type": "token", "text": "Here is the refactored function:"}
{"type": "tool_start", "id": "tu_abc123", "tool": "Read", "input": {"file_path": "src/main.py"}}
{"type": "tool_end", "id": "tu_abc123", "tool": "Read", "summary": "Read 142 lines", "is_error": false}
{"type": "status", "phase": "thinking"}
{"type": "status", "phase": "tool_running", "tool": "Bash"}
{"type": "status", "phase": "idle"}
{"type": "model_progress", "pct": 42}
{"type": "model_status", "loaded": true, "backend": "llama.cpp", "context_size": 32768, "max_new_tokens": 4096}
{"type": "model_status", "backend": "llama.cpp", "loaded": true, "vram_used_mb": 4200, "model_size_mb": 3800, "kv_cache_mb": 400}
{"type": "generation_stats", "tokens": 312, "elapsed_ms": 8400, "tokens_per_sec": 37.1}

Permission request (tool needs user approval)

Section titled “Permission request (tool needs user approval)”
{"type": "tool_permission_request", "id": "perm_a1b2c3d4", "tool": "Bash", "input": {"command": "rm -rf dist/"}}
{"type": "download_progress", "model_id": "gemma-4-e2b-q4km", "pct": 67, "downloaded_mb": 1940.2, "total_mb": 2900.0, "speed_mbps": 12.4}
{"type": "download_done", "model_id": "gemma-4-e2b-q4km", "path": "/Users/alice/CyberPaw/models/gemma-4-E2B-it-Q4_K_M.gguf"}
{"type": "error", "message": "Model not loaded yet."}

A typical agent turn looks like:

← {"type": "status", "phase": "thinking"}
← {"type": "token", "text": "I'll read the file first.\n"}
← {"type": "tool_start", "id": "t1", "tool": "Read", ...}
← {"type": "status", "phase": "tool_running", "tool": "Read"}
← {"type": "tool_end", "id": "t1", ...}
← {"type": "status", "phase": "thinking"}
← {"type": "token", "text": "The file contains..."}
← {"type": "generation_stats", ...}
← {"type": "status", "phase": "idle"}