Documentation
¶
Overview ¶
Package agentadapters: approvals.go declares the wire types, constants, store interfaces, and shared sentinel errors for the adapter approval system. The coordinator implementation lives in approvals_coordinator.go; the operator-facing Resolve/Cancel/list API lives in approvals_resolve.go; ID helpers live in approvals_ids.go; the in-memory store lives in approvals_memory.go; the SQL-backed store lives in approvals_sqlite.go.
Index ¶
- Constants
- Variables
- func DetectAuthStatus(adapter Adapter) (string, string)
- func DetectVersion(ctx context.Context, path string) string
- func DetectVersionProbe(ctx context.Context, probe VersionProbe, lookup LookupFunc) string
- func DevOverrideActive(adapterID string) bool
- func IsFailedPromptCommandLifecycleRaw(raw string) bool
- func IsLaunchConfigOption(adapterID, configID string) bool
- func IsPrivateACPRawOutputWithheld(raw string) bool
- func LaunchConfigOptionForSet(adapterID, configID, value string) (agentcontrols.ConfigOption, bool)
- func LaunchConfigOptions(ctx context.Context, status Status) []agentcontrols.ConfigOption
- func NormalizeError(adapterName string, err error) string
- func NormalizeOutput(adapterID, raw string) string
- func SetProbeMetrics(metrics *telemetry.AgentAdapterMetrics)
- func ValidateWorkspace(path string) (string, error)
- type Activity
- type Adapter
- type AmbiguousOptionError
- type Approval
- type ApprovalCoordinator
- func (c *ApprovalCoordinator) Cancel(ctx context.Context, id string) (Approval, error)
- func (c *ApprovalCoordinator) DeleteGrant(ctx context.Context, id string) error
- func (c *ApprovalCoordinator) GetApproval(ctx context.Context, id string) (Approval, error)
- func (c *ApprovalCoordinator) ListApprovals(ctx context.Context, sessionID string, status ApprovalStatus) ([]Approval, error)
- func (c *ApprovalCoordinator) ListGrants(ctx context.Context, filter GrantFilter) ([]Grant, error)
- func (c *ApprovalCoordinator) Mode() ApprovalMode
- func (c *ApprovalCoordinator) RequestPermission(ctx context.Context, recCtx RecordingContext, ...) (acp.RequestPermissionResponse, error)
- func (c *ApprovalCoordinator) Resolve(ctx context.Context, id string, req ResolveRequest) (Approval, error)
- func (c *ApprovalCoordinator) Store() ApprovalStore
- func (c *ApprovalCoordinator) Timeout() time.Duration
- type ApprovalDecision
- type ApprovalMode
- type ApprovalOption
- type ApprovalResolutionPath
- type ApprovalRetentionStore
- type ApprovalScope
- type ApprovalStatus
- type ApprovalStore
- type AuthenticateResult
- type AvailableCommandsUpdate
- type Capability
- type CoordinatorHooks
- type CoordinatorOptions
- type CredentialMode
- type Grant
- type GrantFilter
- type LaunchModel
- type LaunchModelConfig
- type LaunchSelectConfig
- type LaunchSelectOption
- type LogoutResult
- type LookupFunc
- type MemoryApprovalStore
- func (s *MemoryApprovalStore) CreateApproval(_ context.Context, a Approval) (Approval, error)
- func (s *MemoryApprovalStore) CreateGrant(_ context.Context, g Grant) (Grant, error)
- func (s *MemoryApprovalStore) DeleteGrant(_ context.Context, id string) error
- func (s *MemoryApprovalStore) FindMatchingGrant(_ context.Context, sessionID, workspace, adapterID, toolKind string, ...) (Grant, bool, error)
- func (s *MemoryApprovalStore) GetApproval(_ context.Context, id string) (Approval, error)
- func (s *MemoryApprovalStore) ListApprovals(_ context.Context, sessionID string, status ApprovalStatus) ([]Approval, error)
- func (s *MemoryApprovalStore) ListGrants(_ context.Context, filter GrantFilter, now time.Time) ([]Grant, error)
- func (s *MemoryApprovalStore) Prune(ctx context.Context, maxAge time.Duration, maxCount int) (int, error)
- func (s *MemoryApprovalStore) PruneApprovals(_ context.Context, now time.Time, maxAge time.Duration, maxCount int) (int64, error)
- func (s *MemoryApprovalStore) PruneExpiredGrants(_ context.Context, now time.Time) (int64, error)
- func (s *MemoryApprovalStore) ReconcilePending(_ context.Context, now time.Time) (int64, error)
- func (s *MemoryApprovalStore) ResolveApproval(_ context.Context, id string, status ApprovalStatus, decision ApprovalDecision, ...) (Approval, error)
- type NativeSessionReplacement
- type NativeSessionScope
- type PrepareSessionRequest
- type PrepareSessionResult
- type ProbeAgentInfo
- type ProbeAuthMethod
- type ProbeResult
- type PromptFile
- type PromptInput
- type RecordingContext
- type ResolveRequest
- type RunRequest
- type RunResult
- type Runner
- type SQLiteApprovalStore
- func (s *SQLiteApprovalStore) Backend() string
- func (s *SQLiteApprovalStore) CreateApproval(ctx context.Context, a Approval) (Approval, error)
- func (s *SQLiteApprovalStore) CreateGrant(ctx context.Context, g Grant) (Grant, error)
- func (s *SQLiteApprovalStore) DeleteGrant(ctx context.Context, id string) error
- func (s *SQLiteApprovalStore) FindMatchingGrant(ctx context.Context, sessionID, workspace, adapterID, toolKind string, ...) (Grant, bool, error)
- func (s *SQLiteApprovalStore) GetApproval(ctx context.Context, id string) (Approval, error)
- func (s *SQLiteApprovalStore) ListApprovals(ctx context.Context, sessionID string, status ApprovalStatus) ([]Approval, error)
- func (s *SQLiteApprovalStore) ListGrants(ctx context.Context, filter GrantFilter, now time.Time) ([]Grant, error)
- func (s *SQLiteApprovalStore) Prune(ctx context.Context, maxAge time.Duration, maxCount int) (int, error)
- func (s *SQLiteApprovalStore) PruneApprovals(ctx context.Context, now time.Time, maxAge time.Duration, maxCount int) (int64, error)
- func (s *SQLiteApprovalStore) PruneExpiredGrants(ctx context.Context, now time.Time) (int64, error)
- func (s *SQLiteApprovalStore) ReconcilePending(ctx context.Context, now time.Time) (int64, error)
- func (s *SQLiteApprovalStore) ResolveApproval(ctx context.Context, id string, status ApprovalStatus, ...) (Approval, error)
- type SessionManager
- func (m *SessionManager) CloseSession(ctx context.Context, sessionID string) error
- func (m *SessionManager) Coordinator() *ApprovalCoordinator
- func (m *SessionManager) DeleteSession(ctx context.Context, sessionID string) error
- func (m *SessionManager) PrepareSession(ctx context.Context, req PrepareSessionRequest) (PrepareSessionResult, error)
- func (m *SessionManager) Run(ctx context.Context, req RunRequest) (RunResult, error)
- func (m *SessionManager) SetAdapterMetrics(metrics *telemetry.AgentAdapterMetrics)
- func (m *SessionManager) SetApprovalCoordinator(coordinator *ApprovalCoordinator)
- func (m *SessionManager) SetAvailableCommandsUpdateHook(hook func(AvailableCommandsUpdate))
- func (m *SessionManager) SetLogger(logger *slog.Logger)
- func (m *SessionManager) SetSecretCipher(cipher secrets.Cipher)
- func (m *SessionManager) SetSessionConfigOption(ctx context.Context, req SetSessionConfigOptionRequest) (SetSessionConfigOptionResult, error)
- func (m *SessionManager) SetTerminalSupportEnabled(enabled bool)
- func (m *SessionManager) SetWorkspaceCoordinator(registry *workspacecoord.Registry)
- func (m *SessionManager) Shutdown(ctx context.Context) error
- type SetSessionConfigOptionRequest
- type SetSessionConfigOptionResult
- type SetupCommandStatus
- type Status
- func ApplyProbeCapabilities(status Status, result ProbeResult) Status
- func CatalogStatusForAdapter(ctx context.Context, id string, lookup LookupFunc) (Status, bool)
- func List(ctx context.Context) []Status
- func ListCatalog(ctx context.Context) []Status
- func ListCatalogWithLookup(ctx context.Context, lookup LookupFunc) []Status
- func ListWithLookup(ctx context.Context, lookup LookupFunc) []Status
- func StatusForAdapter(ctx context.Context, id string, lookup LookupFunc) (Status, bool)
- func StatusForAdapterAfterExplicitProbe(ctx context.Context, id string, lookup LookupFunc) (Status, bool)
- type Usage
- type VersionProbe
Constants ¶
const ( AuthenticateStatusAuthenticated = "authenticated" LogoutStatusLoggedOut = "logged_out" ACPAuthMethodAgentLogin = "agent-login" )
const ( ProbeStatusUnverified = "unverified" ProbeStatusReady = "ready" ProbeStatusNotInstalled = "not_installed" ProbeStatusAuthRequired = "auth_required" ProbeStatusError = "error" )
Probe statuses. "unverified" is reserved for passive catalog/health reads; every other status is an operator-facing classification from an explicit probe or a lookup failure. Stable strings — once exported on the wire they are part of the frontend contract.
const ( ProbeStageLookup = "lookup" ProbeStageSpawn = "spawn" ProbeStageInitialize = "initialize" ProbeStageNewSession = "new_session" ProbeStageReady = "ready" )
Probe stages. Track which step in the runtime-and-handshake sequence failed so the UI can give a concrete next-action hint without the operator having to read the raw error.
const ( StatusAvailable = "available" StatusMissing = "missing" )
const ( AuthStatusOK = "ok" AuthStatusUnauthenticated = "unauthenticated" AuthStatusBilling = "billing" AuthStatusUnknown = "unknown" )
const ( CredentialModeLocalLogin = "local_login" CredentialModeAPIKey = "api_key" CredentialModeEnterpriseToken = "enterprise_token" CredentialModeVendorHosted = "vendor_hosted" )
const ( CapabilityPromptSession = "prompt_session" CapabilityStructuredStream = "structured_stream" CapabilityCancel = "cancel" CapabilityPermissions = "permissions" CapabilityMCPServers = "mcp_servers" CapabilityConfigOptions = "config_options" CapabilityTerminalRPC = "terminal_rpc" CapabilityAuthenticate = "authenticate" CapabilityLogout = "logout" )
const ( CapabilityStatusSupported = "supported" CapabilityStatusAdapterDependent = "adapter_dependent" CapabilityStatusOperatorOptIn = "operator_opt_in" CapabilityStatusNotSupported = "not_supported" )
const ( // MaxPromptFiles matches Hecate Chat's public per-message attachment // ceiling. Keeping the transport boundary independently bounded prevents a // non-HTTP caller from constructing an unexpectedly large ACP prompt. MaxPromptFiles = 4 // MaxPromptFileBytes is the public per-file upload ceiling. MaxPromptFileBytes = int64(5 << 20) // MaxPromptFilesBytes preserves the public combined-message attachment // limit. ACP dispatch independently stages rich blocks that would exceed // its conservative inline wire budget. MaxPromptFilesBytes = int64(12 << 20) )
const ( ToolKindFileWrite = "file_write" ToolKindFileRead = "file_read" ToolKindShellExec = "shell_exec" ToolKindNetwork = "network" ToolKindFileMove = "file_move" ToolKindFileDelete = "file_delete" ToolKindSearch = "search" ToolKindThink = "think" ToolKindMCP = "mcp" ToolKindOther = "other" )
Tool-kind taxonomy used by approval records and grants.
We deliberately choose a small, stable closed set rather than the adapter's free-form tool names. Operators reason about "did Codex just want to write a file" not "did Codex just want to call its `apply_patch` v3.1 tool." The mapping below normalizes adapter terms into Hecate's set; unrecognized terms land as "other" and keep the raw adapter name in Approval.ToolName for diagnostics.
const DriverKindACP = "acp"
Variables ¶
var ErrAmbiguousOption = errors.New("ambiguous adapter option; selected_option required")
ErrAmbiguousOption is returned by Coordinator helpers when the operator's decision could match multiple ACP options and no explicit selected_option was provided. Surfaced as 409 by the HTTP handler.
var ErrApprovalAlreadyResolved = errors.New("approval already resolved")
ErrApprovalAlreadyResolved is returned by ResolveApproval when the row is already in a terminal state. Resolutions are append-only from a state-machine perspective even though they're a single row.
var ErrApprovalNotFound = errors.New("approval not found")
ErrApprovalNotFound is returned by ApprovalStore.GetApproval and ResolveApproval when the id doesn't match a known row.
var ErrInvalidDecision = errors.New("decision must be approve or deny")
ErrInvalidDecision / ErrInvalidScope are returned for malformed resolve requests. Surface as 400 invalid_request.
var ErrInvalidScope = errors.New("scope must be once, session, workspace_tool, or adapter_tool")
var ErrLaunchModelRequired = errors.New("launch model required")
ErrLaunchModelRequired means Hecate owns the model launch flag for an adapter and the operator has not selected a concrete model yet.
var ErrNoMatchingOption = errors.New("no ACP option matches the requested decision")
ErrNoMatchingOption is returned by Resolve when the operator's decision has no matching ACP option family on the recorded request (e.g. operator says deny but the adapter offered no reject_* option). Surfaces as 409 conflict; caller may retry as Cancel.
var ErrRemoteCredentialRequired = errors.New("remote-safe external-agent credential required")
ErrRemoteCredentialRequired means a remote-mode request tried to start an external agent without an explicitly allowed credential mode.
var ErrSessionNotActive = errors.New("agent chat session is not active")
var ErrUnknownOption = errors.New("selected_option does not match any option recorded for this approval")
ErrUnknownOption is returned by Resolve when SelectedOption was supplied but doesn't match any option_id on the recorded approval. Surfaces as 400 invalid_request.
Functions ¶
func DetectAuthStatus ¶
DetectAuthStatus is an explicit diagnostic. Most branches inspect local credential hints, while Claude may run its bounded `auth status` command. Callers must keep it behind an operator-owned execution boundary.
func DetectVersion ¶
DetectVersion runs the adapter binary at path with --version and returns the first semver-shaped token found in combined stdout/stderr output. Returns an empty string if the binary is not reachable, does not respond within detectVersionTimeout, or prints no recognisable version string.
func DetectVersionProbe ¶
func DetectVersionProbe(ctx context.Context, probe VersionProbe, lookup LookupFunc) string
func DevOverrideActive ¶
DevOverrideActive reports whether HECATE_AGENT_ADAPTER_DEV_OVERRIDES has a valid fixture for adapterID. API handlers use it to keep visual smoke-test state synthetic end-to-end instead of letting a probe response "correct" the catalog row from the real machine.
func IsFailedPromptCommandLifecycleRaw ¶
IsFailedPromptCommandLifecycleRaw recognizes the persisted form of the command bridge's outer prompt-subprocess start/failed-finish pair. It rejects extra records, provider updates, mismatched sessions, and malformed JSON.
func IsLaunchConfigOption ¶
IsLaunchConfigOption reports whether configID is owned by Hecate's launch-time adapter wrapper instead of the live ACP session.
func IsPrivateACPRawOutputWithheld ¶
IsPrivateACPRawOutputWithheld reports whether raw ACP diagnostics were intentionally replaced because a turn carried private staged file inputs.
func LaunchConfigOptionForSet ¶
func LaunchConfigOptionForSet(adapterID, configID, value string) (agentcontrols.ConfigOption, bool)
LaunchConfigOptionForSet builds the Hecate-owned launch option for a pending config update. It is used when an older persisted chat session has no copy of the launch controls that the current adapter registry exposes.
func LaunchConfigOptions ¶
func LaunchConfigOptions(ctx context.Context, status Status) []agentcontrols.ConfigOption
LaunchConfigOptions returns Hecate-managed adapter options that can be selected before a concrete ACP session exists. It may execute bounded help/model discovery and therefore belongs only behind an explicit operator action, never passive catalog discovery. Built-ins must not require one of these options until a separate passive schema path exists.
func NormalizeError ¶
func NormalizeOutput ¶
func SetProbeMetrics ¶
func SetProbeMetrics(metrics *telemetry.AgentAdapterMetrics)
SetProbeMetrics installs the AgentAdapterMetrics used by every subsequent Probe call. Pass nil to disable. Callers wire this once at startup; Probe uses an atomic load so the setter is safe to call after handlers are already serving.
func ValidateWorkspace ¶
Types ¶
type Adapter ¶
type Adapter struct {
ID string
Name string
Command string
Args []string
CandidatePaths []string
// Embedded means Hecate serves this adapter in-process. Command and
// CandidatePaths then identify the provider CLI used by the embedded
// adapter. TestProcess* exists only for hermetic protocol fixtures; it is not
// a supported product runtime mode.
Embedded bool
TestProcessCommand string
TestProcessArgs []string
TestProcessCandidatePaths []string
AgentVersion VersionProbe
LaunchSuffixArgs []string
LaunchModel LaunchModelConfig
LaunchOptions []LaunchSelectConfig
Kind string
Description string
CostMode string
DocsURL string
SupportedRange string
SupportsAuthenticate bool
SupportsLogout bool
// NativeSessionScope describes whether a stored ACP session id can be
// restored after the adapter runtime exits. Process-scoped adapters require
// an explicit fresh-session replacement after restart; the zero value fails
// closed when session/load fails.
NativeSessionScope NativeSessionScope
CredentialModes []CredentialMode
Capabilities []Capability
}
func BuiltInByID ¶
func FindAdapter ¶
FindAdapter returns the built-in adapter matching id (exact match, case-sensitive — adapter ids are stable identifiers chosen by the gateway, not user-typed). Second return is false when id doesn't match any registered adapter.
type AmbiguousOptionError ¶
type AmbiguousOptionError struct {
Decision ApprovalDecision
Options []ApprovalOption
}
AmbiguousOptionError carries the candidate options when Resolve can't pick one unambiguously. The HTTP layer surfaces this as 409 conflict with the option list in the body so the operator UI can re-render the choices.
func (*AmbiguousOptionError) Error ¶
func (e *AmbiguousOptionError) Error() string
type Approval ¶
type Approval struct {
ID string `json:"id"`
SessionID string `json:"session_id"`
AdapterID string `json:"adapter_id"`
Workspace string `json:"workspace,omitempty"`
ToolKind string `json:"tool_kind"`
ToolName string `json:"tool_name,omitempty"`
Status ApprovalStatus `json:"status"`
ACPPayload json.RawMessage `json:"acp_payload,omitempty"`
ACPOptions []ApprovalOption `json:"acp_options"`
ScopeChoices []ApprovalScope `json:"scope_choices,omitempty"`
SelectedOption string `json:"selected_option,omitempty"`
Scope ApprovalScope `json:"scope,omitempty"`
Decision ApprovalDecision `json:"decision,omitempty"`
Path ApprovalResolutionPath `json:"path,omitempty"`
DecisionNote string `json:"decision_note,omitempty"`
CreatedAt time.Time `json:"created_at"`
ResolvedAt *time.Time `json:"resolved_at,omitempty"`
ExpiresAt time.Time `json:"expires_at"`
}
Approval is one recorded approval row. The shape mirrors the wire shape in the RFC; endpoints and persistence backends serialize this directly.
type ApprovalCoordinator ¶
type ApprovalCoordinator struct {
// contains filtered or unexported fields
}
ApprovalCoordinator applies the configured ApprovalMode to incoming ACP RequestPermission calls. It records every request, looks up matching grants, applies the mode default, and produces the ACP response that gets sent back to the adapter. In prompt mode, a blocked RequestPermission registers a process-local waiter that the operator's Resolve / Cancel call wakes via the wake() helper.
Waiters are intentionally not persisted: a Hecate restart cannot resurrect an in-flight ACP RequestPermission, so any pending row found in storage on startup is invalid as far as live blocking goes — the SQL backend startup reconcile pass marks such rows as `timed_out`.
func NewApprovalCoordinator ¶
func NewApprovalCoordinator(opts CoordinatorOptions) *ApprovalCoordinator
NewApprovalCoordinator constructs a coordinator with the given options. Sensible defaults are filled in for empty fields.
func (*ApprovalCoordinator) Cancel ¶
Cancel transitions a pending approval to cancelled (ACP Cancelled outcome). Different from a deny resolution: deny selects a reject option (telling the adapter the action is forbidden); cancel says "the operator declined to decide; back off and ask again later."
func (*ApprovalCoordinator) DeleteGrant ¶
func (c *ApprovalCoordinator) DeleteGrant(ctx context.Context, id string) error
DeleteGrant removes a grant by id.
func (*ApprovalCoordinator) GetApproval ¶
GetApproval is a thin store-backed accessor for the HTTP GET handler.
func (*ApprovalCoordinator) ListApprovals ¶
func (c *ApprovalCoordinator) ListApprovals(ctx context.Context, sessionID string, status ApprovalStatus) ([]Approval, error)
ListApprovals proxies to the store. Empty status returns all rows.
func (*ApprovalCoordinator) ListGrants ¶
func (c *ApprovalCoordinator) ListGrants(ctx context.Context, filter GrantFilter) ([]Grant, error)
ListGrants returns grants matching the filter. Empty filter returns all live grants. Expired grants are excluded.
func (*ApprovalCoordinator) Mode ¶
func (c *ApprovalCoordinator) Mode() ApprovalMode
Mode returns the configured mode (test introspection).
func (*ApprovalCoordinator) RequestPermission ¶
func (c *ApprovalCoordinator) RequestPermission(ctx context.Context, recCtx RecordingContext, params acp.RequestPermissionRequest) (acp.RequestPermissionResponse, error)
RequestPermission records the incoming ACP RequestPermission, applies the configured mode, and returns the ACP response to send back to the adapter.
Behavior by mode:
- All modes record the approval row.
- ModeAuto resolves immediately by selecting the first allow option (the original auto-approve behavior, opt-in only).
- ModeDeny resolves immediately with the first reject option, or Cancelled if none.
- ModePrompt records a pending approval and waits for operator resolve/cancel through the HTTP API, the configured timeout, or context cancellation.
func (*ApprovalCoordinator) Resolve ¶
func (c *ApprovalCoordinator) Resolve(ctx context.Context, id string, req ResolveRequest) (Approval, error)
Resolve transitions a pending approval to approved/denied per the operator's decision, persists a grant when scope > once, and (when a prompt-mode RequestPermission is blocked on this id) wakes the waiter so the adapter receives the operator's chosen ACP option without further delay.
Returns the resolved row. Errors:
- ErrApprovalNotFound — id doesn't match a known row
- ErrApprovalAlreadyResolved — row is already terminal
- ErrInvalidDecision / ErrInvalidScope — malformed input
- ErrUnknownOption — selected_option not in row's options
- ErrNoMatchingOption — decision has no matching option family
- *AmbiguousOptionError — multiple options match, no selected_option supplied
func (*ApprovalCoordinator) Store ¶
func (c *ApprovalCoordinator) Store() ApprovalStore
Store returns the configured store (test introspection).
func (*ApprovalCoordinator) Timeout ¶
func (c *ApprovalCoordinator) Timeout() time.Duration
Timeout returns the configured timeout.
type ApprovalDecision ¶
type ApprovalDecision string
ApprovalDecision is the operator's high-level intent. Selected option is recorded separately so we don't lose adapter-named choices.
const ( ApprovalDecisionApprove ApprovalDecision = "approve" ApprovalDecisionDeny ApprovalDecision = "deny" )
type ApprovalMode ¶
type ApprovalMode string
ApprovalMode controls what the coordinator does with an incoming RequestPermission. The package default is ModeAuto, which preserves legacy behavior (auto-select the first allow option). Operator-facing runtime flips this default to ModePrompt — see internal/config.
See docs/design/external-adapter-approvals-v1.md.
const ( // ModeAuto auto-resolves every approval with the first allow option. // Danger mode — preserved for batch / CI / local smoke and for // backward compat in tests that don't construct an approval store. ModeAuto ApprovalMode = "auto" // ModePrompt blocks waiting for an operator decision (or a matching // grant). If no operator resolves the request before // HECATE_AGENT_ADAPTER_APPROVAL_TIMEOUT, it resolves to a Cancelled // outcome. Operators who need fully unattended adapters can set // HECATE_AGENT_ADAPTER_APPROVAL_MODE=auto. ModePrompt ApprovalMode = "prompt" // ModeDeny auto-rejects every approval. Audit / compliance // scenarios where adapter tool use must not proceed. ModeDeny ApprovalMode = "deny" )
type ApprovalOption ¶
type ApprovalOption struct {
OptionID string `json:"option_id"`
Kind string `json:"kind"`
Name string `json:"name"`
}
ApprovalOption mirrors acp.PermissionOption in a stable wire shape we own. We keep the original adapter-supplied option_id verbatim so the resolution can route back to the exact ACP option the adapter expects.
type ApprovalResolutionPath ¶
type ApprovalResolutionPath string
ApprovalResolutionPath labels how a pending approval got resolved. Telemetry uses this label to distinguish operator-driven decisions from grant-cache hits and from default-mode auto-resolutions.
const ( PathOperator ApprovalResolutionPath = "operator" PathGrant ApprovalResolutionPath = "grant" PathDefaultMode ApprovalResolutionPath = "default_mode" PathTimeout ApprovalResolutionPath = "timeout" // PathRequestCancelled labels approvals that resolved because // the request context was cancelled — session shutdown, adapter // teardown, HTTP context cancellation, or process stop. Distinct // from PathOperator (an explicit operator decision) so telemetry // and the SSE stream can distinguish "operator declined to act" // from "the request died under us." PathRequestCancelled ApprovalResolutionPath = "request_cancelled" )
type ApprovalRetentionStore ¶
type ApprovalRetentionStore interface {
ApprovalStore
// PruneApprovals deletes resolved (non-pending) approval rows
// older than maxAge OR beyond maxCount, whichever fires.
// Pending rows are never pruned. Returns total deleted.
PruneApprovals(ctx context.Context, now time.Time, maxAge time.Duration, maxCount int) (int64, error)
// PruneExpiredGrants removes grants whose ExpiresAt is in the
// past. Live grants (no expiry, or future expiry) are never
// touched. Returns total deleted.
PruneExpiredGrants(ctx context.Context, now time.Time) (int64, error)
// ReconcilePending sweeps any pending approval rows from a prior
// process and marks them status=timed_out, path=startup_reconcile.
// Process-local waiters can't be resurrected; callers must invoke
// this at startup before serving requests. Returns rows
// reconciled.
ReconcilePending(ctx context.Context, now time.Time) (int64, error)
// Prune implements retention.Pruner — one call that runs both
// the resolved-approval sweep (subject to maxAge / maxCount)
// and the expired-grant sweep (grants honor only ExpiresAt;
// maxAge / maxCount don't apply). Returns the sum so operators
// see total rows removed by this subsystem in one number.
// Captures `now := time.Now().UTC()` internally; the
// per-deletion `now`-tolerant methods stay on the interface for
// tests and ad-hoc callers.
Prune(ctx context.Context, maxAge time.Duration, maxCount int) (int, error)
}
ApprovalRetentionStore extends ApprovalStore with maintenance operations the retention worker calls. Memory and SQL stores both satisfy it; the type assertion in the worker keeps the smaller ApprovalStore interface clean for the coordinator.
type ApprovalScope ¶
type ApprovalScope string
ApprovalScope is the breadth of an operator's "always" decision. `once` means no persistence; the others persist as a grant entry.
const ( ApprovalScopeOnce ApprovalScope = "once" ApprovalScopeSession ApprovalScope = "session" ApprovalScopeWorkspaceTool ApprovalScope = "workspace_tool" ApprovalScopeAdapterTool ApprovalScope = "adapter_tool" )
type ApprovalStatus ¶
type ApprovalStatus string
ApprovalStatus is the lifecycle state of a single approval row.
const ( ApprovalStatusPending ApprovalStatus = "pending" ApprovalStatusApproved ApprovalStatus = "approved" ApprovalStatusDenied ApprovalStatus = "denied" ApprovalStatusTimedOut ApprovalStatus = "timed_out" ApprovalStatusCancelled ApprovalStatus = "cancelled" )
type ApprovalStore ¶
type ApprovalStore interface {
// CreateApproval persists a pending approval and returns the row
// with its assigned ID + timestamps filled in.
CreateApproval(ctx context.Context, a Approval) (Approval, error)
// ResolveApproval transitions a pending approval to a terminal
// status. Returns the updated row. Returns ErrApprovalNotFound
// when id is unknown and ErrApprovalAlreadyResolved when the row
// is already terminal — the second writer always loses the race.
ResolveApproval(ctx context.Context, id string, status ApprovalStatus, decision ApprovalDecision, selectedOption string, scope ApprovalScope, path ApprovalResolutionPath, note string, resolvedAt time.Time) (Approval, error)
// GetApproval fetches an approval by id.
GetApproval(ctx context.Context, id string) (Approval, error)
// ListApprovals returns approvals for a session, oldest-first.
// status="" returns all statuses; otherwise filters.
ListApprovals(ctx context.Context, sessionID string, status ApprovalStatus) ([]Approval, error)
// CreateGrant persists an operator-authored "always allow / always
// deny" grant. Used by the coordinator when scope > once.
CreateGrant(ctx context.Context, g Grant) (Grant, error)
// ListGrants returns grants matching the filter, newest-first.
// Expired grants (ExpiresAt <= now) are excluded.
ListGrants(ctx context.Context, filter GrantFilter, now time.Time) ([]Grant, error)
// DeleteGrant removes a grant by id. Returns ErrApprovalNotFound
// when the id is unknown so the HTTP layer can surface 404.
DeleteGrant(ctx context.Context, id string) error
// FindMatchingGrant returns the most-specific live grant for the
// given (sessionID, workspace, adapterID, toolKind) tuple, or
// (Grant{}, false). Lookup walks scopes session → workspace_tool →
// adapter_tool, returning the first match. Expired grants are
// ignored. The returned grant carries the operator's decision.
FindMatchingGrant(ctx context.Context, sessionID, workspace, adapterID, toolKind string, now time.Time) (Grant, bool, error)
}
ApprovalStore is the persistence interface. Memory and SQL backends both implement it. Backend selection follows HECATE_BACKEND in cmd/hecate.
type AuthenticateResult ¶
type AuthenticateResult struct {
AdapterID string `json:"adapter_id"`
Status string `json:"status"`
MethodID string `json:"method_id"`
Path string `json:"path,omitempty"`
DurationMS int64 `json:"duration_ms"`
}
func Authenticate ¶
func Authenticate(ctx context.Context, adapterID string) (AuthenticateResult, error)
type AvailableCommandsUpdate ¶
type AvailableCommandsUpdate struct {
SessionID string
AdapterID string
Commands []agentcontrols.Command
// contains filtered or unexported fields
}
type CoordinatorHooks ¶
type CoordinatorHooks struct {
OnRequested func(approval Approval)
OnResolved func(approval Approval, durationMS int64)
OnTimedOut func(approval Approval, durationMS int64)
// OnGrantCreated fires after a successful CreateGrant inside the
// coordinator's resolve path (i.e. when the operator's decision
// scope is broader than `once`). Used to drive the
// `approval.grants_active` UpDownCounter; nil-safe.
OnGrantCreated func(grant Grant)
// OnGrantDeleted fires after a successful DeleteGrant. Symmetric
// with OnGrantCreated; nil-safe.
OnGrantDeleted func()
}
CoordinatorHooks are optional callbacks invoked by the coordinator at well-defined lifecycle points. The coordinator is the single place that knows the (adapter, tool_kind, mode, path) tuple, so all telemetry instrumentation goes through here. Implementations live in the telemetry package; the coordinator package keeps no metric dependencies of its own.
type CoordinatorOptions ¶
type CoordinatorOptions struct {
Mode ApprovalMode
Timeout time.Duration
Store ApprovalStore
Logger *slog.Logger
// NowFunc is used by tests; defaults to time.Now.UTC.
NowFunc func() time.Time
// IDFunc generates approval ids; defaults to ULID-shaped hex.
IDFunc func() string
// Hooks are optional callbacks for telemetry. Zero values are no-ops.
Hooks CoordinatorHooks
}
CoordinatorOptions configure an ApprovalCoordinator.
type CredentialMode ¶
type Grant ¶
type Grant struct {
ID string `json:"id"`
Scope ApprovalScope `json:"scope"`
AdapterID string `json:"adapter_id"`
ToolKind string `json:"tool_kind"`
Workspace string `json:"workspace,omitempty"`
SessionID string `json:"session_id,omitempty"`
Decision ApprovalDecision `json:"decision"`
GrantedBy string `json:"granted_by,omitempty"`
GrantedAt time.Time `json:"granted_at"`
ExpiresAt *time.Time `json:"expires_at,omitempty"`
}
Grant is a persisted "always" decision. Memory and SQL backends both implement it.
type GrantFilter ¶
type GrantFilter struct {
AdapterID string
Scope ApprovalScope
ToolKind string
}
GrantFilter narrows ListGrants results.
type LaunchModel ¶
type LaunchModelConfig ¶
type LaunchModelConfig struct {
ConfigID string
ArgTemplate []string
ListArgs []string
FallbackModels []LaunchModel
}
type LaunchSelectConfig ¶
type LaunchSelectOption ¶
type LogoutResult ¶
type LookupFunc ¶
type MemoryApprovalStore ¶
type MemoryApprovalStore struct {
// contains filtered or unexported fields
}
MemoryApprovalStore is a goroutine-safe in-process ApprovalStore. All state lives in maps and is discarded on process exit. Suitable for tests, dev, and anyone running with HECATE_BACKEND=memory (the default).
func NewMemoryApprovalStore ¶
func NewMemoryApprovalStore() *MemoryApprovalStore
NewMemoryApprovalStore returns an empty in-memory store.
func (*MemoryApprovalStore) CreateApproval ¶
func (*MemoryApprovalStore) CreateGrant ¶
CreateGrant inserts a grant row. Used by tests + the resolve handler when an operator picks a scope broader than `once`.
func (*MemoryApprovalStore) DeleteGrant ¶
func (s *MemoryApprovalStore) DeleteGrant(_ context.Context, id string) error
DeleteGrant removes a grant by id. Returns ErrApprovalNotFound (the shared not-found sentinel) when the id is unknown.
func (*MemoryApprovalStore) FindMatchingGrant ¶
func (*MemoryApprovalStore) GetApproval ¶
func (*MemoryApprovalStore) ListApprovals ¶
func (s *MemoryApprovalStore) ListApprovals(_ context.Context, sessionID string, status ApprovalStatus) ([]Approval, error)
func (*MemoryApprovalStore) ListGrants ¶
func (s *MemoryApprovalStore) ListGrants(_ context.Context, filter GrantFilter, now time.Time) ([]Grant, error)
ListGrants returns grants matching the filter. Expired grants are dropped using the supplied now timestamp.
func (*MemoryApprovalStore) Prune ¶
func (s *MemoryApprovalStore) Prune(ctx context.Context, maxAge time.Duration, maxCount int) (int, error)
Prune implements retention.Pruner. See ApprovalRetentionStore.Prune for the contract.
func (*MemoryApprovalStore) PruneApprovals ¶
func (s *MemoryApprovalStore) PruneApprovals(_ context.Context, now time.Time, maxAge time.Duration, maxCount int) (int64, error)
PruneApprovals deletes resolved approval rows older than maxAge or beyond maxCount. Mirrors the SQL store's behavior so the retention worker can dispatch through ApprovalRetentionStore without caring which backend is wired. Pending rows are never auto-pruned.
func (*MemoryApprovalStore) PruneExpiredGrants ¶
PruneExpiredGrants removes grants whose ExpiresAt has passed. Live grants are never touched; the retention worker must not erase operator-authored intent.
func (*MemoryApprovalStore) ReconcilePending ¶
ReconcilePending sweeps pending rows and marks them timed_out with path=startup_reconcile. The memory backend never has rows surviving a restart in practice (the map is process-local), but the method exists so memory and sqlite share the ApprovalRetentionStore surface. Returns 0 on a normal startup; non-zero only if the same process is restarted in-place (rare; e.g. tests).
func (*MemoryApprovalStore) ResolveApproval ¶
func (s *MemoryApprovalStore) ResolveApproval(_ context.Context, id string, status ApprovalStatus, decision ApprovalDecision, selectedOption string, scope ApprovalScope, path ApprovalResolutionPath, note string, resolvedAt time.Time) (Approval, error)
type NativeSessionScope ¶
type NativeSessionScope string
const ( NativeSessionScopeProcess NativeSessionScope = "process" NativeSessionScopeDurable NativeSessionScope = "durable" )
type PrepareSessionRequest ¶
type PrepareSessionRequest struct {
SessionID string
AdapterID string
Workspace string
PreviousNativeSessionID string
ConfigOptions []agentcontrols.ConfigOption
MCPServers []types.MCPServerConfig
}
type PrepareSessionResult ¶
type PrepareSessionResult struct {
Adapter Adapter
DriverKind string
NativeSessionID string
AgentInfo *agentcontrols.ImplementationInfo
SessionStarted bool
SessionResumed bool
SessionRecovery string
ConfigOptions []agentcontrols.ConfigOption
AvailableCommands []agentcontrols.Command
AvailableCommandsKnown bool
}
type ProbeAgentInfo ¶
type ProbeAgentInfo = agentcontrols.ImplementationInfo
ProbeAgentInfo keeps the health-probe name for the shared ACP implementation metadata projection.
type ProbeAuthMethod ¶
type ProbeAuthMethod struct {
ID string `json:"id"`
Kind string `json:"kind"`
Name string `json:"name,omitempty"`
Description string `json:"description,omitempty"`
}
ProbeAuthMethod is the non-secret subset of ACP Initialize authMethods that Hecate can safely surface in health responses. Env var names and terminal env payloads intentionally stay inside the adapter runtime boundary.
type ProbeResult ¶
type ProbeResult struct {
AdapterID string `json:"adapter_id"`
Status string `json:"status"`
Stage string `json:"stage"`
Path string `json:"path,omitempty"`
Error string `json:"error,omitempty"`
Stderr string `json:"stderr,omitempty"`
Hint string `json:"hint,omitempty"`
AgentInfo *ProbeAgentInfo `json:"agent_info,omitempty"`
CapabilitiesKnown bool `json:"capabilities_known,omitempty"`
SupportsAuthenticate bool `json:"supports_authenticate"`
SupportsLogout bool `json:"supports_logout"`
SupportsLoadSession bool `json:"supports_load_session"`
AuthMethods []ProbeAuthMethod `json:"auth_methods,omitempty"`
DurationMS int64 `json:"duration_ms"`
}
ProbeResult is the typed outcome of a single Probe call. Stage names the step that completed (on success) or that failed (on error). When Status == "auth_required" or "error", Error and Stderr carry the raw diagnostic; the UI surfaces them verbatim because adapters phrase auth failures inconsistently and any forced normalization would destroy operator-actionable detail.
func Probe ¶
func Probe(ctx context.Context, adapterID string) (res ProbeResult)
Probe attempts a minimal start-and-handshake against the named adapter to determine whether it can prepare an ACP session. It does not prove that an embedded bridge can launch its prompt-serving vendor process, authenticate, or serve a turn. Session setup may still run bounded provider discovery.
Sequence: resolve provider/runtime command → start runtime → ACP Initialize → ACP NewSession (against a temporary workspace) → terminate. On any failure, the stage that failed is recorded and the error + captured stderr are surfaced as-is. We deliberately do NOT issue a chat prompt — the goal is "would startACPSession succeed?", not "does the adapter launch its deferred prompt-serving vendor process or produce useful output?".
Side effects: a fresh ACP session is created and immediately abandoned. Adapters that bill on session-create will see a single no-op session per probe; adapters that bill on prompt completion will see no charge. The `cwd` passed to NewSession is a temporary directory that's removed before Probe returns.
type PromptFile ¶
type PromptFile struct {
Filename string
MediaType string
SizeBytes int64
SHA256 string
Data []byte
}
PromptFile is an immutable attachment snapshot passed to one selected ACP session. Size and digest are checked again at the adapter boundary before any content block or staged file is created.
type PromptInput ¶
type PromptInput struct {
Text string
Files []PromptFile
}
PromptInput is the provider-neutral input for one External Agent turn. Attachment bodies remain Hecate-owned and are copied into this short-lived request only after session-scoped claim admission succeeds.
type RecordingContext ¶
RecordingContext bundles the per-request context that the session manager carries about an in-flight ACP RequestPermission. Kept separate from CoordinatorOptions so the coordinator is reusable across many sessions without rebuilding.
type ResolveRequest ¶
type ResolveRequest struct {
Decision ApprovalDecision `json:"decision"`
Scope ApprovalScope `json:"scope"`
SelectedOption string `json:"selected_option,omitempty"`
Note string `json:"note,omitempty"`
GrantedBy string `json:"granted_by,omitempty"`
}
ResolveRequest is the input to ApprovalCoordinator.Resolve. The HTTP layer parses POST bodies into this shape; coordinator-level callers (tests, future programmatic users) build it directly.
type RunRequest ¶
type RunRequest struct {
SessionID string
AdapterID string
Workspace string
PreviousNativeSessionID string
Prompt PromptInput
ConfigOptions []agentcontrols.ConfigOption
MCPServers []types.MCPServerConfig
Timeout time.Duration
MaxOutputBytes int64
OnOutput func(string)
OnActivity func(Activity)
// OnTerminalActivity is bound to terminals created by this turn and may be
// called after Run returns, until OnTerminalClosed reports that terminal's
// authoritative settlement. Callers must return promptly, keep it safe for
// concurrent late delivery, and bind it to the originating durable message
// rather than mutable current-turn state.
OnTerminalActivity func(Activity)
// OnTerminalClosed runs exactly once for each successfully-created terminal,
// after its final OnTerminalActivity callback. A session-close deadline makes
// the emitted cancellation authoritative: no transcript callbacks occur for
// that terminal after OnTerminalClosed returns. Callers must return promptly.
OnTerminalClosed func(terminalID string)
// AllowNativeSessionReplacement is explicit host authority to replace a
// provider-native conversation that the adapter proves is missing. The
// zero value fails closed. OnNativeSessionReplaced must durably persist the
// new native ID before Hecate sends the prompt again.
AllowNativeSessionReplacement bool
OnNativeSessionReplaced func(NativeSessionReplacement) error
}
type RunResult ¶
type RunResult struct {
Adapter Adapter
DriverKind string
NativeSessionID string
AgentInfo *agentcontrols.ImplementationInfo
StopReason string
SessionStarted bool
SessionResumed bool
SessionRecovery string
Output string
RawOutput string
ExitCode int
StartedAt time.Time
CompletedAt time.Time
DiffStat string
Diff string
Usage Usage
ConfigOptions []agentcontrols.ConfigOption
AvailableCommands []agentcontrols.Command
AvailableCommandsKnown bool
// contains filtered or unexported fields
}
type Runner ¶
type Runner interface {
PrepareSession(context.Context, PrepareSessionRequest) (PrepareSessionResult, error)
Run(context.Context, RunRequest) (RunResult, error)
SetSessionConfigOption(context.Context, SetSessionConfigOptionRequest) (SetSessionConfigOptionResult, error)
CloseSession(context.Context, string) error
DeleteSession(context.Context, string) error
Shutdown(context.Context) error
}
type SQLiteApprovalStore ¶
type SQLiteApprovalStore struct {
// contains filtered or unexported fields
}
SQLiteApprovalStore is the durable backend for agent-chat approvals and operator-authored grants. It satisfies ApprovalStore plus the grant-management surface the coordinator's HTTP layer uses.
Schema is created by migrate() on construction; the store is safe to instantiate multiple times against the same client. Two tables:
- chat_approvals — one row per RequestPermission. The full ACP payload + options are stored as JSON blobs so the wire shape can evolve without schema churn.
- chat_approval_grants — operator-authored "always allow / always deny" decisions broader than `once` scope.
Process-local waiters are NOT persisted: a Hecate restart cannot resurrect an in-flight ACP RequestPermission. ReconcilePending() (called from cmd/hecate at startup, before the gateway accepts requests) sweeps any pending rows from a prior process and marks them status=timed_out, path=startup_reconcile.
func NewPostgresApprovalStore ¶
func NewPostgresApprovalStore(ctx context.Context, client *storage.PostgresClient) (*SQLiteApprovalStore, error)
func NewSQLiteApprovalStore ¶
func NewSQLiteApprovalStore(ctx context.Context, client *storage.SQLiteClient) (*SQLiteApprovalStore, error)
NewSQLiteApprovalStore opens the store and runs migrations. Returns the store ready for use.
func (*SQLiteApprovalStore) Backend ¶
func (s *SQLiteApprovalStore) Backend() string
Backend identifies the backend choice for diagnostics + tests.
func (*SQLiteApprovalStore) CreateApproval ¶
func (*SQLiteApprovalStore) CreateGrant ¶
CreateGrant persists an operator-authored grant. Used by the coordinator's Resolve method when scope > once.
func (*SQLiteApprovalStore) DeleteGrant ¶
func (s *SQLiteApprovalStore) DeleteGrant(ctx context.Context, id string) error
DeleteGrant removes a grant by id. Returns ErrApprovalNotFound when the id is unknown so the HTTP layer can surface 404 uniformly.
func (*SQLiteApprovalStore) FindMatchingGrant ¶
func (*SQLiteApprovalStore) GetApproval ¶
func (*SQLiteApprovalStore) ListApprovals ¶
func (s *SQLiteApprovalStore) ListApprovals(ctx context.Context, sessionID string, status ApprovalStatus) ([]Approval, error)
func (*SQLiteApprovalStore) ListGrants ¶
func (s *SQLiteApprovalStore) ListGrants(ctx context.Context, filter GrantFilter, now time.Time) ([]Grant, error)
ListGrants returns grants matching the filter, newest-first. Expired grants are excluded by the SQL predicate.
func (*SQLiteApprovalStore) Prune ¶
func (s *SQLiteApprovalStore) Prune(ctx context.Context, maxAge time.Duration, maxCount int) (int, error)
Prune implements retention.Pruner. See ApprovalRetentionStore.Prune for the contract.
func (*SQLiteApprovalStore) PruneApprovals ¶
func (s *SQLiteApprovalStore) PruneApprovals(ctx context.Context, now time.Time, maxAge time.Duration, maxCount int) (int64, error)
PruneApprovals deletes resolved (non-pending) approval rows older than maxAge or beyond maxCount, whichever fires first. Pending rows are never auto-pruned — they're caller state, not history. Returns total rows deleted.
func (*SQLiteApprovalStore) PruneExpiredGrants ¶
PruneExpiredGrants removes grants whose ExpiresAt is in the past. Returns the number deleted. Called by the retention worker. Live grants (no expiry, or expiry in the future) are never touched.
func (*SQLiteApprovalStore) ReconcilePending ¶
ReconcilePending sweeps any approval rows that survived a Hecate restart in the pending state and marks them status=timed_out, path=startup_reconcile. Process-local waiters can't be resurrected, so the operator UI must not surface these as actionable.
Called from cmd/hecate at startup, after migrate() and before the gateway accepts requests. Returns the number of rows reconciled.
func (*SQLiteApprovalStore) ResolveApproval ¶
func (s *SQLiteApprovalStore) ResolveApproval(ctx context.Context, id string, status ApprovalStatus, decision ApprovalDecision, selectedOption string, scope ApprovalScope, path ApprovalResolutionPath, note string, resolvedAt time.Time) (Approval, error)
type SessionManager ¶
type SessionManager struct {
// contains filtered or unexported fields
}
func NewSessionManager ¶
func NewSessionManager() *SessionManager
func (*SessionManager) CloseSession ¶
func (m *SessionManager) CloseSession(ctx context.Context, sessionID string) error
func (*SessionManager) Coordinator ¶
func (m *SessionManager) Coordinator() *ApprovalCoordinator
Coordinator returns the installed approval coordinator (or nil). HTTP handlers route operator resolve/cancel calls through this.
func (*SessionManager) DeleteSession ¶
func (m *SessionManager) DeleteSession(ctx context.Context, sessionID string) error
func (*SessionManager) PrepareSession ¶
func (m *SessionManager) PrepareSession(ctx context.Context, req PrepareSessionRequest) (PrepareSessionResult, error)
func (*SessionManager) Run ¶
func (m *SessionManager) Run(ctx context.Context, req RunRequest) (RunResult, error)
func (*SessionManager) SetAdapterMetrics ¶
func (m *SessionManager) SetAdapterMetrics(metrics *telemetry.AgentAdapterMetrics)
SetAdapterMetrics installs the AgentAdapterMetrics used by every acpChatClient spawned from this manager (currently for the terminal-RPC-unsupported counter; probe metrics are wired separately via SetProbeMetrics). Nil is safe and matches the construction pattern used by tests that don't care about metrics.
func (*SessionManager) SetApprovalCoordinator ¶
func (m *SessionManager) SetApprovalCoordinator(coordinator *ApprovalCoordinator)
SetApprovalCoordinator installs the coordinator used to handle ACP RequestPermission calls. When unset, the legacy auto-approve behavior is preserved (matches existing tests + dev workflows that build a SessionManager without going through internal/config).
func (*SessionManager) SetAvailableCommandsUpdateHook ¶
func (m *SessionManager) SetAvailableCommandsUpdateHook(hook func(AvailableCommandsUpdate))
func (*SessionManager) SetLogger ¶
func (m *SessionManager) SetLogger(logger *slog.Logger)
func (*SessionManager) SetSecretCipher ¶
func (m *SessionManager) SetSecretCipher(cipher secrets.Cipher)
func (*SessionManager) SetSessionConfigOption ¶
func (m *SessionManager) SetSessionConfigOption(ctx context.Context, req SetSessionConfigOptionRequest) (SetSessionConfigOptionResult, error)
func (*SessionManager) SetTerminalSupportEnabled ¶
func (m *SessionManager) SetTerminalSupportEnabled(enabled bool)
SetTerminalSupportEnabled controls whether ACP sessions advertise and honor client-side terminal/* callbacks. It is intentionally opt-in because terminal/create is a command-execution surface.
func (*SessionManager) SetWorkspaceCoordinator ¶
func (m *SessionManager) SetWorkspaceCoordinator(registry *workspacecoord.Registry)
SetWorkspaceCoordinator installs the process-scoped registry used by ACP terminal callbacks. A terminal receives its own writer lease before spawn so it remains visible to destructive workspace operations even after the ACP turn that created it has returned. Wire it before preparing or running sessions; like the other manager launch settings, an existing session keeps the composition it started with.
type SetSessionConfigOptionResult ¶
type SetSessionConfigOptionResult struct {
ConfigOptions []agentcontrols.ConfigOption
AvailableCommands []agentcontrols.Command
AvailableCommandsKnown bool
}
type SetupCommandStatus ¶
type SetupCommandStatus struct {
Available bool `json:"available"`
Command string `json:"command,omitempty"`
ExecutablePath string `json:"executable_path,omitempty"`
}
func DetectClaudeCodeCLI ¶
func DetectClaudeCodeCLI(probe VersionProbe, lookup LookupFunc) SetupCommandStatus
type Status ¶
type Status struct {
Adapter
Available bool
Status string
Path string
Error string
AdapterVersion string
AgentVersion string
VersionOutsideRange bool
AuthStatus string
AuthError string
RemoteCredentialMode string
RemoteCredentialOK bool
RemoteCredentialHint string
ClaudeCodeCLI SetupCommandStatus
}
func ApplyProbeCapabilities ¶
func ApplyProbeCapabilities(status Status, result ProbeResult) Status
ApplyProbeCapabilities makes live ACP Initialize capabilities authoritative for a freshly probed adapter row. Static registry flags remain the fallback before a probe has successfully completed Initialize.
func CatalogStatusForAdapter ¶
CatalogStatusForAdapter returns one adapter's passive discovery state. It resolves and validates paths but never runs version, auth, or ACP commands.
func ListCatalog ¶
ListCatalog returns the built-in adapter catalog using only cheap local discovery. It intentionally avoids version/auth subprocess probes so app startup and the Connections list can render immediately; explicit probe endpoints refresh the expensive health details on demand.
func ListCatalogWithLookup ¶
func ListCatalogWithLookup(ctx context.Context, lookup LookupFunc) []Status
func ListWithLookup ¶
func ListWithLookup(ctx context.Context, lookup LookupFunc) []Status
func StatusForAdapter ¶
type Usage ¶
type VersionProbe ¶
Source Files
¶
- acp_chat_client.go
- acp_mcp.go
- acp_peer.go
- acp_prompt.go
- acp_prompt_cleanup.go
- acp_prompt_namespace.go
- acp_prompt_redactor.go
- acp_prompt_redactor_posix.go
- acp_prompt_stage_linux.go
- acp_prompt_stage_posix.go
- acp_protocol_diagnostics.go
- acp_session.go
- acp_session_lifecycle.go
- acp_terminal.go
- acp_turn.go
- approvals.go
- approvals_coordinator.go
- approvals_ids.go
- approvals_memory.go
- approvals_resolve.go
- approvals_sqlite.go
- auth_status.go
- claude_setup.go
- diagnostic_process.go
- diagnostic_process_exit_linux.go
- embedded_server.go
- launch_config.go
- logout.go
- normalize.go
- probe.go
- process_unix.go
- registry.go
- remote_build_default.go
- session_manager.go
- toolkind.go
- version.go