iachat/hermes-plugins/captain-webhook/plugin.yaml
Rodribm10 d781f4a048 feat(hermes): plugin captain-webhook (stable session_chat_id)
Plugin pro Hermes Agent que SUBSTITUI o WebhookAdapter built-in pra
suportar session_chat_id estável derivado de campo no payload.

Por que existe
--------------
O WebhookAdapter built-in monta a chave de sessão como:

    session_chat_id = f"webhook:{route}:{delivery_id}"

delivery_id é único por POST → cada msg cria sessão nova no Hermes. OK pra
webhooks one-shot, ERRADO pra integração de chat onde múltiplas mensagens
da mesma conversa precisam compartilhar memória de sessão.

Como funciona
-------------
Quando o caller (Captain) inclui `conversation_id` ou `hermes_session_id`
no payload, o plugin reescreve chat_id pra:

    session_chat_id = f"webhook:{route}:session:{conversation_id}"

Mesma conversation_id em múltiplas POSTs → mesma sessão Hermes →
contexto e memória preservados. Sem o campo, fallback ao comportamento
default (session nova por POST). 100% backward-compatible.

Implementação
-------------
- kind: platform — registra com name="webhook" pra substituir built-in
  (Hermes prioriza platform_registry sobre código built-in em
  gateway/run.py:_create_adapter)
- Herda WebhookAdapter — só override `handle_message` (rewrite chat_id)
  e `connect` (recupera gateway_runner via _gateway_runner_ref pq o
  plugin path não seta isso explicitamente)
- Outros adapters (HMAC, rate limit, idempotency, parsing, deliver
  dispatch) — herdados sem cópia

Validado end-to-end na VPS (profile valentina):
- POST com conversation_id=99999 (msg 1) → session:99999 criada
- POST com conversation_id=99999 (msg 2) → MESMA session reutilizada
- Hermes responde via Codex em ~10s (2 turnos cumulativos)
- http_callback faz POST de volta no Captain (HTTP 200)
- Logs mostram: [captain-webhook] Stable session: ... -> session:99999

Combinado com captain-http-callback, completa o ciclo Captain ↔ Hermes:
Captain manda webhook com conversation_id → Hermes processa em sessão
estável → http_callback POSTa resposta de volta → Captain envia ao
WhatsApp.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 15:16:05 -03:00

29 lines
1.3 KiB
YAML

name: captain-webhook
kind: platform
version: 0.1.0
description: >
Drop-in replacement for the built-in `webhook` platform adapter that
supports stable session_chat_id via payload field.
The default Hermes WebhookAdapter creates a fresh session per POST
(session_chat_id = "webhook:<route>:<delivery_id>" — and delivery_id is
unique per request). For backend integrations like Captain ↔ Hermes
where multiple messages of the same conversation must share session
memory, the caller can include `conversation_id` (or `hermes_session_id`)
in the payload — this adapter constructs:
session_chat_id = "webhook:<route>:session:<conversation_id>"
keeping the Hermes session continuous across messages of the same
conversation. Idempotency (delivery_id) remains unchanged.
When the payload has neither `conversation_id` nor `hermes_session_id`,
behavior is identical to the built-in adapter (every msg is fresh
session). 100% backward-compatible.
Inheritance-only override: this plugin extends WebhookAdapter and only
overrides handle_message() to rewrite event.source.chat_id when the
payload carries a stable session id. All other behavior (HMAC, rate
limiting, idempotency, parsing, deliver) is inherited unchanged.
author: Captain (fazer.ai)