zeekay 9631675dff Publish both architectures, not just the pool's own
The lab runs amd64 (evo) and arm64 (spark), and this image was cut
linux/amd64 only — so it deploys on half the fleet and an arm64 node
cannot pull it at all.

`docker build` + `docker push` cannot carry two platforms: the daemon's
built-in builder builds one, and a manifest list cannot be loaded into a
local daemon at all. So the publish runs on a docker-container builder and
pushes straight to the registry, with binfmt for the emulated arm64 leg.
Every native dependency in uv.lock has an aarch64 wheel, so the leg
resolves rather than compiling from source.

The two gates keep the daemon they had: both setups sit BELOW them, so the
suites still build and run this arch natively instead of testing a QEMU
translation of the binary.
2026-09-05 19:07:42 -07:00

speech

CPU speech for the Hanzo platform: STT (faster-whisper, CTranslate2 int8) and TTS (kokoro-onnx, 82M) behind one OpenAI-shaped surface.

Routes

  • POST /v1/audio/transcriptions — multipart file + model (+language, response_format) → {"text": …}
  • POST /v1/audio/speech — {model, input, voice, response_format} → audio bytes (mp3 default, wav native)
  • GET /v1/models, GET /healthz

Trust model

No auth of its own, in-cluster only. api.hanzo.ai fronts it through the ai plane, which authenticates and meters every caller — a provider row pointing at http://speech.hanzo.svc/v1 is the whole integration. Weights bake into the image at build; the container boots without the network.

Run

uv sync && uv run uvicorn main:app --port 8000

Phase 2 is /v1/realtime: websocket full-duplex (silero-vad segmentation, partial transcripts, kokoro frames, barge-in) plus camera-frame relay into the multimodal models.

S
Description
CPU speech service: STT (faster-whisper) + TTS (kokoro) behind api.hanzo.ai /v1/audio
Readme Apache-2.0
361 KiB
Languages
Go 98.8%
Dockerfile 1.2%