agent

package
v0.1.0-p8a.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 10, 2026 License: MIT Imports: 71 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrDepthLimitExceeded   = errors.New("sub-turn depth limit exceeded")
	ErrInvalidSubTurnConfig = errors.New("invalid sub-turn config")
	ErrConcurrencyTimeout   = errors.New("timeout waiting for concurrency slot")
)

Functions

func EstimateMessageTokens

func EstimateMessageTokens(msg providers.Message) int

EstimateMessageTokens estimates the token count for a single message. Delegates to the shared tokenizer package for consistency across agent and seahorse.

func EstimateToolDefsTokens

func EstimateToolDefsTokens(defs []providers.ToolDefinition) int

EstimateToolDefsTokens estimates the total token cost of tool definitions as they appear in the LLM request. Delegates to the shared tokenizer package.

func RegisterBuiltinHook

func RegisterBuiltinHook(name string, factory BuiltinHookFactory) error

RegisterBuiltinHook registers a named in-process hook factory for config-driven mounting.

func RegisterContextManager

func RegisterContextManager(name string, factory ContextManagerFactory) error

RegisterContextManager registers a named ContextManager factory.

func SpawnSubTurn

func SpawnSubTurn(ctx context.Context, cfg SubTurnConfig) (*toolshared.ToolResult, error)

SpawnSubTurn is the exported entry point for tools to spawn sub-turns. It retrieves AgentLoop and parent turnState from context and delegates to spawnSubTurn.

func TurnStateFromContext

func TurnStateFromContext(ctx context.Context) *turnState

TurnStateFromContext retrieves turnState from context (exported for tools)

func WithAgentLoop

func WithAgentLoop(ctx context.Context, al *AgentLoop) context.Context

WithAgentLoop injects AgentLoop into context for tool access

Types

type ActiveTurnInfo

type ActiveTurnInfo struct {
	TurnID       string
	AgentID      string
	SessionKey   string
	Channel      string
	ChatID       string
	UserMessage  string
	Phase        TurnPhase
	Iteration    int
	StartedAt    time.Time
	Depth        int
	ParentTurnID string
	ChildTurnIDs []string
}

type AgentContextDefinition

type AgentContextDefinition struct {
	Source AgentDefinitionSource  `json:"source,omitempty"`
	Agent  *AgentPromptDefinition `json:"agent,omitempty"`
	Soul   *SoulDefinition        `json:"soul,omitempty"`
	User   *UserDefinition        `json:"user,omitempty"`
}

AgentContextDefinition captures the workspace agent definition in a runtime-friendly shape.

type AgentDefinitionSource

type AgentDefinitionSource string

AgentDefinitionSource identifies which agent bootstrap file produced the definition.

const (
	// AgentDefinitionSourceAgent indicates the new AGENT.md format.
	AgentDefinitionSourceAgent AgentDefinitionSource = "AGENT.md"
	// AgentDefinitionSourceAgents indicates the legacy AGENTS.md format.
	AgentDefinitionSourceAgents AgentDefinitionSource = "AGENTS.md"
)

type AgentDescriptor

type AgentDescriptor struct {
	ID          string `json:"id"`
	Name        string `json:"name"`
	Description string `json:"description"`
}

AgentDescriptor is the structured discovery payload injected into each agent's system prompt so the LLM can choose a peer by identity.

type AgentFrontmatter

type AgentFrontmatter struct {
	Name        string         `json:"name"`
	Description string         `json:"description"`
	Tools       []string       `json:"tools,omitempty"`
	ToolPolicy  *PatternPolicy `json:"-"`
	Model       string         `json:"model,omitempty"`
	MaxTurns    *int           `json:"maxTurns,omitempty"`
	Skills      []string       `json:"skills,omitempty"`
	MCPServers  []string       `json:"mcpServers,omitempty"`
	MCPPolicy   *PatternPolicy `json:"-"`
	Fields      map[string]any `json:"-"`
}

AgentFrontmatter holds machine-readable AGENT.md configuration.

Known fields are exposed directly for convenience. Fields keeps the full parsed frontmatter so future refactors can read additional keys without changing the loader contract again.

type AgentInstance

type AgentInstance struct {
	ID                        string
	Name                      string
	Model                     string
	Fallbacks                 []string
	Workspace                 string
	Layout                    RuntimeLayout
	MaxIterations             int
	MaxTokens                 int
	Temperature               float64
	ThinkingLevel             ThinkingLevel
	ThinkingLevelConfigured   bool
	ContextWindow             int
	SummarizeMessageThreshold int
	SummarizeTokenPercent     int
	Provider                  providers.LLMProvider
	Sessions                  session.SessionStore
	ContextBuilder            *ContextBuilder
	Tools                     *tools.ToolRegistry

	Definition       AgentContextDefinition
	Subagents        *config.SubagentsConfig
	SkillsFilter     []string
	MCPServerPolicy  *PatternPolicy
	ToolPolicy       *PatternPolicy
	Candidates       []providers.FallbackCandidate
	MaxParallelTurns int

	// Router is non-nil when model routing is configured and the light model
	// was successfully resolved. It scores each incoming message and decides
	// whether to route to LightCandidates or stay with Candidates.
	Router *routing.Router
	// LightCandidates holds the resolved provider candidates for the light model.
	// Pre-computed at agent creation to avoid repeated model_list lookups at runtime.
	LightCandidates []providers.FallbackCandidate
	// LightProvider is the concrete provider instance for the configured light model.
	// It is only used when routing selects the light tier for a turn.
	LightProvider providers.LLMProvider
	// CandidateProviders maps "provider/model" keys to per-candidate LLMProvider
	// instances. This allows each fallback model to use its own api_base and api_key
	// from model_list, instead of inheriting the primary model's provider config.
	CandidateProviders map[string]providers.LLMProvider
	ToolLoopDetection  loopguard.Config
	// contains filtered or unexported fields
}

AgentInstance represents a fully configured agent with its own workspace, session manager, context builder, and tool registry.

func NewAgentInstance

func NewAgentInstance(
	agentCfg *config.AgentConfig,
	defaults *config.AgentDefaults,
	cfg *config.Config,
	provider providers.LLMProvider,
) *AgentInstance

NewAgentInstance creates an agent instance from config.

func (*AgentInstance) AllowsMCPServer

func (a *AgentInstance) AllowsMCPServer(serverName string) bool

func (*AgentInstance) Close

func (a *AgentInstance) Close() error

Close releases resources held by the agent's session store.

type AgentLoop

type AgentLoop struct {
	// contains filtered or unexported fields
}

func AgentLoopFromContext

func AgentLoopFromContext(ctx context.Context) *AgentLoop

AgentLoopFromContext retrieves AgentLoop from context

func NewAgentLoop

func NewAgentLoop(
	cfg *config.Config,
	msgBus *bus.MessageBus,
	provider providers.LLMProvider,
	opts ...AgentLoopOption,
) *AgentLoop

func NewAgentLoopChecked

func NewAgentLoopChecked(
	cfg *config.Config,
	msgBus *bus.MessageBus,
	provider providers.LLMProvider,
	opts ...AgentLoopOption,
) (*AgentLoop, error)

NewAgentLoopChecked constructs an AgentLoop and returns context-manager initialization failures to startup callers.

func NewAgentLoopWithRuntimeProfile

func NewAgentLoopWithRuntimeProfile(
	cfg *config.Config,
	msgBus *bus.MessageBus,
	provider providers.LLMProvider,
	profile RuntimeProfile,
	opts ...AgentLoopOption,
) (*AgentLoop, error)

NewAgentLoopWithRuntimeProfile applies a resolved profile before registry and agent construction. It is the strict entry point for frontends that require distinct execution and state roots.

func (*AgentLoop) ActiveTurnCount

func (al *AgentLoop) ActiveTurnCount() int

func (*AgentLoop) Close

func (al *AgentLoop) Close()

Close releases resources held by agent session stores. Call after Stop.

func (*AgentLoop) Continue

func (al *AgentLoop) Continue(
	ctx context.Context,
	workspace, sessionKey, channel, chatID string,
) (string, error)

Continue resumes an idle agent by dequeuing any pending steering messages and running them through the agent loop. This is used when the agent's last message was from the assistant (i.e., it has stopped processing) and the user has since enqueued steering messages.

If no steering messages are pending, it returns an empty string.

func (*AgentLoop) GetActiveTurn

func (al *AgentLoop) GetActiveTurn() *ActiveTurnInfo

func (*AgentLoop) GetActiveTurnByScope

func (al *AgentLoop) GetActiveTurnByScope(workspace, sessionKey string) *ActiveTurnInfo

func (*AgentLoop) GetActiveTurnBySession

func (al *AgentLoop) GetActiveTurnBySession(sessionKey string) *ActiveTurnInfo

func (*AgentLoop) GetConfig

func (al *AgentLoop) GetConfig() *config.Config

func (*AgentLoop) GetRegistry

func (al *AgentLoop) GetRegistry() *AgentRegistry

func (*AgentLoop) GetStartupInfo

func (al *AgentLoop) GetStartupInfo() map[string]any

func (*AgentLoop) HardAbort

func (al *AgentLoop) HardAbort(sessionKey string) error

HardAbort immediately cancels the running agent loop for the given session, cascading the cancellation to all child SubTurns. This is a destructive operation that terminates execution without waiting for graceful cleanup.

Use this when the user explicitly requests immediate termination (e.g., "stop now", "abort"). For graceful interruption that allows the agent to finish the current tool and summarize, use Steer() instead.

func (*AgentLoop) InjectFollowUp

func (al *AgentLoop) InjectFollowUp(
	workspace, sessionKey, agentID string,
	msg providers.Message,
) error

InjectFollowUp enqueues a message to be automatically processed after the current turn completes. Unlike Steer(), which interrupts the current execution, InjectFollowUp waits for the current turn to finish naturally before processing the message.

This is useful for: - Automated workflows that need to chain multiple turns - Background tasks that should run after the main task completes - Scheduled follow-up actions

The message will be processed via Continue() when the agent becomes idle.

func (*AgentLoop) InjectSteering

func (al *AgentLoop) InjectSteering(
	workspace, sessionKey, agentID string,
	msg providers.Message,
) error

