CommunityCodierung & Entwicklunggithub.com

vietanhdev/edgevox

Offline-Sprachagenten-Framework für Roboter – Agents, Skills, Workflows, Sub-Sekunden-Sprachpipeline, 2D/3D-Simulation (IR-SIM + MuJoCo), 15 Sprachen, 56 Stimmen, ROS2-nativ. Läuft auf CPU/CUDA/Metal, keine Cloud.

Was ist edgevox?

EdgeVox ist ein vollständig lokales, reines Python-Framework für Sprachagenten in der Robotik, das ohne Cloud-Abhängigkeiten auskommt und auf CPU, CUDA oder Metal läuft. Es bietet eine durchgängige Sprachpipeline (Spracherkennung, Sprachverstehen, Sprachsynthese) mit unterstützten Backends wie faster-whisper, sherpa-onnx, Kokoro und Piper und deckt 15 Sprachen mit über 56 Stimmen ab. Das Framework ist modular aufgebaut und ermöglicht den Austausch jeder Komponente – STT, TTS, LLM, VAD, Agentenlogik – über ein Plugin-System und Hooks. Es enthält eine integrierte Agenten-Harness mit sechsstufiger Schleife, parallelem Dispatch, Barge-In-Mechanismus und Multi-Agenten-Unterstützung (Blackboard, BackgroundAgent, AgentPool). EdgeVox unterstützt ROS 2 nativ, bietet eine TUI, eine Web-Oberfläche (FastAPI + React), Simulationen über IR-SIM und MuJoCo sowie CLI-Tools für Setup und Betrieb. Entwickler können das Framework über ein agents-Paket mit streng typisierten Kontexten und Hooks nutzen und müssen lediglich `uv`, `ruff` und `pytest` als Werkzeuge einsetzen – zusätzliche Abhängigkeiten sind vor der Aufnahme lizenzrechtlich zu prüfen (MIT-Lizenz).

Funktioniert mit✓Claude Code~Codex CLI~Cursor
npx skills add vietanhdev/edgevox

Installed? Explore more Codierung & Entwicklung skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

EdgeVox — Claude Code-Regeln

Offline-Sprachagenten-Framework für Roboter. Reines Python-Paket, keine Cloud-Abhängigkeiten, läuft auf CPU/CUDA/Metal.

Projektstruktur

edgevox/
├── edgevox/            # Quellpaket
│   ├── audio/          # VAD, Mikrofonaufnahme, Wiedergabe
│   ├── stt/            # STT-Backends (faster-whisper, sherpa-onnx)
│   ├── llm/            # llama.cpp / Gemma-Integration
│   ├── tts/            # TTS-Backends (Kokoro, Piper, Supertonic, PyThaiTTS)
│   ├── core/           # Pipeline-Orchestrierung
│   ├── cli/            # CLI-Einstiegspunkte
│   ├── ui/             # TUI-Widgets
│   ├── integrations/   # ROS2-Bridge, etc.
│   ├── tui.py          # Haupt-TUI-App
│   └── setup_models.py # Modell-Downloader
│   ├── server/         # FastAPI-Web-UI + WebSocket-Server
├── webui/              # React-Frontend (Vite + Tailwind)
├── scripts/            # Dienstprogramme (Modell-Upload, etc.)
├── voices/             # Sprachkonfigurationsdateien
├── docs/               # Projektdokumentation
├── website/            # VitePress-Seite
└── pyproject.toml

Einstiegspunkte (siehe pyproject.toml):

  • edgevox → edgevox.tui:main (TUI-Standard, --web-ui für Web, --simple-ui für CLI)
  • edgevox-cli → edgevox.cli.main:main
  • edgevox-setup → edgevox.setup_models:main

Unterstützte Sprachen und Backends

SpracheSTTTTS
Englisch, Französisch, Spanisch, usw.faster-whisperKokoro
Vietnamesischsherpa-onnx (zipformer)Piper
Deutsch, Russisch, Arabisch, Indonesischfaster-whisperPiper
Koreanischfaster-whisperSupertonic
Thailändischfaster-whisperPyThaiTTS

