EdgeVox — Regras do Claude Code

Framework de agente de voz offline para robôs — agentes, habilidades, fluxos de trabalho, pipeline de voz de submilissegundos, simulação 2D/3D (IR-SIM + MuJoCo), 15 idiomas, 56 vozes, nativo ROS2. Funciona em CPU/CUDA/Metal, sem nuvem.

O que é EdgeVox — Regras do Claude Code?

EdgeVox é um framework de agente de voz offline completo, otimizado para robôs, com suporte a 15 idiomas e 56 vozes. Totalmente baseado em Python puro, ele opera inteiramente offline (CPU, CUDA ou Metal da Apple) e elimina dependências de nuvem, oferecendo baixa latência com pipeline de voz submilissegundo. O framework integra VAD, STT (faster-whisper e sherpa-onnx), LLM (llama.cpp/Gemma), TTS (Kokoro, Piper, Supertonic, PyThaiTTS) e um sistema flexível de agentes com loops de execução, hooks e memória. Suporta simulação 2D/3D via IR-SIM e MuJoCo, é nativo ROS2 e permite automação local completa. O código é modular e extensível: todos os componentes (backends de STT/TTS, LLM, VAD, hooks, ferramentas) são intercambiáveis por meio de protocolos e registros, sem necessidade de editar o código principal. Inclui CLI (simples, TUI e web UI), React frontend, e documentação detalhada sobre loop de agente, hooks, memória, interrupção e multiagente. A licença é MIT.

Funciona com✓Claude Code~Codex CLI~Cursor
npx skills add vietanhdev/edgevox

Installed? Explore more Programação e Desenvolvimento skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

O que EdgeVox — Regras do Claude Code faz?

Framework de agente de voz offline para robôs. Pacote puro Python, sem dependências de nuvem, funciona em CPU/CUDA/Metal.

Estrutura do projeto

edgevox/
├── edgevox/            # Pacote fonte
│   ├── audio/          # VAD, captura de microfone, reprodução
│   ├── stt/            # Backends STT (faster-whisper, sherpa-onnx)
│   ├── llm/            # Integração llama.cpp / Gemma
│   ├── tts/            # Backends TTS (Kokoro, Piper, Supertonic, PyThaiTTS)
│   ├── core/           # Orquestração do pipeline
│   ├── cli/            # Pontos de entrada CLI
│   ├── ui/             # Widgets TUI
│   ├── integrations/   # Ponte ROS2, etc.
│   ├── tui.py          # Aplicativo TUI principal
│   └── setup_models.py # Download de modelos
│   ├── server/         # Web UI FastAPI + servidor WebSocket
├── webui/              # Frontend React (Vite + Tailwind)
├── scripts/            # Scripts utilitários (upload de modelo, etc.)
├── voices/             # Arquivos de configuração de voz
├── docs/               # Documentação do projeto
├── website/            # Site VitePress
└── pyproject.toml

Pontos de entrada (veja pyproject.toml):

  • edgevox → edgevox.tui:main (padrão TUI, --web-ui para web, --simple-ui para CLI)
  • edgevox-cli → edgevox.cli.main:main
  • edgevox-setup → edgevox.setup_models:main

Idiomas e backends suportados

IdiomaSTTTTS
Inglês, Francês, Espanhol, etc.faster-whisperKokoro
Vietnamitasherpa-onnx (zipformer)Piper
Alemão, Russo, Árabe, Indonésiofaster-whisperPiper
Coreanofaster-whisperSupertonic
Tailandêsfaster-whisperPyThaiTTS

Os modelos estão hospedados em nrl-ai/edgevox-models (HuggingFace) com fallback para repositórios upstream.

Princípios de arquitetura

  • Plug-and-play, customizável por padrão. Todo componente — backend STT, backend TTS, LLM, VAD, comportamento do loop do agente, estágio do pipeline, ferramenta, habilidade, hook — deve ser intercambiável sem editar o código principal. Prefira Protocols, registries e decoradores em vez de caminhos fixos. Novo comportamento chega como um novo plugin/hook/backend, não como um patch em um módulo existente. Se você se pegar adicionando uma condicional no núcleo para um caso de uso específico, dê um passo para trás e extraia-a para um ponto de injeção.

Arquitetura do harness do agente

O harness do agente (edgevox/agents/ + edgevox/llm/hooks_slm.py + edgevox/llm/tool_parsers/) está totalmente documentado em docs/documentation/:

  • agent-loop.md — o loop de seis pontos de fogo, despacho paralelo, curto-circuito de handoff.
  • hooks.md — contrato de autoria de hooks, hooks embutidos, regras de ordenação.
  • memory.md — MemoryStore / SessionStore / NotesFile / Compactor.
  • interrupt.md — sinais de barge-in + fiação de cancelamento.
  • multiagent.md — Blackboard, BackgroundAgent, AgentPool.
  • tool-calling.md — cadeia de parsers + roteiro para decodificação com restrição gramatical.