InjectSteering is an alias for Steer() to match the design document naming. It injects a steering message into the currently running agent loop.

func (*AgentLoop) InterruptGraceful

func (al *AgentLoop) InterruptGraceful(hint string) error

func (*AgentLoop) InterruptHard deprecated

func (al *AgentLoop) InterruptHard() error

InterruptHard aborts an arbitrary active turn. In parallel mode this may target the wrong session. Prefer HardAbort(sessionKey) instead.

Deprecated: Use HardAbort(sessionKey) for session-safe aborts.

func (*AgentLoop) MountHook

func (al *AgentLoop) MountHook(reg HookRegistration) error

MountHook registers an in-process hook on the agent loop.

func (*AgentLoop) MountProcessHook

func (al *AgentLoop) MountProcessHook(ctx context.Context, name string, opts ProcessHookOptions) error

func (*AgentLoop) PrepareConfigReload

func (al *AgentLoop) PrepareConfigReload(
	ctx context.Context,
	provider providers.LLMProvider,
	cfg *config.Config,
) (*PreparedConfigReload, error)

func (*AgentLoop) ProcessDirect

func (al *AgentLoop) ProcessDirect(
	ctx context.Context,
	content, sessionKey string,
) (string, error)

func (*AgentLoop) ProcessDirectWithChannel

func (al *AgentLoop) ProcessDirectWithChannel(
	ctx context.Context,
	content, sessionKey, channel, chatID string,
) (string, error)

func (*AgentLoop) ProcessDirectWithOptions

func (al *AgentLoop) ProcessDirectWithOptions(
	ctx context.Context,
	content, sessionKey, channel, chatID string,
	opts DirectTurnOptions,
) (string, error)

ProcessDirectWithOptions processes a direct turn with explicit persistence semantics.

func (*AgentLoop) ProcessHeartbeat

func (al *AgentLoop) ProcessHeartbeat(
	ctx context.Context,
	content, channel, chatID string,
) (string, error)

func (*AgentLoop) ProcessScheduledWithChannel

func (al *AgentLoop) ProcessScheduledWithChannel(
	ctx context.Context,
	content, sessionKey, channel, chatID string,
) (string, error)

func (*AgentLoop) ProcessScheduledWithIdentity

func (al *AgentLoop) ProcessScheduledWithIdentity(
	ctx context.Context,
	content, sessionKey, channel, chatID string,
) (string, string, error)

func (*AgentLoop) PublishResponseIfNeeded

func (al *AgentLoop) PublishResponseIfNeeded(
	ctx context.Context,
	workspace, agentID, channel, chatID, sessionKey, response string,
)

func (*AgentLoop) QuiesceTurns

func (al *AgentLoop) QuiesceTurns(ctx context.Context) (func(), error)

QuiesceTurns blocks new turn admission and waits for admitted turns to drain.

func (*AgentLoop) RecordLastChannel

func (al *AgentLoop) RecordLastChannel(channel string) error

func (*AgentLoop) RecordLastChatID

func (al *AgentLoop) RecordLastChatID(chatID string) error

func (*AgentLoop) RecoverHumanInteractions

func (al *AgentLoop) RecoverHumanInteractions(ctx context.Context) int

RecoverHumanInteractions retries prompt delivery, claims timeouts, and resumes answers whose durable owner disappeared during restart or reload.

func (*AgentLoop) RecoverUnansweredSessions

func (al *AgentLoop) RecoverUnansweredSessions(ctx context.Context) int

RecoverUnansweredSessions resumes sessions whose durable history ends with a user message. This closes the small gap left after a steering message has crossed from ingress spool into session history but the process exits before producing the assistant response.

func (*AgentLoop) RefreshRuntimeTools

func (al *AgentLoop) RefreshRuntimeTools(names ...string) error

RefreshRuntimeTools rebuilds selected generation-bound tools on the active registry without changing their retained factories.

func (*AgentLoop) RegisterRuntimeAgentTool

func (al *AgentLoop) RegisterRuntimeAgentTool(name string, factory RuntimeAgentToolFactory) error

func (*AgentLoop) RegisterRuntimeTool

func (al *AgentLoop) RegisterRuntimeTool(name string, factory RuntimeToolFactory) error

func (*AgentLoop) RegisterRuntimeToolDecorator

func (al *AgentLoop) RegisterRuntimeToolDecorator(name string, factory RuntimeToolDecoratorFactory) error

RegisterRuntimeToolDecorator installs a per-agent wrapper around an existing tool and remembers the factory for registry rebuilds after configuration reload. It never creates a tool that the agent did not already have. A nil result leaves the local tool unchanged.

func (*AgentLoop) RegisterTool

func (al *AgentLoop) RegisterTool(tool toolshared.Tool)

func (*AgentLoop) ReloadProviderAndConfig

func (al *AgentLoop) ReloadProviderAndConfig(
	ctx context.Context,
	provider providers.LLMProvider,
	cfg *config.Config,
) error

ReloadProviderAndConfig atomically swaps the provider and config with proper synchronization. It uses a context to allow timeout control from the caller. Returns an error if the reload fails or context is canceled.

func (*AgentLoop) Run

func (al *AgentLoop) Run(ctx context.Context) error

func (*AgentLoop) RuntimeEventBus

func (al *AgentLoop) RuntimeEventBus() runtimeevents.Bus

RuntimeEventBus returns the runtime event bus used by the agent loop.

func (*AgentLoop) RuntimeEventStats

func (al *AgentLoop) RuntimeEventStats() runtimeevents.Stats

RuntimeEventStats returns runtime event bus counters.

func (*AgentLoop) RuntimeEvents

func (al *AgentLoop) RuntimeEvents() runtimeevents.EventChannel

RuntimeEvents returns the root runtime event channel.

func (*AgentLoop) SetChannelManager

func (al *AgentLoop) SetChannelManager(cm *channels.Manager)

func (*AgentLoop) SetMediaStore

func (al *AgentLoop) SetMediaStore(s media.MediaStore)

func (*AgentLoop) SetOutboundOutbox

func (al *AgentLoop) SetOutboundOutbox(coordinator *outbox.Coordinator)

func (*AgentLoop) SetReloadFunc

func (al *AgentLoop) SetReloadFunc(fn func() error)

func (*AgentLoop) SetSteeringMode

func (al *AgentLoop) SetSteeringMode(mode SteeringMode)

SetSteeringMode updates the steering mode.

func (*AgentLoop) SetTranscriber

func (al *AgentLoop) SetTranscriber(t asr.Transcriber)

func (*AgentLoop) Steer

func (al *AgentLoop) Steer(
	workspace, sessionKey, agentID string,
	msg providers.Message,
) error

Steer enqueues a user message to be injected into the currently running agent loop. The message will be picked up after the current tool finishes executing, causing any remaining tool calls in the batch to be skipped.

func (*AgentLoop) SteeringMode

func (al *AgentLoop) SteeringMode() SteeringMode

SteeringMode returns the current steering mode.

func (*AgentLoop) Stop

func (al *AgentLoop) Stop()

func (*AgentLoop) SubscribeEvents

func (al *AgentLoop) SubscribeEvents(buffer int) EventSubscription

SubscribeEvents exposes the previous in-agent event subscription API on top of the runtime event bus for tests and compatibility.

func (*AgentLoop) TaskRegistryForWorkspace

func (al *AgentLoop) TaskRegistryForWorkspace(workspace string) *taskregistry.Registry

TaskRegistryForWorkspace returns the durable task registry shared by agent tools and gateway-managed runtimes for the given workspace.

func (*AgentLoop) UnmountHook

func (al *AgentLoop) UnmountHook(name string)

UnmountHook removes a previously registered in-process hook.

func (*AgentLoop) UnsubscribeEvents

func (al *AgentLoop) UnsubscribeEvents(id uint64)

func (*AgentLoop) ValidateConfigReload

func (al *AgentLoop) ValidateConfigReload(cfg *config.Config) error

ValidateConfigReload reports restart-only changes without mutating live runtime state.

func (*AgentLoop) WaitStartup

func (al *AgentLoop) WaitStartup(ctx context.Context) error

WaitStartup blocks until Run completes initialization (hooks/MCP) or ctx is canceled, returning the init outcome so callers can fail before readiness.

type AgentLoopOption

type AgentLoopOption func(*AgentLoop)

AgentLoopOption configures an AgentLoop at construction time.

func WithIsolatedSkillBootstrap

func WithIsolatedSkillBootstrap() AgentLoopOption

WithIsolatedSkillBootstrap restricts every agent's skill loader to its own workspace. It prevents tests and evaluations from observing global or built-in skills installed in the host process environment.

func WithIsolatedToolBootstrap

func WithIsolatedToolBootstrap() AgentLoopOption

WithIsolatedToolBootstrap prevents shared production tools and their state managers from being constructed. Callers must provide an explicit tool allowlist and register every permitted tool after construction.

func WithRuntimeEvents

func WithRuntimeEvents(bus runtimeevents.Bus) AgentLoopOption

WithRuntimeEvents injects the runtime event bus used for new observation APIs.

The injected bus is treated as externally owned and will not be closed by AgentLoop.Close. Passing nil leaves the default owned runtime bus enabled.

type AgentLoopSpawner

type AgentLoopSpawner struct {
	// contains filtered or unexported fields
}

AgentLoopSpawner implements tools.SubTurnSpawner interface. This allows tools to spawn sub-turns without circular dependency.

func NewSubTurnSpawner

func NewSubTurnSpawner(al *AgentLoop) *AgentLoopSpawner

NewSubTurnSpawner creates a SubTurnSpawner for the given AgentLoop.

func (*AgentLoopSpawner) SpawnSubTurn

func (s *AgentLoopSpawner) SpawnSubTurn(
	ctx context.Context,
	cfg tools.SubTurnConfig,
) (*toolshared.ToolResult, error)

SpawnSubTurn implements tools.SubTurnSpawner interface.

type AgentPromptDefinition

type AgentPromptDefinition struct {
	Path           string           `json:"path"`
	Raw            string           `json:"raw"`
	Body           string           `json:"body"`
	RawFrontmatter string           `json:"raw_frontmatter,omitempty"`
	Frontmatter    AgentFrontmatter `json:"frontmatter"`
	FrontmatterErr string           `json:"frontmatter_error,omitempty"`
}

