Documentação oficial desta página · v0.20.6
Integração Programática
O Hermes traz três protocolos para dirigir o agente a partir de programas externos — plugins de IDE, interfaces próprias, pipelines de CI, subagentes embutidos. Escolha o que combina com o seu transporte e com quem vai consumir.
| Protocolo | Transporte | Melhor para | Definido em |
|---|---|---|---|
| ACP | JSON-RPC sobre stdio | Clientes de IDE (VS Code, Zed, JetBrains) que já falam o Agent Client Protocol | acp_adapter/ |
| Gateway da TUI | JSON-RPC sobre stdio (ou WebSocket) | Hosts próprios que querem controle fino de sessões, comandos de barra, aprovações e eventos em streaming | tui_gateway/server.py |
| Servidor de API | HTTP + Server-Sent Events | Frontends compatíveis com a OpenAI (Open WebUI, LobeChat, LibreChat…) e clientes web em qualquer linguagem | gateway/platforms/api_server.py |
Os três dirigem o mesmo núcleo AIAgent. Eles diferem só no formato de fio e no conjunto de
recursos que expõem.
ACP (Agent Client Protocol)
O hermes acp sobe um servidor JSON-RPC em stdio falando ACP. Está em produção no VS Code (a
extensão ACP da Zed Industries), no Zed e em qualquer IDE da JetBrains com um plugin de ACP.
Capacidades expostas: criação de sessão, envio de prompt, streaming dos pedaços de mensagem do
agente, eventos de chamada de ferramenta, pedidos de permissão, bifurcação de sessão, cancelamento
e autenticação. A saída das ferramentas é desenhada em blocos de conteúdo Diff/ToolCall do ACP
que a IDE entende.
Ciclo de vida completo, ponte de eventos e fluxo de aprovação: ACP por dentro.
hermes acp # servir ACP em stdio
hermes acp --check # conferir as dependências do ACP e os imports do adaptador
hermes acp --setup # configuração interativa de provedor/modelo para a autenticação de terminal do ACP
JSON-RPC do gateway da TUI
O tui_gateway/server.py é o protocolo com que a TUI em Ink (hermes --tui) e a ponte de PTY do
painel embutido conversam. Qualquer host externo pode falar o mesmo protocolo por stdio (ou por
WebSocket, via tui_gateway/ws.py).
Catálogo de métodos (seleção)
prompt.submit prompt.background session.steer
session.create session.list session.active_list
session.activate session.close session.interrupt
session.history session.compress session.branch
session.title session.usage session.status
clarify.respond sudo.respond secret.respond
approval.respond config.set / config.get commands.catalog
command.resolve command.dispatch cli.exec
reload.mcp reload.env process.stop
delegation.status subagent.interrupt subagent.steer
spawn_tree.save / list / load
terminal.resize clipboard.paste image.attach
session.active_list, session.activate e session.close são os controles de sessão viva locais
ao processo que o alternador de sessões da TUI usa. Use session.list / /resume para descobrir
transcrições salvas; use os métodos de sessão ativa só para sessões abertas agora no processo do
gateway da TUI.
Rebobinar o histórico no prompt.submit
Rebobinar, editar ou regerar é um prompt.submit que descarta parte da transcrição guardada antes
de rodar o novo turno. Como essa escrita é uma reescrita destrutiva das linhas duráveis da sessão,
o gateway só a aceita quando o cliente declara a intenção:
| Parâmetro | Significado |
|---|---|
truncate_before_user_ordinal | Índice, começando em zero, do turno de usuário onde cortar. Tudo daquele turno em diante é descartado. Linhas de linha do tempo só para exibição (display_kind) não contam. Precisa ser um inteiro de verdade — um booleano JSON é recusado com o código 4004. |
truncate_before_row_id | ID inteiro da linha no SQLite (messages.id / row_id) do turno de usuário alvo do corte. É o endereço durável preferido. Quando o ordinal e o ID de linha vêm juntos, o gateway confere se eles batem (devolvendo 4030 quando não batem). Um ID de linha desconhecido ou velho é recusado com 4018 — ele não recai para o ordinal. |
confirm_truncate | Obrigatório sempre que um ordinal, um ID de mensagem ou um ID de linha é enviado. Declara que este envio é mesmo um rebobinamento, e não um envio comum que por acaso carrega parâmetros esquecidos. Mandá-lo sem um alvo é recusado com o código 4004. |
confirm_empty_truncate | Obrigatório também quando o corte deixaria a transcrição vazia (ordinal 0). |
Um parâmetro de truncamento sem confirm_truncate é recusado com o código 4004 ou 4029 e nada
é gravado. Hosts que implementam rebobinamento precisam marcar a flag no momento em que a pessoa
pede, e nunca podem manter parâmetros de truncamento no estado entre envios comuns. Prefira
truncate_before_row_id (vindo do row_id / _row_id do resume) aos ordinais; deixe o ordinal
como caminho de compatibilidade ou de linha otimista só enquanto não houver um id durável.
Num envio com truncamento bem-sucedido contra uma sessão durável, o resultado do prompt.submit
carrega também survivor_user_row_ids — os novos IDs de linha, pós-reescrita, dos turnos de
usuário que sobraram, na ordem do ordinal visível. A reescrita reinsere o prefixo mantido como
linhas novas, então todo ID de linha que o host tinha em cache antes do rebobinamento fica velho
depois; refaça o vínculo dos IDs em cache a partir dessa lista (uma entrada null significa que
aquele turno não tem ID durável — jogue fora o que estava em cache) ou o próximo rebobinamento
mirando um turno sobrevivente mais antigo será recusado com 4018.
Eventos devolvidos em streaming
message.delta, message.complete, tool.start, tool.progress, tool.complete,
approval.request, clarify.request, sudo.request, sudo.expire, secret.request,
secret.expire, gateway.ready, mais os eventos de ciclo de vida de sessão e de erro. Os eventos
de expiração carregam o { request_id } original; hosts externos devem limpar só o pedido pendente
correspondente.
Mapeamento para o RPC no estilo Pi
Todo comando da especificação de RPC do Pi-mono (issue #360) tem um equivalente no gateway da TUI:
| Comando do Pi | Equivalente no Hermes |
|---|---|
prompt | prompt.submit (ou session/prompt do ACP) |
steer | session.steer |
follow_up | prompt.submit enfileirado depois do turno atual |
abort | session.interrupt |
set_model | command.dispatch com /model <provedor:modelo> (no meio da sessão, persistente) |
compact | session.compress |
get_state | session.status |
get_messages | session.history |
switch_session | session.resume |
fork | session.branch |
ui_request / ui_response | clarify.respond / sudo.respond / secret.respond / approval.respond |
Servidor de API compatível com a OpenAI
O gateway/platforms/api_server.py expõe o Hermes por HTTP para qualquer cliente que já fale o
formato da OpenAI. Serve quando você quer um frontend web, um executor de CI movido a curl ou um
consumidor fora do Python.
Endpoints:
POST /v1/chat/completions Chat Completions da OpenAI (streaming por SSE)
POST /v1/responses API Responses da OpenAI (com estado)
POST /v1/runs Inicia uma execução, devolve run_id (202)
GET /v1/runs/{id} Status da execução
GET /v1/runs/{id}/events Fluxo SSE dos eventos de ciclo de vida
POST /v1/runs/{id}/approval Resolve uma aprovação pendente
POST /v1/runs/{id}/steer Injeta orientação no meio da execução, na próxima borda de ferramenta
POST /v1/runs/{id}/stop Interrompe a execução
GET /v1/capabilities Flags de recurso legíveis por máquina
POST /v1/browser-control/register Registra um controlador de navegador
GET /v1/browser-control/ws WebSocket do controlador de navegador
GET /v1/models Lista o hermes-agent
GET /api/model/options Inventário do seletor, ciente dos provedores
GET /health, /health/detailed
Configuração, cabeçalhos (X-Hermes-Session-Id, X-Hermes-Session-Key) e ligação com o frontend:
Servidor de API.
Extensões de navegador podem aderir ao protocolo de controlador, desligado por padrão, para dirigir exatamente a sessão de navegador que abriu a conversa do Hermes. Os transportes da API e do painel compartilham um único intermediário atrelado ao principal e uma única lista de permissão explícita de capacidades; veja Controle por extensão de navegador.
Superfícies do catálogo de modelos
A API compatível com a OpenAI mantém o GET /v1/models mínimo de propósito: ele é o endpoint de
compatibilidade que os frontends esperam, não o catálogo completo do seletor de provedores e
modelos do Hermes.
Se um plano de controle externo precisa das linhas de provedor curadas do Hermes, do preço por modelo ou das dicas de capacidade, use uma das superfícies autenticadas do seletor:
- REST do servidor de API:
GET /api/model/optionscom a chave bearer do servidor de API - REST do backend do painel:
GET /api/model/optionscom oX-Hermes-Session-Token - RPC do gateway da TUI:
model.options
Essas superfícies compartilham o mesmo construtor de payload e a mesma política de sondagem de provedores personalizados:
- Abertura normal: sonda só o provedor personalizado atual, para que endpoints salvos e fora do ar não travem o seletor.
- Atualização explícita (
refresh=1ourefresh: true): invalida o cache de provedor-modelo e sonda todos os provedores personalizados salvos, para que os catálogos ao vivo voltem completos.
Use /v1/models para compatibilidade com clientes da OpenAI. Use /api/model/options ou
model.options quando estiver construindo um seletor de modelos que conhece o Hermes.
O POST /v1/runs/{id}/steer é o equivalente HTTP do /steer do Hermes: ele não cria um turno novo
de usuário nem reescreve na hora a saída do assistente que já está em voo. Em vez disso, o texto é
anexado à execução viva e fica visível para o agente depois da próxima borda de ferramenta, então
ele consegue corrigir o rumo sem jogar fora o laço de chamada de ferramentas em andamento.
O /v1/runs/{id}/steer só é aceito enquanto o status da execução é running. Execuções
enfileiradas, pausadas por aprovação, parando, canceladas, com falha e concluídas devolvem
409 run_not_accepting_steer, mesmo que o servidor ainda guarde referências internas ao agente
durante um desligamento cooperativo.
Um 200 (e o evento run.steered) significa que o texto foi enfileirado, não que o agente o
consumiu. Se um steer chega depois da resposta final do agente — sem nenhuma borda de ferramenta
posterior onde entregá-lo —, o texto não entregue volta como pending_steer no evento terminal
run.completed e no status da execução, para que o cliente possa reenviá-lo como o próximo turno
de usuário em vez de perdê-lo.
Qual deles usar?
- Você está escrevendo um plugin de IDE e a IDE já fala ACP → ACP. Zero trabalho de protocolo do lado da IDE.
- Você está escrevendo um host próprio de desktop, web ou terminal e quer todo recurso do Hermes (comandos de barra, aprovações, esclarecimentos, multiagente, bifurcação de sessão) → JSON-RPC do gateway da TUI.
- Você quer qualquer frontend compatível com a OpenAI, um cliente HTTP em qualquer linguagem ou automação movida a curl → servidor de API.
- Você quer embutir em Python no mesmo processo, sem subprocesso → importe
run_agent.AIAgentdireto. Veja Laço do agente.
Troca de modelo a quente
Trocar de modelo no meio da sessão funciona em toda superfície — por baixo, é o comando de barra
/model.
- CLI / TUI:
/model claude-sonnet-4ou/model openrouter:anthropic/claude-sonnet-4.6 - RPC do gateway da TUI:
command.dispatchcom{"command": "/model claude-sonnet-4"} - ACP: a IDE manda o comando de barra como um prompt; o agente o despacha
- Servidor de API: inclua um campo
modelno corpo da requisição
A resolução ciente do provedor (o mesmo nome de modelo escolhe o formato certo para o provedor em
que você está) já vem pronta. Veja hermes_cli/model_switch.py.
Um recado sobre --mode rpc
O Hermes não tem uma flag --mode rpc. Os três protocolos acima já cobrem os casos de uso — ACP
para clientes de protocolo de IDE, o gateway da TUI para hosts de JSON-RPC em stdio e o servidor de
API para HTTP. Se você encontrar uma lacuna de verdade que nenhum deles preenche, abra uma issue
descrevendo o consumidor concreto que você está construindo.