Documentation
¶
Overview ¶
Package hermesacp exposes Hermes as an Agent Client Protocol agent.
Serve starts one authenticated loopback Hermes gateway per ACP session. The harness inherits the adapter environment and keeps its native state in HERMES_HOME, so the conversation can also continue through Hermes's CLI.
WithSessionStore supplies durable per-conversation snapshots. Load restores and replays history; resume restores without replay. The adapter preserves native state when sessions close.
Hosts supply telemetry providers through WithTracerProvider and WithMeterProvider; the package never configures global providers.
Index ¶
- Constants
- func Serve(ctx context.Context, input io.Reader, output io.Writer, opts ...Option) (returnErr error)
- func SetModelRequest(sessionID acp.SessionId, model string) acp.SetSessionConfigOptionRequest
- func ValidateHermesSessionMeta(meta map[string]any) error
- func WithSessionHermesOptions(options HermesOptions) wire.SessionRequestOption
- func WithSessionRawEvents(enabled bool) wire.SessionRequestOption
- type Agent
- func (a *Agent) Authenticate(_ context.Context, params acp.AuthenticateRequest) (acp.AuthenticateResponse, error)
- func (a *Agent) Cancel(ctx context.Context, params acp.CancelNotification) (err error)
- func (a *Agent) Close() error
- func (a *Agent) CloseSession(ctx context.Context, params acp.CloseSessionRequest) (resp acp.CloseSessionResponse, err error)
- func (a *Agent) HandleExtensionMethod(ctx context.Context, method string, params json.RawMessage) (any, error)
- func (a *Agent) Initialize(ctx context.Context, params acp.InitializeRequest) (resp acp.InitializeResponse, err error)
- func (a *Agent) ListSessions(ctx context.Context, params acp.ListSessionsRequest) (resp acp.ListSessionsResponse, err error)
- func (a *Agent) LoadSession(ctx context.Context, params acp.LoadSessionRequest) (resp acp.LoadSessionResponse, err error)
- func (a *Agent) Logout(_ context.Context, params acp.LogoutRequest) (acp.LogoutResponse, error)
- func (a *Agent) NewSession(ctx context.Context, params acp.NewSessionRequest) (resp acp.NewSessionResponse, err error)
- func (a *Agent) Prompt(ctx context.Context, params acp.PromptRequest) (resp acp.PromptResponse, err error)
- func (a *Agent) ResumeSession(ctx context.Context, params acp.ResumeSessionRequest) (resp acp.ResumeSessionResponse, err error)
- func (a *Agent) SetSessionConfigOption(ctx context.Context, params acp.SetSessionConfigOptionRequest) (resp acp.SetSessionConfigOptionResponse, err error)
- func (a *Agent) SetSessionMode(_ context.Context, params acp.SetSessionModeRequest) (acp.SetSessionModeResponse, error)
- func (a *Agent) UnstableDeleteSession(ctx context.Context, params acp.UnstableDeleteSessionRequest) (resp acp.UnstableDeleteSessionResponse, err error)
- type ConcurrencyLimits
- type HermesOption
- type HermesOptions
- type ImageLimits
- type Option
- func WithAgentName(name string) Option
- func WithAgentTitle(title string) Option
- func WithAgentVersion(version string) Option
- func WithConcurrencyLimits(limits ConcurrencyLimits) Option
- func WithConfiguredModels(ids []string) Option
- func WithDefaultModel(model string) Option
- func WithEnv(env map[string]string) Option
- func WithExecutablePath(path string) Option
- func WithHome(path string) Option
- func WithImageLimits(limits ImageLimits) Option
- func WithInputHandoffRoot(dir string) Option
- func WithLogger(logger *slog.Logger) Option
- func WithMeterProvider(provider metric.MeterProvider) Option
- func WithScratchDir(dir string) Option
- func WithSeedFiles(files map[string]string) Option
- func WithSessionStore(store acpcore.SessionStore) Option
- func WithTextMapPropagator(propagator propagation.TextMapPropagator) Option
- func WithTracerProvider(provider trace.TracerProvider) Option
- type Options
Examples ¶
Constants ¶
const ( // RawEventMethod is the notification carrying one raw hermes event when a // session opted in through _meta.hermes.rawEvent.enabled. RawEventMethod = "_hermes/rawEvent" // AccountUsageMethod reads a provider's account usage through the gateways // hermes's config routes to. AccountUsageMethod = "_hermes/accountUsage" // SessionStoreFormat identifies the store layout this package writes: native // per-conversation JSON exports under main plus the adapter's session // record under the config subpath. SessionStoreFormat = "hermes-session-json-v1" )
Variables ¶
This section is empty.
Functions ¶
func Serve ¶
func Serve(ctx context.Context, input io.Reader, output io.Writer, opts ...Option) (returnErr error)
Serve runs an ACP agent over the provided streams. It blocks until the context is cancelled or the peer closes the connection, then closes the agent.
Example (Initialize) ¶
ExampleServe_initialize embeds the agent over a pair of pipes, the same wiring a host uses for stdio, and reads the capabilities the handshake advertises.
package main
import (
"bufio"
"context"
"encoding/json"
"fmt"
"io"
hermesacp "github.com/savid/acp-go-hermes"
)
func main() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
clientToAgentReader, clientToAgentWriter := io.Pipe()
agentToClientReader, agentToClientWriter := io.Pipe()
done := make(chan error, 1)
go func() {
done <- hermesacp.Serve(ctx, clientToAgentReader, agentToClientWriter)
}()
_, _ = fmt.Fprintln(clientToAgentWriter,
`{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":1}}`)
line, _ := bufio.NewReader(agentToClientReader).ReadString('\n')
cancel()
_ = clientToAgentWriter.Close()
<-done
var response struct {
Result struct {
AuthMethods []any `json:"authMethods"`
AgentCapabilities struct {
LoadSession bool `json:"loadSession"`
SessionCapabilities map[string]any `json:"sessionCapabilities"`
} `json:"agentCapabilities"`
} `json:"result"`
}
_ = json.Unmarshal([]byte(line), &response)
fmt.Println(len(response.Result.AuthMethods))
fmt.Println(response.Result.AgentCapabilities.LoadSession)
fmt.Println(len(response.Result.AgentCapabilities.SessionCapabilities))
}
Output: 0 true 5
func SetModelRequest ¶
func SetModelRequest(sessionID acp.SessionId, model string) acp.SetSessionConfigOptionRequest
SetModelRequest constructs a model selector update as "provider/id".
func ValidateHermesSessionMeta ¶
ValidateHermesSessionMeta runs the owned-namespace parsing of a session lifecycle request's _meta without an Agent and returns the same refusal.
func WithSessionHermesOptions ¶
func WithSessionHermesOptions(options HermesOptions) wire.SessionRequestOption
WithSessionHermesOptions merges hermes-specific options into _meta.hermes.options of a session lifecycle request.
func WithSessionRawEvents ¶
func WithSessionRawEvents(enabled bool) wire.SessionRequestOption
WithSessionRawEvents toggles raw hermes event emission for the session.
Types ¶
type Agent ¶
type Agent struct {
// contains filtered or unexported fields
}
Agent exposes the hermes coding agent through ACP.
func NewAgent ¶
NewAgent creates an ACP agent for the hermes coding agent CLI. Construction never fails; a refused option is reported by Initialize and every session-establishing method as hermes_invalid_options.
func (*Agent) Authenticate ¶
func (a *Agent) Authenticate(_ context.Context, params acp.AuthenticateRequest) (acp.AuthenticateResponse, error)
Authenticate exists because the SDK interface requires it. The harness authenticates itself in its own home, outside ACP.
func (*Agent) Cancel ¶
Cancel interrupts the session's in-flight turn. It is wire-silent on an unknown session or with no turn in flight.
func (*Agent) Close ¶
Close runs the shutdown ladder for every session and refuses every later request.
func (*Agent) CloseSession ¶
func (a *Agent) CloseSession(ctx context.Context, params acp.CloseSessionRequest) (resp acp.CloseSessionResponse, err error)
CloseSession runs the shutdown ladder for one session.
func (*Agent) HandleExtensionMethod ¶
func (a *Agent) HandleExtensionMethod(ctx context.Context, method string, params json.RawMessage) (any, error)
HandleExtensionMethod serves the account-usage read; every other extension method is method-not-found.
func (*Agent) Initialize ¶
func (a *Agent) Initialize(ctx context.Context, params acp.InitializeRequest) (resp acp.InitializeResponse, err error)
Initialize implements ACP initialize.
func (*Agent) ListSessions ¶
func (a *Agent) ListSessions(ctx context.Context, params acp.ListSessionsRequest) (resp acp.ListSessionsResponse, err error)
ListSessions lists live sessions and stored sessions, newest first.
func (*Agent) LoadSession ¶
func (a *Agent) LoadSession(ctx context.Context, params acp.LoadSessionRequest) (resp acp.LoadSessionResponse, err error)
LoadSession restores a session and replays its history.
func (*Agent) Logout ¶
func (a *Agent) Logout(_ context.Context, params acp.LogoutRequest) (acp.LogoutResponse, error)
Logout exists because the SDK interface requires it.
func (*Agent) NewSession ¶
func (a *Agent) NewSession(ctx context.Context, params acp.NewSessionRequest) (resp acp.NewSessionResponse, err error)
NewSession creates and starts a hermes session.
func (*Agent) Prompt ¶
func (a *Agent) Prompt(ctx context.Context, params acp.PromptRequest) (resp acp.PromptResponse, err error)
Prompt sends one turn to hermes and streams updates until it settles.
func (*Agent) ResumeSession ¶
func (a *Agent) ResumeSession(ctx context.Context, params acp.ResumeSessionRequest) (resp acp.ResumeSessionResponse, err error)
ResumeSession restores a session without replaying its history.
func (*Agent) SetSessionConfigOption ¶
func (a *Agent) SetSessionConfigOption(ctx context.Context, params acp.SetSessionConfigOptionRequest) (resp acp.SetSessionConfigOptionResponse, err error)
SetSessionConfigOption applies one select value.
func (*Agent) SetSessionMode ¶
func (a *Agent) SetSessionMode(_ context.Context, params acp.SetSessionModeRequest) (acp.SetSessionModeResponse, error)
SetSessionMode exists because the SDK interface requires it. Native modes are config options, never ACP session modes.
func (*Agent) UnstableDeleteSession ¶
func (a *Agent) UnstableDeleteSession(ctx context.Context, params acp.UnstableDeleteSessionRequest) (resp acp.UnstableDeleteSessionResponse, err error)
UnstableDeleteSession tombstones the session first, then closes any live session with the same id. Native state stays in hermes's home.
type ConcurrencyLimits ¶
ConcurrencyLimits controls per-agent backpressure. Zero fields use defaults.
type HermesOption ¶
type HermesOption func(*HermesOptions)
HermesOption configures HermesOptions values.
func WithHermesEffort ¶
func WithHermesEffort(level string) HermesOption
WithHermesEffort configures the reasoning level passed to hermes.
func WithHermesEnv ¶
func WithHermesEnv(env map[string]string) HermesOption
WithHermesEnv configures the session environment overlay.
func WithHermesExtraPathDirs ¶
func WithHermesExtraPathDirs(dirs ...string) HermesOption
WithHermesExtraPathDirs configures the directories prepended to the session PATH.
func WithHermesModel ¶
func WithHermesModel(model string) HermesOption
WithHermesModel configures the session model as "provider/id".
type HermesOptions ¶
type HermesOptions struct {
// Model selects the hermes model for this session as "provider/id".
Model string `json:"model,omitempty"`
// Env overlays the session's hermes process environment.
Env map[string]string `json:"env,omitempty"`
// ExtraPathDirs are absolute directories prepended, in order, to the PATH
// of this session's hermes process.
ExtraPathDirs []string `json:"extraPathDirs,omitempty"`
// Effort is a reasoning-level value passed unchanged to hermes.
Effort string `json:"effort,omitempty"`
}
HermesOptions is the per-session options struct carried at _meta.hermes.options.
func NewHermesOptions ¶
func NewHermesOptions(opts ...HermesOption) HermesOptions
NewHermesOptions constructs HermesOptions from functional options.
Example ¶
package main
import (
"fmt"
hermesacp "github.com/savid/acp-go-hermes"
)
func main() {
options := hermesacp.NewHermesOptions(
hermesacp.WithHermesModel("provider/model"),
hermesacp.WithHermesEffort("high"),
)
fmt.Println(options.Model)
fmt.Println(options.Effort)
}
Output: provider/model high
func (HermesOptions) Meta ¶
func (options HermesOptions) Meta() map[string]any
Meta returns exactly {"hermes": {"options": {...}}} with the selected fields.
type ImageLimits ¶
type ImageLimits struct {
MaxInputBytesPerImage int64
MaxInputBytesPerPrompt int64
MaxOutputBytesPerImage int64
MaxOutputBytesPerToolCall int64
}
ImageLimits bounds decoded image bytes. A zero field disables that policy limit; the frame clamp still applies.
type Option ¶
type Option func(*Options)
Option configures the hermes ACP agent.
func WithAgentName ¶
WithAgentName sets the protocol identifier advertised during ACP initialize.
func WithAgentTitle ¶
WithAgentTitle sets the human-readable agent name advertised during ACP initialize.
func WithAgentVersion ¶
WithAgentVersion sets the agent version advertised during ACP initialize.
func WithConcurrencyLimits ¶
func WithConcurrencyLimits(limits ConcurrencyLimits) Option
WithConcurrencyLimits sets process-local backpressure limits.
func WithConfiguredModels ¶
WithConfiguredModels names the models the host lists explicitly.
func WithDefaultModel ¶
WithDefaultModel selects the model for new sessions as "provider/id".
func WithEnv ¶
WithEnv sets the static agent-scoped environment overlay applied to every hermes process after the inherited environment and before the session env.
func WithExecutablePath ¶
WithExecutablePath selects the hermes executable.
func WithImageLimits ¶
func WithImageLimits(limits ImageLimits) Option
WithImageLimits bounds decoded image bytes. A zero field disables that policy limit; a negative field fails construction.
func WithInputHandoffRoot ¶
WithInputHandoffRoot sets the absolute directory under which handoff-form prompt images are read. The adapter never writes there.
func WithLogger ¶
WithLogger configures structured diagnostic logging.
func WithMeterProvider ¶
func WithMeterProvider(provider metric.MeterProvider) Option
WithMeterProvider configures the OpenTelemetry meter provider.
func WithScratchDir ¶
WithScratchDir accepts the configured parent for ephemeral adapter state. This adapter allocates none.
func WithSeedFiles ¶
WithSeedFiles registers files written into hermes's config root before each launch. Keys are paths relative to that root; values are the contents.
func WithSessionStore ¶
func WithSessionStore(store acpcore.SessionStore) Option
WithSessionStore configures the session store.
func WithTextMapPropagator ¶
func WithTextMapPropagator(propagator propagation.TextMapPropagator) Option
WithTextMapPropagator configures trace-context extraction from ACP _meta.
func WithTracerProvider ¶
func WithTracerProvider(provider trace.TracerProvider) Option
WithTracerProvider configures the OpenTelemetry tracer provider.
type Options ¶
type Options struct {
// AgentName is the protocol identifier advertised during ACP initialize.
AgentName string
// AgentTitle is the human-readable agent name advertised during ACP initialize.
AgentTitle string
// AgentVersion is the agent version advertised during ACP initialize.
AgentVersion string
// ExecutablePath selects the hermes executable. A bare name is searched on the
// base PATH; a path containing a separator is used as given. Empty means
// "hermes".
ExecutablePath string
// Home is hermes's native config, auth, and runtime root, passed to every
// session as HERMES_HOME. Empty leaves hermes to resolve its home from
// the inherited environment exactly as it would from a shell.
Home string
// ScratchDir is accepted and ignored. This adapter allocates no ephemeral
// state, so nothing is written under it.
ScratchDir string
// InputHandoffRoot is the absolute directory under which handoff-form
// prompt images are read. Empty rejects the handoff form.
InputHandoffRoot string
// DefaultModel selects the model for new sessions as "provider/id".
DefaultModel string
// ConfiguredModels are the model ids the host lists explicitly, each as
// "provider/id".
ConfiguredModels []string
// Env is the static agent-scoped overlay on the inherited process
// environment every hermes process runs with.
Env map[string]string
// Logger receives structured diagnostic logs. If nil, the default logger is used.
Logger *slog.Logger
// TracerProvider records adapter spans. If nil, tracing is a no-op.
TracerProvider trace.TracerProvider
// MeterProvider records adapter metrics. If nil, metrics are no-ops.
MeterProvider metric.MeterProvider
// TextMapPropagator extracts trace context from ACP _meta. If nil, W3C
// trace context plus baggage propagation is used.
TextMapPropagator propagation.TextMapPropagator
// SessionStore is the durability boundary for session rows. Nil installs a
// fresh in-memory store.
SessionStore acpcore.SessionStore
// ConcurrencyLimits controls process-local backpressure.
ConcurrencyLimits ConcurrencyLimits
// SeedFiles maps paths relative to hermes's config root to file contents
// written there before each launch.
SeedFiles map[string]string
// ImageLimits bounds decoded image bytes on prompt input and emitted
// output. Every field defaults to 6 MiB when the option is omitted.
ImageLimits ImageLimits
// contains filtered or unexported fields
}
Options configures the ACP agent process and the hermes serve gateway sessions it starts.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
cmd
|
|
|
acp-go-hermes
command
|
|
|
Package integration holds the tests that run against an installed Hermes.
|
Package integration holds the tests that run against an installed Hermes. |
|
internal
|
|