AgentPromptDefinition represents the parsed AGENT.md or AGENTS.md prompt file.

type AgentRegistry

type AgentRegistry struct {
	// contains filtered or unexported fields
}

AgentRegistry manages multiple agent instances and routes messages to them.

func NewAgentRegistry

func NewAgentRegistry(
	cfg *config.Config,
	provider providers.LLMProvider,
) *AgentRegistry

NewAgentRegistry creates a registry from config, instantiating all agents.

func (*AgentRegistry) CanSpawnSubagent

func (r *AgentRegistry) CanSpawnSubagent(parentAgentID, targetAgentID string) bool

CanSpawnSubagent checks if parentAgentID is allowed to spawn targetAgentID.

func (*AgentRegistry) Close

func (r *AgentRegistry) Close()

Close releases resources held by all registered agents.

func (*AgentRegistry) ForEachTool

func (r *AgentRegistry) ForEachTool(name string, fn func(toolshared.Tool))

ForEachTool calls fn for every tool registered under the given name across all agents. This is useful for propagating dependencies (e.g. MediaStore) to tools after registry construction.

func (*AgentRegistry) GetAgent

func (r *AgentRegistry) GetAgent(agentID string) (*AgentInstance, bool)

GetAgent returns the agent instance for a given ID.

func (*AgentRegistry) GetAgentDescriptor

func (r *AgentRegistry) GetAgentDescriptor(agentID string) (*AgentDescriptor, bool)

GetAgentDescriptor returns the structured discovery payload for one agent.

func (*AgentRegistry) GetDefaultAgent

func (r *AgentRegistry) GetDefaultAgent() *AgentInstance

GetDefaultAgent returns the default agent instance.

func (*AgentRegistry) ListAgentIDs

func (r *AgentRegistry) ListAgentIDs() []string

ListAgentIDs returns all registered agent IDs.

func (*AgentRegistry) ListAgents

func (r *AgentRegistry) ListAgents(workspace string) []AgentDescriptor

ListAgents returns structured descriptors for every agent in the current MintClaw instance. The current workspace, when provided, is used only to order the matching agent first for prompt readability.

func (*AgentRegistry) ListSpawnableAgents

func (r *AgentRegistry) ListSpawnableAgents(agentID string) []AgentDescriptor

ListSpawnableAgents returns descriptors only when the current agent can call spawn, and only for peers it is allowed to spawn. Restricted peers are intentionally omitted from discovery.

func (*AgentRegistry) ResolveRoute

func (r *AgentRegistry) ResolveRoute(inbound bus.InboundContext) routing.ResolvedRoute

ResolveRoute determines which agent handles the normalized inbound context.

type ApprovalDecision

type ApprovalDecision struct {
	Approved       bool   `json:"approved"`
	RequireHuman   bool   `json:"require_human,omitempty"`
	Reason         string `json:"reason,omitempty"`
	ActionSummary  string `json:"action_summary,omitempty"`
	TimeoutSeconds int    `json:"timeout_seconds,omitempty"`
}

type AssembleRequest

type AssembleRequest struct {
	Agent         *AgentInstance // exact owner of the session
	SessionKey    string         // session identifier
	Budget        int            // context window in tokens
	MaxTokens     int            // max response tokens
	ReserveTokens int            // non-history prompt/tool tokens reserved outside context manager
}

AssembleRequest is the input to Assemble.

type AssembleResponse

type AssembleResponse struct {
	History []providers.Message  // assembled conversation history for BuildMessages
	Summary string               // conversation summary embedded into system prompt by BuildMessages
	Budget  *ContextBudgetReport // optional bounded-context selection details
}

AssembleResponse is the output of Assemble.

type AsyncCompletionInput

type AsyncCompletionInput struct {
	SourceTool   string
	CompletionID string
	Content      string
	Origin       bus.InboundContext
	SenderID     string
}

AsyncCompletionInput is the typed internal form of an async tool completion that needs parent-agent synthesis. Legacy system inbound messages are still adapted into this shape for compatibility, but new runtime code should call processAsyncCompletion directly instead of publishing a synthetic chat message.

type AsyncCompletionPayload

type AsyncCompletionPayload struct {
	SourceTool   string
	CompletionID string
	TaskID       string
	DeliveryMode string
	ContentLen   int
	ForUserLen   int
	MediaCount   int
	IsError      bool
	WillUser     bool
	WillParent   bool
}

AsyncCompletionPayload describes a typed async tool completion event before the runtime applies user/parent delivery policy.

type AsyncDeliveryDecision

type AsyncDeliveryDecision struct {
	TaskID        string
	DeliveryMode  toolshared.AsyncDeliveryMode
	PublishToUser bool
	QueueParent   bool
	ParentHandled bool
	ContentLen    int
	ForUserLen    int
	MediaCount    int
	IsError       bool
}

AsyncDeliveryDecision is the routing plan for a completed async tool result.

This is intentionally decision-only for now. The current runtime still performs delivery in pipeline_execute.go, but all routing policy should flow through this type so media, duplicate, timeout, and restart handling can move behind the same coordinator boundary later.

type AsyncDeliveryRequest

type AsyncDeliveryRequest struct {
	TurnState    *turnState
	ToolName     string
	CompletionID string
	Result       *toolshared.ToolResult
	Decision     AsyncDeliveryDecision
	TraceScopes  []runtimeevents.TraceScope
}

type BuiltinHookFactory

type BuiltinHookFactory func(ctx context.Context, spec config.BuiltinHookConfig) (any, error)

BuiltinHookFactory constructs an in-process hook from config.

type CompactRequest

type CompactRequest struct {
	Agent      *AgentInstance           // exact owner of the session
	SessionKey string                   // session identifier
	Workspace  string                   // canonical workspace owner
	TraceScope runtimeevents.TraceScope // exact owner for synchronous turn work; zero for background work
	Reason     ContextCompressReason    // proactive_budget | llm_retry | summarize
	Budget     int                      // effective history budget for compact/overflow repair
}

CompactRequest is the input to Compact.

type ContextBudgetReport

type ContextBudgetReport struct {
	ContextWindow            int
	OutputReserve            int
	NonHistoryReserve        int
	AvailableContext         int
	HistoryBudget            int
	SummaryBudget            int
	SourceHistoryTokens      int
	SourceSummaryTokens      int
	SelectedHistoryTokens    int
	SelectedSummaryTokens    int
	RequestedRecentTailTurns int
	RecentTailTurns          int
	RecentTailTokens         int
	RecentTailOverflowTokens int
	RecentTailDegraded       bool
	Truncated                bool
	NeedsCompaction          bool
	PressureReasons          []string
}

ContextBudgetReport describes one context manager selection decision.

type ContextBuilder

type ContextBuilder struct {
	// contains filtered or unexported fields
}

func NewContextBuilder

func NewContextBuilder(workspace string) *ContextBuilder

func (*ContextBuilder) AddAssistantMessage

func (cb *ContextBuilder) AddAssistantMessage(
	messages []providers.Message,
	content string,
	toolCalls []map[string]any,
) []providers.Message

func (*ContextBuilder) AddToolResult

func (cb *ContextBuilder) AddToolResult(
	messages []providers.Message,
	toolCallID, toolName, result string,
) []providers.Message

func (*ContextBuilder) BuildMessages

func (cb *ContextBuilder) BuildMessages(
	history []providers.Message,
	summary string,
	currentMessage string,
	media []string,
	channel, chatID, senderID, senderDisplayName string,
	activeSkills ...string,
) []providers.Message

func (*ContextBuilder) BuildMessagesFromPrompt

func (cb *ContextBuilder) BuildMessagesFromPrompt(req PromptBuildRequest) []providers.Message

func (*ContextBuilder) BuildSystemPrompt

func (cb *ContextBuilder) BuildSystemPrompt() string

func (*ContextBuilder) BuildSystemPromptParts

func (cb *ContextBuilder) BuildSystemPromptParts() []PromptPart

func (*ContextBuilder) BuildSystemPromptWithCache

func (cb *ContextBuilder) BuildSystemPromptWithCache() string

BuildSystemPromptWithCache returns the cached system prompt if available and source files haven't changed, otherwise builds and caches it. Source file changes are detected via mtime checks (cheap stat calls).

func (*ContextBuilder) EstimateSystemTokens

func (cb *ContextBuilder) EstimateSystemTokens(summary string, activeSkills []string) int

EstimateSystemTokens estimates the token count of the full system message that would be sent to the LLM, mirroring the composition logic in BuildMessages. It includes: static prompt, dynamic context, active skills, and summary with wrapping prefixes and separators. This avoids needing all per-request parameters that BuildMessages requires (media, channel, chatID, sender, etc.).

func (*ContextBuilder) GetSkillsInfo

func (cb *ContextBuilder) GetSkillsInfo() map[string]any

GetSkillsInfo returns information about loaded skills.

func (*ContextBuilder) InvalidateCache

func (cb *ContextBuilder) InvalidateCache()

InvalidateCache clears the cached system prompt. Normally not needed because the cache auto-invalidates via mtime checks, but this is useful for tests or explicit reload commands.

func (*ContextBuilder) ListSkillNames

func (cb *ContextBuilder) ListSkillNames() []string

func (*ContextBuilder) LoadAgentDefinition

func (cb *ContextBuilder) LoadAgentDefinition() AgentContextDefinition

LoadAgentDefinition parses the workspace agent bootstrap files.

It prefers the new AGENT.md format and its paired SOUL.md file. When the structured files are absent, it falls back to the legacy AGENTS.md layout so the current runtime can transition incrementally.

func (*ContextBuilder) LoadBootstrapFiles

func (cb *ContextBuilder) LoadBootstrapFiles() string

func (*ContextBuilder) RegisterPromptContributor

func (cb *ContextBuilder) RegisterPromptContributor(contributor PromptContributor) error

func (*ContextBuilder) RegisterPromptSource

func (cb *ContextBuilder) RegisterPromptSource(desc PromptSourceDescriptor) error

func (*ContextBuilder) ResolveActiveSkillsForContext

func (cb *ContextBuilder) ResolveActiveSkillsForContext(skillNames []string) []string

func (*ContextBuilder) ResolveSkillName

