Move audio keep-alive into the gateway container (Cloudron scheduler addon, every 10m)
This commit is contained in:
1 parent
3397d07ec1
commit
acceb43995
3 files changed
+47
-1
No files matched your search
@@ -16,7 +16,13 @@
|
|||||||
"addons": {
|
"addons": {
|
||||||
"postgresql": {},
|
"postgresql": {},
|
||||||
"redis": {},
|
"redis": {},
|
||||||
"localstorage": {}
|
"localstorage": {},
|
||||||
|
"scheduler": {
|
||||||
|
"audio_keepalive": {
|
||||||
|
"schedule": "*/10 * * * *",
|
||||||
|
"command": "/app/code/audio_keepalive.py"
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"tags": [
|
"tags": [
|
||||||
"ai",
|
"ai",
|
||||||
|
|||||||
@@ -29,6 +29,11 @@ COPY config.yaml /app/data/config.yaml
|
|||||||
COPY patch_budget_message.py /app/code/patch_budget_message.py
|
COPY patch_budget_message.py /app/code/patch_budget_message.py
|
||||||
RUN python3 /app/code/patch_budget_message.py
|
RUN python3 /app/code/patch_budget_message.py
|
||||||
|
|
||||||
|
# Audio keep-alive: scheduled pings keep the Tinfoil TEE audio enclave
|
||||||
|
# warm so voice mode skips the ~24s cold-start (see audio_keepalive.py header).
|
||||||
|
COPY audio_keepalive.py /app/code/audio_keepalive.py
|
||||||
|
RUN chmod +x /app/code/audio_keepalive.py
|
||||||
|
|
||||||
# Override the base image's ENTRYPOINT (which is `litellm`) so our
|
# Override the base image's ENTRYPOINT (which is `litellm`) so our
|
||||||
# startup script runs instead of being passed as an argument to litellm.
|
# startup script runs instead of being passed as an argument to litellm.
|
||||||
ENTRYPOINT ["/app/code/start.sh"]
|
ENTRYPOINT ["/app/code/start.sh"]
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Audio keep-alive: ping the Tinfoil TEE audio models through localhost LiteLLM
|
||||||
|
so voice mode doesn't pay the ~24s cold-start after idle.
|
||||||
|
|
||||||
|
Runs INSIDE the gateway container via the Cloudron scheduler addon. Uses the
|
||||||
|
LITELLM_MASTER_KEY already in the container env. TTS-only (STT pings cost
|
||||||
|
$0.01/request each; TTS $0.002 — see docs, keep-alive economics). Silent on
|
||||||
|
success; prints + exits non-zero on failure so scheduler logs capture it.
|
||||||
|
"""
|
||||||
|
import json, os, urllib.request, urllib.error, sys
|
||||||
|
|
||||||
|
PORT = os.environ.get("PORT", "4000")
|
||||||
|
KEY = os.environ.get("LITELLM_MASTER_KEY", "")
|
||||||
|
if not KEY:
|
||||||
|
print("keepalive: LITELLM_MASTER_KEY not set", file=sys.stderr)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
fail = 0
|
||||||
|
|
||||||
|
# TTS warm (voxtral-tts) — $0.002/request (Tinfoil request-priced)
|
||||||
|
req = urllib.request.Request(
|
||||||
|
f"http://127.0.0.1:{PORT}/v1/audio/speech",
|
||||||
|
data=json.dumps({"model": "tinfoil/voxtral-tts", "input": "ok",
|
||||||
|
"voice": "casual_female"}).encode(),
|
||||||
|
method="POST",
|
||||||
|
headers={"Authorization": f"Bearer {KEY}", "Content-Type": "application/json"})
|
||||||
|
try:
|
||||||
|
urllib.request.urlopen(req, timeout=30)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"keepalive: TTS ping failed: {e}", file=sys.stderr)
|
||||||
|
fail = 1
|
||||||
|
|
||||||
|
# STT warm disabled 2026-10-11: $0.01/STT request × 6/hr ≈ $52/mo. Revisit only
|
||||||
|
# with a cheaper warm strategy.
|
||||||
|
sys.exit(fail)
|
||||||
Reference in new issue
Block a user