Regras do harness

  • Campos AgentContext tipados (ctx.tool_registry, ctx.llm, ctx.interrupt, ctx.memory, ctx.artifacts, ctx.blackboard) são a superfície pública de conexão. ctx.state é área de rascunho apenas para o usuário — o código do framework não deve escrever chaves mágicas ali.
  • Estado pertencente a hooks vive em ctx.hook_state[id(self)]. A chave id(self) garante que duas instâncias da mesma classe de hook não compartilham estado.
  • Barge-in é aplicável, não opcional. Cada chamada LLM.complete encaminha ctx.interrupt.cancel_token via stop_event=… para que stopping_criteria do llama-cpp realmente pare a geração dentro de uma etapa de decodificação.
  • Contagens de tokens exatas do tokenizador. estimate_tokens(messages, llm) e LLM.count_tokens substituem a heurística chars // 4 quando um LLM está disponível. Necessário para decisões corretas de janela de contexto para CJK / Vietnamita / Tailandês.
  • Parsing de chamada de ferramenta executa primeiro no raw. parse_tool_calls_from_content tenta detectores contra o conteúdo bruto antes de remover blocos thinking — Qwen3 emite chamadas de ferramenta dentro de blocos de raciocínio (veja llama.cpp#20837).
  • Parsers predefinidos são validados no carregamento. resolve_preset(slug) afirma que cada nome em tool_call_parsers=(...) é um detector registrado; um erro de digitação falha ruidosamente em vez de desabilitar a detecção silenciosamente.
  • IDs de chamada de ferramenta emitidos pelo modelo fazem round-trip. O formato [TOOL_CALLS] do Mistral carrega um id de 9 caracteres que a mensagem role="tool" de acompanhamento deve reutilizar. ToolCallItem.id canaliza isso através da cadeia de parsers e do loop do agente.

Superfícies de importação preferidas

  • Framework do agente: from edgevox.agents import LLMAgent, AgentContext, Session, Handoff, ...
  • Hooks embutidos: from edgevox.agents.hooks_builtin import MemoryInjectionHook, TokenBudgetHook, ...
  • Fortalecimento SLM: from edgevox.llm.hooks_slm import default_slm_hooks
  • Memória: from edgevox.agents.memory import JSONMemoryStore, NotesFile, Compactor, estimate_tokens
  • Multiagente: from edgevox.agents.multiagent import Blackboard, BackgroundAgent, AgentPool
  • Interrupção: from edgevox.agents.interrupt import InterruptController, InterruptPolicy, EnergyBargeInWatcher

Evite acessar módulos privados ou _agent_harness.py diretamente.

Regras de codificação

  • Python ≥ 3.10. Use sintaxe moderna (X | Y unions, match, dict[str, int]).
  • Formate e faça lint com ruff. Comprimento de linha 120. Execute ruff format e depois ruff check --fix.
  • Sem resumos finais em comentários de código. Comente o porquê, não o o quê.
  • Dicas de tipo em funções públicas. Helpers internos podem omiti-las quando óbvio.
  • Sem prints no código de biblioteca. Use rich/textual para saída voltada ao usuário, logging para diagnósticos.
  • Imports vão no topo do arquivo. Apenas mova um import para dentro de uma função quando algo concreto o forçar — quebra de importação circular, dependência opcional/pesada atrás de uma verificação de capacidade, ou carregamento lento para reduzir latência de inicialização da CLI. Conveniência ou "só é usado em um lugar" não é motivo; mova para cima.
  • Sem novas dependências de alto nível sem motivo. Prefira a stdlib. Se precisar adicionar uma, atualize pyproject.toml.
  • Caminhos de código conscientes de hardware devem degradar graciosamente — fallbacks CUDA/Metal/CPU, nunca trave em acelerador ausente.
  • Nunca envie arquivos de modelo (.gguf, .onnx, .bin, pesos). Eles ficam em models/, que está no .gitignore.

Convenções de áudio / modelo

  • Taxa de amostragem: 16 kHz mono int16 para captura e entrada STT.
  • Saída TTS: reamostrada para a taxa do dispositivo via sounddevice.
  • Tamanho do quadro VAD: 32 ms (512 amostras @ 16 kHz).
  • Orçamento de latência: STT < 0,5 s, primeiro token LLM < 0,4 s, primeiro trecho TTS < 0,1 s em RTX 3080.
  • Trate o pipeline de streaming como o contrato: não introduza chamadas bloqueantes que seguram o event loop.

Ferramentas

  • uv para gerenciamento de pacotes. Use uv pip install / uv venv em vez de pip / python -m venv puro. Veja https://docs.astral.sh/uv/.
  • pre-commit executa ruff (lint + format), gitleaks e hooks de higiene padrão. Instale uma vez com pre-commit install.
  • gitleaks escaneia segredos em cada commit. Se um achado for um falso positivo, coloque-o na lista de permissões em .gitleaks.toml com um comentário explicando o porquê — não delete o achado.
  • pytest para testes (pytest, modo asyncio = auto). Testes ficam em tests/.

Expectativas de fluxo de trabalho

  • Leia arquivos antes de editá-los. Não proponha mudanças no código que você não olhou.
  • Execute ruff format + ruff check --fix antes de declarar uma tarefa concluída.
  • Não pule hooks (--no-verify) — corrija o problema subjacente.
  • Não se adicione ou adicione Claude como autor/coautor de commit. Especificamente: sem trailer Co-Authored-By: Claude …, sem rodapé 🤖 Generated with Claude Code — mensagens de commit terminam após o corpo, nada mais.
  • Prefira editar arquivos existentes em vez de criar novos; não crie arquivos README/docs a menos que solicitado.
  • Se uma mudança tocar o pipeline de streaming, anote manualmente o impacto na latência na descrição do PR.
  • Prefira diagramas Mermaid em vez de arte ASCII em qualquer documento markdown (docs/, website/, README.md, descrições de PR). GitHub e VitePress renderizam blocos mermaid nativamente; ASCII desenhado à mão com caixas e linhas é mais difícil de ler, impossível de editar limpos e quebra com mudanças de fonte monoespaçada. Os únicos diagramas ASCII aceitáveis são árvores de diretório (├── / └──) — esses permanecem como estão.

Escrevendo docs (docs/, README.md, website/)

  • Sempre cite rótulos Mermaid que contenham (, ), @, :, ,, &, <br/>, ou pontuação diferente de letras, dígitos, _ e -. Use ["foo(args)"] para nós e -->|"@tool call"| para rótulos de aresta. Parênteses não citados dentro de [...] ou |...| quebram o parser de flowchart silenciosamente — a página ainda carrega, mas o diagrama desaparece. Depois de editar qualquer bloco mermaid, abra a página localmente (npm run docs:dev) e confirme zero entradas Parse error on line N no console do navegador. A quebra é invisível na revisão do código fonte.
  • Teste docs no servidor de desenvolvimento antes de declarar concluído. npm run docs:dev (VitePress em :5173) captura erros de parse do mermaid, links quebrados e âncoras mortas que a fonte markdown esconde. Para mudanças visuais (novos diagramas, layout, hero, sidebar), capture uma captura de tela Playwright da página afetada para que o revisor possa detectar regressões sem iniciar o servidor.
  • Links entre páginas são absolutos pela raiz, sem extensão — /documentation/hooks, nunca ./hooks.md ou hooks (o último resolve errado sob cleanUrls: true). Alvos de clique em nós Mermaid seguem a mesma convenção.
  • Registro na sidebar é obrigatório. Uma nova página em docs/documentation/ é invisível até ser adicionada ao bloco sidebar em docs/.vitepress/config.ts. Atualize ambos ao mesmo tempo.

O que NÃO fazer

  • Não adicione chamadas de API de nuvem ou telemetria. EdgeVox é offline-first.
  • Não introduza dependências licenciadas sob GPL (o projeto é MIT).
  • Verificação de licença é obrigatória antes de adicionar qualquer nova dependência. Verifique a licença real do pacote (PyPI/GitHub/documentação — não apenas um palpite) e registre o resultado inline em pyproject.toml ao lado da dependência (ex.: # MIT / # LGPL-3 — linked dinamicamente, compatível). Licenças copyleft a recusar: GPL-2/3, AGPL, SSPL. LGPL é aceitável apenas para bibliotecas de ligação dinâmica pura (PySide6, Qt Multimedia, rlottie). CC-BY-SA é aceitável para assets (conjuntos de peças SVG etc.), nunca para dependências em nível de código fonte. Em caso de dúvida, escolha uma alternativa permissiva ou sinalize para discussão.
  • Não envie dist/, build/, *.egg-info/, pesos de modelo ou gravações.
  • Não adicione abstrações especulativas ou "proteção para o futuro" além do que a tarefa requer.

Habilidades Relacionadas