Files
pheby-hermes-platform-adapter/docs/spec-source/Pheby-Platform-Plugin-SPEC-2026-09-02.txt
Pheby 53ffdb8aa2 feat: Pheby platform adapter/plugin for Hermes (protocol v1)
Third-party Hermes platform plugin serving the Pheby WebSocket+HTTPS
protocol for the native Android client, behind Caddy:

- Platform adapter (BasePlatformAdapter subclass) registered via the
  documented plugin system (plugins.platforms pattern, kind: platform)
- Multiple conversations mapped to Hermes sessions (authoritative state)
- Streaming chat via GatewayStreamConsumer edit path (message.delta)
- Structured tool events (never fake tool text in chat), incl.
  post_tool_call hook relay with Hermes tool_call_ids
- Native approval + clarification round-trips via tools.approval /
  tools.clarify_gateway primitives
- Attachment delivery: adapter-owned copies, opaque IDs, persistent
  metadata, 7-day retention + safe cleanup, authenticated HTTPS download
- Model + reasoning-effort query/change via Hermes picker data and
  session/global overrides
- Shared-secret auth (constant-time, lockout), size limits, path-
  traversal-proof attachment resolution, minimal health endpoint
- Protocol v1 spec with JSON examples (docs/PROTOCOL.md)
- Install/config/Caddy/security docs + discovered Hermes limitations
- 37 passing tests (auth, conversations, protocol, attachments incl.
  expiry/traversal, tool events, approvals, clarifications, cancel,
  reconnect re-sync, live WS smoke tests) — gateway-free fakes

No Hermes core modifications required.
2026-09-02 19:31:17 +00:00

274 lines
16 KiB
Plaintext

