Mapa da trilha
Conteúdo detalhado
🧭 O que é OpenHuman
Visão, missão e por que um AI assistant local muda o jogo para comunidades e operações multi-canal.
OpenHuman se posiciona como um assistente pessoal de IA que combina memória local, serviços gerenciados quando necessário, e um harness simples e poderoso. É AI para comunidades — não um chatbot genérico.
Sem entender a missão, você usa OpenHuman como qualquer outro chat. Com ela, percebe por que cada decisão de arquitetura (local-first, desktop, Rust) existe.
Local-first, harness aberto, foco em comunidades, super-inteligência pessoal, alternativa a SaaS centralizado.
Comunidades vivem espalhadas em Slack, Discord, WhatsApp, Telegram, Gmail, iMessage e Meet. OpenHuman unifica esses canais sob um único agente com contexto compartilhado.
É a tese de produto. Toda funcionalidade — webview accounts, channels, threads — existe para resolver essa fragmentação.
Multi-canal, contexto unificado, custo cognitivo de troca de app, perda de histórico entre ferramentas.
Operações comunitárias (moderação, onboarding), suporte distribuído, automação multi-canal, encontros de Meet com transcrição e ação, captura de conhecimento.
Casos concretos ajudam você a posicionar OpenHuman no seu próprio fluxo — em vez de tentar usar para tudo.
Agente persistente, gatilhos por canal, scheduler/cron, webhooks, meet agent.
Dados sensíveis (mensagens, memória, credenciais) ficam na máquina. Core em Rust para performance e segurança. Tauri em vez de Electron para binário enxuto. Open source para auditoria.
São esses diferenciais que sustentam casos de uso impossíveis em ChatGPT/Claude SaaS — como ler mensagens privadas de Slack/WhatsApp sem mandar para servidores de terceiros.
Privacidade por construção, soberania de dados, performance nativa, auditabilidade.
Três camadas: Rust core (lógica e domínios), Tauri shell (host desktop, janelas, IPC) e React app (UI). Tudo roda no mesmo processo desktop — Windows, macOS, Linux.
Saber onde cada coisa vive evita debugar no lugar errado. Lógica de negócio? Core. UX? React. Janela travada? Shell.
Separation of concerns, core como source of truth, shell como veículo, JSON-RPC entre camadas.
Comunidades engajadas, equipes pequenas operando vários canais, builders que querem AI sem renunciar privacidade, devs que precisam estender o assistente com código próprio.
Recomendar OpenHuman para o caso errado gera frustração. Saber o perfil ideal evita expectativas furadas.
Community ops, power users, builders, equipes pequenas e médias, desktop-first.
🏗️ Arquitetura
Como Rust core, Tauri shell e React app se compõem em um único processo desktop, com JSON-RPC autenticado por bearer token.
Core (Rust, src/) tem a lógica autoritativa. Shell (Tauri, app/src-tauri/) hospeda janelas e ciclo de vida. App (React+Vite, app/src/) renderiza a UX.
Cada camada tem um propósito estrito. Misturar lógica de produto no shell ou regras no React é débito técnico garantido.
Core autoritativo, shell descartável, app apenas orquestra e apresenta.
O core roda como uma task tokio dentro do próprio host Tauri. Não há mais binário openhuman-core sidecar em produção — Cmd+Q encerra tudo junto.
Documentação e exemplos antigos falam de sidecar. Saber que sumiu evita debugar processos fantasmas e simplifica setup de dev.
CoreProcessHandle, tokio task, lifecycle unificado, OPENHUMAN_CORE_REUSE_EXISTING para debug.
Frontend chama http://127.0.0.1:<port>/rpc com bearer token por launch (OPENHUMAN_CORE_TOKEN) via core_rpc_relay. Não usar fetch() direto — causa CORS preflight.
Toda nova feature do produto atravessa esse canal. Saber o contrato é pré-requisito para qualquer integração frontend/core.
JSON-RPC 2.0, bearer token efêmero, invoke('core_rpc_relay', ...), namespace openhuman.<dominio>_<funcao>.
OpenHuman usa CEF (Chromium Embedded Framework) em vez do WebKit padrão do Tauri. Por isso requer um tauri-cli vendored que empacota Chromium em Contents/Frameworks/.
Tentar usar o tauri-cli stock quebra o bundle (panic em cef::library_loader). Entender o porquê evita meia hora perdida em ferramenta errada.
CEF, webviews de provedores (Slack/WhatsApp/Telegram), CDP para scraping, scripts/ensure-tauri-cli.sh.
A árvore de providers começa em Sentry.ErrorBoundary e desce até AppShell, passando por Redux, PersistGate, BootCheckGate, CoreStateProvider, SocketProvider, ChatRuntimeProvider, HashRouter.
Quase todo bug de "estado não chega" se resolve sabendo qual provider deveria ter injetado a coisa. Sem o mapa, você fica chutando.
Ordem dos providers, autenticação fora do redux-persist, snapshot do core via fetchCoreAppSnapshot.
Shell Rust é apenas delivery vehicle. UI/produto fica em React. Lógica de negócio no core. Plugin de webview de terceiros? Nada de injetar JS — usar CDP nativo.
A regra parece dogmática, mas evita acoplamentos que travam refactor. Quem entende, entrega features em camada certa.
Core autoritativo, no-JS-injection em webviews de terceiros, plugins Tauri auditados, CEF handlers + CDP.
🔄 Domínios e fluxo de dados
Mapa dos domínios do core (agent, memory, channels, threads, skills…), event bus tipado, controllers e a pipeline de memória.
Cada domínio vive em src/openhuman/<dominio>/: agent, memory, channels, threads, skills, cron, webhooks, providers, voice, meet, billing — entre dezenas de outros.
Saber em qual diretório aterrissar economiza horas. Novos arquivos pertencem ao domínio certo — não a src/openhuman/util.rs.
Domínio = pasta, mod.rs leve, ops.rs/store.rs/types.rs/rpc.rs/schemas.rs.
O agent harness (src/openhuman/agent/) orquestra prompts, ferramentas, contexto, aprovação. É a superfície que o modelo "vê".
Qualquer mudança no comportamento do assistente — nova tool, mudança de prompt, política de aprovação — passa por aqui.
Prompts bundled, tool surface, approval gates, tool timeout, autocomplete.
Memória passa por subconscious (consolidação assíncrona) e tree_summarizer (resumos hierárquicos). Resultado: contexto longo sem estourar a janela.
É o diferencial frente a chats sem memória persistente. Sem isso, OpenHuman seria mais um wrapper de LLM.
Embeddings, retrieval, sumarização hierárquica, consolidação em background.
channels abstrai cada origem (Slack, WhatsApp, Gmail, …). threads agrupa mensagens em conversas com contexto compartilhado.
É como mensagens externas viram input para o agente. Saber a topologia evita confundir "canal" com "thread" ao depurar.
ChannelInboundSubscriber, fan-in de fontes, threading por contexto.
Pub/sub tipado em src/core/event_bus/. publish_global faz fan-out broadcast. request_native_global faz request/response 1:1 por método, sem serialização.
É a espinha dorsal de coordenação entre domínios. Sem entender, você acopla módulos com chamadas diretas e quebra o desacoplamento.
DomainEvent, EventHandler, NativeRegistry, SubscriptionHandle com RAII.
Cada domínio expõe operações via controller registry (schemas.rs + rpc.rs). CLI e JSON-RPC consomem do mesmo lugar — sem branches manuais em core/cli.rs ou core/jsonrpc.rs.
Adicionar feature exige seguir esse contrato. Furar o padrão quebra tipagem e quebra testes E2E.
ControllerSchema, FieldSchema, RpcOutcome<T>, registro automático.