Documentation
¶
Index ¶
- Constants
- Variables
- func AdoptDraftSessionOverrides(sessionID string)
- func AppliedAutoPersona(sessionID string) (name, source string)
- func ApplyToolDiscovery(allTools []tools.BaseTool, gateway *mcpgateway.Gateway) []tools.BaseTool
- func AttachSessionMCPServers(ctx context.Context, sessionID string, servers map[string]config.MCPServer, ...) error
- func BuildGoalContinuationPrompt(objective string, iteration int, maxIterations int, progress string, ...) string
- func BuildGoalInitialPrompt(objective string, additionalInstructions string) string
- func CachedMcpToolNames() []string
- func CavemanMode(sessionID string) caveman.Mode
- func CoderAgentTools(permissions permission.Service, history history.Service, ...) []tools.BaseTool
- func CoderAgentToolsWithMesnada(mesnadaOrchestrator *orchestrator.Orchestrator, ...) []tools.BaseTool
- func ContextEnricherAgentTools(remembrances *rag.RemembrancesService, lspProvider tools.LSPProvider) []tools.BaseTool
- func CreateAgentProvider(ctx context.Context, agentName config.AgentName) (provider.Provider, error)
- func DesignTools(permissions permission.Service) []tools.BaseTool
- func DetachSessionMCPServers(sessionID string)
- func ExtensionManager() *extension.Manager
- func ForgetSessionPersona(sessionID string)
- func GetActivePersona() string
- func GetMcpFavoriteTools(ctx context.Context, permissions permission.Service, gw *mcpgateway.Gateway) []tools.BaseTool
- func GetMcpTools(ctx context.Context, permissions permission.Service) []tools.BaseTool
- func GetMcpToolsWithGateway(ctx context.Context, permissions permission.Service, gw *mcpgateway.Gateway) []tools.BaseTool
- func GetPersonaManager() *persona.Manager
- func LastRoutedModel(sessionID string) (models.ModelID, bool)
- func LearningMode(sessionID string) bool
- func ListAvailablePersonas() []string
- func NewAgentTool(Sessions session.Service, Messages message.Service, ...) tools.BaseTool
- func NewMcpTool(name string, tool mcp.Tool, permissions permission.Service, ...) tools.BaseTool
- func NewSetupBridge(sessions session.Service) tools.SetupBridge
- func PonytailMode(sessionID string) ponytail.Mode
- func ResetMcpToolsCache()
- func ResetSharedDiscoveryRegistry()
- func RunLearningFinish(ctx context.Context, svc Service, sessionID string) (<-chan AgentEvent, error)
- func RunSuperpowersFinish(ctx context.Context, svc Service, sessionID string) (<-chan AgentEvent, error)
- func SessionAutoMode(sessionID string) bool
- func SessionModelID(sessionID string) models.ModelID
- func SessionModelOverrideID(sessionID string) models.ModelID
- func SessionTools(sessionID string) []tools.BaseTool
- func SetActivePersona(name string) error
- func SetAndPersistActivePersona(name string) error
- func SetCavemanMode(sessionID string, mode caveman.Mode)
- func SetContextEnricher(e ContextEnricher)
- func SetContextTrimmer(ct ContextTrimmer)
- func SetExtensionManager(mgr *extension.Manager)
- func SetLearningMode(sessionID string, enabled bool)
- func SetLuaManager(fm *luaengine.FilterManager)
- func SetMemoryInjector(m MemoryInjector)
- func SetNonInteractiveMode(enabled bool)
- func SetPersonaManager(mgr *persona.Manager)
- func SetPersonaManagerRefresher(fn func())
- func SetPersonaSelector(ps *PersonaSelector)
- func SetPonytailMode(sessionID string, mode ponytail.Mode)
- func SetProjectServiceForTools(svc project.Service)
- func SetSessionAutoMode(sessionID string, auto bool)
- func SetSessionLLMOverrides(sessionID string, overrides SessionLLMOverrides)
- func SetSessionModelOverride(sessionID string, model models.ModelID)
- func SetSuperpowersMode(sessionID string, enabled bool)
- func SharedDiscoveryRegistry() *tooldiscovery.Registry
- func SuperpowersMode(sessionID string) bool
- func TaskAgentTools(lspProvider tools.LSPProvider) []tools.BaseTool
- type AgentEvent
- type AgentEventType
- type AgentParams
- type AutoModeController
- type ContextEnricher
- type ContextFilterCounts
- type ContextFilterInfo
- type ContextTrimmer
- type EvaluationResult
- type FilteredContextEnricher
- type FilteredMemoryInjector
- type FilteredSessionContextEnricher
- type GoalEvaluator
- type GoalEvent
- type GoalEventType
- type GoalOptions
- type GoalRunner
- type GoalState
- func (g *GoalState) Advance(progress string, nextStep string)
- func (g *GoalState) CanTransitionTo(next string) bool
- func (g *GoalState) Cancel()
- func (g *GoalState) Elapsed() time.Duration
- func (g *GoalState) IsCancelled() bool
- func (g *GoalState) IsRunning() bool
- func (g *GoalState) IsTerminal() bool
- func (g *GoalState) RecordIteration(progress string, nextStep string, todoSignature string, ...)
- func (g *GoalState) RemainingDuration() time.Duration
- func (g *GoalState) SetStatus(s string)
- func (g *GoalState) Status() string
- func (g *GoalState) Transition(next string, now time.Time) error
- type GoalStore
- type HeuristicGoalEvaluator
- type MCPClient
- type MemoryInjector
- type PersonaRoutingInfo
- type PersonaSelector
- type ResumeHandler
- type ResumeRegistry
- type ResumeStart
- type RoutingInfo
- type Service
- type SessionContextEnricher
- type SessionLLMOverrides
- type TokenUsageInfo
- type ToolDescription
- type ToolsSetter
Constants ¶
const ( GoalStatusRunning = "running" GoalStatusCompleted = "completed" GoalStatusFailed = "failed" GoalStatusCancelled = "cancelled" GoalStatusBlocked = "blocked" GoalStatusTimeout = "timeout" GoalStatusStalled = "stalled" )
Goal status constants
const ( RoutingKindRouted = "routed" RoutingKindNoMatch = "no_match" RoutingKindRouteUnusable = "route_unusable" RoutingKindFailover = "failover" )
Routing notice kinds (RoutingInfo.Kind).
const ( PersonaSourceDecision = "decision" PersonaSourceLLM = "llm" PersonaSourceSticky = "sticky" PersonaSourceDefault = "default" )
Persona routing sources (PersonaRoutingInfo.Source).
const ( ResumePriorityFallback = 0 ResumePriorityOwner = 100 )
Handler priorities. Handlers are consulted from the highest priority to the lowest; handlers of equal priority in registration order. A surface that only owns the sessions it opened itself (e.g. an ACP client session) registers at ResumePriorityOwner and returns taken == false for any other session; a surface that can show any session (the WebUI API) registers at ResumePriorityFallback and takes everything that no specific owner claimed.
const (
AgentToolName = "agent"
)
const DraftSessionID = "draft:new-session"
DraftSessionID keys the model selection made before a session exists (the TUI model dialog on an empty chat). It is never a real session: the selection is moved onto the session created by the first prompt with AdoptDraftSessionOverrides.
const ReasonRouteUnusable = "route_unusable"
ReasonRouteUnusable is the routing reason used when the decision matched a route but none of its models can serve the turn (unknown, disabled, cooling down, no attachment support, context too small). The turn runs on the coder.
Variables ¶
var ( ErrRequestCancelled = errors.New("request cancelled by user") ErrSessionBusy = errors.New("session is currently processing another request") // ErrSessionNotBusy is returned by Steer when the session has no active run to // steer. Callers should fall back to a normal Run in that case. ErrSessionNotBusy = errors.New("session is not currently processing a request") )
Common errors
var ( ErrGoalMaxIterationsReached = errors.New("goal reached max iterations") ErrGoalMaxDurationExceeded = errors.New("goal exceeded max duration") )
var ErrLearningNotActive = errors.New("learning mode is not active for this session")
ErrLearningNotActive is returned when a Learning-only operation (the closing turn) is requested for a session that never enabled the mode.
var ErrNoModel = fmt.Errorf("no model configured, please select a model")
ErrNoModel is returned when the agent has no model configured.
var ErrSuperpowersNotActive = errors.New("superpowers mode is not active for this session")
ErrSuperpowersNotActive is returned when a Superpowers-only operation (the closing turn) is requested for a session that never enabled the mode.
Functions ¶
func AdoptDraftSessionOverrides ¶ added in v1.2.7
func AdoptDraftSessionOverrides(sessionID string)
AdoptDraftSessionOverrides moves the model selection stored under DraftSessionID onto sessionID and clears the draft. It is a no-op when no draft selection exists.
func AppliedAutoPersona ¶ added in v1.2.7
AppliedAutoPersona returns the persona the auto-selection applied to the session on its last user turn and where the choice came from (a PersonaSource* value; "llm" when the decision model option is off). The name is empty when nothing was applied yet.
func ApplyToolDiscovery ¶ added in v0.416.3
ApplyToolDiscovery applies the unified tool selection policy to allTools. When discovery is enabled it:
- Adds extension-contributed tools and applies extension tool middleware (see internal/extensions.ApplyTools). This happens even when discovery is disabled.
- Syncs all live tools into the shared registry (upsert by name).
- When gateway is non-nil, syncs the full MCP catalog as catalog-only entries and wires the gateway as the remote executor so any MCP tool — favorite or not — is searchable and executable through tool_search.
- Creates the unified tool_search tool (search + call) backed by the registry.
- Returns only the visible subset (core tools + tool_search + session-discovered).
When discovery is disabled the tool set is returned as-is after step 0.
func AttachSessionMCPServers ¶ added in v1.0.4
func AttachSessionMCPServers(ctx context.Context, sessionID string, servers map[string]config.MCPServer, permissions permission.Service) error
AttachSessionMCPServers connects to every server in servers, initializes it and lists its tools, then exposes those tools to the session's agent runs only. It replaces whatever was attached to the session before (a session/load re-attaches). A server that fails is skipped: the successful ones stay attached and the failures come back joined in the error.
Connections are owned by the registry, not by ctx: ctx only bounds the discovery, so a stdio server keeps running after the ACP request that asked for it has returned. DetachSessionMCPServers releases them.
func BuildGoalContinuationPrompt ¶ added in v0.324.0
func BuildGoalInitialPrompt ¶ added in v0.324.0
func CachedMcpToolNames ¶ added in v0.720.2
func CachedMcpToolNames() []string
CachedMcpToolNames returns the "<server>_<tool>" names of the MCP tools already discovered in this process, without connecting to anything and without constructing a permission service. It returns nil when discovery has not run yet: a name list for a prompt is not a reason to open MCP connections, and it is certainly not a reason to populate the shared cache (PANDO-US-0031, defect 2).
func CavemanMode ¶ added in v0.621.0
CavemanMode returns the effective caveman mode for a session: the session's explicit choice when set, otherwise the configured default (off when none).
func CoderAgentTools ¶
func CoderAgentToolsWithMesnada ¶
func CoderAgentToolsWithMesnada( mesnadaOrchestrator *orchestrator.Orchestrator, remembrances *rag.RemembrancesService, gateway *mcpgateway.Gateway, permissions permission.Service, history history.Service, lspProvider tools.LSPProvider, userInput userinput.Service, sessions session.Service, ) []tools.BaseTool
func ContextEnricherAgentTools ¶ added in v0.646.4
func ContextEnricherAgentTools(remembrances *rag.RemembrancesService, lspProvider tools.LSPProvider) []tools.BaseTool
ContextEnricherAgentTools returns the read-only retrieval tool set used by the context-enrichment agent loop: knowledge base, memories, past events and the code index, plus plain file inspection. No tool in this set can modify state, so the loop can never touch the workspace while it gathers context for the main agent.
func CreateAgentProvider ¶ added in v0.403.0
func CreateAgentProvider(ctx context.Context, agentName config.AgentName) (provider.Provider, error)
CreateAgentProvider creates a provider for the given agent name. It is exported for use in app-layer code that needs a provider outside of the agent itself (e.g. the context-enricher LLM planner adapter).
func DesignTools ¶ added in v0.700.0
func DesignTools(permissions permission.Service) []tools.BaseTool
DesignTools returns the full Design Studio tool set. The Design Studio is always active; MCP server mode decides separately whether to expose these tools to external clients.
func DetachSessionMCPServers ¶ added in v1.0.4
func DetachSessionMCPServers(sessionID string)
DetachSessionMCPServers closes every connection attached to the session and removes its tools. It is a no-op for a session with nothing attached.
func ExtensionManager ¶ added in v0.700.0
ExtensionManager returns the wired manager, or nil when the build has none.
func ForgetSessionPersona ¶ added in v1.2.7
func ForgetSessionPersona(sessionID string)
ForgetSessionPersona drops the remembered persona and the persona warning state of a session.
func GetActivePersona ¶ added in v0.200.0
func GetActivePersona() string
GetActivePersona returns the currently active persona name. An empty string means no persona is active (auto-select or none).
func GetMcpFavoriteTools ¶ added in v0.646.4
func GetMcpFavoriteTools(ctx context.Context, permissions permission.Service, gw *mcpgateway.Gateway) []tools.BaseTool
GetMcpFavoriteTools returns the gateway's favorite MCP tools as direct wrappers so the LLM can call them without going through a proxy (lower latency, richer schema visibility). The rest of the MCP catalog stays reachable through the unified tool_search tool.
func GetMcpTools ¶
GetMcpTools returns the MCP catalog as tools bound to the permission service the CALLER passed. The discovery result is cached and shared (one connection per server per process, as before); only the permission binding is per call.
func GetMcpToolsWithGateway ¶ added in v0.8.0
func GetMcpToolsWithGateway(ctx context.Context, permissions permission.Service, gw *mcpgateway.Gateway) []tools.BaseTool
GetMcpToolsWithGateway returns MCP-backed tools for the LLM agent. When gw is non-nil (gateway mode), it exposes two proxy tools plus any favorite tools as direct wrappers. When gw is nil it falls back to the standard per-server tool list.
NOTE: this is the legacy gateway exposure path, kept for the ToolDiscovery-disabled configuration and for the pando mcp-server mode. The unified discovery path uses GetMcpFavoriteTools plus the tool_search tool wired in ApplyToolDiscovery.
func GetPersonaManager ¶ added in v0.200.0
GetPersonaManager returns the global persona manager, or nil if not initialised.
func LastRoutedModel ¶ added in v1.2.7
LastRoutedModel returns the model the last Auto turn of the session ran on.
func LearningMode ¶ added in v0.622.0
LearningMode reports whether the Learning policy is active for a session.
func ListAvailablePersonas ¶ added in v0.200.0
func ListAvailablePersonas() []string
ListAvailablePersonas returns the names of all loaded personas. Uses the global persona manager when available; falls back to the selector's manager.
func NewAgentTool ¶
func NewAgentTool( Sessions session.Service, Messages message.Service, lspProvider tools.LSPProvider, skillManager *skills.SkillManager, ) tools.BaseTool
func NewMcpTool ¶
func NewSetupBridge ¶ added in v0.629.4
func NewSetupBridge(sessions session.Service) tools.SetupBridge
NewSetupBridge wires the pando_setup tool to the session store and the session-mode registry. A nil session service is tolerated: usage reporting then fails with a clear message instead of panicking.
func PonytailMode ¶ added in v0.605.1
PonytailMode returns the effective ponytail mode for a session: the session's explicit choice when set, otherwise the configured default (off when none).
func ResetMcpToolsCache ¶ added in v0.310.3
func ResetMcpToolsCache()
ResetMcpToolsCache drops the discovered catalog. Its meaning is unchanged: the next GetMcpTools re-runs discovery.
func ResetSharedDiscoveryRegistry ¶ added in v0.646.4
func ResetSharedDiscoveryRegistry()
ResetSharedDiscoveryRegistry drops the shared registry (tests, config reloads).
func RunLearningFinish ¶ added in v0.622.0
func RunLearningFinish(ctx context.Context, svc Service, sessionID string) (<-chan AgentEvent, error)
RunLearningFinish runs the closing turn for /learning-finish as a normal agent turn (so it streams, persists and is cancellable like any other), consolidating what was learned into KB/memory, then disables the mode only once that turn reaches a successful terminal response. A cancelled or failed run keeps the mode on, so the workflow is never silently abandoned.
Keeping the success-only rule here — rather than in each of the ACP, Web UI and TUI command handlers — is what guarantees all three surfaces behave identically. The returned channel must be drained by the caller, exactly like Service.Run's.
func RunSuperpowersFinish ¶ added in v0.609.1
func RunSuperpowersFinish(ctx context.Context, svc Service, sessionID string) (<-chan AgentEvent, error)
RunSuperpowersFinish runs the closing turn for /superpowers-finish as a normal agent turn (so it streams, persists and is cancellable like any other), and disables the mode only once that turn reaches a successful terminal response. A cancelled or failed run keeps the mode on, so the workflow is never silently abandoned.
Keeping the success-only rule here — rather than in each of the ACP, Web UI and TUI command handlers — is what guarantees all three surfaces behave identically. The returned channel must be drained by the caller, exactly like Service.Run's.
func SessionAutoMode ¶ added in v1.2.7
SessionAutoMode reports whether the session runs in Auto mode: the explicit per-session flag when set, otherwise the global selection. It is always false when modelAutoMode.enabled is off.
func SessionModelID ¶ added in v0.643.1
SessionModelID returns the model a session actually runs on: its runtime override when one is set, otherwise the coder agent's configured model. Surfaces (TUI status bar, ACP model picker) must use this instead of reading the configured agent model, which does not know about per-session switches.
func SessionModelOverrideID ¶ added in v0.643.1
SessionModelOverrideID returns only the runtime override of a session, empty when the session still runs on the configured model. Callers that keep their own notion of the selected model (the ACP session state) use this to tell "the agent switched model" apart from "the global default differs from what this session picked", which must not be overwritten.
func SessionTools ¶ added in v1.0.4
SessionTools returns the tools attached to the session, or nil.
func SetActivePersona ¶ added in v0.200.0
SetActivePersona sets the active persona by name. Pass an empty string to clear the active persona (revert to auto-select or none). Returns an error if the named persona does not exist (and name is non-empty).
func SetAndPersistActivePersona ¶ added in v1.2.5
SetAndPersistActivePersona activates the persona like SetActivePersona and then saves the choice to the config (project file when present, else global) so it survives a restart. Persistence failures are returned after the in-memory switch has already taken effect.
func SetCavemanMode ¶ added in v0.621.0
SetCavemanMode sets the caveman mode for a session. It is safe for concurrent use and is the single mutation point used by every surface that exposes the /caveman command (ACP, Web UI, TUI). Turning it off clears the override unless a non-off default is configured, in which case an explicit "off" is recorded so the session stays disabled despite the default.
func SetContextEnricher ¶ added in v0.236.1
func SetContextEnricher(e ContextEnricher)
SetContextEnricher sets the context enricher used to prepend KB/code context to user messages. Pass nil to disable context enrichment.
func SetContextTrimmer ¶ added in v0.407.0
func SetContextTrimmer(ct ContextTrimmer)
SetContextTrimmer sets the context trimmer used to filter the tool list for new sessions. Pass nil to disable context trimming (all tools will always be included).
func SetExtensionManager ¶ added in v0.700.0
SetExtensionManager wires the process-wide extension manager into the agent's tool-set builder. Called once from internal/app after extensions are loaded. Passing nil detaches it (tests, teardown).
func SetLearningMode ¶ added in v0.622.0
SetLearningMode enables or disables the Learning learner/documentarian policy for a session. It is the entry point used by every surface that exposes the /learning commands (ACP, Web UI, TUI), mirroring SetSuperpowersMode. The state itself lives in internal/learning so tools can read it without importing this package.
func SetLuaManager ¶ added in v0.8.0
func SetLuaManager(fm *luaengine.FilterManager)
SetLuaManager sets the global Lua filter manager used for MCP tool input/output filtering.
func SetMemoryInjector ¶ added in v0.416.3
func SetMemoryInjector(m MemoryInjector)
SetMemoryInjector wires the memory injector used to prepend a <memories> block to the system prompt. Pass nil to disable memory injection.
func SetNonInteractiveMode ¶ added in v0.291.0
func SetNonInteractiveMode(enabled bool)
SetNonInteractiveMode configures all agents to run autonomously without waiting for user input. Call this before running a session when a prompt is provided via the -p flag or stdin pipe.
func SetPersonaManager ¶ added in v0.200.0
SetPersonaManager sets the global persona manager used for persona listing and manual persona selection. This should be called during app initialisation.
func SetPersonaManagerRefresher ¶ added in v1.2.7
func SetPersonaManagerRefresher(fn func())
SetPersonaManagerRefresher installs a hook the agent calls before every auto-selection so the app can reload the persona manager when the persona path changed. It must be cheap when nothing changed.
func SetPersonaSelector ¶ added in v0.41.0
func SetPersonaSelector(ps *PersonaSelector)
SetPersonaSelector sets the global persona selector used in the main conversation agent.
func SetPonytailMode ¶ added in v0.605.1
SetPonytailMode sets the ponytail mode for a session. It is safe for concurrent use and is the single mutation point used by every surface that exposes the /ponytail command (ACP, Web UI, TUI). Turning it off clears the override unless a non-off default is configured, in which case an explicit "off" is recorded so the session stays disabled despite the default.
func SetProjectServiceForTools ¶ added in v0.647.5
SetProjectServiceForTools wires the project registry used by pando_setup's "projects" command. Called once at startup from app.go; a nil service is tolerated and leaves the command reporting "unavailable".
func SetSessionAutoMode ¶ added in v1.2.7
SetSessionAutoMode sets the explicit per-session Auto flag. Turning it on also drops any manual model override so the next turn routes; turning it off keeps the session on the configured coder model (or whatever model the caller selects next).
func SetSessionLLMOverrides ¶ added in v0.407.0
func SetSessionLLMOverrides(sessionID string, overrides SessionLLMOverrides)
func SetSessionModelOverride ¶ added in v0.643.1
SetSessionModelOverride replaces only the model of a session's overrides, keeping persona and inference settings intact. Writing the whole struct here would silently drop the persona ACP or the Web UI installed for the session. An empty model clears just the model override.
Selecting a concrete (non-empty) model also switches Auto mode off for the session: picking a model by hand is an explicit "stop routing". Auto's own turn-scoped application uses setAutoTurnModelOverride, which leaves the flag alone.
func SetSuperpowersMode ¶ added in v0.609.1
SetSuperpowersMode enables or disables the Superpowers workflow policy for a session. It is the entry point used by every surface that exposes the /superpowers commands (ACP, Web UI, TUI), mirroring SetPonytailMode. The state itself lives in internal/superpowers so tools can read it without importing this package.
func SharedDiscoveryRegistry ¶ added in v0.646.4
func SharedDiscoveryRegistry() *tooldiscovery.Registry
SharedDiscoveryRegistry returns the process-wide tool discovery registry, creating it on first use.
func SuperpowersMode ¶ added in v0.609.1
SuperpowersMode reports whether the Superpowers policy is active for a session.
func TaskAgentTools ¶
func TaskAgentTools(lspProvider tools.LSPProvider) []tools.BaseTool
Types ¶
type AgentEvent ¶
type AgentEvent struct {
Type AgentEventType
Message message.Message
Error error
Delta string
ToolCall *message.ToolCall
ToolResult *message.ToolResult
// MessageID identifies the assistant message this event belongs to. It is
// populated on ThinkingDelta/ContentDelta/ToolCall events with the ID of the
// in-flight assistant message (assistantMsg.ID) so ACP-side streaming can
// group live chunks under the same messageId used by session/load replay,
// from the very first delta rather than only after AgentEventTypeResponse.
MessageID string
// When summarizing
SessionID string
Progress string
Done bool
// Todos is populated when Type == AgentEventTypeTodosUpdated.
Todos []tools.TodoItem
// SystemMessage is populated when Type == AgentEventTypeSystemMessage.
// It carries a human-readable status message (context compaction, retries, etc.)
// that should be shown to the user regardless of the transport (TUI, ACP, web).
SystemMessage string
// TokenUsage is populated when Type == AgentEventTypeTokenUsage.
TokenUsage *TokenUsageInfo
// Routing is set on the AgentEventTypeSystemMessage event that announces an
// Auto model mode decision or failover (SystemMessage carries the same
// notice text, e.g. "Auto: implementation → gpt-x (p=0.93, 38 ms via
// ollama/tev1:0.8b)"). Nil on every other event.
Routing *RoutingInfo
// ContextFilter is set on the AgentEventTypeSystemMessage event that
// announces the decision model dropped part of the injected context
// (SystemMessage carries the same text, e.g. "Context filter: kept 4/9
// (38 ms) — code 1/3, kb 2/4, events 1/2"). Nil on every other event.
ContextFilter *ContextFilterInfo
}
type AgentEventType ¶
type AgentEventType string
const ( AgentEventTypeError AgentEventType = "error" AgentEventTypeResponse AgentEventType = "response" AgentEventTypeSummarize AgentEventType = "summarize" AgentEventTypeContentDelta AgentEventType = "content_delta" AgentEventTypeThinkingDelta AgentEventType = "thinking_delta" AgentEventTypeToolCall AgentEventType = "tool_call" AgentEventTypeToolResult AgentEventType = "tool_result" // AgentEventTypeTodosUpdated is emitted when the TodoWrite tool runs successfully. // It carries the current todo list for non-ACP consumers (TUI, WebUI). AgentEventTypeTodosUpdated AgentEventType = "todos_updated" // AgentEventTypeSystemMessage carries internal status messages (context compaction, // retries, etc.) that should be displayed to the user but are not part of the // LLM response. Unlike ContentDelta these are sent with a blocking channel write // so they are never silently dropped. AgentEventTypeSystemMessage AgentEventType = "system_message" // AgentEventTypeTokenUsage carries a live context-window token update so the // TUI/WebUI can show consumption as it grows during the agent loop (e.g. while // tools execute or a file is produced), not only when the LLM response finishes. // When TokenUsage.Estimated is true the value is a heuristic estimate that the // next confirmed usage (EventComplete) will reconcile. AgentEventTypeTokenUsage AgentEventType = "token_usage" // AgentEventTypeSteeringQueued is emitted when the user submits a steering // message (mid-run feedback) that is queued for injection at the next safe // boundary of the agent loop. SystemMessage carries a human-readable note. AgentEventTypeSteeringQueued AgentEventType = "steering_queued" // AgentEventTypeSteeringInjected is emitted when one or more queued steering // messages have been injected into the conversation and the loop will continue // taking them into account. SystemMessage carries a human-readable note. AgentEventTypeSteeringInjected AgentEventType = "steering_injected" // AgentEventTypeConclusionQueued is emitted when a delegated-task conclusion // is queued (via InjectConclusion) for injection into a still-running parent // loop at the next safe boundary. SystemMessage carries a human-readable note. AgentEventTypeConclusionQueued AgentEventType = "conclusion_queued" // AgentEventTypeConclusionInjected is emitted when one or more queued delegated // conclusions have been injected into the conversation so the parent loop can // react to the subagent's result. SystemMessage carries a human-readable note. AgentEventTypeConclusionInjected AgentEventType = "conclusion_injected" // AgentEventTypeResurrected is emitted at the start of a system-initiated run // that resumes an idle parent session because one or more delegated tasks // finished (Case B of the delegation protocol). It lets the UI frame the turn // as "resuming because a delegated task reported its result" rather than as a // user message. SystemMessage carries a human-readable note. AgentEventTypeResurrected AgentEventType = "resurrected" )
type AgentParams ¶
type AgentParams struct {
Prompt string `json:"prompt"`
}
type AutoModeController ¶ added in v1.2.7
type AutoModeController interface {
SetSessionAutoMode(sessionID string, auto bool)
SessionAutoMode(sessionID string) bool
LastRoutedModel(sessionID string) (models.ModelID, bool)
LastRouting(sessionID string) (RoutingInfo, bool)
}
AutoModeController is implemented by the coder agent. It is kept out of Service so test doubles of Service do not have to implement it; callers type-assert (or use the package-level functions, which are session keyed).
type ContextEnricher ¶ added in v0.236.1
ContextEnricher is the interface used by the agent to enrich the user's prompt with context retrieved from the KB and code index before sending it to the LLM. A local interface is used to avoid import cycles between agent and rag packages.
type ContextFilterCounts ¶ added in v1.2.7
ContextFilterCounts is the kept/dropped count of one source.
type ContextFilterInfo ¶ added in v1.2.7
type ContextFilterInfo struct {
Kept int `json:"kept"`
Dropped int `json:"dropped"`
// BySource maps "code", "kb", "events" and "memory" to {kept, dropped};
// only sources with at least one candidate are present.
BySource map[string]ContextFilterCounts `json:"bySource"`
Threshold float64 `json:"threshold"`
LatencyMs int64 `json:"latencyMs"`
RouterProvider string `json:"routerProvider,omitempty"`
RouterModel string `json:"routerModel,omitempty"`
// Reason is empty on full success, otherwise "partial:<class>".
Reason string `json:"reason,omitempty"`
// Notice is the human readable line (same text as the system message).
Notice string `json:"notice"`
}
ContextFilterInfo summarises the relevance filtering of one turn. It is the payload of the context filter notice (AgentEvent.ContextFilter). It never carries prompt or snippet text.
type ContextTrimmer ¶ added in v0.407.0
type ContextTrimmer interface {
// ProfileTask returns the recommended tool names for the task.
// Returns nil/empty to indicate "use all tools" (e.g., on error or low confidence).
ProfileTask(ctx context.Context, firstMessage string, availableTools []ToolDescription) ([]string, error)
}
ContextTrimmer analyzes the user's first message and recommends a minimal tool set to reduce context window usage by filtering irrelevant tools from the initial API call. It is wired from app.go via SetContextTrimmer.
type EvaluationResult ¶ added in v0.324.0
type FilteredContextEnricher ¶ added in v1.2.7
type FilteredContextEnricher interface {
EnrichContextWithResult(ctx context.Context, query string) (string, rag.FilterResult)
}
FilteredContextEnricher is an optional extension of ContextEnricher for enrichers that report what the relevance filter did.
type FilteredMemoryInjector ¶ added in v1.2.7
type FilteredMemoryInjector interface {
BuildMemoryBlockWithResult(ctx context.Context, query string) (string, rag.FilterResult)
}
FilteredMemoryInjector is an optional extension of MemoryInjector that reports what the relevance filter did.
type FilteredSessionContextEnricher ¶ added in v1.2.7
type FilteredSessionContextEnricher interface {
EnrichContextForSessionWithResult(ctx context.Context, sessionID, query string) (string, rag.FilterResult)
}
FilteredSessionContextEnricher is the session-aware counterpart of FilteredContextEnricher.
type GoalEvaluator ¶ added in v0.324.0
type GoalEvent ¶ added in v0.324.0
type GoalEvent struct {
Type GoalEventType
GoalState *GoalState
Message string
}
GoalEvent represents a state change event for a goal.
type GoalEventType ¶ added in v0.324.0
type GoalEventType string
GoalEventType represents the type of goal event.
const ( GoalEventStart GoalEventType = "goal_start" GoalEventIteration GoalEventType = "goal_iteration" GoalEventComplete GoalEventType = "goal_complete" GoalEventFailed GoalEventType = "goal_failed" GoalEventCancelled GoalEventType = "goal_cancelled" GoalEventBlocked GoalEventType = "goal_blocked" GoalEventTimeout GoalEventType = "goal_timeout" GoalEventStalled GoalEventType = "goal_stalled" )
type GoalOptions ¶ added in v0.324.0
type GoalRunner ¶ added in v0.324.0
type GoalRunner struct {
// contains filtered or unexported fields
}
func NewGoalRunner ¶ added in v0.324.0
func NewGoalRunner(agent Service, goalStore GoalStore) *GoalRunner
func (*GoalRunner) Run ¶ added in v0.324.0
func (gr *GoalRunner) Run(ctx context.Context, sessionID string, objective string, opts GoalOptions) (<-chan AgentEvent, error)
type GoalState ¶ added in v0.324.0
type GoalState struct {
ID string
SessionID string
Objective string
StatusValue string
Iteration int
MaxIterations int
MaxDurationSecs int
StartedAt time.Time
CompletedAt *time.Time
LastProgress string
NextStep string
BlockedReason string
CreatedAt time.Time
InitialTodoSignature string
LastTodoSignature string
LastEvaluationSignature string
ConsecutiveNoProgress int
// contains filtered or unexported fields
}
GoalState represents the current state of a goal.
func NewGoalState ¶ added in v0.324.0
func (*GoalState) CanTransitionTo ¶ added in v0.324.0
func (*GoalState) Cancel ¶ added in v0.324.0
func (g *GoalState) Cancel()
Cancel signals the goal to stop.
func (*GoalState) Elapsed ¶ added in v0.324.0
Elapsed returns the time elapsed since the goal started.
func (*GoalState) IsCancelled ¶ added in v0.324.0
IsCancelled returns true if the goal has been cancelled.
func (*GoalState) IsRunning ¶ added in v0.324.0
IsRunning returns true if the goal is currently active.
func (*GoalState) IsTerminal ¶ added in v0.324.0
IsTerminal returns true if the status is a terminal state.
func (*GoalState) RecordIteration ¶ added in v0.324.0
func (*GoalState) RemainingDuration ¶ added in v0.324.0
RemainingDuration returns the remaining time before max duration.
func (*GoalState) SetStatus ¶ added in v0.324.0
SetStatus updates the status and marks done if terminal.
type GoalStore ¶ added in v0.324.0
type GoalStore interface {
CreateGoal(ctx context.Context, arg db.CreateGoalParams) (db.SessionGoal, error)
UpdateGoalStatus(ctx context.Context, arg db.UpdateGoalStatusParams) (db.SessionGoal, error)
}
type HeuristicGoalEvaluator ¶ added in v0.324.0
type HeuristicGoalEvaluator struct {
// contains filtered or unexported fields
}
func NewHeuristicGoalEvaluator ¶ added in v0.324.0
func NewHeuristicGoalEvaluator() *HeuristicGoalEvaluator
func NewHeuristicGoalEvaluatorWithThreshold ¶ added in v0.324.0
func NewHeuristicGoalEvaluatorWithThreshold(stallThreshold int) *HeuristicGoalEvaluator
type MCPClient ¶
type MCPClient interface {
Initialize(
ctx context.Context,
request mcp.InitializeRequest,
) (*mcp.InitializeResult, error)
ListTools(ctx context.Context, request mcp.ListToolsRequest) (*mcp.ListToolsResult, error)
CallTool(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error)
Close() error
}
type MemoryInjector ¶ added in v0.416.3
MemoryInjector builds the <memories> block prepended to the system prompt. The agent builds it once per session and freezes it (see sessionMemoryBlock). It is a separate interface from ContextEnricher so memory enrichment can be enabled independently of the main context-enrichment pipeline.
type PersonaRoutingInfo ¶ added in v1.2.7
type PersonaRoutingInfo struct {
// Persona is the applied persona, empty when none.
Persona string
// Source: "decision" (router matched), "llm" (fallback model chose),
// "sticky" (previous persona kept) or "default" (assistant / none).
Source string
// Reason is the decision outcome: matched, no_match, low_probability,
// no_personas, router_error or no_router.
Reason string
Probability float64
LatencyMs int64
CostUSD *float64
// ErrClass is the typed router error when the decision model was unavailable.
ErrClass string
// Changed reports that Persona differs from the previous turn's persona.
Changed bool
}
PersonaRoutingInfo summarises the last auto-selection of a session. It never carries the prompt text.
func LastPersonaRouting ¶ added in v1.2.7
func LastPersonaRouting(sessionID string) (PersonaRoutingInfo, bool)
LastPersonaRouting returns the last auto-selection of the session.
type PersonaSelector ¶ added in v0.41.0
type PersonaSelector struct {
// contains filtered or unexported fields
}
PersonaSelector is the LLM based persona classifier. It uses a lite LLM provider (configured via agents["persona-selector"]) to pick the best matching persona from the personas directory. It is the selection path when the decision model option is off, and the fallback when the decision model cannot answer.
func NewLazyPersonaSelector ¶ added in v1.2.7
func NewLazyPersonaSelector() *PersonaSelector
NewLazyPersonaSelector creates a selector that can always be installed: it is only active while personaAutoSelect.enabled is on, resolves personas from the global persona manager and builds its LLM provider on first use from the current persona-selector agent configuration (rebuilt when that changes).
func NewPersonaSelector ¶ added in v0.41.0
func NewPersonaSelector(personaPath string) (*PersonaSelector, error)
NewPersonaSelector creates a PersonaSelector that loads personas from personaPath and uses the model configured under agents["persona-selector"] to perform selection. Returns an error if the persona-selector agent is not configured or the model is unavailable.
func (*PersonaSelector) SelectAndApply ¶ added in v0.41.0
func (ps *PersonaSelector) SelectAndApply(ctx context.Context, userPrompt string) string
SelectAndApply selects the best persona for userPrompt and returns the prompt with the persona content prepended. Kept for backward compatibility; prefer SelectPersonaContent when the content will be injected into the system prompt.
func (*PersonaSelector) SelectPersonaContent ¶ added in v0.265.0
func (ps *PersonaSelector) SelectPersonaContent(ctx context.Context, userPrompt string) string
SelectPersonaContent selects the best persona for userPrompt and returns its raw content (the persona instructions). Returns an empty string if no persona matches, the selector is disabled, or an error occurs. The content is intended to be injected into the system prompt rather than prepended to the user message.
func (*PersonaSelector) SelectPersonaName ¶ added in v1.2.7
func (ps *PersonaSelector) SelectPersonaName(ctx context.Context, userPrompt string) (string, error)
SelectPersonaName asks the persona-selector LLM which persona fits userPrompt. It returns "" with a nil error when the model answered "none" or an unknown name, and a non-nil error when the model could not be consulted (no usable model, provider creation failed, the call failed).
type ResumeHandler ¶ added in v1.2.7
type ResumeHandler func(sessionID string, start ResumeStart) (taken bool, err error)
ResumeHandler is offered every run the delegation supervisor resumes for an idle session (Case B). It decides whether its surface owns the session:
- taken == false: not mine, start was NOT called; the next handler is tried.
- taken == true: the handler owns the run. It has called start (and is responsible for consuming the events) or failed trying, in which case err is returned. ErrSessionBusy makes the supervisor fall back to live injection.
type ResumeRegistry ¶ added in v1.2.7
type ResumeRegistry struct {
// contains filtered or unexported fields
}
ResumeRegistry holds the surfaces that may own a resumed run. The zero value is not usable; build it with NewResumeRegistry. A nil *ResumeRegistry is safe: Offer reports nothing taken, so callers without any surface (TUI, CLI) need no special case and fall back to Resume (drain only).
func NewResumeRegistry ¶ added in v1.2.7
func NewResumeRegistry() *ResumeRegistry
NewResumeRegistry creates an empty registry.
func (*ResumeRegistry) Offer ¶ added in v1.2.7
func (r *ResumeRegistry) Offer(sessionID string, start ResumeStart) (taken bool, err error)
Offer presents a resumed run to the registered handlers, highest priority first. It returns taken == true as soon as one handler takes it (err is that handler's result); taken == false means nobody owns the session and the caller must run it itself (Resume).
func (*ResumeRegistry) Register ¶ added in v1.2.7
func (r *ResumeRegistry) Register(priority int, h ResumeHandler) (unregister func())
Register adds a handler and returns a function that removes it again (safe to call more than once). A surface registers when it starts serving and unregisters when it stops.
type ResumeStart ¶ added in v1.2.7
type ResumeStart func(ctx context.Context) (<-chan AgentEvent, error)
ResumeStart starts the system-initiated run of a resumed session and returns its event channel (it is a closure over agent.ResumeRun). The context bounds the run: cancelling it cancels the run. A handler that takes a run MUST call it at most once and read the returned channel until it is closed.
type RoutingInfo ¶ added in v1.2.7
type RoutingInfo struct {
// RouteID is the matched route, empty when nothing matched.
RouteID string `json:"routeId,omitempty"`
// Model is the model that is (or last was) answering the turn. It changes
// when the turn fails over.
Model models.ModelID `json:"model"`
// Matched reports that a route matched with enough probability.
Matched bool `json:"matched"`
Probability float64 `json:"probability"`
Confidence float64 `json:"confidence"`
// Reason: matched, no_match, low_probability, low_confidence, router_error,
// no_routes, route_unusable, failover.
Reason string `json:"reason"`
// FallbackUsed is true when Model is a failover candidate rather than the
// first choice.
FallbackUsed bool `json:"fallbackUsed"`
// ErrorClass is the typed router error (unreachable, unauthorized, ...)
// when the router was unavailable.
ErrorClass string `json:"errorClass,omitempty"`
RouterProvider string `json:"routerProvider,omitempty"`
RouterModel string `json:"routerModel,omitempty"`
RouterLatencyMs int64 `json:"routerLatencyMs"`
RouterCostUSD *float64 `json:"routerCostUsd,omitempty"`
Candidates []models.ModelID `json:"candidates,omitempty"`
// Kind classifies the notice: "routed", "no_match", "router_unavailable",
// "route_unusable" or "failover".
Kind string `json:"kind"`
// Notice is the human readable line (same text as the system message).
Notice string `json:"notice"`
}
RoutingInfo summarises the last Auto routing decision of a session. It is also the payload of the routing notice (AgentEvent.Routing).
func LastRouting ¶ added in v1.2.7
func LastRouting(sessionID string) (RoutingInfo, bool)
LastRouting returns the summary of the last Auto routing decision.
type Service ¶
type Service interface {
pubsub.Suscriber[AgentEvent]
Model() models.Model
Run(ctx context.Context, sessionID string, content string, attachments ...message.Attachment) (<-chan AgentEvent, error)
LastRunSystemMessages(sessionID string) []string
Cancel(sessionID string)
// Steer queues a mid-run feedback message for the given session. It is injected
// into the conversation at the next safe boundary of the agent loop (after the
// current iteration's tool results, or at the end of the current turn) without
// cancelling the run. Returns ErrSessionNotBusy if there is no active run.
Steer(sessionID string, content string, attachments ...message.Attachment) error
// PendingSteering reports how many steering messages are queued for the session.
PendingSteering(sessionID string) int
// InjectConclusion queues a delegated-task conclusion for injection into a
// still-running parent loop at the next safe boundary (Case A of the delegation
// protocol). The content must already be the fully formatted text the parent
// will see — the agent does not re-frame it. Behaviour mirrors Steer but the
// message is typed as a conclusion (distinct UI framing) and it carries no
// attachments. Returns ErrSessionNotBusy when the session is idle; the
// supervisor uses that signal to fall back to resurrection (a later phase).
InjectConclusion(sessionID string, content string) error
// Resume starts a NEW system-initiated run for an IDLE session (Case B of the
// delegation protocol). The content is the pre-framed resurrection text the
// supervisor built. It is distinct from Run (user-initiated) and from
// InjectConclusion (live-loop steering): events still reach UIs via the pubsub
// broker, but the returned run channel is drained internally so the caller does
// not have to. Returns ErrSessionBusy if a run is already active. Each Resume
// increments the session's resurrection counter (see ResurrectionCount); a
// user-initiated Run resets it.
Resume(ctx context.Context, sessionID string, content string) error
// ResumeRun is Resume for a surface that owns the run: it returns the run's
// event channel instead of draining it, with AgentEventTypeResurrected as the
// first event on it. The caller must read the channel until it is closed;
// cancelling ctx cancels the run. Same busy/counter semantics as Resume. See
// ResumeRegistry for how a surface claims the runs the supervisor resumes.
ResumeRun(ctx context.Context, sessionID string, content string) (<-chan AgentEvent, error)
// ResurrectionCount reports how many times the session has been resurrected via
// Resume since the last user-initiated Run. The supervisor reads it to enforce
// the MaxResurrections cap; the count auto-resets whenever the user sends a new
// manual message (Run) and is cleared on Cancel.
ResurrectionCount(sessionID string) int
IsSessionBusy(sessionID string) bool
IsBusy() bool
Update(agentName config.AgentName, modelID models.ModelID) (models.Model, error)
Summarize(ctx context.Context, sessionID string) error
// SummarizeStream performs a manual summary and returns a channel of progress
// events that is closed when the summary finishes (or fails). Callers that need
// to know when the (asynchronous) summary is actually done must use this instead
// of Summarize, which returns immediately and only broadcasts via pubsub.
SummarizeStream(ctx context.Context, sessionID string) (<-chan AgentEvent, error)
SetLuaManager(fm *luaengine.FilterManager)
// GetTools returns the tools available to this agent instance.
GetTools() []tools.BaseTool
}
type SessionContextEnricher ¶ added in v0.646.4
type SessionContextEnricher interface {
ContextEnricher
EnrichContextForSession(ctx context.Context, sessionID, query string) string
// SessionStartOnly reports whether enrichment must run only for the first message
// of a session instead of every turn.
SessionStartOnly() bool
// Announce reports whether the run should be announced in the chat with start and
// end status messages (same treatment as context compaction).
Announce() bool
}
SessionContextEnricher is an optional extension of ContextEnricher for enrichers that need the active chat session — the agent-loop enricher attaches its run to that session as a child session so the user can inspect it from the UI.
type SessionLLMOverrides ¶ added in v0.407.0
type SessionLLMOverrides struct {
// Model, when non-empty, replaces the agent's configured model for this
// session only (request-scoped; does not touch global config).
Model models.ModelID
// ReasoningEffort / ThinkingMode override inference settings per session.
ReasoningEffort string
ThinkingMode config.ThinkingMode
// Persona, when non-empty, selects a specific persona for this session.
// It is only honored when PersonaScoped is true.
Persona string
// PersonaScoped marks the session as managing its own persona
// authoritatively: when true, the per-session Persona (or, if empty,
// auto-selection) takes precedence over the package-global active persona.
// This is what lets concurrent sessions use different personas safely.
PersonaScoped bool
// Prompt is extra system-prompt text appended for this session only, on
// top of whatever persona content PersonaScoped resolves (see
// getPersonaContent in persona_selector.go). It is only honored when
// PersonaScoped is true, exactly like Persona above: this is the AG-UI
// per-profile Prompt override (PANDO-US-0014) reusing the existing
// per-session mechanism instead of adding a second one.
Prompt string
// AutoMode is the explicit per-session Auto model mode choice: nil means
// "follow the global selection" (config modelAutoMode), true/false force it
// on/off for this session (see SessionAutoMode in model_auto.go).
AutoMode *bool
}
SessionLLMOverrides holds per-session runtime overrides that should take precedence over agent config when building a request-scoped provider.
These overrides are the mechanism that makes a single process safe to run several agent loops in parallel (e.g. an ACP server serving multiple concurrent sessions, or a warm delegation instance): instead of mutating shared/global agent state per prompt, each session threads its model, persona and inference settings through the request context so two concurrent runs never clobber each other.
func SessionLLMOverridesFor ¶ added in v0.643.1
func SessionLLMOverridesFor(sessionID string) SessionLLMOverrides
SessionLLMOverridesFor returns the overrides stored for a session, or the zero value when none are set. Unlike sessionLLMOverridesForContext it does not need a request context, so callers outside the agent loop (the pando_setup bridge) can read the session's effective model.
type TokenUsageInfo ¶ added in v0.418.12
type TokenUsageInfo struct {
PromptTokens int64
CompletionTokens int64
ContextWindow int64
Estimated bool
// CacheReadTokens, CacheCreationTokens, ReasoningTokens and Cost are only
// populated on confirmed updates (Estimated == false); estimated updates
// during tool execution have no breakdown/cost data available.
CacheReadTokens int64
CacheCreationTokens int64
ReasoningTokens int64
Cost float64
}
TokenUsageInfo carries a live token-usage snapshot for AgentEventTypeTokenUsage. PromptTokens/CompletionTokens are cumulative for the session (same semantics as session.Session), ContextWindow is the effective window for the active model, and Estimated marks the value as provisional (not yet confirmed by the provider).
type ToolDescription ¶ added in v0.407.0
ToolDescription carries the minimal information the ContextTrimmer needs about each tool.
type ToolsSetter ¶ added in v0.643.1
ToolsSetter is implemented by agents whose tool set can be swapped while the process runs. It is deliberately kept out of the Service interface so test doubles do not have to implement it; callers type-assert on it.
Source Files
¶
- agent-tool.go
- agent.go
- caveman_session.go
- context_filter.go
- extension_tools.go
- fixture_hitl_agent_stub.go
- goal_evaluator.go
- goal_prompts.go
- goal_runner.go
- goal_state.go
- learning_session.go
- mcp-tools.go
- mcp_bridge_client.go
- memory_block.go
- model_auto.go
- model_auto_failover.go
- model_switch.go
- persona_decision.go
- persona_selector.go
- ponytail_session.go
- resume_registry.go
- session_mcp.go
- session_overrides.go
- setup_bridge.go
- setup_bridge_model.go
- superpowers_session.go
- tool_discovery.go
- tools.go