Socket Protocol
Unix socket API for programmatic access to the whisp daemon.
Socket Protocol
The whisp daemon exposes a Unix socket API for programmatic access. This enables integration with scripts, tools, and custom applications.
Connection
Connect to the Unix socket at /tmp/whisp.sock (or $WHISP_SOCKET if set).
# Test connection
echo '{"type":"ping"}' | nc -U /tmp/whisp.sockProtocol Format
- Transport: Unix domain socket
- Message format: Line-delimited JSON (one JSON object per line)
- Request: Single JSON object with
typefield - Response: Wrapped in
StreamEventwitheventfield
Response Wrapper
All responses are wrapped in a StreamEvent:
{
"event": "complete",
"response": { ... },
"model": "gpt-5-nano-2025-08-07",
"duration_ms": 234
}Or on error:
{
"event": "error",
"message": "Error description"
}Request Types
Ping
Check daemon connectivity.
{"type": "ping"}Response:
{"status": "ok"}Health
Get detailed daemon health metrics.
{"type": "health"}Response:
{
"uptime_secs": 3600,
"request_count": 150,
"error_count": 2,
"active_connections": 1,
"provider": "openai",
"last_request_time": 1704067200,
"memory_usage_bytes": 52428800,
"version": "0.1.0"
}Metrics
Get performance and token usage metrics.
{"type": "metrics"}Response:
{
"uptime_secs": 3600,
"avg_response_ms": 450.5,
"p50_response_ms": 380,
"p95_response_ms": 890,
"p99_response_ms": 1200,
"requests_per_hour": 25.5,
"total_input_tokens": 45000,
"total_output_tokens": 12000,
"request_type_counts": {
"query": 100,
"explain": 30,
"chat": 20
}
}Query
Generate a shell command from natural language.
{
"type": "query",
"query": "find files larger than 100MB",
"cwd": "/home/user/projects",
"shell": "bash",
"session_id": "abc123",
"project_type": "rust",
"project_root": "/home/user/projects/myapp",
"git_branch": "main",
"git_dirty": false
}| Field | Required | Description |
|---|---|---|
query | Yes | Natural language description |
cwd | Yes | Current working directory |
shell | Yes | Shell type (bash, zsh, fish) |
session_id | No | Session ID for context tracking |
project_type | No | Detected project type (rust, node, python, etc.) |
project_root | No | Project root directory |
git_branch | No | Current git branch |
git_dirty | No | Whether git working tree has changes |
Response (Command):
{
"command": "find . -type f -size +100M",
"explanation": "Finds all files larger than 100MB in the current directory and subdirectories.",
"warning": null
}Response (Clarification):
{
"clarification": "Do you want to find files by size or by name pattern?"
}Error
Analyze a failed command and suggest a fix.
{
"type": "error",
"command": "npm start",
"exit_code": 1,
"stderr": "Error: Cannot find module 'express'",
"cwd": "/home/user/projects/app",
"session_id": "abc123",
"project_type": "node",
"project_root": "/home/user/projects/app",
"git_branch": "main",
"git_dirty": true
}Response:
{
"fix": "npm install express",
"explanation": "The 'express' module is missing. Install it as a dependency."
}Pipe
Process piped input with a query.
{
"type": "pipe",
"query": "summarize the errors",
"stdin": "Error: connection refused\nError: timeout\nError: connection refused",
"cwd": "/home/user",
"shell": "bash",
"session_id": "abc123"
}For binary or multi-line input, use base64 encoding:
{
"type": "pipe",
"query": "analyze this log",
"stdin_base64": "RXJyb3I6IGNvbm5lY3Rpb24gcmVmdXNlZAo=",
"cwd": "/home/user",
"shell": "bash"
}| Field | Required | Description |
|---|---|---|
stdin | No* | Plain text input |
stdin_base64 | No* | Base64-encoded input |
stdin_b64 | No* | Alias for stdin_base64 (fish compatibility) |
*One of stdin, stdin_base64, or stdin_b64 should be provided.
Response: Same as Query (Command response).
Explain
Explain what a command does.
{
"type": "explain",
"command": "find . -name '*.log' -mtime +7 -delete",
"cwd": "/var/log",
"shell": "bash"
}Response:
{
"explanation": "Finds and deletes all .log files older than 7 days in the current directory.",
"breakdown": [
"find . - search in current directory",
"-name '*.log' - match files ending in .log",
"-mtime +7 - modified more than 7 days ago",
"-delete - remove matching files"
],
"warning": "This command may be destructive. Please review carefully before executing."
}DryRun
Preview command effects without execution.
{
"type": "dry_run",
"command": "rm -rf ./build",
"cwd": "/home/user/project",
"shell": "bash"
}Response:
{
"effects": [
"Recursively deletes the ./build directory",
"Removes all files and subdirectories within ./build"
],
"files_affected": ["./build/", "./build/**/*"],
"reversible": false,
"warning": "This command may be destructive. Please review carefully before executing."
}Variants
Get alternative commands for the same task.
{
"type": "variants",
"original_query": "find large files",
"original_command": "find . -size +100M",
"cwd": "/home/user",
"shell": "bash"
}Response:
{
"variants": [
{
"command": "du -ah . | sort -rh | head -20",
"explanation": "Lists top 20 largest files/directories with human-readable sizes",
"tradeoff": "Shows directories too, not just files"
},
{
"command": "find . -type f -size +100M -exec ls -lh {} \\;",
"explanation": "Finds large files and shows detailed info including size",
"tradeoff": "More verbose output, slower for many files"
}
]
}Chat
Send a message in an interactive conversation.
{
"type": "chat",
"message": "How do I set up Docker for this project?",
"conversation_id": "conv_123",
"cwd": "/home/user/project",
"shell": "bash",
"clear_history": false
}| Field | Required | Description |
|---|---|---|
message | Yes | User message |
conversation_id | Yes | Unique conversation identifier |
cwd | Yes | Current working directory |
shell | Yes | Shell type |
clear_history | No | Set true to reset conversation |
Response:
{
"message": "To set up Docker for this Node.js project, create a Dockerfile...",
"command": "docker build -t myapp ."
}The command field is optional and included when the response suggests a specific command.
SearchHistory
Search the command history/audit log.
{
"type": "search_history",
"query": "docker",
"limit": 10,
"semantic": false
}| Field | Required | Description |
|---|---|---|
query | Yes | Search query |
limit | No | Max results (default: 10) |
semantic | No | Enable semantic search (default: false) |
Response:
{
"results": [
{
"command": "docker-compose up -d",
"cwd": "/home/user/project",
"timestamp": "2024-01-01T12:00:00Z",
"relevance": 0.95,
"context": "Starting development services"
}
]
}Context
Record a command for session context (internal use).
{
"type": "context",
"command": "cd /var/log",
"cwd": "/var/log",
"session_id": "abc123"
}Response:
{"status": "recorded"}Error Responses
All request types may return an error:
{
"event": "error",
"message": "API rate limit exceeded"
}Or within the complete event:
{
"event": "complete",
"response": {
"error": "Invalid request format"
},
"model": "gpt-5-nano-2025-08-07",
"duration_ms": 5
}Example: Python Client
import socket
import json
def whisp_query(query: str, cwd: str = ".") -> dict:
"""Send a query to the whisp daemon."""
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
sock.connect("/tmp/whisp.sock")
request = {
"type": "query",
"query": query,
"cwd": cwd,
"shell": "bash"
}
sock.send((json.dumps(request) + "\n").encode())
response = sock.recv(65536).decode()
sock.close()
event = json.loads(response)
if event.get("event") == "complete":
return event["response"]
else:
raise Exception(event.get("message", "Unknown error"))
# Usage
result = whisp_query("list all python files")
print(result["command"]) # find . -name "*.py"Example: Bash Script
#!/bin/bash
whisp_query() {
local query="$1"
local cwd="${2:-$(pwd)}"
echo "{\"type\":\"query\",\"query\":\"$query\",\"cwd\":\"$cwd\",\"shell\":\"bash\"}" \
| nc -U /tmp/whisp.sock \
| jq -r '.response.command // .message'
}
# Usage
cmd=$(whisp_query "compress all log files")
echo "Suggested command: $cmd"Connection Limits
The daemon limits concurrent connections to prevent resource exhaustion:
- Maximum concurrent connections: 100
- When the limit is reached, new connections wait until a slot becomes available
Security Notes
- Socket permissions: The socket is created with
0700permissions (owner-only access) - Secret redaction: All data sent to AI providers has secrets automatically redacted
- Local only: The Unix socket is only accessible from the local machine