53ffdb8aa2
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.
274 lines
16 KiB
Plaintext
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. |