mcspeak/.env.example
Ryan Malloy f00d0e27a2 Add transcribe tool — Parakeet STT via gpu.supported.systems
mcspeak gains a `transcribe` MCP tool that accepts an audio file path
and returns text. Hits the Whisper-API-shaped Parakeet endpoint at
mcspeak.gpu.supported.systems/v1/audio/transcriptions with the shared
bearer key from TTS_PARAKEET_KEY. The mcspeak.* subdomain flows
through to Langfuse as user=mcspeak for tenant attribution.

Input audio_path validates against /output/ and /tmp/mcspeak/ —
symmetric with generate_audio's _resolve_output_path discipline. That
covers the primary round-trip use case (transcribing audio mcspeak
just generated) without extra mounts. Path canonicalization rejects
both absolute paths outside the allowlist and ../-traversal escapes.

The tool exposes forward-compat params (timestamp_granularities,
diarize, num_speakers, vad, punctuation, min_confidence) that the
current phonescribe gateway silently ignores. When the gpu-stack
agent lands word-level alignment or speaker diarization, the same
calls start producing richer responses with no client change. The
shaped-now-instead-of-later approach saves a breaking change later.

response_format dispatch: json/verbose_json parse as JSON dict
directly; text/srt/vtt wrap as {"text": <body>, "format": <fmt>}.
The gateway today rejects srt/vtt with HTTP 400 "use json | text |
verbose_json" — that's a clean error users see, not silent garbage.

transcribe.py: shared httpx.AsyncClient mirrored from orpheus.py's
pattern (explicit timeouts, ConnectError/ReadError/TimeoutException
catches). Closed via lifespan finalizer.

httpx 0.28 gotcha: passing `data=` as list-of-tuples silently routes
the value to `content=`, which wraps as SyncByteStream and crashes
the AsyncClient with "Attempted to send a sync request." `data` must
be a Mapping; list values inside the dict become repeated form
fields automatically.
2026-06-16 07:18:13 -06:00

33 lines
1.7 KiB
Plaintext

# Compose project namespace -- prevents collisions with other stacks
COMPOSE_PROJECT=mcspeak
# Host directory for generate_audio output (output_path / format params).
# Mounted as /output inside the container. Defaults to ~/mcspeak-out when unset.
# TTS_OUTPUT_HOST_DIR=/home/you/audio-out
# Default Piper voice to pre-warm at piper-tts container start. Other voices
# requested via the speak() voice= param are downloaded on demand. Full list:
# https://github.com/rhasspy/piper/blob/master/VOICES.md
# TTS_PIPER_VOICE=es_MX-ald-medium
# Parakeet speech-to-text via the gpu.supported.systems gateway.
# Without TTS_PARAKEET_KEY set, the transcribe() tool returns
# "Parakeet not configured". The shared bearer is documented in
# ~/.claude/rules/gpu.md. The mcspeak.* subdomain flows through to
# Langfuse as user=mcspeak for tenant attribution.
# TTS_PARAKEET_URL=https://mcspeak.gpu.supported.systems/v1/audio/transcriptions
# TTS_PARAKEET_KEY=sk-gpu-lb-master-key-2026
# Path to Orpheus GGUF model file (required by llama-server service)
# Tip: if you've already pulled it via Ollama, find the blob with:
# ollama show --modelfile orpheus | grep FROM
ORPHEUS_GGUF_PATH=/path/to/orpheus.gguf
# Optional overrides -- see README "Configuration" for the full list
# TTS_ENTRY_TONE=chirp # chirp | apollo | none | /path/to.wav
# TTS_EXIT_TONE=roger # roger | quindar-out | none | /path/to.wav
# TTS_CANCEL_TONE=scratch # scratch | reverse-roger | none | /path/to.wav
# TTS_DUCK_MEDIA=true # fade host audio while speaking
# TTS_VOICE_IDENTITY=true # auto-assign distinct voices per project
# TTS_SHUTDOWN_TIMEOUT=30 # max seconds to wait for current speech on stop