func (cb *ContextBuilder) ResolveSkillName(name string) (string, bool)

func (*ContextBuilder) WithAgentDiscovery

func (cb *ContextBuilder) WithAgentDiscovery(
	agentID string,
	discover func(agentID string) []AgentDescriptor,
) *ContextBuilder

func (*ContextBuilder) WithPromptMemoryConfig

func (cb *ContextBuilder) WithPromptMemoryConfig(prompt config.PromptMemoryConfig) *ContextBuilder

func (*ContextBuilder) WithSplitOnMarker

func (cb *ContextBuilder) WithSplitOnMarker(enabled bool) *ContextBuilder

func (*ContextBuilder) WithToolDiscovery

func (cb *ContextBuilder) WithToolDiscovery(useBM25, useRegex bool) *ContextBuilder

type ContextCompressPayload

type ContextCompressPayload struct {
	Reason                   ContextCompressReason
	DroppedMessages          int
	RemainingMessages        int
	ContextWindow            int
	OutputReserve            int
	NonHistoryReserve        int
	AvailableContext         int
	HistoryBudget            int
	SummaryBudget            int
	SourceHistoryTokens      int
	SourceSummaryTokens      int
	SelectedHistoryTokens    int
	SelectedSummaryTokens    int
	RequestedRecentTailTurns int
	RecentTailTurns          int
	RecentTailTokens         int
	RecentTailOverflowTokens int
	RecentTailDegraded       bool
	Truncated                bool
	PressureReasons          []string
	TokensSaved              int
	SummariesCreated         int
	LeafSummaries            int
	CondensedSummaries       int
}

ContextCompressPayload describes a forced history compression.

type ContextCompressReason

type ContextCompressReason string

ContextCompressReason identifies why emergency compression ran.

const (
	// ContextCompressReasonProactive indicates compression before the first LLM call.
	ContextCompressReasonProactive ContextCompressReason = "proactive_budget"
	// ContextCompressReasonRetry indicates compression during context-error retry handling.
	ContextCompressReasonRetry ContextCompressReason = "llm_retry"
	// ContextCompressReasonSummarize indicates post-turn async summarization.
	ContextCompressReasonSummarize ContextCompressReason = "summarize"
)

type ContextManager

type ContextManager interface {
	// Assemble builds budget-aware context from the ContextManager's own storage.
	// Called before BuildMessages. Returns assembled messages ready for LLM.
	Assemble(ctx context.Context, req *AssembleRequest) (*AssembleResponse, error)

	// Compact compresses conversation history.
	// Called by background schedulers for routine/proactive pressure and
	// synchronously only on emergency context-overflow retry.
	Compact(ctx context.Context, req *CompactRequest) error

	// Ingest records a message into the ContextManager's own storage.
	// Called after each message is persisted to session JSONL.
	Ingest(ctx context.Context, req *IngestRequest) error

	// Clear removes all stored context for a session (messages, summaries, etc.).
	// Called when the user issues /clear or /reset.
	Clear(ctx context.Context, agent *AgentInstance, sessionKey string) error
}

ContextManager manages conversation context via a pluggable strategy. Exactly ONE ContextManager is active per AgentLoop, selected by config. Seahorse is the default; "none" explicitly disables stored context assembly.

type ContextManagerFactory

type ContextManagerFactory func(cfg json.RawMessage, al *AgentLoop) (ContextManager, error)

ContextManagerFactory constructs a ContextManager from config. al provides access to the AgentLoop's runtime resources (provider, model, workspace, etc.) cfg is the raw JSON configuration from config.json (may be nil).

type ContextSnapshotPayload

type ContextSnapshotPayload struct {
	MessageCount     int
	SnapshotHash     string
	GoalHash         string
	SteeringCount    int
	ToolPairingValid bool
}

type Control

type Control int
const (
	// ControlContinue tells the runner to jump back to the top of the turn loop
	// (equivalent to the original "goto turnLoop").
	ControlContinue Control = iota
	// ControlBreak tells the runner to exit the turn loop and proceed to Finalize.
	ControlBreak
	// ControlToolLoop tells the runner to execute the tool loop.
	ControlToolLoop
)

type DirectTurnOptions

type DirectTurnOptions struct {
	// Stateless prevents the turn from loading or saving conversation history.
	// Tool calls and results remain available for the duration of the turn.
	Stateless bool
}

DirectTurnOptions controls persistence for a directly invoked agent turn.

type DispatchRequest

type DispatchRequest struct {
	RouteSessionKey string
	BaseSessionKey  string
	SessionKey      string
	SessionAliases  []string
	InboundContext  *bus.InboundContext
	RouteResult     *routing.ResolvedRoute
	SessionScope    *session.SessionScope
	UserMessage     string
	Media           []string
}

DispatchRequest is the normalized runtime input passed into the agent loop after routing and session allocation have completed.

func (DispatchRequest) Channel

func (r DispatchRequest) Channel() string

func (DispatchRequest) ChatID

func (r DispatchRequest) ChatID() string

func (DispatchRequest) ChatType

func (r DispatchRequest) ChatType() string

func (DispatchRequest) MessageID

func (r DispatchRequest) MessageID() string

func (DispatchRequest) ReplyToMessageID

func (r DispatchRequest) ReplyToMessageID() string

func (DispatchRequest) SenderID

func (r DispatchRequest) SenderID() string

type ErrorPayload

type ErrorPayload struct {
	Stage   string
	Message string
}

ErrorPayload describes an execution error inside the agent loop.

type Event

type Event struct {
	Kind    EventKind
	Time    time.Time
	Meta    EventMeta
	Context *TurnContext
	Payload any
}

Event is the legacy agent event envelope exposed by SubscribeEvents and a handful of tests. Runtime code publishes pkg/events.Event internally.

type EventKind

type EventKind = runtimeevents.Kind

EventKind is the legacy in-agent event kind alias kept for tests and compatibility shims on top of the runtime event bus.

const (
	EventKindTurnStart              EventKind = runtimeevents.KindAgentTurnStart
	EventKindTurnEnd                EventKind = runtimeevents.KindAgentTurnEnd
	EventKindLLMRequest             EventKind = runtimeevents.KindAgentLLMRequest
	EventKindLLMDelta               EventKind = runtimeevents.KindAgentLLMDelta
	EventKindLLMResponse            EventKind = runtimeevents.KindAgentLLMResponse
	EventKindLLMRetry               EventKind = runtimeevents.KindAgentLLMRetry
	EventKindLLMFallbackAttempt     EventKind = runtimeevents.KindAgentLLMFallbackAttempt
	EventKindContextCompress        EventKind = runtimeevents.KindAgentContextCompress
	EventKindContextSnapshot        EventKind = runtimeevents.KindAgentContextSnapshot
	EventKindSessionSummarize       EventKind = runtimeevents.KindAgentSessionSummarize
	EventKindToolExecStart          EventKind = runtimeevents.KindAgentToolExecStart
	EventKindToolExecEnd            EventKind = runtimeevents.KindAgentToolExecEnd
	EventKindToolExecSkipped        EventKind = runtimeevents.KindAgentToolExecSkipped
	EventKindToolLoopDecision       EventKind = runtimeevents.KindAgentToolLoopDecision
	EventKindSteeringInjected       EventKind = runtimeevents.KindAgentSteeringInjected
	EventKindFollowUpQueued         EventKind = runtimeevents.KindAgentFollowUpQueued
	EventKindAsyncCompletion        EventKind = runtimeevents.KindAgentAsyncCompletion
	EventKindInterruptReceived      EventKind = runtimeevents.KindAgentInterruptReceived
	EventKindSubTurnSpawn           EventKind = runtimeevents.KindAgentSubTurnSpawn
	EventKindSubTurnEnd             EventKind = runtimeevents.KindAgentSubTurnEnd
	EventKindSubTurnResultDelivered EventKind = runtimeevents.KindAgentSubTurnResultDelivered
	EventKindSubTurnOrphan          EventKind = runtimeevents.KindAgentSubTurnOrphan
	EventKindError                  EventKind = runtimeevents.KindAgentError
)

type EventMeta

type EventMeta = HookMeta

EventMeta is the legacy name for hook metadata.

type EventSubscription

type EventSubscription struct {
	ID uint64
	C  <-chan Event
}

EventSubscription identifies a legacy subscriber channel returned by AgentLoop.SubscribeEvents.

type FinalizationContext

type FinalizationContext struct {
	// contains filtered or unexported fields
}

FinalizationContext is the terminal snapshot consumed by Finalize. It keeps iteration-owned state out of the finalization phase.

type FollowUpQueuedPayload

type FollowUpQueuedPayload struct {
	SourceTool string
	ContentLen int
}

FollowUpQueuedPayload describes an async follow-up queued back into the inbound bus.

type HookAction

type HookAction string
const (
	HookActionContinue  HookAction = "continue"
	HookActionModify    HookAction = "modify"
	HookActionRespond   HookAction = "respond" // Return result directly, skip tool execution. SECURITY: This bypasses ApproveTool checks, allowing hooks to return results for any tool (including sensitive ones like bash) without approval. Use with caution.
	HookActionDenyTool  HookAction = "deny_tool"
	HookActionAbortTurn HookAction = "abort_turn"
	HookActionHardAbort HookAction = "hard_abort"
)

type HookDecision

type HookDecision struct {
	Action HookAction `json:"action"`
	Reason string     `json:"reason,omitempty"`
}

type HookManager

type HookManager struct {
	// contains filtered or unexported fields
}

func NewHookManager

func NewHookManager(runtimeEvents runtimeevents.EventChannel) *HookManager

func (*HookManager) AfterLLM

func (*HookManager) AfterTool

func (*HookManager) ApproveTool

func (hm *HookManager) ApproveTool(ctx context.Context, req *ToolApprovalRequest) ApprovalDecision

func (*HookManager) BeforeLLM

func (*HookManager) BeforeTool

func (*HookManager) Close

func (hm *HookManager) Close()

func (*HookManager) ConfigureTimeouts

func (hm *HookManager) ConfigureTimeouts(observer, interceptor, approval time.Duration)

func (*HookManager) Mount

func (hm *HookManager) Mount(reg HookRegistration) error

func (*HookManager) Unmount

func (hm *HookManager) Unmount(name string)

type HookMeta