Modelle werden auf nrl-ai/edgevox-models (HuggingFace) gehostet, mit Fallback auf die ursprünglichen Repositories.

Architekturprinzipien

  • Plug-and-Play, standardmäßig anpassbar. Jede Komponente – STT-Backend, TTS-Backend, LLM, VAD, Agent-Schleifenverhalten, Pipeline-Stufe, Tool, Skill, Hook – muss austauschbar sein, ohne Kerncode zu bearbeiten. Bevorzuge Protokolle, Registries und Dekorateure gegenüber hartcodierten Pfaden. Neues Verhalten landet als neues Plugin/Hook/Backend, nicht als Patch in einem bestehenden Modul. Wenn du dich dabei ertappst, für einen bestimmten Anwendungsfall eine Bedingung zum Kern hinzuzufügen, tritt einen Schritt zurück und extrahiere sie stattdessen in einen Injektionspunkt.

Agenten-Harness-Architektur

Die Agenten-Harness (edgevox/agents/ + edgevox/llm/hooks_slm.py + edgevox/llm/tool_parsers/) ist vollständig unter docs/documentation/ dokumentiert:

  • agent-loop.md – die sechs-Feuerpunkte-Schleife, paralleler Dispatch, Handoff-Short-Circuit.
  • hooks.md – Hook-Autoren-Vertrag, eingebaute Hooks, Reihenfolgeregeln.
  • memory.md – MemoryStore / SessionStore / NotesFile / Compactor.
  • interrupt.md – Barge-In-Signale + Cancel-Token-Verbindungen.
  • multiagent.md – Blackboard, BackgroundAgent, AgentPool.
  • tool-calling.md – Parser-Kette + Grammar-beschränktes Decoding (Fahrplan).

