package ports import ( "context" "errors" "github.com/aoagents/agent-orchestrator/backend/internal/domain" ) // ErrAgentBinaryNotFound is returned by agent adapters when neither PATH nor // any well-known install location holds the agent's binary. The session // manager surfaces this BEFORE creating the runtime so a missing CLI doesn't // silently launch into an empty tmux pane that the reaper later mistakes // for a live session. var ErrAgentBinaryNotFound = errors.New("agent: binary not found on PATH") // Agent is the contract every CLI coding agent adapter (claude-code, codex, …) // must satisfy. It supplies the argv and process configuration the Session // Manager needs to launch, restore, and read back a native agent session. type Agent interface { // GetConfigSpec describes the agent-specific config keys AO can // expose to users in the AO config. GetConfigSpec(ctx context.Context) (ConfigSpec, error) // GetLaunchCommand builds the argv AO should run to start this agent. GetLaunchCommand(ctx context.Context, cfg LaunchConfig) (cmd []string, err error) // GetPromptDeliveryStrategy tells AO whether the prompt is included in // the launch command or must be sent after the agent process starts. GetPromptDeliveryStrategy(ctx context.Context, cfg LaunchConfig) (PromptDeliveryStrategy, error) // GetAgentHooks installs or merges AO hooks into the agent's // native workspace-local hook config. It must preserve user-defined hooks. GetAgentHooks(ctx context.Context, cfg WorkspaceHookConfig) error // GetRestoreCommand builds an argv that continues an existing native agent // session. ok=false means no existing native session can be continued. GetRestoreCommand(ctx context.Context, cfg RestoreConfig) (cmd []string, ok bool, err error) // SessionInfo reads agent-owned session metadata such as native session id, // display title, or summary. ok=false means no info is available. SessionInfo(ctx context.Context, session SessionRef) (info SessionInfo, ok bool, err error) } // AgentResolver maps a session's harness onto the Agent adapter that drives it, // so the Session Manager can spawn (and restore) a different agent per session // without depending on the concrete adapter registry. ok=false means no adapter // is registered for that harness. type AgentResolver interface { Agent(harness domain.AgentHarness) (Agent, bool) } // MetadataKeyAgentSessionID is the SessionRef.Metadata key that carries an // agent's native session id. It matches the json tag on // domain.SessionMetadata.AgentSessionID and the key the adapters read, so the // Session Manager can bridge its typed metadata onto a SessionRef without // either side hard-coding the other's vocabulary. const MetadataKeyAgentSessionID = "agentSessionId" // MetadataKeyTitle and MetadataKeySummary are the SessionRef.Metadata keys // carrying a session's human title and one-line summary. They are the shared // vocabulary every adapter reports under, so the dashboard renders agents // uniformly. const ( MetadataKeyTitle = "title" MetadataKeySummary = "summary" ) // AgentConfig is the typed per-project agent config handed to adapters at // launch. It aliases domain.AgentConfig so storage, services, and adapters // share one definition without a translation layer. type AgentConfig = domain.AgentConfig // ConfigSpec describes the agent-specific config keys AO can expose to users. type ConfigSpec struct { Fields []ConfigField } // ConfigField describes one user-facing agent config key. type ConfigField struct { Key string Type ConfigFieldType Description string Required bool Default any Enum []string } // ConfigFieldType is the primitive value kind AO expects for a field. type ConfigFieldType string // The primitive value kinds a ConfigField can declare. const ( ConfigFieldString ConfigFieldType = "string" ConfigFieldBool ConfigFieldType = "bool" ConfigFieldNumber ConfigFieldType = "number" ConfigFieldStringList ConfigFieldType = "string_list" ConfigFieldEnum ConfigFieldType = "enum" ) // LaunchConfig carries inputs needed to build a new agent launch command. type LaunchConfig struct { Config AgentConfig IssueID string Permissions PermissionMode Prompt string SessionID string // AllowedTools and DisallowedTools scope the agent to a tool allowlist when // it runs in a non-bypass permission mode (allow rules auto-approve, deny // rules auto-reject). They are the enforced read-only guarantee the reviewer // relies on: bypassPermissions ignores both lists, so a restricted launch // must leave Permissions off bypass. Empty means no restriction, so worker // sessions are unaffected. AllowedTools []string DisallowedTools []string SystemPrompt string SystemPromptFile string WorkspacePath string } // WorkspaceHookConfig carries inputs needed to install workspace-local agent hooks. type WorkspaceHookConfig struct { Config AgentConfig DataDir string SessionID string WorkspacePath string } // RestoreConfig carries inputs needed to continue an existing native agent session. type RestoreConfig struct { Config AgentConfig Permissions PermissionMode Session SessionRef // SystemPrompt carries the session's standing instructions (e.g. the // orchestrator role). Agent CLIs rebuild their system prompt from flags on // resume — it is not part of the transcript — so adapters whose CLI has a // system-prompt flag should re-apply this in their resume command. SystemPrompt string } // SessionRef identifies an AO session whose agent-owned metadata may be read. type SessionRef struct { ID string Metadata map[string]string WorkspacePath string } // SessionInfo contains agent-owned session metadata. type SessionInfo struct { AgentSessionID string Metadata map[string]string Title string Summary string } // PermissionMode controls how much review an agent requires before acting. It // is a type alias for domain.PermissionMode so adapters keep using // ports.PermissionMode while the typed AgentConfig (in domain) reuses the same // type. type PermissionMode = domain.PermissionMode // The permission modes adapters map onto their agent's native approval flags. // These re-export the domain constants so existing adapter code is unchanged. const ( PermissionModeDefault = domain.PermissionModeDefault PermissionModeAcceptEdits = domain.PermissionModeAcceptEdits PermissionModeAuto = domain.PermissionModeAuto PermissionModeBypassPermissions = domain.PermissionModeBypassPermissions ) // PromptDeliveryStrategy describes how AO should deliver the initial prompt. type PromptDeliveryStrategy string // How the orchestrator hands the initial prompt to a freshly launched agent. const ( PromptDeliveryInCommand PromptDeliveryStrategy = "in_command" PromptDeliveryAfterStart PromptDeliveryStrategy = "after_start" )