type HookMeta struct {
	runtimeevents.TraceScope
	AgentID      string
	ParentTurnID string
	SessionKey   string
	Iteration    int
	TracePath    string
	Source       string
	// contains filtered or unexported fields
}

HookMeta contains correlation fields shared by agent hook requests and runtime events emitted from turn processing.

type HookRegistration

type HookRegistration struct {
	Name     string
	Priority int
	Source   HookSource
	Hook     any
}

func NamedHook

func NamedHook(name string, hook any) HookRegistration

type HookSource

type HookSource uint8
const (
	HookSourceInProcess HookSource = iota
	HookSourceProcess
)

type InboundMessageRelation

type InboundMessageRelation struct {
	Kind      InboundRelationKind
	MediaOnly bool
}

func (InboundMessageRelation) IsZero

func (r InboundMessageRelation) IsZero() bool

type InboundRelationKind

type InboundRelationKind string
const (
	InboundRelationStandalone            InboundRelationKind = "standalone"
	InboundRelationReplyToMessage        InboundRelationKind = "reply_to_message"
	InboundRelationAdjacentFollowupMedia InboundRelationKind = "adjacent_followup_media"
)

type IngestRequest

type IngestRequest struct {
	Agent             *AgentInstance    // exact owner of the session
	SessionKey        string            // session identifier
	Message           providers.Message // the message submitted to canonical history
	CanonicalWriteErr error             // non-nil when canonical persistence failed
}

IngestRequest is the input to Ingest.

type InteractionEventPayload

type InteractionEventPayload struct {
	InteractionID string                 `json:"interaction_id"`
	ShortID       string                 `json:"short_id,omitempty"`
	Kind          interactions.Kind      `json:"kind"`
	Event         interactions.EventType `json:"event"`
	Status        interactions.Status    `json:"status"`
	Outcome       interactions.Outcome   `json:"outcome,omitempty"`
	Revision      int64                  `json:"revision"`
	Code          string                 `json:"code,omitempty"`
	Success       *bool                  `json:"success,omitempty"`
}

type InterruptKind

type InterruptKind string
const (
	InterruptKindSteering InterruptKind = "steering"
	InterruptKindGraceful InterruptKind = "graceful"
	InterruptKindHard     InterruptKind = "hard_abort"
)

type InterruptReceivedPayload

type InterruptReceivedPayload struct {
	Kind              InterruptKind
	Role              string
	ContentLen        int
	QueueDepth        int
	HintLen           int
	MessageHash       string
	DiagnosticContent string
}

InterruptReceivedPayload describes accepted turn-control input.

type LLMCallOutcome

type LLMCallOutcome struct {
	Control      Control
	FinalContent string
	AbortCause   TurnAbortCause
}

LLMCallOutcome is the explicit result of one LLM phase.

type LLMDeltaPayload

type LLMDeltaPayload struct {
	ContentDeltaLen   int
	ReasoningDeltaLen int
}

LLMDeltaPayload describes a streamed LLM delta.

type LLMFallbackAttemptPayload

type LLMFallbackAttemptPayload struct {
	Provider    string
	Model       string
	IdentityKey string
	Attempt     int
	Status      string
	Reason      string
	ErrorCode   string
	Skipped     bool
}

type LLMHookRequest

type LLMHookRequest struct {
	Meta             HookMeta                   `json:"meta"`
	Context          *TurnContext               `json:"context,omitempty"`
	Model            string                     `json:"model"`
	Messages         []providers.Message        `json:"messages,omitempty"`
	Tools            []providers.ToolDefinition `json:"tools,omitempty"`
	Options          map[string]any             `json:"options,omitempty"`
	GracefulTerminal bool                       `json:"graceful_terminal,omitempty"`
}

func (*LLMHookRequest) Clone

func (r *LLMHookRequest) Clone() *LLMHookRequest

type LLMHookResponse

type LLMHookResponse struct {
	Meta     HookMeta               `json:"meta"`
	Context  *TurnContext           `json:"context,omitempty"`
	Model    string                 `json:"model"`
	Response *providers.LLMResponse `json:"response,omitempty"`
}

func (*LLMHookResponse) Clone

func (r *LLMHookResponse) Clone() *LLMHookResponse

type LLMInterceptor

type LLMInterceptor interface {
	BeforeLLM(ctx context.Context, req *LLMHookRequest) (*LLMHookRequest, HookDecision, error)
	AfterLLM(ctx context.Context, resp *LLMHookResponse) (*LLMHookResponse, HookDecision, error)
}

type LLMIterationState

type LLMIterationState struct {
	// contains filtered or unexported fields
}

type LLMRequestPayload

type LLMRequestPayload struct {
	Provider           string
	Model              string
	PromptHash         string
	MessagesCount      int
	ToolsCount         int
	MaxTokens          int
	Temperature        float64
	DiagnosticMessages string
}

LLMRequestPayload describes an outbound LLM request.

type LLMResponsePayload

type LLMResponsePayload struct {
	ResponseHash        string
	ContentLen          int
	ToolCalls           int
	HasReasoning        bool
	PromptTokens        int
	CompletionTokens    int
	TotalTokens         int
	HasProviderUsage    bool
	DiagnosticContent   string
	DiagnosticReasoning string
	DiagnosticToolCalls string
}

LLMResponsePayload describes an inbound LLM response.

type LLMRetryPayload

type LLMRetryPayload struct {
	Attempt    int
	MaxRetries int
	Reason     string
	Error      string
	Backoff    time.Duration
}

LLMRetryPayload describes a retry of an LLM request.

type MemoryStore

type MemoryStore struct {
	// contains filtered or unexported fields
}

MemoryStore manages persistent memory for the agent. - Long-term memory: memory/MEMORY.md - Daily notes: memory/YYYYMM/YYYYMMDD.md

func NewMemoryStore

func NewMemoryStore(workspace string) *MemoryStore

NewMemoryStore creates a new MemoryStore with the given workspace path. It ensures the memory directory exists.

func (*MemoryStore) AppendToday

func (ms *MemoryStore) AppendToday(content string) error

AppendToday appends content to today's daily note. If the file doesn't exist, it creates a new file with a date header.

func (*MemoryStore) GetMemoryContext

func (ms *MemoryStore) GetMemoryContext() string

GetMemoryContext returns formatted memory context for the agent prompt. Includes long-term memory and recent daily notes.

func (*MemoryStore) GetRecentDailyNotes

func (ms *MemoryStore) GetRecentDailyNotes(days int) string

GetRecentDailyNotes returns daily notes from the last N days. Contents are joined with "---" separator.

func (*MemoryStore) ReadLongTerm

func (ms *MemoryStore) ReadLongTerm() string

ReadLongTerm reads the long-term memory (MEMORY.md). Returns empty string if the file doesn't exist.

func (*MemoryStore) ReadToday

func (ms *MemoryStore) ReadToday() string

ReadToday reads today's daily note. Returns empty string if the file doesn't exist.

func (*MemoryStore) WriteLongTerm

func (ms *MemoryStore) WriteLongTerm(content string) error

WriteLongTerm writes content to the long-term memory file (MEMORY.md).

type PatternPolicy

type PatternPolicy struct {
	Allow []string
	Deny  []string
	// contains filtered or unexported fields
}

type Pipeline

type Pipeline struct {
	Cfg         *config.Config
	Runtime     PipelineRuntimeServices
	Config      PipelineConfigServices
	Context     PipelineContextServices
	Interaction PipelineInteractionServices
}

Pipeline holds the runtime dependencies used by Pipeline methods. It is constructed by runTurn via NewPipeline and passed to sub-methods so that the coordinator can delegate phase execution.

func NewPipeline

func NewPipeline(al *AgentLoop) *Pipeline

NewPipeline creates a Pipeline from an AgentLoop instance.

func NewPipelineFromDependencies

func NewPipelineFromDependencies(deps PipelineDependencies) *Pipeline

NewPipelineFromDependencies creates a Pipeline from explicit dependencies.

func (*Pipeline) CallLLM

func (p *Pipeline) CallLLM(
	ctx context.Context,
	turnCtx context.Context,
	ts *turnState,
	exec *turnExecution,
	llm *LLMIterationState,
) (LLMCallOutcome, error)

CallLLM performs an LLM call with fallback support, hook invocation, and retry logic. It handles PreLLM setup, the actual LLM invocation with retry, and AfterLLM processing. Returns an explicit outcome indicating what the coordinator should do next.

func (*Pipeline) ExecuteTools

func (p *Pipeline) ExecuteTools(
	ctx context.Context,
	turnCtx context.Context,
	ts *turnState,
	exec *turnExecution,
	llm *LLMIterationState,
) (outcome ToolLoopOutcome)

ExecuteTools executes the tool loop, handling BeforeTool/ApproveTool/AfterTool hooks, tool execution with async callbacks, media delivery, and steering injection. Returns an explicit outcome indicating what the coordinator should do next:

  • ToolControlContinue: all tool results handled, pendingMessages or steering exists, continue turn
  • ToolControlBreak: tool loop exited, proceed to coordinator's hardAbort/finalContent/finalize
  • ToolControlHalt: finalize exact runtime safety content without another model call

func (*Pipeline) Finalize

func (p *Pipeline) Finalize(
	turnCtx context.Context,
	ts *turnState,
	finalization FinalizationContext,
) (turnResult, error)

Finalize commits and delivers a terminal turn snapshot.

func (*Pipeline) SetupTurn

func (p *Pipeline) SetupTurn(ctx context.Context, ts *turnState) (*turnExecution, error)

SetupTurn extracts the one-time initialization phase, returning a turnExecution populated with history, messages, and candidate selection. It replaces lines 56-145 of the original runTurn.

type PipelineConfigServices

type PipelineConfigServices struct {
	ChannelStreaming      channelStreamingConfigProvider
	NativeSearch          nativeSearchPolicy
	LLMRetry              llmRetryPolicy
	RetrySleeper          retrySleeper
	MediaLimits           mediaLimitsProvider
	FinalTurnRender       finalTurnRenderPolicy
	ModelResolution       pipelineModelResolution
	PromptBuilder         pipelinePromptBuilder
	ToolContentFilter     toolContentFilter
	TrustAllToolExecution bool
	HashToolArguments     func(string, map[string]any) (string, error)
}