Harness-Regeln

  • Typisierte AgentContext-Felder (ctx.tool_registry, ctx.llm, ctx.interrupt, ctx.memory, ctx.artifacts, ctx.blackboard) sind die öffentliche Schnittstelle. ctx.state ist nur für Benutzer gedacht – Framework-Code darf dort keine magischen Schlüssel schreiben.
  • Hook-eigener Zustand lebt unter ctx.hook_state[id(self)]. Die Schlüsselung mit id(self) stellt sicher, dass zwei Instanzen derselben Hook-Klasse keinen Zustand teilen.
  • Barge-In ist durchsetzbar, nicht nur ein Hinweis. Jeder LLM.complete-Aufruf übergibt ctx.interrupt.cancel_token über stop_event=…, sodass stopping_criteria von llama-cpp die Generierung innerhalb eines Dekodierschritts tatsächlich anhält.
  • Token-genaue Token-Anzahlen. estimate_tokens(messages, llm) und LLM.count_tokens ersetzen die Heuristik chars // 4, wenn ein LLM verfügbar ist. Erforderlich für korrekte Kontextfenster-Entscheidungen bei CJK / Vietnamesisch / Thailändisch.
  • Tool-Call-Parsing läuft roh zuerst. parse_tool_calls_from_content versucht Detektoren gegen den rohen Inhalt, bevor -Blöcke entfernt werden – Qwen3 gibt Tool-Calls innerhalb von Reasoning-Blöcken aus (siehe llama.cpp#20837).
  • Voreingestellte Parser werden beim Laden validiert. resolve_preset(slug) stellt sicher, dass jeder Name in tool_call_parsers=(...) ein registrierter Detektor ist; ein Tippfehler führt zu einem lauten Fehler, anstatt die Erkennung stillschweigend zu deaktivieren.
  • Vom Modell ausgegebene Tool-Call-IDs sind rundum gültig. Das [TOOL_CALLS]-Format von Mistral trägt eine 9-stellige ID, die die folgende role="tool"-Nachricht wiederverwenden muss. ToolCallItem.id leitet diese durch die Parser-Kette und die Agenten-Schleife.

Bevorzugte Import-Oberflächen

  • Agenten-Framework: from edgevox.agents import LLMAgent, AgentContext, Session, Handoff, ...
  • Eingebaute Hooks: from edgevox.agents.hooks_builtin import MemoryInjectionHook, TokenBudgetHook, ...
  • SLM-Härtung: from edgevox.llm.hooks_slm import default_slm_hooks
  • Speicher: from edgevox.agents.memory import JSONMemoryStore, NotesFile, Compactor, estimate_tokens
  • Multi-Agent: from edgevox.agents.multiagent import Blackboard, BackgroundAgent, AgentPool
  • Unterbrechung: from edgevox.agents.interrupt import InterruptController, InterruptPolicy, EnergyBargeInWatcher

Vermeide es, in private Module oder _agent_harness.py direkt zu greifen.

Codierungsregeln

  • Python ≥ 3.10. Verwende moderne Syntax (X | Y-Unions, match, dict[str, int]).
  • Formatiere und lint mit ruff. Zeilenlänge 120. Führe ruff format und dann ruff check --fix aus.
  • Keine abschließenden Zusammenfassungen in Code-Kommentaren. Kommentiere das Warum, nicht das Was.
  • Typannotationen bei öffentlichen Funktionen. Interne Helfer dürfen sie bei Offensichtlichkeit weglassen.
  • Keine Prints in Bibliothekscode. Verwende rich/textual für benutzergerichtete Ausgabe, logging für Diagnose.
  • Importe stehen am Anfang der Datei. Verschiebe einen Import nur dann innerhalb einer Funktion, wenn etwas Konkretes dazu zwingt – circular-import-Break, optionale/schwere Abhängigkeit hinter einer Capability-Prüfung oder Lazy-Load zur Reduzierung der CLI-Startlatenz. Bequemlichkeit oder „es wird nur an einer Stelle verwendet“ ist kein Grund; verschiebe ihn nach oben.
  • Keine neuen Abhängigkeiten auf oberster Ebene ohne Grund. Bevorzuge die Standardbibliothek. Wenn du eine hinzufügen musst, aktualisiere pyproject.toml.
  • Hardware-bewusste Codepfade müssen sich elegant verschlechtern – CUDA/Metal/CPU-Fallbacks, nie einen Absturz bei fehlendem Beschleuniger verursachen.
  • Commite niemals Modell-Dateien (.gguf, .onnx, .bin, Gewichte). Sie leben unter models/, das in .gitignore ist.

Audio- / Modell-Konventionen

  • Abtastrate: 16 kHz mono int16 für Aufnahme und STT-Eingabe.
  • TTS-Ausgabe: mit sounddevice auf die Geräterate neu abtasten.
  • VAD-Frame-Größe: 32 ms (512 Samples @ 16 kHz).
  • Latenzbudget: STT < 0,5 s, LLM erstes Token < 0,4 s, TTS erster Chunk < 0,1 s auf RTX 3080.
  • Behandle die Streaming-Pipeline als Vertrag: Führe keine blockierenden Aufrufe ein, die die Ereignisschleife anhalten.

Werkzeuge

  • uv für die Paketverwaltung. Verwende uv pip install / uv venv anstelle von nacktem pip / python -m venv. Siehe https://docs.astral.sh/uv/.
  • pre-commit führt ruff (Lint + Format), gitleaks und Standard-Hygiene-Hooks aus. Installiere einmalig mit pre-commit install.
  • gitleaks durchsucht bei jedem Commit nach Geheimnissen. Wenn ein Befund ein False-Positive ist, whiteliste ihn in .gitleaks.toml mit einem Kommentar, der erklärt, warum – lösche den Befund nicht.
  • pytest für Tests (pytest, asyncio-Modus = auto). Tests befinden sich unter tests/.

Workflow-Erwartungen

  • Lese Dateien, bevor du sie bearbeitest. Schlage keine Änderungen an Code vor, den du dir nicht angesehen hast.
  • Führe ruff format + ruff check --fix aus, bevor du eine Aufgabe für erledigt erklärst.
  • Umgehe keine Hooks (--no-verify) – behebe das zugrunde liegende Problem.
  • Füge dich selbst oder Claude nicht als Commit-Autor / Co-Autor hinzu. Insbesondere: kein Co-Authored-By: Claude …-Trailer, kein 🤖 Generiert mit Claude Code-Footer – Commit-Nachrichten enden nach dem Body, nichts weiter.
  • Bevorzuge das Bearbeiten vorhandener Dateien gegenüber dem Erstellen neuer Dateien; erstelle keine README/Dokumentationsdateien, es sei denn, du wirst darum gebeten.
  • Wenn eine Änderung die Streaming-Pipeline betrifft, notiere die Latenzauswirkungen manuell in der PR-Beschreibung.
  • Bevorzuge Mermaid-Diagramme gegenüber ASCII-Kunst in jedem Markdown-Dokument (docs/, website/, README.md, PR-Beschreibungen). GitHub und VitePress rendern mermaid-Codeblöcke nativ; handgezeichnete Box-und-Linie-ASCII ist schwerer zu lesen, unmöglich sauber zu bearbeiten und bricht bei Änderungen der nichtproportionalen Schriftart. Die einzigen akzeptablen ASCII-Diagramme sind Verzeichnisbäume (├── / └──) – die bleiben wie sie sind.

Dokumentation schreiben (docs/, README.md, website/)

  • Zitiere Mermaid-Beschriftungen immer in Anführungszeichen, die (, ), @, :, ,, &, <br/> oder andere Satzzeichen als Buchstaben, Ziffern, _ und - enthalten. Verwende ["foo(args)"] für Knoten und -->|"@tool call"| für Kantenbeschriftungen. Unzitierte Klammern innerhalb von [...] oder |...| bringen den Flussdiagramm-Parser zum Absturz – die Seite lädt noch, aber das Diagramm verschwindet. Nachdem du einen Mermaid-Block bearbeitet hast, öffne die Seite lokal (npm run docs:dev) und bestätige, dass keine Parse error on line N-Einträge in der Browserkonsole erscheinen. Der Fehler ist in der Quellcode-Überprüfung unsichtbar.
  • Teste Dokumentation im Dev-Server, bevor du sie für erledigt erklärst. npm run docs:dev (VitePress auf :5173) fängt Mermaid-Parse-Fehler, kaputte Links und tote Anker, die die Markdown-Quelle verbirgt. Bei visuellen Änderungen (neue Diagramme, Layout, Hero, Sidebar) erstelle einen Playwright-Screenshot der betroffenen Seite, damit der Reviewer Regressionen erkennen kann, ohne den Server hochzufahren.
  • Cross-Page-Links sind root-absolut, ohne Erweiterung – /documentation/hooks, niemals ./hooks.md oder hooks (letzteres löst unter cleanUrls: true falsch auf). Mermaid-Knoten-Ziel-Links folgen derselben Konvention.
  • Sidebar-Registrierung ist obligatorisch. Eine neue Seite unter docs/documentation/ ist unsichtbar, bis sie im sidebar-Block in docs/.vitepress/config.ts hinzugefügt wird. Aktualisiere beide gleichzeitig.

Was NICHT zu tun ist

  • Füge keine Cloud-API-Aufrufe oder Telemetrie hinzu. EdgeVox ist offline-first.
  • Führe keine GPL-lizenzierten Abhängigkeiten ein (Projekt ist MIT).
  • Lizenzprüfung ist obligatorisch, bevor eine neue Abhängigkeit hinzugefügt wird. Überprüfe die tatsächliche Lizenz des Pakets (PyPI/GitHub/Dokumentation – nicht nur eine Vermutung) und dokumentiere das Ergebnis inline in pyproject.toml neben der Abhängigkeit (z.B. # MIT / # LGPL-3 – dynamisch gelinkt, kompatibel). Copyleft-Lizenzen, die abgelehnt werden müssen: GPL-2/3, AGPL, SSPL. LGPL ist nur für reine dynamische Link-Bibliotheken akzeptabel (PySide6, Qt Multimedia, rlottie). CC-BY-SA ist für Assets akzeptabel (SVG-Figurensätze usw.), niemals für Abhängigkeiten auf Quellcode-Ebene. Im Zweifelsfall wähle eine permissive Alternative oder markiere es zur Diskussion.
  • Commite nicht dist/, build/, *.egg-info/, Modell-Gewichte oder Aufnahmen.
  • Füge keine spekulativen Abstraktionen oder „Zukunftssicherung“ hinzu, die über die Anforderungen der Aufgabe hinausgehen.

Verwandte Skills