Who is speaking? Speaker embeddings (ERes2Net, 192-d, on CPU, no cgo) and cosine scores as a local CLI, a loopback server for heypoul, or a stateless container. Audio in, numbers out, nothing stored.
pks-agent-speaker embed|score|serve|runtime|health|version [flags]$ pks model speaker-eres2net init && pks-agent-speaker runtime --checkFetch the model through pks, fetch the sherpa-onnx libraries, load once and time an embedding
$ pks-agent-speaker embed me.wavOne 192-dimensional unit vector for a 16 kHz mono clip
$ pks-agent-speaker embed meeting.wav --window 3A vector per 3 s window, silence skipped — the ctx catalog scheme
$ pks-agent-speaker score me.wav them.wavCosine between two clips (or two JSON vectors)
$ pks-agent-speaker serve --localLoopback API, port in %LOCALAPPDATA%\pks-speaker\port, no auth, for tools on this machine
$ docker run --rm -p 8080:8080 -e SPEAKER_API_KEYS=k1 registry.agentics.dk/agentics/pks-agent-speaker:latestThe hosted shape: same API behind a bearer key, model and libraries baked in
The calculator in the voice family. heypoul hears a meeting; this turns a clip into a 192-dimensional voiceprint and says how close two voiceprints are; pks-cli remembers who is who; pks-agent-notch asks you when nobody knows.
serve --local send nothing anywhere. A voiceprint is
biometric data; the hosted container exists for machines that cannot run the model and
keeps nothing.irm https://agentics.dk/install/pks-agent-speaker.ps1 | iex
curl -fsSL https://agentics.dk/install/pks-agent-speaker.sh | sh
Then the two downloads, 26 MB + 10 MB, both pinned by SHA-256:
pks model speaker-eres2net init # the ONNX model → ~/.pks-cli/models/speaker-eres2net/
pks-agent-speaker runtime # the sherpa-onnx libraries for this OS → <model dir>/runtime/<os>-<arch>/
pks-agent-speaker runtime --check # verifies hashes, loads, embeds a test tone
Without pks: pks-agent-speaker runtime --with-model. On Windows, if --check reports
"a dependency is missing", install the Visual C++ Redistributable 2015–2022 x64 (onnxruntime.dll
needs it).
| Command | Does |
|---|---|
embed <clip.wav> [--window S --hop S --min-len S --min-rms F] | JSON with embedding (or windows), unit-length float32 |
score <a> <b> [--mean mean.json] | cosine between two clips or vectors; --mean centres both first |
serve --local | loopback HTTP API, port file, no auth |
serve --listen :8080 | hosted; needs SPEAKER_API_KEYS=k1,k2 |
runtime [--check] [--with-model] [--force] | fetch or verify the libraries (and the model) |
health [--url] | exit 0 when a server answers /api/health |
version | the version |
Every command takes --model-dir / --runtime-dir (or SPEAKER_MODEL_DIR /
SPEAKER_RUNTIME_DIR). Audio is 16-bit PCM mono 16 kHz; nothing resamples in v0.1.
GET /api/health · POST /v1/embed (audio/wav or raw s16le; ?window=3 for windows) ·
POST /v1/score ({a,b} or {embedding,candidates}, optional mean). Full detail, error
codes and the note on centring (the catalog's thresholds are measured after subtracting
a mean this stateless service does not have) are in the repo's docs/protocol.md.
pks exec pks-agent-speaker -- embed me.wav works: the discovery manifest declares no
capabilities, so pks runs it as-is. The model is a pks catalog entry (speaker-eres2net)
rather than a capability, because it is a file, not a credential.