type PipelineContextServices

type PipelineContextServices struct {
	Runtime              pipelineContextRuntime
	BackgroundCompaction backgroundCompactionScheduler
	ModelExecution       modelExecutionResolver
	Steering             steeringDequeuer
	MediaResolver        mediaResolver
}

type PipelineDependencies

type PipelineDependencies struct {
	Cfg         *config.Config
	Runtime     PipelineRuntimeServices
	Config      PipelineConfigServices
	Context     PipelineContextServices
	Interaction PipelineInteractionServices
}

PipelineDependencies is the explicit dependency set required by Pipeline.

type PipelineInteractionServices

type PipelineInteractionServices struct {
	Reasoning        reasoningPublisher
	ToolFeedback     toolFeedbackManager
	SyncToolDelivery syncToolResultDeliveryManager
	ToolDelivery     toolDeliveryManager
	Hooks            hookInterceptor
	Fallback         fallbackExecutor
	Suspension       toolSuspensionManager
}

type PipelineRuntimeServices

type PipelineRuntimeServices struct {
	Bus            pipelineBus
	Events         runtimeEventEmitter
	ActiveRequests activeRequestTracker
	TurnControl    turnController
}

type PreparedConfigReload

type PreparedConfigReload struct {
	// contains filtered or unexported fields
}

PreparedConfigReload owns an unpublished registry and provider until Commit.

func (*PreparedConfigReload) Abort

func (prepared *PreparedConfigReload) Abort()

func (*PreparedConfigReload) Commit

func (prepared *PreparedConfigReload) Commit(ctx context.Context) error

func (*PreparedConfigReload) RefreshRuntimeTools

func (prepared *PreparedConfigReload) RefreshRuntimeTools(names ...string) error

RefreshRuntimeTools rebuilds selected generation-bound tools on the unpublished registry after the owning runtime has reconciled.

func (*PreparedConfigReload) RegisterTool

func (prepared *PreparedConfigReload) RegisterTool(tool toolshared.Tool)

type ProcessHook

type ProcessHook struct {
	// contains filtered or unexported fields
}

func NewProcessHook

func NewProcessHook(ctx context.Context, name string, opts ProcessHookOptions) (*ProcessHook, error)

func (*ProcessHook) AfterLLM

func (ph *ProcessHook) AfterLLM(
	ctx context.Context,
	resp *LLMHookResponse,
) (*LLMHookResponse, HookDecision, error)

func (*ProcessHook) AfterTool

func (*ProcessHook) ApproveTool

func (ph *ProcessHook) ApproveTool(ctx context.Context, req *ToolApprovalRequest) (ApprovalDecision, error)

func (*ProcessHook) BeforeLLM

func (ph *ProcessHook) BeforeLLM(
	ctx context.Context,
	req *LLMHookRequest,
) (*LLMHookRequest, HookDecision, error)

func (*ProcessHook) BeforeTool

func (*ProcessHook) Close

func (ph *ProcessHook) Close() error

func (*ProcessHook) OnRuntimeEvent

func (ph *ProcessHook) OnRuntimeEvent(ctx context.Context, evt runtimeevents.Event) error

type ProcessHookOptions

type ProcessHookOptions struct {
	Command       []string
	Dir           string
	Env           []string
	Observe       bool
	ObserveKinds  []string
	InterceptLLM  bool
	InterceptTool bool
	ApproveTool   bool
}

type PromptBuildRequest

type PromptBuildRequest struct {
	History []providers.Message
	Summary string

	CurrentMessage string
	Media          []string

	Channel           string
	ChatID            string
	SenderID          string
	SenderDisplayName string
	ReplyToMessageID  string
	// AllowAdjacentMediaFollowup enables inferred media-only continuation from
	// the previous user turn. Callers should only set it when the session scope
	// is known to be single-sender-safe, or when sender metadata can prove the
	// prior user message came from the same sender.
	AllowAdjacentMediaFollowup bool
	CurrentMessageRelation     InboundMessageRelation

	ActiveSkills []string
	Overlays     []PromptPart

	SuppressDefaultSystemPrompt bool
	SuppressSkillContext        bool
	SuppressToolUseRule         bool
	AllowedSkills               []string
	AllowedTools                []string
	ToolUseFallback             bool
}

type PromptCachePolicy

type PromptCachePolicy string
const (
	PromptCacheDefault   PromptCachePolicy = ""
	PromptCacheEphemeral PromptCachePolicy = "ephemeral"
	PromptCacheNone      PromptCachePolicy = "none"
)

type PromptContributor

type PromptContributor interface {
	PromptSource() PromptSourceDescriptor
	ContributePrompt(ctx context.Context, req PromptBuildRequest) ([]PromptPart, error)
}

type PromptLayer

type PromptLayer string
const (
	PromptLayerKernel      PromptLayer = "kernel"
	PromptLayerInstruction PromptLayer = "instruction"
	PromptLayerCapability  PromptLayer = "capability"
	PromptLayerContext     PromptLayer = "context"
	PromptLayerTurn        PromptLayer = "turn"
)

type PromptPart

type PromptPart struct {
	ID      string
	Layer   PromptLayer
	Slot    PromptSlot
	Source  PromptSource
	Title   string
	Content string
	Stable  bool
	Cache   PromptCachePolicy
}

type PromptPlacement

type PromptPlacement struct {
	Layer PromptLayer
	Slot  PromptSlot
}

type PromptRegistry

type PromptRegistry struct {
	// contains filtered or unexported fields
}

func NewPromptRegistry

func NewPromptRegistry() *PromptRegistry

func (*PromptRegistry) Collect

func (*PromptRegistry) RegisterContributor

func (r *PromptRegistry) RegisterContributor(contributor PromptContributor) error

func (*PromptRegistry) RegisterSource

func (r *PromptRegistry) RegisterSource(desc PromptSourceDescriptor) error

func (*PromptRegistry) ValidatePart

func (r *PromptRegistry) ValidatePart(part PromptPart) error

type PromptSlot

type PromptSlot string
const (
	PromptSlotIdentity     PromptSlot = "identity"
	PromptSlotHierarchy    PromptSlot = "hierarchy"
	PromptSlotWorkspace    PromptSlot = "workspace"
	PromptSlotTooling      PromptSlot = "tooling"
	PromptSlotMCP          PromptSlot = "mcp"
	PromptSlotSkillCatalog PromptSlot = "skill_catalog"
	PromptSlotActiveSkill  PromptSlot = "active_skill"
	PromptSlotMemory       PromptSlot = "memory"
	PromptSlotRuntime      PromptSlot = "runtime"
	PromptSlotSummary      PromptSlot = "summary"
	PromptSlotMessage      PromptSlot = "message"
	PromptSlotSteering     PromptSlot = "steering"
	PromptSlotSubTurn      PromptSlot = "subturn"
	PromptSlotToolResult   PromptSlot = "tool_result"
	PromptSlotInterrupt    PromptSlot = "interrupt"
	PromptSlotOutput       PromptSlot = "output"
)

type PromptSource

type PromptSource struct {
	ID   PromptSourceID
	Name string
	Path string
}

type PromptSourceDescriptor

type PromptSourceDescriptor struct {
	ID              PromptSourceID
	Owner           string
	Description     string
	Allowed         []PromptPlacement
	StableByDefault bool
}

type PromptSourceID

type PromptSourceID string
const (
	PromptSourceKernel         PromptSourceID = "runtime.kernel"
	PromptSourceHierarchy      PromptSourceID = "runtime.hierarchy"
	PromptSourceWorkspace      PromptSourceID = "workspace.definition"
	PromptSourceRuntime        PromptSourceID = "runtime.context"
	PromptSourceSummary        PromptSourceID = "context.summary"
	PromptSourceMemory         PromptSourceID = "memory:workspace"
	PromptSourceSkillCatalog   PromptSourceID = "skill:index"
	PromptSourceActiveSkills   PromptSourceID = "skill:active"
	PromptSourceAgentDiscovery PromptSourceID = "agent:discovery"
	PromptSourceToolRegistry   PromptSourceID = "tool_registry:native"
	PromptSourceToolDiscovery  PromptSourceID = "tool_registry:discovery"
	PromptSourceOutputPolicy   PromptSourceID = "runtime.output"
	PromptSourceSubTurnProfile PromptSourceID = "subturn.profile"
	PromptSourceUserMessage    PromptSourceID = "turn:user_message"
	PromptSourceSteering       PromptSourceID = "turn:steering"
	PromptSourceSubTurnResult  PromptSourceID = "turn:subturn_result"
	PromptSourceToolResult     PromptSourceID = "turn:tool_result"
	PromptSourceInterrupt      PromptSourceID = "turn:interrupt"
)

type PromptStack

type PromptStack struct {
	// contains filtered or unexported fields
}

func NewPromptStack

func NewPromptStack(registry *PromptRegistry) *PromptStack

func (*PromptStack) Add

func (s *PromptStack) Add(part PromptPart) error

func (*PromptStack) Parts

func (s *PromptStack) Parts() []PromptPart

func (*PromptStack) Seal

func (s *PromptStack) Seal()

type RuntimeAgentToolFactory

type RuntimeAgentToolFactory func(cfg *config.Config, agentID string) (toolshared.Tool, error)

RuntimeAgentToolFactory builds one agent-scoped runtime tool so its schema and authority can be projected without exposing another agent's grants.

type RuntimeEventObserver

type RuntimeEventObserver interface {
	OnRuntimeEvent(ctx context.Context, evt runtimeevents.Event) error
}

type RuntimeLayout

type RuntimeLayout struct {
	// contains filtered or unexported fields
}

RuntimeLayout separates the roots historically represented by AgentInstance.Workspace.

Every runtime keeps StateRoot outside ExecutionRoot so construction cannot place MintClaw-owned state in a personal workspace or source checkout.

func NewRuntimeLayout

func NewRuntimeLayout(
	owner RuntimeOwner,
	executionRoot string,
	stateRoot string,
	instructionRoots []string,
) (RuntimeLayout, error)

NewRuntimeLayout validates and returns a side-effect-free runtime layout.

func (RuntimeLayout) ExecutionRoot

func (l RuntimeLayout) ExecutionRoot() string

