Skip to main content
stimm

Optimistic VUI. One agent talks fast, one agent thinks deep, both collaborate in real-time.

Tests License Python LiveKit Documentation Ruff Bandit

Stimm is an Optimistic VUI runtime built on livekit-agents. It brings optimistic UI thinking to voice: acknowledge early, speak early, and keep reasoning in parallel.

Use it when you want a voice agent that feels immediate without giving up tool use, planning, or deeper supervision.

Why Stimm

  • Optimistic VUI for speech-first products: fast acknowledgement, progressive response, safe supervisor steering.
  • Low-latency conversational loop (VAD -> STT -> fast LLM -> TTS).
  • Dual-agent runtime: one agent handles the live turn, one agent reasons in the background.
  • Typed protocol for Python and TypeScript supervisors.
  • Runtime-safe provider contract and generated provider catalog from LiveKit docs.
  • Wizard-first onboarding flow: discover providers first, install extras second.

What Is Optimistic VUI?

Optimistic VUI is the voice equivalent of optimistic UI.

Instead of making the user wait for the entire reasoning chain to complete, the system starts behaving usefully as soon as it has enough confidence to move the conversation forward.

  • Acknowledge the user immediately.
  • Start speaking as early as possible.
  • Keep the response interruptible and steerable.
  • Let deeper reasoning continue in parallel.

That is the core idea behind Stimm: one agent talks fast, one agent thinks deep.

Use Cases

  • Customer support voice agents that must answer quickly while deeper retrieval or tool calls continue in the background.
  • Phone and SIP assistants that need to feel responsive before business logic fully resolves.
  • Realtime copilots where speech should start early, but supervision, correction, and orchestration still matter.
  • Embedded or kiosk voice experiences where perceived latency is more important than raw model latency.

Architecture

flowchart LR
    U[User speech] --> V[VoiceAgent]
    V --> P1[VAD + STT]
    P1 --> F[Fast LLM]
    F --> B[Pre-TTS buffering]
    B --> T[TTS]
    T --> A[Spoken response]

    V <--> C[StimmProtocol]
    C <--> S[Supervisor]
    S --> R[Reasoning, tools, planning]
    R --> S
    S --> I[Steering instructions]
    I --> V

The VoiceAgent owns the live turn. The Supervisor watches the transcript, reasons asynchronously, and can steer the conversation without blocking the first response.

Install

# 1) Core package only
pip install stimm

# 2) Install only the providers you selected
pip install stimm[deepgram,openai]

# Optional: install all runtime-supported providers
pip install stimm[all]

# TypeScript supervisor client
npm install @stimm/protocol

Plugin dependencies are installed in the integrator app environment. Stimm does not vendor provider plugin code inside its wheel.

Quick Start

Voice Agent (Python)

from livekit.agents import AgentServer, AgentSession, JobContext, cli
from livekit.plugins import deepgram, openai, silero
from stimm import VoiceAgent

server = AgentServer()


@server.rtc_session()
async def entrypoint(ctx: JobContext) -> None:
    agent = VoiceAgent(
        stt=deepgram.STT(),
        tts=openai.TTS(),
        vad=silero.VAD.load(),
        fast_llm=openai.LLM(model="gpt-4o-mini"),
        buffering_level="MEDIUM",
        mode="hybrid",
        instructions="You are a helpful voice assistant.",
    )
    await ctx.connect()
    await AgentSession().start(agent=agent, room=ctx.room)


if __name__ == "__main__":
    cli.run_app(server)

Supervisor (Python)

from stimm import Supervisor, TranscriptMessage


class MySupervisor(Supervisor):
    async def on_transcript(self, msg: TranscriptMessage):
        if not msg.partial:
            result = await my_big_llm.process(msg.text)
            await self.instruct(result.text, speak=True)

Supervisor (TypeScript)

import { StimmSupervisorClient } from "@stimm/protocol";

const client = new StimmSupervisorClient({
  livekitUrl: "ws://localhost:7880",
  token: supervisorToken,
});

client.on("transcript", async (msg) => {
  if (!msg.partial) {
    const result = await myAgent.process(msg.text);
    await client.instruct({ text: result, speak: true, priority: "normal" });
  }
});

