@humain-voice/agent
v0.19.0-beta.1
Published
Browser SDK for HUMAIN Voice Agent calls, built on livekit-client
Readme
@humain-voice/agent
Join a HUMAIN Voice Agent call from the browser. Built on livekit-client, which you install
next to it. Your backend starts the session with @humain-voice/sdk/agent (or the Python or
Go SDK) and returns { server_url, participant_token }; this package never sees your API key.
npm install @humain-voice/agent livekit-clientimport { AgentSession } from '@humain-voice/agent'
const call = await AgentSession.start({
token: () => fetch('/agent-session', { method: 'POST' }).then((res) => res.json()),
clientTools: { lookup_order: async ({ order }) => ({ status: 'shipped', order }) },
onStatusChange: (status) => console.log('status:', status),
onMessage: (message) => message.final && console.log(`${message.role}: ${message.text}`),
onEnd: ({ reason }) => console.log('ended:', reason),
})
await call.end()The SDK plays the agent's audio. With LiveKit's React RoomAudioRenderer on call.room, pass
audio: false so it isn't played twice.
If the call ends before it is ready, start() rejects with AgentSessionError code
AGENT_UNAVAILABLE. When the agent sent a reason, it is in endReason (for example
concurrency_limit, credits_exhausted or account_disabled, which the agent reports while it
joins):
try {
await AgentSession.start(options)
} catch (err) {
if (err instanceof AgentSessionError && err.endReason === 'concurrency_limit') {
showBusyMessage()
}
}After the call ends, sendText(), interrupt(), updateContext() and setMicMuted() do nothing
and log a warning. An error thrown by one of your callbacks is logged with console.error and
doesn't affect the call.
Full reference: the Voice Agent browser SDK page in the HUMAIN Voice docs.
Development
bun install
bun test
bun run tsc
bun run lint
bun run buildChangelog
All notable changes to the HUMAIN Voice SDK (Python humain-voice, JS @humain-voice/sdk,
Go module) are documented here. The format follows Keep a Changelog,
and the project adheres to Semantic Versioning.
Versions are shared across all three language packages; a release tags
python/vX.Y.Z, javascript/vX.Y.Z, and golang/vX.Y.Z together. The Teams
release notification posts the section matching the tag's version, so keep the
top section here current before tagging.
[Unreleased]
[0.19.0-beta.2] - 2026-10-13
Fixed
- Python: the LiveKit TTS plugin now uses one request id per sentence in a
SynthesizeStream(kept across that sentence's retries). A single id for the whole stream made the server reject every sentence after the first withfingerprint_mismatch, so they were skipped as "billing authorization unavailable". Python-only release; the JavaScript and Go packages stay at 0.19.0-beta.1.
[0.19.0-beta.1] - 2026-10-12
Added
- Voice Agent sessions (beta). A server helper starts a call with
POST /agent/sessions:AgentClient.createSession()from@humain-voice/sdk/agent,AgentClient.create_session()/create_session_sync()fromhumain_voice.agent, andagent.NewClient(...).CreateSession()in Go. Each returns the session credentials (server_url,participant_token,session_id,expires_at,effective,limits) and raisesAgentError,AgentAuthError(401) orAgentRateLimitError(429); Go uses*agent.APIError,*agent.AuthErrorand*agent.RateLimitError. @humain-voice/agent, a browser package onlivekit-clientthat joins the call:AgentSession.start()with status, agent mode, transcripts, warnings, end reasons, client tools,sendText,interrupt,updateContext,setMicMuted,startAudioandend. It ships with the JavaScript release at the same version.- Python: the HUMAIN Voice LiveKit Agents plugin now ships in
humain-voiceaslivekit.plugins.humain, installed withpip install "humain-voice[livekit]"(livekit-agents>=1.3.9,<2). It replaceslivekit-plugins-sautech. Unset connection options fall back toHUMAIN_VOICE_API_URL,HUMAIN_VOICE_API_KEY, andHUMAIN_VOICE_API_PATH;SAUTECH_API_*still work with aDeprecationWarning.api_pathis now optional (defaults to/socket.io).
Removed
- Python: the deprecated
sautechimport path. Importhumain_voiceinstead.
[0.19.0-beta.0] - 2026-09-23
Added
BatchDiarization.D3(d3: 4 speakers or fewer, fastest) in the Python, JavaScript, and Go batch clients.BatchDiarization.Onnow resolves server-side tod3.BayanAuto(bayan_auto) in the batch, fast, and compatibility ASR model enums in all three languages. It is the default the service uses when no ASR model is sent.
Deprecated
NidaAr(nida_ar) andFastEn(fast_en) in every ASR model enum. The API keeps accepting them until 2026-12-31 and then returnsASR_MODEL_NOT_FOUND; useBayanArEnV2(bayan_cs_ar_en_v2), which serves the same model.
Changed
- Examples use
BayanArEnV2instead ofNidaAr.
[0.18.0] - 2026-08-30
Removed
- The TTS latency-eagerness option is removed from Python, JavaScript, and Go synthesis APIs and is no longer included in TTS request payloads.
Migration
- Remove the TTS latency-eagerness argument or option from synthesis calls. The platform owns synthesis latency behavior; no replacement option is required.
[0.17.3] - 2026-08-30
Added
- Python, JavaScript, and Go now export
TTS_INPUT_NOT_ALLOWEDandTTS_MODERATION_UNAVAILABLE(TTSInputNotAllowedandTTSModerationUnavailablein Go). - Both codes are classified as TTS-owned so structured guardrail failures terminate the matching synthesis request instead of leaving it pending.
[0.17.2] - 2026-08-28
Added
- TTS voice-list items can now include optional multilingual
profilemetadata in Python, JavaScript, and Go. A profile exposes its supported BCP-47languagesand shared speakergenderanddialect; physical voices remain the existing{id, label}shape.
Compatibility
- Existing callers remain source-compatible because
profileis optional. Invalid profile metadata is omitted without dropping the underlying voice.
[0.17.1] - 2026-08-26
Added
- Socket.IO errors now preserve the platform's
retry_after_seconds,data,reason, andretry_scopemetadata in Python, JavaScript, and Go. - The SDK exports the current realtime and batch API error codes, including credit, concurrency, session-limit, stream-expiry, and TTS limit failures.
Fixed
- Python Fast Transcription and TTS clients again accept the pre-0.17 positional
order
(api_url, api_path, api_key, ...). Keyword arguments remain recommended; legacy positional calls emit a deprecation warning.
[0.17.0] - 2026-08-09
Fixed
- Realtime STT
close()no longer loses the terminal transcript on long audio. All three clients (Python, JavaScript, Go) latched the session-final signal on the model's mid-utteranceis_speech_final. On audio containing a natural pause followed by more speech,close()then treated the stream as already final, skipped the final-flag handshake, and the terminal consolidated transcript was silently lost while the server session was abandoned to disconnect teardown. The session-final latch is now gated on the protocol-levelis_final(which the terminal response always carries), matching the diarization clients. Streams where the model endpointed early now pay one extra round-trip (~0.2 s measured) onclose(); short conversational streams are unaffected.
Changed
- Single Socket.IO path for every subsystem. All Socket.IO clients —
Realtime STT, Fast Transcription STT, TTS, and Diarization — now default
api_pathto/socket.io, the one path the platform serves for all subsystems.api_pathis now optional; pass it only to override for a self-hosted or proxied deployment. Constructing a client requires justapi_urlandapi_key, and the missing-argument error is now"api_url and api_key are required". Mirrored across Python, JavaScript, and Go via a shared default (DEFAULT_API_PATHin Python/JS,DefaultAPIPathin Go). The per-service path concept (/fast-transcription/socket.io,/tts/socket.io) is removed from the public contract. This is a backward-compatible change: callers that still passapi_pathcontinue to work unchanged.
Migration
- Remove any hardcoded per-service
api_path(e.g./fast-transcription/socket.ioor/tts/socket.io). The platform now serves every subsystem under/socket.io, which the SDK uses by default — callers pinning an old per-service path will fail to connect against the consolidated platform. Drop theapi_pathargument (recommended) or set it to/socket.io. - Endpoints that have not consolidated yet still require an explicit
api_path. In particular,sautech.humain.comdoes not serve the unprefixed/socket.ioroute — callers targeting it must passapi_path="/realtime/socket.io"./realtime/socket.ioalso still routes on environments that keep the prefixed route, so callers pinning it are unaffected until that route is retired.
[0.16.1-beta.2] - 2026-06-18
Changed
- Rebranded repository, package, and release documentation to HUMAIN Voice across the root, Python, JavaScript, and Go docs.
- Python, JavaScript, and Go examples, comments, and release metadata now use HUMAIN Voice wording instead of the old product name.
- The deprecated JavaScript compatibility package now emits
HUMAIN_VOICE_COMPAT_PACKAGE_DEPRECATEDand uses neutral compatibility wording in its warning message. - The legacy Python import path now emits
HumainVoiceCompatibilityWarningwith neutral compatibility wording. - Example package manifests now depend on the registry package names instead of local source paths that expose old package-directory names.
- Archived live-diarization planning docs were condensed so the public docs no longer preserve obsolete package paths.
[0.16.1-beta.1] - 2026-06-18
Added
- The Python SDK can now be imported as
humain_voice, matching thehumain-voicedistribution name. - The deprecated JavaScript compatibility package now wraps
@humain-voice/sdk. - PyPI and npm publish jobs now generate registry READMEs that append this root changelog, so package registry pages show release notes from the same source as the repository.
- The Go module now includes a checked-in
golang/CHANGELOG.mdmirror so tagged Go source includes release notes for Go consumers and pkg.go.dev.
Changed
- JavaScript examples now import
@humain-voice/sdk. - Go dependencies were refreshed and the Go CI/container baseline moved to Go 1.25.
- Go README and release notes no longer reference the non-existent
pkg/fasttranscriptioncompatibility wrapper.
Deprecated
- The legacy Python import path remains available for compatibility, but now
emits a deprecation warning. New code should import from
humain_voice. - The legacy JavaScript compatibility package remains available, but now emits
a deprecation warning. New code should import from
@humain-voice/sdk.
[0.16.1] - 2026-06-15
Changed
- We now recommend selecting the Arabic/English model with the unversioned
BayanArEnconstant instead of pinning toBayanArEnV1. The unversioned constant always maps to the current production model, so you automatically benefit from accuracy improvements without a code change. If you have a specific reason to stay on a fixed model version, theBayanArEnV1andBayanArEnV2constants remain available — nothing you ship today breaks.
[0.16.0] - 2026-06-11
⚠️ Breaking Changes
ASR and diarization model identifiers were renamed. The SDK constants used to select a model changed, so any code that selects a model must be updated before upgrading. Functionality is unchanged; these are the same models under new, brand-aligned names. Always select models through the SDK constants below rather than raw strings. Migration from 0.15.x:
| What you used (0.15.x) | New constant | | ---------------------- | -------------------------- | |
ASRModel.Ar_1|ASRModel.NidaAr| |ASRModel.Ar_2|ASRModel.BayanAr| |ASRModel.Ar_8k_1|ASRModel.NidaArTelephony| |ASRModel.ArEn|ASRModel.BayanArEn| |ASRModel.ArEn_1|ASRModel.BayanArEnV1| |ASRModel.ArEn_2|ASRModel.BayanArEnV2| |BatchDiarization.M1|BatchDiarization.D1| |BatchDiarization.M2|BatchDiarization.D2|Go callers use the package-prefixed forms (e.g.
ASRModelBayanArEnV1,BatchDiarizationD1). The old constants are no longer accepted — code using them will need to migrate to the new names.The batch transcription client no longer retries failed requests automatically. Previous versions retried internally (via
tenacityin Python andp-retryin JS). The client now makes exactly one HTTP call per operation and raises immediately on failure. Themax_retries/maxRetriesconstructor option is kept for compatibility but is now a no-op; passing a non-zero value emits a deprecation warning. If you depend on retries, you must now implement your own policy — every raised error exposesretryable,retry_after, andcapacity(for HTTP 429) so you can back off correctly.Error handling moved to a structured, typed exception hierarchy. Errors are now routed by error code to the client that owns them, and failures raise a specific exception type instead of a generic error. For batch transcription: HTTP 401 raises an auth error, HTTP 429 raises a rate-limit error (carrying
retry_afterandcapacity), and all other failures raise the baseBatchTranscribeError. The full server payload is available on the exception (payload/raw_body) for inspection. If you currently catch a broad error type or parse error strings, switch to catching the typed exceptions and reading their attributes.
Added
- Realtime speaker diarization over the streaming transport — receive per-speaker labels on transcripts as audio streams in.
- SRT and VTT subtitle helpers in Python, JS, and Go to turn transcription results directly into ready-to-use subtitle files.
[0.15.1] - 2026-05-13
Added
- Official Go SDK, at full feature parity with the Python and JavaScript packages: realtime speech-to-text, fast transcription, text-to-speech, and batch transcription, all over the same streaming transport. If you work in Go, you no longer need to call the platform API directly.
[0.15.0] - 2026-05-06
⚠️ Breaking Changes
- Client imports, event names, and configuration shapes changed. Internally the STT and TTS clients were rebuilt on a shared connection layer, and that shifted parts of the public surface — some import paths, streaming event names, and configuration option shapes are different. Review your client setup and event handlers against the updated examples when upgrading from 0.14.x.
disconnect_socketiowas removed. Connection teardown is now handled by the client itself; if you importeddisconnect_socketiodirectly, drop the call — closing the client cleans up the connection for you.
Changed
- STT and TTS clients now share a single connection and lifecycle, which makes connection handling more consistent and predictable across both. This is an internal change, but it is the reason for the surface adjustments noted above.
[0.14.5] - 2026-02-03
Added
- Run multiple concurrent streams from a single
RealtimeClient. You can now open several independent realtime sessions from one client instance instead of constructing a separate client per stream.
Changed
- Invalid ASR and TTS request fields are now rejected up front. The SDK validates request fields — including voice-reference inputs for TTS — before sending, so mistakes surface immediately as a clear client-side error rather than failing partway through a request. Requests that previously appeared to start before failing server-side may now raise a validation error sooner; fix the flagged field and the request proceeds as normal.
