Two-agent voice assistant (Cosmo + Люся) via OpenClaw Gateway. Streaming STT (Groq) + LLM + TTS (ElevenLabs) pipeline with keep-alive sessions, barge-in, and daily conversation sessions. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
86 lines
2.7 KiB
Python
86 lines
2.7 KiB
Python
import os
|
|
import sys
|
|
import logging
|
|
import requests as _requests
|
|
from dotenv import load_dotenv
|
|
from groq import Groq
|
|
|
|
load_dotenv()
|
|
|
|
# Логгер — ошибки в файл + короткое сообщение в консоль
|
|
LOG_FILE = os.getenv("LOG_FILE", "errors.log")
|
|
|
|
logging.basicConfig(
|
|
level=logging.WARNING,
|
|
format="%(asctime)s [%(levelname)s] %(name)s: %(message)s",
|
|
handlers=[
|
|
logging.FileHandler(LOG_FILE, encoding="utf-8"),
|
|
],
|
|
)
|
|
log = logging.getLogger("cosmo")
|
|
|
|
# OpenClaw Gateway — Cosmo (по умолчанию)
|
|
GATEWAY_URL = os.getenv("GATEWAY_URL", "http://192.168.31.103:18789")
|
|
GATEWAY_TOKEN = os.getenv("GATEWAY_TOKEN")
|
|
AGENT = os.getenv("AGENT", "openclaw/main")
|
|
VOICE_MODEL = os.getenv("VOICE_MODEL", "openai/gpt-4o-mini")
|
|
|
|
# OpenClaw Gateway — Люся
|
|
LUSYA_GATEWAY_URL = os.getenv("LUSYA_GATEWAY_URL", "http://192.168.31.103:18790")
|
|
LUSYA_GATEWAY_TOKEN = os.getenv("LUSYA_GATEWAY_TOKEN", GATEWAY_TOKEN)
|
|
LUSYA_AGENT = os.getenv("LUSYA_AGENT", "openclaw/wife")
|
|
LUSYA_VOICE_MODEL = os.getenv("LUSYA_VOICE_MODEL", VOICE_MODEL)
|
|
|
|
# Keep-alive HTTP сессии — переиспользуют TCP/TLS соединения
|
|
def _make_session(token: str) -> _requests.Session:
|
|
s = _requests.Session()
|
|
s.headers.update({
|
|
"Authorization": f"Bearer {token}",
|
|
"Content-Type": "application/json",
|
|
})
|
|
return s
|
|
|
|
|
|
# Конфиги агентов по имени
|
|
AGENTS = {
|
|
"cosmo": {
|
|
"name": "Cosmo",
|
|
"gateway_url": GATEWAY_URL,
|
|
"token": GATEWAY_TOKEN,
|
|
"agent": AGENT,
|
|
"voice_model": VOICE_MODEL,
|
|
"tts_voice": os.getenv("COSMO_TTS_VOICE", ""),
|
|
"session": _make_session(GATEWAY_TOKEN),
|
|
},
|
|
"lusya": {
|
|
"name": "Люся",
|
|
"gateway_url": LUSYA_GATEWAY_URL,
|
|
"token": LUSYA_GATEWAY_TOKEN,
|
|
"agent": LUSYA_AGENT,
|
|
"voice_model": LUSYA_VOICE_MODEL,
|
|
"tts_voice": os.getenv("LUSYA_TTS_VOICE", ""),
|
|
"session": _make_session(LUSYA_GATEWAY_TOKEN),
|
|
},
|
|
}
|
|
|
|
# STT
|
|
STT_PROVIDER = os.getenv("STT_PROVIDER", "groq")
|
|
WHISPER_MODEL = os.getenv("WHISPER_MODEL", "small")
|
|
WHISPER_LANG = os.getenv("WHISPER_LANGUAGE", "ru")
|
|
|
|
# Audio (на Pi: PulseAudio BT sink)
|
|
AUDIO_SINK = os.getenv("AUDIO_SINK", "")
|
|
|
|
# VAD
|
|
SILENCE_THRESHOLD = int(os.getenv("SILENCE_THRESHOLD", "500"))
|
|
SILENCE_DURATION = float(os.getenv("SILENCE_DURATION", "1.5"))
|
|
MAX_DURATION = int(os.getenv("MAX_DURATION", "15"))
|
|
FOLLOWUP_TIMEOUT = float(os.getenv("FOLLOWUP_TIMEOUT", "8"))
|
|
|
|
# Groq client
|
|
groq_client = Groq(api_key=os.getenv("GROQ_API_KEY"))
|
|
|
|
if not GATEWAY_TOKEN:
|
|
print("❌ GATEWAY_TOKEN не задан в .env")
|
|
sys.exit(1)
|