HE SPEAKS?!??!?!?!?!

This commit is contained in:
2026-03-19 14:11:26 +02:00
parent 9eb2681de6
commit 216bb1586e
3 changed files with 668 additions and 14 deletions

View File

@@ -33,6 +33,7 @@ import time
import traceback
import wave
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
from urllib.error import URLError
from urllib.request import Request, urlopen
@@ -81,8 +82,13 @@ def _ollama_chat(user_text: str) -> str:
method="POST",
)
with urlopen(req, timeout=60) as resp:
data = json.loads(resp.read().decode("utf-8"))
try:
with urlopen(req, timeout=60) as resp:
data = json.loads(resp.read().decode("utf-8"))
except Exception as e:
# Let caller decide how to respond; include a useful hint in logs.
_log(f"Ollama request failed url={ollama_url!r} err={e!r}")
raise
msg = data.get("message") or {}
content = msg.get("content")
@@ -91,6 +97,19 @@ def _ollama_chat(user_text: str) -> str:
return content.strip()
def _short_err(e: BaseException) -> str:
s = str(e) or e.__class__.__name__
s = " ".join(s.split())
if len(s) > 240:
s = s[:240] + "..."
return s
def _ollama_down_reply() -> str:
# Keep it short and speakable.
return "My AI server isn't reachable right now. Please start Ollama on the computer, then try again."
def _wav_diagnostics(wav_bytes: bytes) -> dict:
"""Best-effort WAV parsing + signal stats for debugging mic capture."""
info: dict = {"bytes": len(wav_bytes)}
@@ -245,9 +264,16 @@ class Handler(BaseHTTPRequestHandler):
_json_response(self, 400, {"error": "Missing 'text'"})
return
_log(f"{client} /text prompt_chars={len(text)} prompt={text[:200]!r}")
reply = _ollama_chat(text)
_log(f"{client} /text ok reply_chars={len(reply)}")
_json_response(self, 200, {"reply": reply})
try:
reply = _ollama_chat(text)
_log(f"{client} /text ok reply_chars={len(reply)}")
_json_response(self, 200, {"reply": reply})
except URLError as e:
_log(f"{client} /text ollama_unreachable err={_short_err(e)!r}")
_json_response(self, 200, {"reply": _ollama_down_reply(), "ollama_ok": False, "ollama_error": _short_err(e)})
except ConnectionRefusedError as e:
_log(f"{client} /text ollama_refused err={_short_err(e)!r}")
_json_response(self, 200, {"reply": _ollama_down_reply(), "ollama_ok": False, "ollama_error": _short_err(e)})
return
if self.path == "/v1/chat/audio":
@@ -295,9 +321,24 @@ class Handler(BaseHTTPRequestHandler):
_json_response(self, 200, {"reply": "I didn't catch that. Could you say it again?", "text": ""})
return
_log(f"{client} /audio transcript_chars={len(transcript)} transcript={transcript[:200]!r}")
reply = _ollama_chat(transcript)
_log(f"{client} /audio ok text_chars={len(transcript)} reply_chars={len(reply)}")
_json_response(self, 200, {"reply": reply, "text": transcript})
try:
reply = _ollama_chat(transcript)
_log(f"{client} /audio ok text_chars={len(transcript)} reply_chars={len(reply)}")
_json_response(self, 200, {"reply": reply, "text": transcript})
except URLError as e:
_log(f"{client} /audio ollama_unreachable err={_short_err(e)!r}")
_json_response(
self,
200,
{"reply": _ollama_down_reply(), "text": transcript, "ollama_ok": False, "ollama_error": _short_err(e)},
)
except ConnectionRefusedError as e:
_log(f"{client} /audio ollama_refused err={_short_err(e)!r}")
_json_response(
self,
200,
{"reply": _ollama_down_reply(), "text": transcript, "ollama_ok": False, "ollama_error": _short_err(e)},
)
return
_json_response(self, 404, {"error": "Not found"})
@@ -332,6 +373,7 @@ def main():
+ " model="
+ os.environ.get("OLLAMA_MODEL", "phi3.5")
)
_log("Ollama health check: curl -s http://127.0.0.1:11434/api/tags | head")
if not _whisper.available():
_log("STT: faster-whisper not installed; /v1/chat/audio will return 503")
server.serve_forever()