qqq 0.1.1

Quick Query Quorum: an in-memory multi-user voice chat with an AI facilitator
qqq-0.1.1 is not a library.

QQQ

Quick Query Quorum is a minimal, in-memory multi-user voice chat with an OpenAI-compatible AI facilitator. It provides one self-contained Rust binary and a browser interface with no database or frontend build step.

Sessions, credentials, history, and generated audio exist only in process memory and disappear on restart. Participant tokens remain in browser sessionStorage; they are sent as bearer credentials and never appear in URLs or session views.

Install

Install the latest release from crates.io:

cargo install qqq

Create the configuration and start QQQ:

cp .env.example .env
# Set OPENAI_API_KEY, CHAT_MODEL, STT_MODEL, TTS_MODEL, and TTS_VOICE.
qqq

Open http://127.0.0.1:8787 and press the orb.

To run directly from a checkout, use cargo run --release. Exported variables override values loaded from .env.

Docker

Release images are published for linux/amd64 and linux/arm64:

docker run --rm -p 8787:8787 \
  --env-file .env \
  -e QQQ_BIND=0.0.0.0:8787 \
  ghcr.io/maxylev/qqq:latest

Pin a version tag such as 0.1.1 in production. QQQ must bind to 0.0.0.0 inside a container for the published port to be reachable.

Configuration

Variable Default Purpose
QQQ_BIND 127.0.0.1:8787 Listener address
QQQ_PUBLIC_URL unset Optional externally visible URL
OPENAI_BASE_URL https://openrouter.ai/api/v1 OpenAI-compatible API base URL
OPENAI_API_KEY required Server-only provider credential
CHAT_MODEL required Chat-completion model
STT_MODEL required Speech-to-text model
TTS_MODEL required Text-to-speech model
TTS_VOICE required Text-to-speech voice
TTS_FORMAT mp3 Speech response format
OPENAI_HTTP_REFERER unset Optional provider attribution header
OPENAI_APP_TITLE unset Optional provider attribution header
MAX_SESSIONS 100 Maximum active in-memory sessions
MAX_PARTICIPANTS_PER_SESSION 8 Maximum participants per session
SESSION_TTL_SECONDS 14400 Idle session lifetime
MAX_HISTORY_MESSAGES 512 Append-only history limit
MAX_AUDIO_BYTES 10000000 Multipart audio upload limit
INPUT_BATCH_MS 350 Model input batching interval
DELIVERY_TIMEOUT_SECONDS 45 Delivery progress timeout
CLAIM_MODE replace Floor claim behavior: replace or queue
DEFAULT_LANGUAGE en Onboarding and STT fallback language

The selected provider and base URL must support chat completions, speech generation, and transcription.

API Model

Public routes are GET /, GET /health, and GET /api/sessions/:id/exists. Session creation and joining use POST /api/sessions and POST /api/sessions/:id/join. All other session routes require bearer authentication, including the WebSocket hello at /api/sessions/:id/ws.

History begins with one stable system message and is append-only. User messages preserve arrival order, and each assistant send_messages tool call remains paired with its tool result. Each session runs one model call at a time. Deliveries run sequentially, and only the current floor holder may record.

Development

Run the same checks as CI:

cargo fmt --all -- --check
cargo clippy --all-targets --all-features -- -D warnings
cargo test --all-features
cargo package --locked
docker build -t qqq:dev .

Offline tests exercise in-process Axum routes, authorization, multipart and raw audio validation, delivery transitions, and WebSocket semantics.

Live Provider Tests

Ignored live tests use real provider requests and spend credits. Put credentials and model names in the ignored .env.test, then source it without printing its contents:

set -a
source .env.test
set +a
cargo test live_provider_ -- --ignored --test-threads=1

The first test validates a forced chat tool call. The second performs a real TTS-to-STT round trip. A manually dispatched Live provider E2E GitHub workflow can run the same checks with secrets from the protected openrouter-e2e environment.

HTTPS And Limits

Mobile microphone access requires trusted HTTPS. Terminate TLS at a same-origin reverse proxy; QQQ intentionally does not implement TLS:

location / {
    proxy_pass http://127.0.0.1:8787;
    proxy_http_version 1.1;
    proxy_set_header Host $host;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
}

QQQ intentionally provides one process with no persistence, accounts, recovery, audio broadcast, database, or history truncation. A session closes when it reaches its history limit.

License

QQQ is available under the MIT License.