Pular para o conteúdo
omni

Modo servidor

ai serve expõe o roteador como uma API compatível com a OpenAI. Ele usa os mesmos logins, chaves, contas, cooldowns e fallbacks do CLI.

ai serve                       # http://127.0.0.1:8080/v1
ai serve --host 0.0.0.0 --port 9000 --max-concurrent 4 --timeout 600
ai serve keys [list | add NAME | remove NAME]

API de administração

Desligada por padrão. Configura um servidor em execução sem acesso ao shell.

ai serve admin-keys add ops                    # chave própria, mostrada uma única vez
ai serve --enable-admin
curl -H "Authorization: Bearer omni-admin-..." http://127.0.0.1:8080/admin/health
Rota Função
GET/PUT /admin/config Modelos, ordem de fallback (fallback_order) e routing
GET/POST /admin/keys, DELETE /admin/keys/{id} Chaves dos provedores. O id é openrouter ou openrouter.work
GET /admin/accounts Contas, login e cooldown
GET/POST /admin/api-keys, DELETE /admin/api-keys/{nome} Chaves dos clientes de /v1
GET /admin/health Estado do servidor
POST /admin/accounts/{conta}/login Inicia o login por assinatura: devolve o link e o id da tentativa
POST /admin/accounts/{conta}/login/complete Conclui o login
DELETE /admin/accounts/{conta}/login Cancela, com o id em X-Omni-Login-Attempt
  • Chaves separadas: uma chave de /v1 nunca abre /admin, e vice-versa. Sem chave de administração, --enable-admin não inicia.
  • Rede: de fora desta máquina, exige HTTPS por proxy reverso, que precisa definir X-Forwarded-Proto. --admin-allow-http desliga essa checagem. Ela só evita exposição por engano: quem alcança a porta direto consegue forjar o cabeçalho, então deixe a porta aberta só para o proxy. No Docker, a porta publicada conta como acesso externo.
  • Segredos: as respostas mostram só o final das chaves de provedores. A exceção é a chave de cliente criada, mostrada uma única vez.
  • Campos protegidos: modo de permissão, caminhos de binários e config_dir retornam 403.
  • Cuidado: esta chave pode ligar modelos pagos (openrouter_paid) e trocar chaves de provedores. No Docker, use SMART_AI_ADMIN=1.

Login pela API. {conta} é primary e as outras contas Claude, codex, cursor, grok, ou codex.NOME para uma conta extra. Uma tentativa vale 10 minutos e cada conta aceita uma por vez (409).

Ferramenta Como concluir
Claude Code Abra o link e envie {"attempt_id": "...", "code": "..."} com o código obtido
Codex, Grok Abra o link, digite o user_code e envie {"attempt_id": "..."}. A resposta é 202 até concluir
Cursor Abra o link e envie {"attempt_id": "..."}. A resposta é 202 até concluir

O Antigravity e as ferramentas só com chave retornam 400. Os códigos e tokens não aparecem em respostas nem em logs. A exceção é o user_code, que precisa ser digitado no navegador.

Escrita em paralelo

Nos modos de escrita, os pedidos rodam em paralelo, até --max-concurrent, sem mexer na pasta original.

Pasta com git Pasta sem git
Onde trabalha Worktree em uma branch omni/<id>, a partir do último commit Cópia da pasta, até 1 GB
Resultado Commit na branch, informada em X-Omni-Branch. O merge é seu Cópia em ~/.local/share/smart-ai/runs/, informada em X-Omni-Copy
Continuar Envie X-Omni-Branch no pedido seguinte Envie X-Omni-Copy no pedido seguinte
Limpeza O worktree sai ao final. A branch fica até você apagar A cópia fica até você apagar
  • Sem alterações: a branch ou a cópia nova é descartada e o header não vem. Em streaming, o header sai no início e pode apontar para algo descartado.
  • Falha ou timeout: o que já foi feito é mantido, e o header vem na resposta de erro. Depois de uma queda do servidor, as alterações são salvas no próximo início.
  • Concorrência: dois pedidos na mesma branch ou cópia recebem 409. Só branches omni/ podem ser continuadas.
  • Fila: acima do limite, o pedido espera até --queue-wait segundos (60), com até --queue-size na fila (16). Só então recebe 429.
  • Limitações: alterações sem commit e arquivos ignorados pelo git, como node_modules, não entram no worktree. O isolamento vale para arquivos: portas, bancos e outros serviços usados pelos comandos ainda podem colidir, e um comando pode escrever fora da pasta. A memória também conta: cada pedido é um processo de CLI. Os comandos git do próprio servidor não rodam hooks nem core.fsmonitor do repositório. Filtros do git, como os do Git LFS, continuam rodando: sirva só repositórios em que você confia.
ai serve work --workdir PASTA                  # lista
ai serve work remove ID --workdir PASTA        # mostra; com --yes, apaga
ai serve work prune --older-than 30 --workdir PASTA   # também --merged; com --yes, apaga

Sem --yes, nada é apagado. O comando só alcança branches omni/ e cópias do Omni. Um item em uso, ou cópia alterada há menos de 15 minutos, é mantido.

Como serviço

ai serve --install-service [--host H] [--port P] [--mode M] [--workdir PASTA]
ai serve --service-status
ai serve --uninstall-service