ExecutionRoot returns the cwd/project authority for tools and subprocesses.

func (RuntimeLayout) InstructionRoots

func (l RuntimeLayout) InstructionRoots() []string

InstructionRoots returns an ordered copy of the instruction search roots.

func (RuntimeLayout) Owner

func (l RuntimeLayout) Owner() RuntimeOwner

Owner returns the stable owner of this runtime.

func (RuntimeLayout) StatePaths

func (l RuntimeLayout) StatePaths() RuntimeStatePaths

StatePaths returns the path ownership contract for state-producing runtime services.

func (RuntimeLayout) StateRoot

func (l RuntimeLayout) StateRoot() string

StateRoot returns the external root for MintClaw-owned runtime state.

func (RuntimeLayout) Validate

func (l RuntimeLayout) Validate() error

Validate checks the root and owner invariants without creating filesystem state.

type RuntimeOwner

type RuntimeOwner struct {
	Kind RuntimeOwnerKind
	ID   string
}

RuntimeOwner is the stable identity used for runtime state ownership.

type RuntimeOwnerKind

type RuntimeOwnerKind string

RuntimeOwnerKind identifies the domain that owns a runtime layout.

const (
	// RuntimeOwnerPersonalAgent identifies an always-on personal agent.
	RuntimeOwnerPersonalAgent RuntimeOwnerKind = "personal_agent"
	// RuntimeOwnerCodingThread identifies a project-aware coding thread.
	RuntimeOwnerCodingThread RuntimeOwnerKind = "coding_thread"
)

type RuntimeProfile

type RuntimeProfile struct {
	// contains filtered or unexported fields
}

RuntimeProfile is the immutable set of layouts admitted before registry construction.

func NewRuntimeProfile

func NewRuntimeProfile(bindings ...RuntimeProfileBinding) (RuntimeProfile, error)

NewRuntimeProfile validates and indexes bindings without creating filesystem state.

func NewRuntimeProfileWithStoreFactory

func NewRuntimeProfileWithStoreFactory(
	storeFactory RuntimeStoreFactory,
	bindings ...RuntimeProfileBinding,
) (RuntimeProfile, error)

NewRuntimeProfileWithStoreFactory creates a profile with construction-time store injection. It is primarily useful for alternate frontends and fault injection; normal callers should use NewRuntimeProfile.

func (RuntimeProfile) AgentLayout

func (p RuntimeProfile) AgentLayout(agentID string) (RuntimeLayout, bool)

AgentLayout returns the layout bound to a canonical configured agent ID.

func (RuntimeProfile) ToolProfile

func (p RuntimeProfile) ToolProfile() RuntimeToolProfile

ToolProfile returns the immutable tool/trust profile selected by the owner domain.

type RuntimeProfileBinding

type RuntimeProfileBinding struct {
	AgentID string
	Layout  RuntimeLayout
}

RuntimeProfileBinding binds one configured runtime agent to its state owner. Personal agents use the same canonical ID for both. A coding frontend may bind its configured agent to a distinct coding-thread owner ID.

type RuntimeStatePaths

type RuntimeStatePaths struct {
	SessionsRoot       string
	ContextRoot        string
	MemoryRoot         string
	OperationalRoot    string
	RuntimeStateFile   string
	TaskRegistryFile   string
	InteractionFile    string
	InteractionKeyFile string
	DiagnosticsRoot    string
	MediaRoot          string
}

RuntimeStatePaths names the MintClaw-owned paths below a runtime state root.

type RuntimeStoreFactory

type RuntimeStoreFactory interface {
	NewSessionStore(layout RuntimeLayout) (session.SessionStore, error)
	NewSeahorseEngine(config seahorse.Config, complete seahorse.CompleteFn) (*seahorse.Engine, error)
}

RuntimeStoreFactory opens the canonical and derived stores owned by a resolved runtime layout. Implementations must not fall back to legacy paths.

type RuntimeToolDecoratorFactory

type RuntimeToolDecoratorFactory func(
	cfg *config.Config,
	agentID string,
	local toolshared.Tool,
) (toolshared.Tool, error)

RuntimeToolDecoratorFactory wraps one already configured agent tool. Unlike RuntimeToolFactory, it receives the agent-specific local implementation, so routing can preserve each agent's workspace and filesystem policy.

type RuntimeToolFactory

type RuntimeToolFactory func(cfg *config.Config) (toolshared.Tool, error)

type RuntimeToolProfile

type RuntimeToolProfile string

RuntimeToolProfile selects the complete pre-construction tool and trust policy for a homogeneous runtime owner domain.

const (
	RuntimeToolProfilePersonal RuntimeToolProfile = "personal"
	RuntimeToolProfileCoding   RuntimeToolProfile = "coding"
)

type SessionSummarizePayload

type SessionSummarizePayload struct {
	SummarizedMessages int
	KeptMessages       int
	SummaryLen         int
	OmittedOversized   bool
}

SessionSummarizePayload describes a completed async session summarization.

type SkillContextSnapshot

type SkillContextSnapshot struct {
	Sequence   int      `json:"sequence"`
	Trigger    string   `json:"trigger"`
	SkillNames []string `json:"skill_names,omitempty"`
}

type SoulDefinition

type SoulDefinition struct {
	Path    string `json:"path"`
	Content string `json:"content"`
}

SoulDefinition represents the resolved SOUL.md file linked to the agent.

type SteeringInjectedPayload

type SteeringInjectedPayload struct {
	Count           int
	TotalContentLen int
}

SteeringInjectedPayload describes steering messages appended before the next LLM call.

type SteeringMode

type SteeringMode string

SteeringMode controls how queued steering messages are dequeued.

const (
	// SteeringOneAtATime dequeues only the first queued message per poll.
	SteeringOneAtATime SteeringMode = "one-at-a-time"
	// SteeringAll drains the entire queue in a single poll.
	SteeringAll SteeringMode = "all"
	// MaxQueueSize number of possible messages in the Steering Queue
	MaxQueueSize = 10
)

type SubTurnConfig

type SubTurnConfig struct {
	Model        string
	Tools        []toolshared.Tool
	SystemPrompt string
	MaxTokens    int

	// Async controls the result delivery mechanism:
	//
	// When Async = false (synchronous sub-turn):
	//   - The caller blocks until the sub-turn completes
	//   - The result is ONLY returned via the function return value
	//   - The result is NOT delivered to the parent's pendingResults channel
	//   - This prevents double delivery: caller gets result immediately, no need for channel
	//   - Use case: When the caller needs the result immediately to continue execution
	//   - Example: A tool that needs to process the sub-turn result before returning
	//
	// When Async = true (asynchronous sub-turn):
	//   - The sub-turn runs in the background (still blocks the caller, but semantically async)
	//   - The result is delivered to the parent's pendingResults channel
	//   - The result is ALSO returned via the function return value (for consistency)
	//   - The parent turn can poll pendingResults in later iterations to process results
	//   - Use case: Fire-and-forget operations, or when results are processed in batches
	//   - Example: Spawning multiple sub-turns in parallel and collecting results later
	//
	// IMPORTANT: The Async flag does NOT make the call non-blocking. It only controls
	// whether the result is delivered via the channel. For true non-blocking execution,
	// the caller must spawn the sub-turn in a separate goroutine.
	Async bool

	// Critical indicates this SubTurn's result is important and should continue
	// running even after the parent turn finishes gracefully.
	//
	// When parent finishes gracefully (Finish(false)):
	//   - Critical=true: SubTurn continues running, delivers result as orphan
	//   - Critical=false: SubTurn exits gracefully without error
	//
	// When parent finishes with hard abort (Finish(true)):
	//   - All SubTurns are canceled regardless of Critical flag
	Critical bool

	// Timeout is the maximum duration for this SubTurn.
	// If the SubTurn runs longer than this, it will be canceled.
	// Default is 5 minutes (defaultSubTurnTimeout) if not specified.
	Timeout time.Duration

	// MaxContextRunes limits the context size (in runes) passed to the SubTurn.
	// This prevents context window overflow by truncating message history before LLM calls.
	//
	// Values:
	//   0  = Auto-calculate based on model's ContextWindow * 0.75 (default, recommended)
	//   -1 = No limit (disable soft truncation, rely only on hard context errors)
	//   >0 = Use specified rune limit
	//
	// The soft limit acts as a first line of defense before hitting the provider's
	// hard context window limit. When exceeded, older messages are intelligently
	// truncated while preserving system messages and recent context.
	MaxContextRunes int

	// ActualSystemPrompt is injected as the true 'system' role message for the childAgent.
	// The legacy SystemPrompt field is actually used as the first 'user' message (task description).
	ActualSystemPrompt string

	// InitialMessages preloads the ephemeral session history before the agent loop starts.
	// Used by evaluator-optimizer patterns to pass the full worker context across multiple iterations.
	InitialMessages []providers.Message

	// InitialTokenBudget is a shared atomic counter for tracking remaining tokens.
	// If set, the SubTurn will inherit this budget and deduct tokens after each LLM call.
	// If nil, the SubTurn will inherit the parent's tokenBudget (if any).
	// Used by team tool to enforce token limits across all team members.
	InitialTokenBudget *atomic.Int64

	// TargetAgentID, when set, runs the sub-turn as the specified agent.
	// The target agent's workspace, model, tools, and system prompt are used
	// instead of the caller's. If empty, the sub-turn runs as the parent agent.
	TargetAgentID string

	// DeliveryMode controls user-facing delivery ownership for synchronous
	// delegate/sub-turn flows. Reuses the same enum names as async spawn:
	// parent_only, user_only, user_and_parent.
	DeliveryMode toolshared.AsyncDeliveryMode
	TaskID       string
}

SubTurnConfig configures the execution of a child sub-turn.

Usage Examples:

Synchronous sub-turn (Async=false):

cfg := SubTurnConfig{
    Model: "gpt-4o-mini",
    SystemPrompt: "Analyze this code",
    Async: false,  // Result returned immediately
}
result, err := SpawnSubTurn(ctx, cfg)
// Use result directly here
processResult(result)

Asynchronous sub-turn (Async=true):

cfg := SubTurnConfig{
    Model: "gpt-4o-mini",
    SystemPrompt: "Background analysis",
    Async: true,  // Result delivered to channel
}
result, err := SpawnSubTurn(ctx, cfg)
// Result also available in parent's pendingResults channel
// Parent turn will poll and process it in a later iteration