await client.connect();

Wizard-First Provider Flow

For onboarding UIs, use the catalog API to display providers and parameters, then derive extras from the user selection:

from stimm import extras_install_command, get_provider_catalog

catalog = get_provider_catalog()
cmd = extras_install_command(stt="deepgram", tts="openai", llm="azure-openai")
print(cmd)  # pip install stimm[deepgram,openai]

After extras installation, restart the Python process before instantiating LiveKit plugin classes.

Dual-Agent Architecture

Stimm is fundamentally built around two cooperating agents:

  • VoiceAgent: optimized for low-latency spoken interaction.
  • Supervisor: optimized for deeper reasoning, planning, and tool orchestration.

They exchange typed protocol messages over LiveKit data channels, allowing fast turn-by-turn response while retaining high-level control and context.

Component Role
VoiceAgent Handles live turn-by-turn speech interaction
Supervisor Watches transcript and steers behavior asynchronously
StimmProtocol Structured messages over LiveKit data channels

Runtime Modes

  • autonomous: the voice agent acts independently.
  • relay: the voice agent only speaks supervisor instructions.
  • hybrid (default): autonomous first response with supervisor steering.

Supervisor-Provided Speech

instruct() hands text to the voice agent's LLM (hybrid mode) or says it one message at a time (relay mode). When the supervisor already has the exact words, speak() streams them into the voice, in any mode:

class MySupervisor(Supervisor):
    async def on_transcript(self, msg: TranscriptMessage):
        if not msg.partial:
            played = await self.speak(my_backend.stream_sentences(msg.text))
  • Chunks are spoken as they arrive, as one utterance: a barge-in stops all of it.
  • speak() returns False when the user cut it off. The rest of the stream is then never read, and an async generator is closed, which cancels the backend call it wraps.
  • A supervisor that runs in the agent's own job skips the data channel: supervisor.attach(voice_agent) instead of connect(url, token).
  • VoiceAgent.on_supervisor_speech(handle) runs when such an utterance starts.
  • TypeScript supervisors get the same client.speak(...).

Pre-TTS Buffering

  • NONE: send tokens immediately.
  • LOW: buffer until word completion.
  • MEDIUM (default): buffer until 4 words or punctuation.
  • HIGH: buffer until punctuation.

These levels let you choose where to sit between raw latency and cleaner spoken delivery.

Developer Workflow

# Install dev dependencies
pip install -e ".[dev]"

# Local infra
docker compose up -d

# Build local artifacts + sync providers + validate runtime contract
bash scripts/dev_build.sh

# Tests / lint
pytest
ruff check src/ tests/

# Catalog/contract checks (CI-equivalent)
python3 scripts/sync_livekit_plugins.py --check
python3 scripts/validate_runtime_contract.py --import-check

scripts/dev_build.sh is the single local command to rebuild protocol artifacts and provider metadata from the LiveKit source of truth.

Documentation

License

MIT

Metadata

Release files for stimm 0.1.14

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for stimm 0.1.14
File Size Uploaded
stimm-0.1.14.tar.gz 648.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for stimm 0.1.14
File Interpreter ABI Platform
stimm-0.1.14-py3-none-any.whl Python 3 none any Details

Total release size: 697.8 kB

Release files / stimm-0.1.14.tar.gz

Download URL stimm-0.1.14.tar.gz
Size 648.3 kB
Tags Source
SHA-256 checksum
How to use checksums
c877a5c8ff93eaada1899e33529762b56e6160ce13289e521788bbf54cc294c4
BLAKE2b-256 checksum
How to use checksums
aa4e418ff41988168a5208580e99cd271ff13feaa7ce6f606b90c222e97757c7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 7, 2026.

Transparency log

Release files / stimm-0.1.14-py3-none-any.whl

Download URL stimm-0.1.14-py3-none-any.whl
Size 49.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d0bb846624e3da81af93201a0e5e177ac8fda35bb61e44977128116296d7244c
BLAKE2b-256 checksum
How to use checksums
adefe829efb1fced900e736be31a1fe340ae15b5a616d8ebcf8a17c0ff686d5f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 7, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.14 This release

2 release files

0.1.2

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page