I want you to build a private custom Hermes Agent platform adapter/plugin called Pheby.
Before implementing anything, inspect the current Hermes Agent documentation and current Hermes source code, especially its platform adapter/plugin APIs, Gateway architecture, Telegram/Discord adapters, conversation/session handling, tool-call events, clarification/approval mechanisms, model selection, reasoning effort, generated-file/deliverable handling, and plugin loading system. Do not rely on assumptions from older Hermes versions. The implementation must target the currently installed/current upstream Hermes architecture.
The Pheby adapter will serve a native Android application written in Kotlin with Jetpack Compose. For this task, build only the Hermes-side plugin and its protocol/API. Do not build the Android application.
The plugin must be a clean third-party Hermes plugin/platform adapter. Do not modify Hermes core files, monkey-patch Hermes, fork Hermes, or rely on hacks that will make Hermes upgrades difficult. It should install into Hermes's supported user plugin location and use documented extension points.
Overall architecture
Pheby is a single-user private platform.
The adapter should expose a network service intended to sit behind Caddy and be reachable over HTTPS/WSS from the public internet.
Use:
• WebSocket for realtime bidirectional chat/events.
• Normal HTTPS endpoints for downloading generated attachments.
• A shared secret/API-key-style credential for authentication.
• Hermes/Gateway functionality underneath rather than reimplementing the agent loop.
Assume Caddy handles TLS. The Pheby service itself can listen on localhost/plain HTTP and WebSocket.
Do not expose or reuse Hermes's master API-server key as the Pheby client credential.
The Pheby credential should be configurable through an environment variable and every WebSocket connection and HTTP attachment request must require authentication.
This is a single-user application. Do not build account registration, users, roles, password recovery, OAuth, etc. However, avoid unnecessarily designing the protocol in a way that makes future multi-client support impossible.
Conversations
Pheby must expose multiple Hermes conversations.
The Android client needs to be able to:
• List conversations.
• Open/load a conversation and its message history.
• Create a new conversation.
• Rename a conversation.
• Delete a conversation.
Hermes should remain the authoritative source of conversation/session state.
The protocol should provide stable conversation IDs.
When Pheby reconnects, it must be able to retrieve existing conversations and their messages rather than treating the connection as a new chat.
Do not implement message editing, individual message deletion, regeneration, or edit-and-resend.
Sending messages and streaming responses
The client must be able to send a text message into a selected conversation.
Use whichever response-streaming mechanism integrates most cleanly with Hermes. Token-level streaming is not a requirement. Chunk-level streaming is perfectly acceptable if it substantially simplifies the adapter.
The protocol should distinguish between:
• A new assistant message.
• Incremental content being appended to an assistant message.
• A completed assistant message.
• A failed/cancelled assistant run.
The UI should never have to infer these states by parsing arbitrary text.
The client must be able to stop/cancel an active Hermes task/run.
Stopping should use Hermes's supported cancellation/interruption mechanism rather than killing threads/processes or corrupting the conversation.
Tool calls
Tool execution must be represented as structured events, separate from the normal textual chat content.
This is important.
Pheby will display tool activity similarly to ChatGPT: tool calls can appear as compact UI components associated with an assistant turn without cluttering the actual chat transcript.
Do not inject fake text such as:
"Searching the web..." "Running command..." "Tool completed..."
into the assistant's message merely to represent activity.
Expose structured information for tool activity where Hermes makes it available, including at minimum:
• Unique tool-call/event ID.
• Conversation/run association.
• Tool name/type.
• Human-readable description if available.
• Start/running state.
• Completion state.
• Failure state.
• Result/summary information that is safe and appropriate to expose.
Preserve enough raw structured information that the Android client can create richer custom UI later, but do not expose secrets or internal credentials.
If Hermes provides nested/sub-agent/tool execution events, preserve their relationship where practical.
Approvals
Pheby must support Hermes's human approval system.
When Hermes pauses because an action requires approval, send a structured WebSocket event to Pheby containing enough information to render native:
Approve Deny
controls.
The event should include:
• Approval/request ID.
• Conversation/run association.
• Human-readable description.
• Relevant action/tool information.
• Any choices/actions Hermes permits.
Pheby must be able to submit an approval or denial and have the existing Hermes run continue appropriately.
Do not simulate approval through ordinary user chat messages if Hermes exposes a proper approval mechanism.
Clarifications / choices
Pheby must also support Hermes's interactive clarification/choice functionality.
If Hermes asks the user to choose between several structured options, expose the request as structured data over WebSocket so the Android app can render native buttons/options.
Provide:
• Clarification ID.
• Prompt/question.
• Available choices.
• Choice IDs/values.
• Whether free-text input is permitted, if Hermes supports that distinction.
• Conversation/run association.
The client must be able to submit the selected choice or clarification response so Hermes can continue the same pending operation.
Use Hermes's existing clarification/elicitation mechanism rather than inventing a parallel agent workflow.
Generated attachments / Deliverable Mode
This is a critical requirement.
Hermes must be able to generate files and send them to Pheby in the same general spirit as Telegram/Discord deliverables.
Pheby does not need to upload arbitrary files to Hermes.
Agent → Pheby attachments are required.
Reuse Hermes's existing Deliverable Mode/media detection and gateway abstractions wherever possible rather than recreating filename parsing from scratch.
Support arbitrary document/file types that Hermes's deliverable system supports.
At minimum represent:
• Attachment ID.
• Filename.
• MIME type.
• File size.
• Download endpoint/identifier.
• Associated conversation/message.
• Whether it is suitable for inline image preview.
Images should be identifiable as images so Pheby can display an inline preview.
Other files should be downloadable/openable as normal Android documents.
Do NOT expose arbitrary server filesystem paths to the client.
Do NOT provide an API that lets the client request arbitrary filesystem files.
Map generated files to opaque attachment IDs and serve only explicitly registered Hermes deliverables.
Attachment downloads must require the Pheby authentication credential.
Use normal HTTP streaming/downloads rather than transferring large files through the WebSocket.
Attachment cleanup
Generated Pheby attachment files should expire after 7 days.
Implement safe cleanup of expired adapter-managed attachments.
Cleanup must never delete unrelated Hermes/user files.
If Hermes's deliverable mechanism points to files Hermes owns elsewhere, do not blindly delete their originals. Prefer an adapter-managed attachment storage/copy/link strategy where the ownership and lifecycle are unambiguous.
Persist enough attachment metadata that restarting Hermes/Pheby does not immediately make all valid attachments inaccessible.
Expired attachment IDs should cleanly return an appropriate HTTP error rather than exposing implementation details.
Models
The Android client needs to query and change the active Hermes model.
Expose the models/providers Hermes currently makes available through its supported configuration/API.
Do not hardcode model names.
The protocol should expose useful model metadata when Hermes provides it.
The selected model must be changeable through Pheby using Hermes's supported mechanisms.
Reasoning effort
Pheby must expose and allow changing the model's reasoning effort where supported by the active provider/model.
Do not assume every model supports the same reasoning settings.
Expose supported values/capabilities dynamically where Hermes makes that information available.
If Hermes does not currently provide perfect capability metadata, implement the cleanest documented approach and clearly document the limitation instead of hardcoding fragile assumptions.
Skills and toolsets
Pheby does not need to enable, disable, configure, or manage Hermes skills/toolsets.
Normal Hermes tools and configured skills must continue functioning through the agent, but no management UI API is required.
Voice and user file uploads
Do not implement:
• Voice messages.
• Speech-to-text.
• Text-to-speech.
• Arbitrary user file uploads.
Design the protocol cleanly enough that additional event/content types could be added later without breaking existing clients, but don't spend significant implementation effort on features outside this scope.
Realtime / unsolicited messages
The WebSocket is intended to remain connected while Pheby is running.
The adapter must be able to push messages/events originating from Hermes even when they were not an immediate response to the most recent Pheby request. For example, if Hermes Gateway produces a scheduled/automated message destined for the Pheby platform, the connected client should receive it.
Do not implement Firebase Cloud Messaging or another external push-notification service.
Android notification behavior is the client's responsibility.
Make reconnection resilient. The protocol should make it possible for the client to recover messages/events it missed during a temporary WebSocket disconnect, preferably by re-syncing authoritative conversation state rather than requiring a perfectly uninterrupted socket.
Protocol
Design a small, explicit and versioned Pheby protocol.
Prefer JSON messages over WebSocket.
Every event should contain a clear type and whatever IDs are needed to associate it with:
• Conversation.
• Message.
• Run.
• Tool call.
• Approval.
• Clarification.
• Attachment.
Avoid making the Android client parse prose to determine application state.
Use stable opaque IDs.
Include an initial handshake/protocol-version exchange if useful.
Provide clean error responses/events with machine-readable error codes and human-readable messages.
Consider heartbeat/ping handling and clean reconnect behavior.
Do not build unnecessary complexity such as a custom binary protocol.
Document every client → server and server → client message type with JSON examples.
The protocol specification is part of the deliverable.
Configuration
Use Hermes-compatible configuration conventions.
Secrets should use environment variables.
Non-secret behavioral configuration may use Hermes/plugin YAML configuration where appropriate.
At minimum configuration should cover:
• Enabled/disabled.
• Bind host.
• Port.
• Authentication secret.
• Attachment storage location if configurable.
• Attachment retention period, defaulting to 7 days.
• Verbose/debug protocol logging.
The default bind host should be safe for use behind a local Caddy reverse proxy rather than listening publicly on every interface without explicit configuration.
Logging
Provide normal useful logging for:
• Startup/shutdown.
• Connections/disconnections.
• Authentication failures.
• Conversation routing errors.
• Hermes agent errors.
• Attachment handling.
• Cleanup.
• Approval/clarification lifecycle errors.
Include a configurable verbose/debug logging mode useful while developing the Android client.
Debug logging must still avoid printing:
• Authentication secrets.
• Provider API keys.
• Sensitive authorization headers.
Be thoughtful about whether raw chat content or tool results should appear in verbose logs; default to protecting user content unless explicitly configured otherwise.
Security requirements
Treat this adapter as access to a powerful personal Hermes agent capable of using tools on the host.
Do not trust client-provided filesystem paths.
Do not expose arbitrary filesystem downloads.
Prevent path traversal.
Authenticate all non-health-check functionality.
Use constant-time secret comparison where appropriate.
Validate message sizes and input structure.
Apply reasonable limits to avoid trivially exhausting server memory with malformed WebSocket messages.
Do not leak stack traces/internal paths to remote clients.
Design it to be safely reverse-proxied through Caddy over HTTPS/WSS.
CORS is not important because the intended client is native Android.
If HTTP health-check endpoints are included, they should expose minimal information.
Plugin quality
Keep the code maintainable and idiomatic for the existing Hermes codebase.
Reuse Hermes abstractions instead of copying large portions of gateway logic.
Use async code consistently with Hermes where appropriate.
Keep networking, Hermes adapter integration, attachment management, authentication, and protocol serialization separated enough to be understandable and testable.
Add type hints.
Add useful docstrings/comments where behavior is non-obvious.
Avoid unnecessary dependencies. Prefer libraries Hermes already depends on when practical.
Tests
Include tests for important behavior, particularly:
• Authentication success/failure.
• Conversation operations.
• Protocol serialization/parsing.
• Attachment registration and secure download.
• Rejection of arbitrary/path-traversal file access.
• Seven-day attachment expiration/cleanup.
• Tool-call event translation.
• Approval round trip.
• Clarification/choice round trip.
• Cancellation of active runs.
• WebSocket reconnect/recovery behavior where practical.
Mock the Hermes agent/gateway where appropriate rather than making tests consume paid LLM API calls.
Documentation
Create documentation explaining:
• Installation into Hermes.
• Required environment variables.
• Optional configuration.
• Starting Hermes with Pheby enabled.
• Example Caddy reverse-proxy configuration supporting WebSockets and attachment downloads.
• How authentication works.
• Pheby protocol specification.
• Conversation operations.
• Chat/message flow.
• Tool events.
• Approvals.
• Clarifications.
• Cancellation.
• Model selection.
• Reasoning effort.
• Attachment delivery.
• Attachment expiration.
• Reconnection behavior.
• Debugging/logging.
• Security considerations.
Include enough examples that I can implement the Kotlin/Compose client from the protocol documentation later.
Implementation process
Before writing the implementation, inspect the actual current Hermes abstractions and identify how the existing first-party platform adapters accomplish:
• registration,
• inbound messages,
• outbound messages,
• conversations/sessions,
• tool progress,
• deliverables,
• approvals,
• clarification prompts,
• cancellation,
• unsolicited Gateway messages.
Prefer adapting those existing mechanisms over designing parallel ones.
If one of my requirements cannot be implemented cleanly through Hermes's public plugin/adapter APIs, do not modify Hermes core to force it.
Instead:
1. Explain exactly what Hermes currently exposes.
2. Explain what limitation prevents the requested behavior.
3. Implement the cleanest supported approximation if one exists.
4. Keep the protocol extensible so the proper feature can be added later if Hermes exposes it.
Do not silently omit required functionality.
At the end, give me:
• The complete plugin source.
• Installation/configuration files.
• Tests.
• Protocol documentation.
• Caddy example.
• A concise explanation of the architecture.
• Any Hermes-version-specific limitations you discovered.
• A list of the key protocol events/endpoints that the eventual Kotlin client needs to implement.
The resulting Pheby adapter should require no Hermes core modifications and should survive normal Hermes upgrades as well as can reasonably be expected from its documented plugin API.