Inicia sozinho e reinicia em caso de falha, com launchd no macOS e systemd de usuário no Linux. No Windows, em containers e em WSL sem systemd, o comando avisa e não instala; rode ai serve manualmente.

  • Segredos: o arquivo do serviço não guarda chaves. Sem chave salva, a instalação cria uma e a mostra uma única vez. Fora de 127.0.0.1, exige uma chave salva antes.
  • Ambiente: só PATH e as pastas do Omni passam para o serviço. Chaves que existem só no shell não passam: salve com ai --key. A instalação avisa quais são, e também quais CLIs não encontrou.
  • Pasta e modo: o padrão é plan, em ~/.local/share/smart-ai/serve. --mode yolo e sobrescrever um arquivo que o Omni não gerou exigem --yes.
  • Logs: ~/.cache/smart-ai/serve.log, com rotação, e serve.out.log, limpo a cada instalação.
  • Linux: para iniciar no boot sem sessão aberta, rode loginctl enable-linger $USER. A instalação avisa, mas não faz isso sozinha.
  • Atualização: ai --update reinicia o serviço. Em instalações sem git, reinstale o serviço depois.

Uso da API

from openai import OpenAI
client = OpenAI(base_url="http://127.0.0.1:8080/v1", api_key="omni-...")
client.chat.completions.create(model="omni-auto", messages=[{"role": "user", "content": "Olá"}])

No primeiro início, o servidor cria uma chave e a mostra uma única vez. Só o hash fica salvo. Em container, também é possível definir SMART_AI_SERVER_KEY. Não existe modo sem autenticação.

Rota Função
POST /v1/chat/completions Resposta completa ou streaming (SSE)
GET /v1/models omni-auto, que usa o roteador, e omni/<ferramenta> para cada ferramenta configurada
Header da resposta Significado
X-Omni-Provider Ferramenta que respondeu
X-Omni-Usage reported (informado pelo provedor) ou estimated (estimado). Não aparece em streaming
X-Omni-Ignored-Params Parâmetros recebidos e ignorados

Segurança:

  • Por padrão, as ferramentas rodam no modo plan, em uma pasta temporária, seja qual for o SMART_AI_MODE.
  • Para criar, editar e rodar comandos: ai serve --mode edits|auto|yolo --workdir PASTA. A pasta é obrigatória e nada pede aprovação. Cada pedido trabalha isolado. Quem tem a chave pode alterar a pasta e, com comandos, alcançar os logins das contas.
  • Somente leitura não impede ler arquivos. Quem tem a chave pode pedir a uma ferramenta que leia arquivos desta máquina. MCPs configurados também podem estar disponíveis. Trate a chave como acesso à sua conta.
  • O padrão é 127.0.0.1. Para expor em rede, use --host e HTTPS com proxy reverso.
  • Acima do limite de conexões (128 ou mais, conforme o sistema), a resposta é 503. O início de cada pedido precisa chegar em até 30 segundos. Em exposição pública, use também os limites por origem do proxy.
  • Quem compartilha uma instância compartilha as mesmas contas e assinaturas. Verifique os termos de cada provedor.

Limitações:

  • Quando o modo do servidor nega uma ação e a ferramenta encerra com erro, como faz o Grok, a resposta é 403 action_not_allowed.
  • temperature só vale em OpenRouter, DeepSeek e Grok via API. Nos CLIs, é ignorada e aparece em X-Omni-Ignored-Params.
  • max_tokens é aproximado nos CLIs (cerca de 4 caracteres por token).
  • usage é estimado quando o provedor não informa o consumo.
  • Cada pedido pode consumir bastante cota, porque os CLIs de agente carregam o próprio contexto. No Codex, um simples "OK" já usou cerca de 19 mil tokens de entrada.
  • Nos CLIs, o streaming entrega a resposta de uma vez, ao final. Só o OpenRouter envia pedaços durante a geração, exceto quando há dados pessoais mascarados.
  • O fallback é transparente até o primeiro trecho da resposta. Se o provedor falhar depois disso, o cliente recebe um erro.
  • tools/function calling só nos provedores de API (OpenRouter, DeepSeek e Grok via chave). As ferramentas nunca são executadas pelo servidor: a chamada volta para o seu código. Outros modelos retornam 400, porque os CLIs de agente não têm como devolver a chamada, a não ser com --tool-emulation. Com omni-auto, a ordem é OpenRouter, DeepSeek e Grok. No OpenRouter, sem openrouter_paid, só modelos gratuitos. Em streaming, a chamada chega de uma vez, ao final. Argumentos fora do schema fazem o servidor tentar o próximo provedor; só o núcleo do JSON Schema é checado (type, required, enum, properties, items, additionalProperties). functions (formato antigo) retorna 400.
  • Experimental: ai serve --tool-emulation (SMART_AI_TOOL_EMULATION=1 no Docker) emula tools em Claude Code e Grok CLI, com as ferramentas próprias deles desligadas. O modelo escreve a chamada em JSON, o servidor valida e tenta de novo uma vez, o que gasta mais cota. Só entra quando não há provedor de API. Codex e Cursor ficam de fora, porque não dá para desligar as ferramentas deles. O modelo pode errar mais que no modo nativo, os dados pessoais não são mascarados, e o conteúdo do cliente pode imitar o formato.
  • Imagens retornam erro 400.
  • O prompt chega às ferramentas como argumento de linha de comando e fica visível na lista de processos da máquina. O limite é de 100 KB por pedido.
  • Perfis Claude legados, que trocam o arquivo de credenciais, limitam o servidor a um pedido por vez.

Este texto vem do README do projeto. Ver o original no GitHub