type SubTurnEndPayload

type SubTurnEndPayload struct {
	AgentID string
	Status  string
}

SubTurnEndPayload describes the completion of a child turn.

type SubTurnOrphanPayload

type SubTurnOrphanPayload struct {
	ParentTurnID string
	ChildTurnID  string
	Reason       string
}

SubTurnOrphanPayload describes a sub-turn result that could not be delivered.

type SubTurnResultDeliveredPayload

type SubTurnResultDeliveredPayload struct {
	TargetChannel string
	TargetChatID  string
	ContentLen    int
}

SubTurnResultDeliveredPayload describes delivery of a sub-turn result.

type SubTurnSpawnPayload

type SubTurnSpawnPayload struct {
	AgentID      string
	Label        string
	ParentTurnID string
}

SubTurnSpawnPayload describes the creation of a child turn.

type ThinkingLevel

type ThinkingLevel string

ThinkingLevel controls how the provider sends thinking parameters.

  • "adaptive": sends {thinking: {type: "adaptive"}} + output_config.effort (Claude 4.6+)
  • "low"/"medium"/"high"/"xhigh": sends {thinking: {type: "enabled", budget_tokens: N}} (all models)
  • "off": disables thinking
const (
	ThinkingOff      ThinkingLevel = "off"
	ThinkingLow      ThinkingLevel = "low"
	ThinkingMedium   ThinkingLevel = "medium"
	ThinkingHigh     ThinkingLevel = "high"
	ThinkingXHigh    ThinkingLevel = "xhigh"
	ThinkingAdaptive ThinkingLevel = "adaptive"
)

type ToolApprovalConsumptionRequest

type ToolApprovalConsumptionRequest struct {
	Workspace     string
	InteractionID string
	Revision      int64
	Origin        interactions.Origin
}

type ToolApprovalGrant

type ToolApprovalGrant struct {
	InteractionID     string
	Revision          int64
	OriginExecutionID string
	// OriginArgumentHash is the trusted binding stored with the suspended
	// interaction. Fresh approval arguments may differ after retained
	// time-bound tool state expires, but consumption must spend this binding.
	OriginArgumentHash string
}

type ToolApprovalRequest

type ToolApprovalRequest struct {
	Meta      HookMeta       `json:"meta"`
	Context   *TurnContext   `json:"context,omitempty"`
	Tool      string         `json:"tool"`
	Arguments map[string]any `json:"arguments,omitempty"`
}

func (*ToolApprovalRequest) Clone

type ToolApprover

type ToolApprover interface {
	ApproveTool(ctx context.Context, req *ToolApprovalRequest) (ApprovalDecision, error)
}

type ToolCallHookRequest

type ToolCallHookRequest struct {
	Meta       HookMeta               `json:"meta"`
	Context    *TurnContext           `json:"context,omitempty"`
	Tool       string                 `json:"tool"`
	Arguments  map[string]any         `json:"arguments,omitempty"`
	Channel    string                 `json:"channel,omitempty"`
	ChatID     string                 `json:"chat_id,omitempty"`
	HookResult *toolshared.ToolResult `json:"hook_result,omitempty"` // Result returned directly by hook (for respond action). Media is supported - see Media handling section in docs.
}

func (*ToolCallHookRequest) Clone

type ToolControl

type ToolControl int

ToolControl signals returned from ExecuteTools to drive tool loop iteration.

const (
	// ToolControlContinue tells the tool loop to jump to the next iteration
	// (pendingMessages arrived, SubTurn results, etc.).
	ToolControlContinue ToolControl = iota
	// ToolControlBreak tells the tool loop to exit and return to the runner.
	ToolControlBreak
	// ToolControlFinalize tells the runner that all tool responses were
	// handled and the turn should finalize without another LLM call.
	ToolControlFinalize
	// ToolControlSuspend exits without final rendering after durable ownership
	// of a pending human interaction has transferred to the runtime.
	ToolControlSuspend
	// ToolControlHalt terminates the turn with exact runtime safety content.
	// The coordinator must not render another model response or continue queued
	// work after this outcome.
	ToolControlHalt
)

type ToolExecEndPayload

type ToolExecEndPayload struct {
	ToolCallID       string
	Tool             string
	Duration         time.Duration
	ForLLMLen        int
	ForUserLen       int
	IsError          bool
	Async            bool
	ResultHash       string
	Suspended        bool
	InteractionID    string
	DiagnosticResult string
}

ToolExecEndPayload describes the outcome of a tool execution.

type ToolExecSkippedPayload

type ToolExecSkippedPayload struct {
	ToolCallID string
	Tool       string
	Reason     string
}

ToolExecSkippedPayload describes a skipped tool call.

type ToolExecStartPayload

type ToolExecStartPayload struct {
	ToolCallID string
	Tool       string
	Arguments  map[string]any
}

ToolExecStartPayload describes a tool execution request.

type ToolExecutionRecord

type ToolExecutionRecord struct {
	Name         string   `json:"name"`
	Success      bool     `json:"success"`
	ErrorSummary string   `json:"error_summary,omitempty"`
	SkillNames   []string `json:"skill_names,omitempty"`
}

type ToolInterceptor

type ToolInterceptor interface {
	BeforeTool(ctx context.Context, call *ToolCallHookRequest) (*ToolCallHookRequest, HookDecision, error)
	AfterTool(ctx context.Context, result *ToolResultHookResponse) (*ToolResultHookResponse, HookDecision, error)
}

type ToolLoopDecisionPayload

type ToolLoopDecisionPayload struct {
	Tool      string
	ArgsHash  string
	Action    string
	Code      string
	Count     int
	Threshold int
}

ToolLoopDecisionPayload contains only hash-safe loop protection metadata.

type ToolLoopOutcome

type ToolLoopOutcome struct {
	Control                ToolControl
	FinalContent           string
	AbortCause             TurnAbortCause
	SuspendedInteractionID string
	JournalErr             error
}

ToolLoopOutcome is the explicit result of one tool-execution phase.

type ToolResultHookResponse

type ToolResultHookResponse struct {
	Meta      HookMeta               `json:"meta"`
	Context   *TurnContext           `json:"context,omitempty"`
	Tool      string                 `json:"tool"`
	Arguments map[string]any         `json:"arguments,omitempty"`
	Result    *toolshared.ToolResult `json:"result,omitempty"`
	Duration  time.Duration          `json:"duration"`
}

func (*ToolResultHookResponse) Clone

type ToolSuspensionDisposition

type ToolSuspensionDisposition struct {
	InteractionID string
	Durable       bool
}

ToolSuspensionDisposition distinguishes a durable handoff from a failure that is still safe to return to the model as an ordinary tool error.

type ToolSuspensionRequest

type ToolSuspensionRequest struct {
	Workspace        string
	Prompt           interactions.SuspensionRequest
	Route            interactions.Route
	Origin           interactions.Origin
	ApprovalAction   string
	ExecutionContext *bus.InboundContext
	Resolution       func(context.Context, interactions.Outcome) error
}

type TurnAbortCause

type TurnAbortCause int

TurnAbortCause describes why a pipeline phase asked the runner to abort.

const (
	TurnAbortNone TurnAbortCause = iota
	TurnAbortHook
	TurnAbortHard
)

type TurnActionRecord

type TurnActionRecord struct {
	Source        string `json:"source"`
	Tool          string `json:"tool,omitempty"`
	Text          string `json:"text"`
	Error         bool   `json:"error,omitempty"`
	VerifiedWrite bool   `json:"verified_write,omitempty"`
}

type TurnContext

type TurnContext struct {
	Inbound *bus.InboundContext    `json:"inbound,omitempty"`
	Route   *routing.ResolvedRoute `json:"route,omitempty"`
	Scope   *session.SessionScope  `json:"scope,omitempty"`
}

TurnContext carries normalized turn-scoped facts that can be shared across events, hooks, and other runtime observers without re-parsing legacy fields.

type TurnEndPayload

type TurnEndPayload struct {
	Status                TurnEndStatus
	Workspace             string
	DeliveryExpected      bool
	Iterations            int
	Duration              time.Duration
	LLMCalls              int
	PromptTokens          int
	CompletionTokens      int
	TotalTokens           int
	FinalContentLen       int
	UserMessage           string
	FinalContent          string
	ActiveSkills          []string
	AttemptedSkills       []string
	FinalSuccessfulPath   []string
	SkillContextSnapshots []SkillContextSnapshot
	ToolKinds             []string
	ToolExecutions        []ToolExecutionRecord
	InteractionID         string
}

TurnEndPayload describes the completion of a turn.

type TurnEndStatus

type TurnEndStatus string

TurnEndStatus describes the terminal state of a turn.

const (
	// TurnEndStatusCompleted indicates the turn finished normally.
	TurnEndStatusCompleted TurnEndStatus = "completed"
	// TurnEndStatusError indicates the turn ended because of an error.
	TurnEndStatusError TurnEndStatus = "error"
	// TurnEndStatusAborted indicates the turn was hard-aborted and rolled back.
	TurnEndStatusAborted TurnEndStatus = "aborted"
	// TurnEndStatusSuspended indicates durable continuation ownership moved to
	// a pending human interaction without completing or failing the turn.
	TurnEndStatusSuspended TurnEndStatus = "suspended"
)

type TurnPhase

type TurnPhase string
const (
	TurnPhaseSetup      TurnPhase = "setup"
	TurnPhaseRunning    TurnPhase = "running"
	TurnPhaseTools      TurnPhase = "tools"
	TurnPhaseFinalizing TurnPhase = "finalizing"
	TurnPhaseCompleted  TurnPhase = "completed"
	TurnPhaseAborted    TurnPhase = "aborted"
	TurnPhaseSuspended  TurnPhase = "suspended"
)

type TurnStartPayload

type TurnStartPayload struct {
	UserMessage string
	MediaCount  int
	Workspace   string
}

TurnStartPayload describes the start of a turn.

type UserDefinition

type UserDefinition struct {
	Path    string `json:"path"`
	Content string `json:"content"`
}

UserDefinition represents the resolved USER.md file linked to the workspace.

Source Files

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL