Skip to main content
A Mark Parker project — see more at markparker.me

S.T.A.R.K.

Speech and Text Advanced Recognition Kit: a modern, async Python framework for building voice assistants and natural language interfaces. Think FastAPI, but for speech instead of HTTP.

No need to build alone. See Get Involved below.

What Makes S.T.A.R.K. Different

  • 100% on-device: runs fully offline, no cloud dependencies. Your data stays yours. Doesn't stop working when internet connection is lost.
  • 4 required dependencies: pydantic, asyncer, anyio, numpy. Everything else (STT/TTS backends, NLP libraries) is opt-in. See Installation.
  • No AI required: pattern, phonetic, and fuzzy matching are deterministic, fast, and explainable. LLM integration is opt-in, not a dependency. See Fallback Command / LLM Integration and where this is headed in AI Agent Platform.
  • Phonetic and fuzzy matching: misspellings, accents, and cross-language name lookup, handled out of the box. See Tools.
  • Multilingual by design: including commands that mix languages mid-sentence. See Going Multilingual.
  • Nested contexts: multi-level menus, follow-ups, and stateful conversations, not just one-shot Q&A. See Commands Context.
  • Background commands & multiple responses: fire a task, keep listening, get notified as it progresses. See Sync vs Async Commands.
  • Assistant modes: active, waiting, inactive, sleeping (wake-word), explicit, and external-trigger modes, all configurable. See Running Your Assistant.
  • Modular by design: swap commands, processors, type parsers, or the entire IO layer (voice, text, a Telegram bot, your own). See How to Run.
  • STARK-PLACE: the extension ecosystem — installable packages and copy-paste examples built on S.T.A.R.K. Use what others made, or share your own.

Quick Start

pip install stark-engine

Full docs, including installation options and extras, at stark.markparker.me.

Hello, Stark!

import anyio
from stark import run, CommandsManager, Response
from stark.interfaces.vosk import VoskSpeechRecognizer
from stark.interfaces.silero import SileroSpeechSynthesizer

VOSK_MODEL_URL = '...'    # pick one: https://alphacephei.com/vosk/models
SILERO_MODEL_URL = '...'  # pick one: https://github.com/snakers4/silero-models

manager = CommandsManager()

@manager.new('hello')                                                       # 1
def hello_command() -> Response:
    return Response('Hello, Stark!')

async def main():
    recognizer = VoskSpeechRecognizer(model_url=VOSK_MODEL_URL)             # 2
    synthesizer = SileroSpeechSynthesizer(model_url=SILERO_MODEL_URL)
    await run(manager, recognizer, synthesizer)                            # 3

if __name__ == '__main__':
    anyio.run(main)
  1. Register a command with @manager.new(...). The string is the pattern STARK matches against what the user says.
  2. Pick a speech recognizer and synthesizer. STARK ships ready-to-use ones (offline Vosk + Silero here); see Default Speech Interfaces.
  3. run() wires everything together and starts listening. This is the whole assistant.

That's a complete, working voice assistant: no cloud, no API keys. Want text-only, no microphone needed? See How to Run.

Patterns parse parameters too

@manager.new('hello $name:NLWord')
def hello(name: str) -> Response:
    return Response(f'Hello, {name}!')

# "hello Mark" -> "Hello, Mark!"
# "hello Archie" -> "Hello, Archie!"

Patterns aren't fixed phrases. $name:NLWord extracts a parameter and hands it straight to your function, typed and ready to use. See Patterns.

One sentence, multiple commands

# user says: "turn off the light and play some music"

@manager.new('turn off the light')
def lights_off() -> Response:
    return Response('Lights off.')

@manager.new('play (some|the) music')
def play_music() -> Response:
    return Response('Playing music.')

# both commands fire from that single sentence, no extra wiring required

STARK's pattern matcher parses multiple commands out of one utterance on its own, even across two separate phrases stitched together. Most voice assistants still can't do that.

Background commands

import anyio
from stark.core import AsyncResponseHandler

timer_cancelled = False

@manager.new('start timer')
async def start_timer(handler: AsyncResponseHandler) -> Response:
    global timer_cancelled
    timer_cancelled = False
    await handler.respond(Response('Timer started.', commands=[stop_timer]))  # 1
    for percent in (25, 50, 75, 100):
        await anyio.sleep(15)                                                       # 2
        if timer_cancelled:
            return Response('Timer stopped.')                                  # 3
        await handler.respond(Response(f'Timer {percent}% done.'))
    return Response('Timer finished!')

@manager.new('stop timer', hidden=True)
async def stop_timer(handler: AsyncResponseHandler) -> Response:
    global timer_cancelled
    timer_cancelled = True
    handler.pop_context()
    return Response('Stopping timer...')
  1. Responds immediately and offers a stop timer command, scoped to this context only. It won't show up anywhere else.
  2. Keeps running in the background: four checkpoints, 15 seconds apart, a minute total. The assistant is free to handle other input the whole time.
  3. A plain global flag is enough to cancel it, no extra machinery needed. (If your command needs local state instead of a shared flag, define stop_timer inside start_timer so it closes over the same variables.)

This pattern, immediate response, async progress updates, an optional cancel command, is what powers timers, downloads, or any long-running task. See Sync vs Async Commands and Commands Context.

Powered by STARK

Archie, the voice assistant built for MajorDom, runs on STARK: nested contexts for device control, multilingual input, fully offline.

Community

  • 💬 Discussions: questions, feedback, showcase what you built. We need all the feedback we can get to make STARK better, so don't be afraid to be first, every thread starts empty.
  • 📦 STARK-PLACE: the extension ecosystem — installable packages (stark-ai, stark-triggers, stark-devtools) and copy-paste examples built on STARK
  • 🐛 Issues: found a bug?

License

The S.T.A.R.K. project is licensed under the PolyForm Noncommercial License 1.0.0. You're welcome to modify, contribute to the repository, create, and share forks. Just remember to attribute the original repository and its creator, abstain from commercial use, and retain the existing license.

Want to use STARK commercially, or talk about a partnership? Joint projects, hardware, contract development, anything related. Reach out via parker-industries.org/partnership. We're genuinely open to it.

Metadata

Release files for stark-engine 4.7.0

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

Source distribution (sdist)

Source distribution for stark-engine 4.7.0
File Size Uploaded
stark_engine-4.7.0.tar.gz 72.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for stark-engine 4.7.0
File Interpreter ABI Platform
stark_engine-4.7.0-py3-none-any.whl Python 3 none any Details

Total release size: 165.3 kB

Release files / stark_engine-4.7.0.tar.gz

Download URL stark_engine-4.7.0.tar.gz
Size 72.1 kB
Tags Source
SHA-256 checksum
How to use checksums
cde260353d54334f0956970b2c819f41289c658483a04ae6097d36397d37e2f6
BLAKE2b-256 checksum
How to use checksums
48d8c7f2cc0f82078c2ca49229a1b1fdfe6f03242ae0ae6af8154a2579d69408
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / stark_engine-4.7.0-py3-none-any.whl

Download URL stark_engine-4.7.0-py3-none-any.whl
Size 93.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
160adf0bf4ca5487de06214c4391bbe06eae560b2cf8dab1306f7d84bbb19bab
BLAKE2b-256 checksum
How to use checksums
ab38df94ef230b96f09e43571672a0a0013760173bc2c3c720334d5116ef6f73
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release history Release notifications | RSS feed

This release

4.7.0 This release

2 release files

4.6.1

2 release files

4.6.0

2 release files

4.5.5

2 release files

4.5.4

2 release files

4.5.3

2 release files

4.5.2

2 release files

4.5.1

2 release files

4.5.0

2 release files

4.4.1

2 release files

4.4.0

2 release files

4.3.1

2 release files

4.3.0

2 release files

4.2.2

2 release files

4.2.1

2 release files

4.2.0

2 release files

4.1.0

2 release files

4.0.14

2 release files

4.0.11

2 release files

4.0.10

2 release files

4.0.9

2 release files

4.0.8

2 release files

4.0.7

2 release files

4.0.6

2 release files

4.0.5

2 release files

4.0.4

2 release files

4.0.3

2 release files

4.0.2

2 release files

4.0.1

2 release files

4.0.0

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