Documentation
¶
Overview ¶
Package voicein is the host-side voice-dictation bridge: capture the host microphone, transcribe it locally (whisper.cpp — no cloud, no subscription, audio never leaves the machine), and hand the transcript back to the caller, which injects it into a contained agent's prompt. The container never gets audio access — only the transcribed TEXT crosses into the island — so this stays on the deny-all containment posture and works in exactly the tmux+ssh/remote case where Claude Code's native `/voice` explicitly gives up.
Everything here is host-local and dependency-light: a recorder that writes a 16 kHz mono WAV (sox `rec`, or `ffmpeg`/`arecord` if already present) and a whisper.cpp CLI + a small English model (`base.en`, ~142 MB). `dejima voice install` provisions both; `Check` reports readiness so the TUI can nudge.
Index ¶
- Constants
- Variables
- func Dir() (string, error)
- func Install(ctx context.Context, plan InstallPlan, out io.Writer) error
- func ModelPath() (string, error)
- func Record(ctx context.Context, wav string) error
- func Supported() bool
- func Transcribe(ctx context.Context, wav string) (string, error)
- type InstallPlan
- type Status
Constants ¶
const DefaultModel = "ggml-base.en.bin"
DefaultModel is the whisper.cpp model we install by default: the English-only base model — ~142 MB, fast on CPU, Metal-accelerated on Apple Silicon, and accurate enough for dictating a message. Larger models (small.en, medium.en) can be dropped alongside and selected via DEJIMA_VOICE_MODEL.
Variables ¶
var ( // ErrUnsupported is returned when the host platform has no supported mic // capture path (Windows, for now). Callers degrade with a friendly hint. ErrUnsupported = errors.New("voice dictation isn't supported on this host platform yet") // ErrNotInstalled means the whisper.cpp CLI, a recorder, or the model is // missing — `dejima voice install` provisions them. ErrNotInstalled = errors.New("voice dictation isn't set up — run `dejima voice install`") // ErrNoSpeech means the recording transcribed to nothing (silence / no mic // input) — not an error to dump, a "say something" nudge. ErrNoSpeech = errors.New("no speech detected") )
Functions ¶
func Install ¶
Install provisions the plan: brew-installs the missing tools, then downloads the model. Progress/log lines are written to out. Idempotent (an Empty plan is a no-op). brew is required for the package step (macOS / Linuxbrew); without it the caller should print the manual package names.
func ModelPath ¶
ModelPath resolves the selected model file. DEJIMA_VOICE_MODEL overrides the name (a bare name resolves under the model dir; an absolute path is used as-is, so an operator can point at a model they manage).
func Record ¶
Record captures the host microphone to a 16 kHz mono WAV at wav, recording until ctx is cancelled — the push-to-talk model: the caller cancels ctx when the user ends the utterance (e.g. presses Enter / releases the key). It stops the recorder with SIGINT first so the tool writes a valid WAV header, only force-killing if it doesn't exit within stopGrace.
ErrUnsupported on a platform with no recorder path; ErrNotInstalled when a supported platform simply lacks the tool (install provisions sox `rec`).
Types ¶
type InstallPlan ¶
type InstallPlan struct {
BrewPackages []string // missing tools to `brew install` (whisper-cpp, sox)
ModelURL string // "" when the model is already present
ModelDest string
ModelSHA256 string // expected checksum of the download; "" = unverified (custom model)
}
InstallPlan is what `voice install` will do — computed from what's missing so a re-run is a clean no-op and we never reinstall a present tool.
func PlanInstall ¶
func PlanInstall(st Status) InstallPlan
PlanInstall derives the install steps from a Status: only the missing brew packages, and the model download only when absent. Pure — unit-tested.
func (InstallPlan) Empty ¶
func (p InstallPlan) Empty() bool
Empty reports whether there's nothing left to do.
type Status ¶
type Status struct {
Supported bool
WhisperBin string // resolved whisper.cpp CLI, "" if missing
Recorder string // resolved mic recorder, "" if missing
ModelPath string
ModelPresent bool
}
Status is the readiness of the voice-dictation toolchain — the seam the CLI's `voice status` and the TUI tip/settings read.
func Check ¶
func Check() Status
Check probes the toolchain without recording. Cheap; safe to call often (the TUI tip uses it to decide rotation weight).