agent

package
v0.32.0 Latest Latest
Warning

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

Go to latest
Published: May 3, 2026 License: Apache-2.0 Imports: 30 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ErrAdapterKeyNotActive = errors.New("adapter key not active on this channel")

ErrAdapterKeyNotActive is returned when attempting to deactivate an adapter key that is not active on the specified channel.

View Source
var ErrChannelNotFound = errors.New("channel not found")

ErrChannelNotFound is returned when the specified channel does not exist.

View Source
var ErrChannelsNotConfigured = errors.New("channels not configured")

ErrChannelsNotConfigured is returned when channel operations are attempted but no channels are configured.

View Source
var ErrNotEnoughMessages = errors.New("not enough messages to compact")

ErrNotEnoughMessages is returned when a compact operation is attempted on a session with fewer than 2 messages.

Functions

func ResolveChannelByName added in v0.28.0

func ResolveChannelByName(channels map[string]*Channel, name string) (conversationID, adapterName, externalID string, wildcard bool, err error)

ResolveChannelByName looks up a named channel in a channel registry and returns the conversation ID, adapter name, and external ID. When the channel has only wildcard adapter bindings (no specific externalID), wildcard is true. Returns an error if the channel is not found.

Types

type ActiveChannelStore added in v0.26.0

type ActiveChannelStore interface {
	// GetActiveChannel returns the active channel name for the given adapter
	// key ("adapter:externalID"). Returns ("", nil) when no override is set.
	GetActiveChannel(ctx context.Context, adapterKey string) (string, error)

	// SetActiveChannel persists the active channel override for the given
	// adapter key.
	SetActiveChannel(ctx context.Context, adapterKey, channelName string) error

	// ClearActiveChannel removes the active channel override, reverting the
	// adapter key to config-based routing.
	ClearActiveChannel(ctx context.Context, adapterKey string) error

	// ListActiveChannels returns all active channel overrides. Used on startup
	// to populate the dispatcher's in-memory cache.
	ListActiveChannels(ctx context.Context) (map[string]string, error)
}

ActiveChannelStore persists the user's active channel selection per adapter chat. This state survives restarts so users don't lose their /session choice.

type AdapterBinding added in v0.28.0

type AdapterBinding struct {
	Adapter    string
	ExternalID string
}

AdapterBinding is a parsed adapter:externalID pair.

type AgentCostSummary added in v0.30.1

type AgentCostSummary struct {
	Agent        string  `db:"agent"            json:"agent"`
	Cost         float64 `db:"total_cost"       json:"cost"`
	InputTokens  int     `db:"total_prompt"     json:"input_tokens"`
	OutputTokens int     `db:"total_completion"  json:"output_tokens"`
	Messages     int     `db:"total_messages"   json:"messages"`
	Sessions     int     `db:"sessions"         json:"sessions"`
}

AgentCostSummary aggregates cost/token data per agent from persistent storage.

type Binding

type Binding struct {
	Pattern   string // "telegram" or "telegram:12345"
	AgentName string
}

Binding maps an adapter pattern to an agent name. Pattern is either a wildcard ("telegram") or specific ("telegram:12345").

type Channel added in v0.26.0

type Channel struct {
	// Name is the unique identifier for this channel (e.g. "work", "personal").
	Name string

	// AgentName is the agent that handles messages routed through this channel.
	AgentName string

	// Adapters lists the adapter bindings from the config, using the same
	// "adapter" (wildcard) or "adapter:externalID" (specific) format.
	Adapters []string

	// Delivery controls how scheduled messages are delivered through this
	// channel's adapter bindings. "broadcast" delivers through all specific
	// bindings; any other value (including empty) uses the first specific
	// binding only.
	Delivery string

	// Implicit is true when the channel was auto-synthesized from an agent's
	// adapter bindings (backward compatibility). Implicit channels are not
	// shown in /session listings unless the user explicitly opts in.
	Implicit bool

	// SessionMode is "persistent" (default) or "ephemeral". Ephemeral
	// channels create a unique conversation for each interaction.
	SessionMode string
}

Channel is a named routing endpoint that binds adapter chats to an agent with explicit session identity. Channels decouple conversations from the rigid 1:1 agent-adapter binding, enabling session switching (/session) and cross-adapter session sharing.

func (*Channel) ConversationID added in v0.26.0

func (ch *Channel) ConversationID() string

ConversationID returns the persistent conversation ID for this channel. Channel-based conversations use the format "chan:{name}".

func (*Channel) EphemeralConversationID added in v0.29.1

func (ch *Channel) EphemeralConversationID() string

EphemeralConversationID returns a unique conversation ID for a single ephemeral interaction. Format: "chan:{name}:{unix_nano}_{seq}".

func (*Channel) IsBroadcast added in v0.28.0

func (ch *Channel) IsBroadcast() bool

IsBroadcast returns true when the channel is configured for broadcast delivery.

func (*Channel) IsEphemeral added in v0.29.1

func (ch *Channel) IsEphemeral() bool

IsEphemeral returns true when the channel uses ephemeral session mode.

func (*Channel) ResolveAllBindings added in v0.28.0

func (ch *Channel) ResolveAllBindings() []AdapterBinding

ResolveAllBindings returns all specific adapter:externalID bindings from the channel's adapter list. Wildcard-only bindings are skipped. Used for broadcast delivery where a message should be sent through every specific binding.

func (*Channel) ResolveBinding added in v0.28.0

func (ch *Channel) ResolveBinding() (adapterName, externalID string, wildcard, ok bool)

ResolveBinding returns the first specific adapter binding (adapter:externalID) from the channel's adapter list. If only wildcard bindings exist, returns the wildcard adapter name with an empty externalID and wildcard=true. Returns ok=false if the channel has no adapter bindings at all.

type ChatEvent added in v0.14.0

type ChatEvent struct {
	Type     string  `json:"type"`                  // "tool_start", "tool_end", "thinking", "usage", "tool_approval", "content_delta", "thinking_delta"
	Tool     string  `json:"tool,omitempty"`        // tool name
	ToolID   string  `json:"tool_id,omitempty"`     // unique tool call ID (from LLM response)
	Round    int     `json:"round,omitempty"`       // 1-based tool round
	Duration int64   `json:"duration_ms,omitempty"` // tool execution time
	Error    string  `json:"error,omitempty"`       // tool error (if any)
	Text     string  `json:"text,omitempty"`        // human-readable status message / content delta
	Tokens   int     `json:"tokens,omitempty"`      // total tokens used (usage event)
	CostUSD  float64 `json:"cost_usd,omitempty"`    // estimated cost in USD (usage event)

	// ApprovalID and ApprovalCallback are set on "tool_approval" events so
	// the adapter can render inline approve/deny buttons.
	ApprovalID       string `json:"approval_id,omitempty"`
	ApprovalCallback string `json:"approval_callback,omitempty"` // "appr:{id}" prefix

	// ApprovalStatus distinguishes pending approvals from auto-approved ones.
	// Values: "" (pending, needs user action), "auto_approved" (rule matched),
	// "supervisor_approved", "supervisor_denied", "supervisor_escalated",
	// "supervisor_error" (supervisor LLM call failed; falls through to human).
	ApprovalStatus string `json:"approval_status,omitempty"`
}

ChatEvent describes an intermediate pipeline event streamed to SSE clients.

type ChatEventFunc added in v0.14.0

type ChatEventFunc func(ChatEvent)

ChatEventFunc is called for each intermediate pipeline event.

type ConversationInfo

type ConversationInfo struct {
	ID           string    `db:"id"            json:"id"`
	Adapter      string    `db:"adapter"       json:"adapter"`
	ExternalID   string    `db:"external_id"   json:"external_id"`
	CreatedAt    time.Time `db:"created_at"    json:"created_at"`
	MessageCount int       `db:"message_count" json:"message_count"`
}

ConversationInfo provides metadata about a conversation.

type ConversationInfoWithStats added in v0.23.0

type ConversationInfoWithStats struct {
	ConversationInfo
	TotalCost    float64    `db:"total_cost"    json:"total_cost"`
	TotalPrompt  int        `db:"total_tokens_prompt"  json:"total_tokens_prompt"`
	TotalCompl   int        `db:"total_tokens_completion" json:"total_tokens_completion"`
	LastModel    string     `db:"last_model"    json:"last_model"`
	LastProvider string     `db:"last_provider" json:"last_provider"`
	UpdatedAt    *time.Time `db:"updated_at"    json:"updated_at,omitempty"`
}

ConversationInfoWithStats combines conversation metadata with telemetry stats.

type ConversationStatsRow added in v0.23.0

type ConversationStatsRow struct {
	ConversationID  string    `db:"conversation_id"   json:"conversation_id"`
	Agent           string    `db:"agent"             json:"agent"`
	TotalMessages   int       `db:"total_messages"    json:"total_messages"`
	TotalCost       float64   `db:"total_cost"        json:"total_cost"`
	TotalPrompt     int       `db:"total_tokens_prompt"      json:"total_tokens_prompt"`
	TotalCompletion int       `db:"total_tokens_completion"  json:"total_tokens_completion"`
	TotalCached     int       `db:"total_tokens_cached"      json:"total_tokens_cached"`
	TotalToolCalls  int       `db:"total_tool_calls"  json:"total_tool_calls"`
	TotalToolErrors int       `db:"total_tool_errors" json:"total_tool_errors"`
	LastModel       string    `db:"last_model"        json:"last_model"`
	LastProvider    string    `db:"last_provider"     json:"last_provider"`
	UpdatedAt       time.Time `db:"updated_at"        json:"updated_at"`
}

ConversationStatsRow holds aggregated telemetry for a conversation.

type Dispatcher

type Dispatcher struct {

	// OnBroadcast, when set, is called after an adapter message (Telegram,
	// Discord, etc.) is successfully processed. The server uses this to
	// notify WebSocket clients of conversation activity from other adapters.
	OnBroadcast func(agentName, convID, adapterName, channelName, summary string)

	// OnPanic is called when a /panic command is processed. The server uses
	// this to pause the scheduler and broadcast a panic status frame.
	OnPanic func()

	// OnResume is called when a /resume command is processed.
	OnResume func()

	// Auditor emits audit events for routing/session decisions.
	Auditor audit.Emitter
	// contains filtered or unexported fields
}

Dispatcher routes incoming messages to the correct agent Engine based on channel bindings (or legacy adapter bindings). It owns the adapter lifecycle and the shared incoming channel.

func NewDispatcher

func NewDispatcher(
	agents map[string]*Engine,
	bindings []Binding,
	adapters []adapter.Adapter,
	logger *slog.Logger,
	opts ...DispatcherOption,
) *Dispatcher

NewDispatcher creates a Dispatcher from a set of named engines, bindings, and adapters. Bindings are processed in order; specific bindings ("telegram:12345") take priority over wildcard bindings ("telegram").

func (*Dispatcher) ActiveChannelsForChannel added in v0.28.0

func (d *Dispatcher) ActiveChannelsForChannel(channelName string) []string

ActiveChannelsForChannel returns all adapter keys that currently have the given channel as their active override. Always returns a non-nil slice.

func (*Dispatcher) AddAgent added in v0.29.8

func (d *Dispatcher) AddAgent(name string, engine *Engine) error

AddAgent registers a new engine in the dispatcher's runtime map. Returns an error if the name is already taken.

func (*Dispatcher) AddChannel added in v0.29.7

func (d *Dispatcher) AddChannel(ch *Channel) error

AddChannel registers a new channel in the dispatcher's runtime registry and updates binding maps. Returns an error if channels are not configured, the name is already taken, or the referenced agent does not exist.

func (*Dispatcher) Agent

func (d *Dispatcher) Agent(name string) *Engine

Agent returns the Engine for the named agent, or nil if not found.

func (*Dispatcher) Agents

func (d *Dispatcher) Agents() []string

Agents returns the names of all registered agents.

func (*Dispatcher) Channels added in v0.26.0

func (d *Dispatcher) Channels() map[string]*Channel

Channels returns the channel registry. Returns nil when channels are not configured.

func (*Dispatcher) ClearActiveChannelByKey added in v0.28.0

func (d *Dispatcher) ClearActiveChannelByKey(ctx context.Context, adapterKey, channelName string) error

ClearActiveChannelByKey removes the active channel override for the given adapter key, but only if the key is currently active on the specified channel. Returns ErrAdapterKeyNotActive if the key is not active on channelName.

func (*Dispatcher) Dispatch

func (d *Dispatcher) Dispatch(ctx context.Context, agentName string, msg adapter.IncomingMessage) error

Dispatch sends a message to a specific agent by name. Used by the scheduler.

func (*Dispatcher) IsPanicked added in v0.27.1

func (d *Dispatcher) IsPanicked() bool

IsPanicked returns true if the dispatcher is in panic mode.

func (*Dispatcher) ListModelDetails added in v0.16.11

func (d *Dispatcher) ListModelDetails(ctx context.Context, providerFilter string) []llm.ModelInfo

ListModelDetails returns enriched model metadata by querying the default agent's router. When providerFilter is non-empty only the named provider is queried.

func (*Dispatcher) ListModels added in v0.15.1

func (d *Dispatcher) ListModels(ctx context.Context) []string

ListModels returns available LLM models by querying the default agent's router.

func (*Dispatcher) LoadActiveChannels added in v0.26.0

func (d *Dispatcher) LoadActiveChannels(ctx context.Context) error

LoadActiveChannels reads persisted /session selections from the store and populates the in-memory cache. Call once at startup after WithChannels.

func (*Dispatcher) Panic added in v0.27.1

func (d *Dispatcher) Panic()

Panic triggers an emergency stop via the API. Cancels all in-flight requests and calls the OnPanic hook.

func (*Dispatcher) PanicTime added in v0.27.1

func (d *Dispatcher) PanicTime() time.Time

PanicTime returns the time when panic was triggered. Returns zero time if not panicked.

func (*Dispatcher) RemoveAgent added in v0.29.8

func (d *Dispatcher) RemoveAgent(name string) error

RemoveAgent removes an engine from the dispatcher's runtime map. Returns an error if the agent does not exist or is "default". Callers must check for channel/schedule references before calling.

func (*Dispatcher) RemoveChannel added in v0.29.7

func (d *Dispatcher) RemoveChannel(ctx context.Context, name string) error

RemoveChannel removes a channel from the dispatcher's runtime registry, clears its adapter bindings, and removes any active channel overrides that reference it. Returns an error if the channel does not exist or is implicit.

func (*Dispatcher) RenameAgent added in v0.16.9

func (d *Dispatcher) RenameAgent(oldName, newName string) error

RenameAgent atomically renames an agent, updating all routing maps.

func (*Dispatcher) Resume added in v0.27.1

func (d *Dispatcher) Resume()

Resume clears the panic state and calls the OnResume hook.

func (*Dispatcher) Run

func (d *Dispatcher) Run(ctx context.Context) error

Run starts all adapters and processes incoming messages until ctx is cancelled. Each message is handled in its own goroutine so slow LLM calls do not block the dispatch loop.

func (*Dispatcher) SendFor

func (d *Dispatcher) SendFor(adapterName string) SendFunc

SendFor returns a SendFunc that routes outgoing messages through the adapter matching the incoming message's adapter name.

func (*Dispatcher) SendVia

func (d *Dispatcher) SendVia(ctx context.Context, adapterName string, msg adapter.OutgoingMessage) error

SendVia sends a message through the adapter registered under adapterName. Returns an error if no adapter with that name is registered.

func (*Dispatcher) SetActiveChannelByKey added in v0.28.0

func (d *Dispatcher) SetActiveChannelByKey(ctx context.Context, adapterKey, channelName string) error

SetActiveChannelByKey sets the active channel override for the given adapter key (e.g. "telegram:12345"). Returns an error if the channel name is not in the registry or channels are not configured.

func (*Dispatcher) StopChat added in v0.27.1

func (d *Dispatcher) StopChat(adapterName, externalID string) error

StopChat cancels the in-flight request for the given adapter and external ID. Returns an error if no request is in progress. Used by REST API and WebSocket.

func (*Dispatcher) UpdateChannel added in v0.29.7

func (d *Dispatcher) UpdateChannel(name string, ch *Channel) error

UpdateChannel replaces an existing channel in the dispatcher's runtime registry, re-indexing its adapter bindings. Returns an error if the channel does not exist or is implicit.

type DispatcherOption added in v0.26.0

type DispatcherOption func(*Dispatcher)

DispatcherOption configures optional Dispatcher behavior.

func WithChannels added in v0.26.0

func WithChannels(channels []*Channel, activeStore ActiveChannelStore) DispatcherOption

WithChannels configures channel-based routing. When set, the dispatcher routes messages through the channel registry instead of the legacy specific/wildcard binding maps. The activeStore persists /session selections across restarts.

type Engine

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

Engine is the core agent orchestrator. Each named agent gets its own Engine instance with its own persona, skills, permissions, and LLM router.

func NewEngine

func NewEngine(
	name string,
	router *llm.Router,
	memory MemoryStore,
	sendFunc SendFunc,
	permissions *security.PermissionEngine,
	p *persona.Persona,
	fallbackPrompt string,
	skills []skill.Skill,
	tools *tool.Manager,
	approvals *approval.Manager,
	logger *slog.Logger,
) *Engine

func (*Engine) AdapterContext added in v0.24.0

func (e *Engine) AdapterContext() (adapterName, externalID, conversationID string)

AdapterContext returns the adapter routing info for the current in-flight message. Designed to be wired into configmcp.Deps.AdapterContext so that in-process MCP servers can populate approval requests with routing info.

func (*Engine) AppendMemoryEntry added in v0.18.0

func (e *Engine) AppendMemoryEntry(entry string) error

AppendMemoryEntry adds a new entry to the persona's MEMORY.md. Returns an error if no persona is configured.

func (*Engine) AppendSkill

func (e *Engine) AppendSkill(s skill.Skill)

AppendSkill appends a new skill to the engine's in-memory skill list.

func (*Engine) Chat

func (e *Engine) Chat(ctx context.Context, msg adapter.IncomingMessage) (string, error)

Chat processes a single incoming message through the full pipeline and returns the response text. It does not call the sendFunc — use this when the caller wants to receive the reply directly (e.g. the REST API). Any pending approval request is accessible via GET /api/v1/approvals.

func (*Engine) ChatWithEvents added in v0.14.0

func (e *Engine) ChatWithEvents(ctx context.Context, msg adapter.IncomingMessage, onEvent ChatEventFunc) (string, error)

ChatWithEvents is like Chat but calls onEvent for intermediate status events (tool calls, etc.) that can be streamed to the client in real time.

func (*Engine) ClearSession added in v0.29.0

func (e *Engine) ClearSession(ctx context.Context, convID string) error

ClearSession removes all messages from the session but keeps the conversation row so the session identity is preserved.

func (*Engine) CompactSession added in v0.29.0

func (e *Engine) CompactSession(ctx context.Context, convID string) (string, error)

CompactSession summarises the conversation into a single message, replacing the full history. Returns the summary text.

func (*Engine) DisplayName added in v0.16.9

func (e *Engine) DisplayName() string

DisplayName returns a human-friendly name derived from the agent's identity persona (if available), falling back to the agent ID.

func (*Engine) GetSkill added in v0.9.0

func (e *Engine) GetSkill(name string) (skill.Skill, bool)

GetSkill returns a skill by name and true, or a zero value and false if not found.

func (*Engine) HandleMessage

func (e *Engine) HandleMessage(ctx context.Context, msg adapter.IncomingMessage) error

HandleMessage processes a single incoming message and sends the response back via the adapter's SendFunc. It delegates to HandleMessageWithEvents with a nil event callback.

func (*Engine) HandleMessageWithEvents added in v0.15.0

func (e *Engine) HandleMessageWithEvents(ctx context.Context, msg adapter.IncomingMessage, onEvent ChatEventFunc) error

HandleMessageWithEvents is like HandleMessage but calls onEvent for intermediate pipeline events (thinking, tool calls, usage). The Dispatcher uses this to refresh adapter typing indicators during processing.

func (*Engine) HasTools

func (e *Engine) HasTools() bool

HasTools returns true if the agent has MCP tools configured.

func (*Engine) LLMRouter added in v0.17.0

func (e *Engine) LLMRouter() *llm.Router

LLMRouter returns the engine's LLM router for runtime configuration updates.

func (*Engine) ListModelDetails added in v0.16.11

func (e *Engine) ListModelDetails(ctx context.Context, providerFilter string) []llm.ModelInfo

ListModelDetails returns enriched model metadata from all registered providers.

func (*Engine) ListModels added in v0.15.1

func (e *Engine) ListModels(ctx context.Context) []string

ListModels returns available LLM models from all registered providers.

func (*Engine) MaxToolRounds added in v0.29.4

func (e *Engine) MaxToolRounds() int

MaxToolRounds returns the current tool round limit.

func (*Engine) ModelName

func (e *Engine) ModelName() string

ModelName returns the agent's default LLM model.

func (*Engine) Name

func (e *Engine) Name() string

Name returns the agent's name.

func (*Engine) PermissionTier

func (e *Engine) PermissionTier() string

PermissionTier returns the agent's default permission tier.

func (*Engine) PersonaDir

func (e *Engine) PersonaDir() string

PersonaDir returns the directory the agent's persona was loaded from. Returns an empty string if no persona is configured.

func (*Engine) PersonaSection added in v0.10.0

func (e *Engine) PersonaSection(section string) (content string, editable bool, agentMutable bool, ok bool)

PersonaSection returns the content, editability, and agent-mutability of a persona section. Returns ("", false, false, false) if no persona is configured or section is unknown.

func (*Engine) PersonaSections

func (e *Engine) PersonaSections() map[string]bool

PersonaSections returns which persona sections are loaded (soul/user/memory). Returns nil if no persona is configured.

func (*Engine) ProviderName added in v0.17.2

func (e *Engine) ProviderName() string

ProviderName returns the agent's default LLM provider.

func (*Engine) RemoveMemoryEntry added in v0.18.0

func (e *Engine) RemoveMemoryEntry(heading string) error

RemoveMemoryEntry removes a memory entry by heading from the persona's MEMORY.md. Returns an error if no persona is configured.

func (*Engine) RemoveSkill added in v0.9.0

func (e *Engine) RemoveSkill(name string) bool

RemoveSkill removes a skill by name from the engine's in-memory skill list. Returns false if the skill was not found.

func (*Engine) SavePersonaSection added in v0.10.0

func (e *Engine) SavePersonaSection(section, content string) error

SavePersonaSection writes content to the named persona section. Returns an error if no persona is configured.

func (*Engine) SetApprovalConfig added in v0.21.2

func (e *Engine) SetApprovalConfig(timeout time.Duration, retries int)

SetApprovalConfig configures the approval timeout and retry count. Call this after NewEngine, before the engine starts handling messages.

func (*Engine) SetAuditor added in v0.26.0

func (e *Engine) SetAuditor(a audit.Emitter)

SetAuditor sets the audit emitter for this engine.

func (*Engine) SetMaxContextMessages added in v0.22.0

func (e *Engine) SetMaxContextMessages(n int)

SetMaxContextMessages overrides the default context message limit. Call this after NewEngine, before the engine starts handling messages.

func (*Engine) SetMaxToolRounds added in v0.27.1

func (e *Engine) SetMaxToolRounds(n int)

SetMaxToolRounds overrides the default tool round limit. Call this after NewEngine, before the engine starts handling messages.

func (*Engine) SetModel added in v0.11.0

func (e *Engine) SetModel(model string)

SetModel changes the engine's default LLM model.

func (*Engine) SetName added in v0.16.9

func (e *Engine) SetName(name string)

SetName updates the agent's name (used during rename).

func (*Engine) SetPermissionTier added in v0.11.0

func (e *Engine) SetPermissionTier(tier string) error

SetPermissionTier replaces the engine's permission engine with one for the new tier.

func (*Engine) SetProvider added in v0.20.0

func (e *Engine) SetProvider(provider string) error

SetProvider changes the engine's default LLM provider.

func (*Engine) SetScheduler

func (e *Engine) SetScheduler(sched *scheduler.Scheduler)

SetScheduler provides a Scheduler reference so the engine can register new schedules at runtime via SCHEDULE_ADD directives. Call this after the Scheduler is initialized.

func (*Engine) SetSkillDirs

func (e *Engine) SetSkillDirs(agentSkillsDir, globalSkillsDir string)

SetSkillDirs configures the directories used for skill creation and hot-reload. agentSkillsDir is where new skill files are written; globalSkillsDir is the shared skills directory merged on top of agent-specific skills. Call this after NewEngine, before the engine starts handling messages.

func (*Engine) SetSupervisor added in v0.30.0

func (e *Engine) SetSupervisor(s *Engine)

SetSupervisor configures a supervisor engine that reviews tool calls before they reach the human approval flow. Call this after all engines are constructed.

func (*Engine) SetSupervisorConfig added in v0.30.0

func (e *Engine) SetSupervisorConfig(timeout time.Duration, contextMessages int)

SetSupervisorConfig configures supervisor review parameters. Zero values are ignored (the existing default is kept): pass 0 for timeout to keep the default 15s, pass 0 for contextMessages to keep the default 5. Call this after NewEngine, before the engine starts handling messages.

func (*Engine) Skills

func (e *Engine) Skills() []skill.Skill

Skills returns the agent's loaded skills (global + agent-specific, merged).

func (*Engine) SkillsDir added in v0.9.0

func (e *Engine) SkillsDir() string

SkillsDir returns the directory where agent-specific skill files are stored.

func (*Engine) Supervisor added in v0.30.0

func (e *Engine) Supervisor() *Engine

Supervisor returns the supervisor engine, if any.

func (*Engine) ToolNames

func (e *Engine) ToolNames() []string

ToolNames returns the names of all registered MCP tools for this agent. Returns nil if the agent has no tools configured.

func (*Engine) UpdateSkill added in v0.9.0

func (e *Engine) UpdateSkill(name string, updated skill.Skill) bool

UpdateSkill replaces an existing skill by name in the engine's in-memory skill list. Returns false if the skill was not found.

type MemoryStore

type MemoryStore interface {
	GetOrCreateConversation(ctx context.Context, adapter, externalID string) (string, error)
	// GetOrCreateConversationByID ensures a conversation row exists for the
	// given convID. The adapter and externalID are stored as metadata so that
	// ListConversations can report the correct source (e.g. "ws", "api",
	// "sched"). If the row already exists (INSERT OR IGNORE) the stored
	// adapter/externalID are left unchanged.
	GetOrCreateConversationByID(ctx context.Context, convID, adapter, externalID string) error
	AddMessage(ctx context.Context, convID string, msg StoredMessage) (int64, error)
	GetMessages(ctx context.Context, convID string, limit int) ([]StoredMessage, error)
	ListConversations(ctx context.Context, opts SessionListOpts) ([]ConversationInfo, int, error)
	// DeleteConversation removes a conversation and all its messages by ID.
	// Returns nil if the conversation does not exist (idempotent).
	DeleteConversation(ctx context.Context, convID string) error
	// ClearMessages removes all messages, tool calls, skill usages, and stats
	// for a conversation but keeps the conversation row itself. This allows
	// the session identity to be preserved while starting fresh.
	ClearMessages(ctx context.Context, convID string) error
	// ReplaceMessages atomically clears all messages and telemetry for a
	// conversation and inserts a single replacement message in one transaction.
	ReplaceMessages(ctx context.Context, convID string, replacement StoredMessage) error
	Close() error
}

MemoryStore defines the interface for conversation persistence.

type ModelCostSummary added in v0.23.0

type ModelCostSummary struct {
	Model        string  `db:"model"          json:"model"`
	Provider     string  `db:"provider"       json:"provider"`
	TotalCost    float64 `db:"total_cost"     json:"total_cost"`
	MessageCount int     `db:"message_count"  json:"message_count"`
	TotalPrompt  int     `db:"total_prompt"   json:"total_tokens_prompt"`
	TotalCompl   int     `db:"total_completion" json:"total_tokens_completion"`
	TotalCached  int     `db:"total_cached"   json:"total_tokens_cached"`
}

ModelCostSummary aggregates cost/token data per model.

type SQLiteMemoryStore

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

SQLiteMemoryStore implements MemoryStore and TelemetryStore using SQLite.

func NewInMemoryStore

func NewInMemoryStore() (*SQLiteMemoryStore, error)

NewInMemoryStore creates an in-memory SQLite store (for testing).

func NewSQLiteMemoryStore

func NewSQLiteMemoryStore(dbPath string) (*SQLiteMemoryStore, error)

NewSQLiteMemoryStore opens or creates a SQLite database at the given path.

func (*SQLiteMemoryStore) AddMessage

func (s *SQLiteMemoryStore) AddMessage(ctx context.Context, convID string, msg StoredMessage) (int64, error)

func (*SQLiteMemoryStore) AddSkillUsages added in v0.23.0

func (s *SQLiteMemoryStore) AddSkillUsages(ctx context.Context, convID string, messageID int64, skills []SkillUsageRecord) error

AddSkillUsages persists skill usage records linked to a user message.

func (*SQLiteMemoryStore) AddToolCalls added in v0.23.0

func (s *SQLiteMemoryStore) AddToolCalls(ctx context.Context, convID string, messageID int64, calls []ToolCallRecord) error

AddToolCalls persists tool call records linked to an assistant message.

func (*SQLiteMemoryStore) ClearActiveChannel added in v0.26.0

func (s *SQLiteMemoryStore) ClearActiveChannel(ctx context.Context, adapterKey string) error

func (*SQLiteMemoryStore) ClearMessages added in v0.29.0

func (s *SQLiteMemoryStore) ClearMessages(ctx context.Context, convID string) error

ClearMessages removes all messages, tool calls, skill usages, and stats for a conversation but keeps the conversation row itself.

func (*SQLiteMemoryStore) Close

func (s *SQLiteMemoryStore) Close() error

func (*SQLiteMemoryStore) ConversationCost added in v0.7.0

func (s *SQLiteMemoryStore) ConversationCost(ctx context.Context, convID string) (float64, error)

ConversationCost returns the total cost of all messages in a conversation.

func (*SQLiteMemoryStore) CountConversationsBefore added in v0.7.0

func (s *SQLiteMemoryStore) CountConversationsBefore(ctx context.Context, before time.Time) (int, error)

CountConversationsBefore returns the number of conversations created before the given time.

func (*SQLiteMemoryStore) DeleteConversation

func (s *SQLiteMemoryStore) DeleteConversation(ctx context.Context, convID string) error

func (*SQLiteMemoryStore) GetActiveChannel added in v0.26.0

func (s *SQLiteMemoryStore) GetActiveChannel(ctx context.Context, adapterKey string) (string, error)

func (*SQLiteMemoryStore) GetConversationStats added in v0.23.0

func (s *SQLiteMemoryStore) GetConversationStats(ctx context.Context, convID string) (*ConversationStatsRow, error)

GetConversationStats returns the aggregated telemetry for a conversation.

func (*SQLiteMemoryStore) GetCostsByAgent added in v0.30.1

func (s *SQLiteMemoryStore) GetCostsByAgent(ctx context.Context) ([]AgentCostSummary, error)

GetCostsByAgent returns per-agent aggregated cost data from persistent storage.

func (*SQLiteMemoryStore) GetMessages

func (s *SQLiteMemoryStore) GetMessages(ctx context.Context, convID string, limit int) ([]StoredMessage, error)

func (*SQLiteMemoryStore) GetOrCreateConversation

func (s *SQLiteMemoryStore) GetOrCreateConversation(ctx context.Context, adapterName, externalID string) (string, error)

func (*SQLiteMemoryStore) GetOrCreateConversationByID

func (s *SQLiteMemoryStore) GetOrCreateConversationByID(ctx context.Context, convID, adapter, externalID string) error

func (*SQLiteMemoryStore) GetSkillUsages added in v0.23.0

func (s *SQLiteMemoryStore) GetSkillUsages(ctx context.Context, convID string) ([]SkillUsageRecord, error)

GetSkillUsages returns all skill usage records for a conversation.

func (*SQLiteMemoryStore) GetTelemetrySummary added in v0.23.0

func (s *SQLiteMemoryStore) GetTelemetrySummary(ctx context.Context, since, until *time.Time) (*TelemetrySummary, error)

GetTelemetrySummary returns aggregated telemetry data, optionally filtered by time range.

func (*SQLiteMemoryStore) GetToolCalls added in v0.23.0

func (s *SQLiteMemoryStore) GetToolCalls(ctx context.Context, convID string) ([]ToolCallRecord, error)

GetToolCalls returns all tool call records for a conversation.

func (*SQLiteMemoryStore) ListActiveChannels added in v0.26.0

func (s *SQLiteMemoryStore) ListActiveChannels(ctx context.Context) (map[string]string, error)

func (*SQLiteMemoryStore) ListConversations

func (s *SQLiteMemoryStore) ListConversations(ctx context.Context, opts SessionListOpts) ([]ConversationInfo, int, error)

func (*SQLiteMemoryStore) ListConversationsWithStats added in v0.23.0

func (s *SQLiteMemoryStore) ListConversationsWithStats(ctx context.Context, opts SessionListOpts) ([]ConversationInfoWithStats, int, error)

ListConversationsWithStats returns conversations joined with their telemetry stats.

func (*SQLiteMemoryStore) PruneByCount added in v0.23.0

func (s *SQLiteMemoryStore) PruneByCount(ctx context.Context, maxConversations int) (int, error)

PruneByCount deletes the oldest conversations when the total exceeds maxConversations. Returns the number of conversations deleted.

func (*SQLiteMemoryStore) PruneConversations added in v0.7.0

func (s *SQLiteMemoryStore) PruneConversations(ctx context.Context, before time.Time) (int, error)

PruneConversations deletes all conversations (and their messages, tool calls, skill usages, and stats) created before the given time. Returns the number of conversations deleted.

func (*SQLiteMemoryStore) ReplaceMessages added in v0.29.0

func (s *SQLiteMemoryStore) ReplaceMessages(ctx context.Context, convID string, replacement StoredMessage) error

ReplaceMessages atomically clears all messages and telemetry for a conversation and inserts a single replacement message in one transaction.

func (*SQLiteMemoryStore) SetActiveChannel added in v0.26.0

func (s *SQLiteMemoryStore) SetActiveChannel(ctx context.Context, adapterKey, channelName string) error

func (*SQLiteMemoryStore) UpdateConversationStats added in v0.23.0

func (s *SQLiteMemoryStore) UpdateConversationStats(ctx context.Context, convID, agent string, msg StoredMessage, toolCallCount, toolErrorCount int) error

UpdateConversationStats incrementally updates the conversation_stats row.

type SendFunc

type SendFunc func(ctx context.Context, msg adapter.OutgoingMessage) error

SendFunc is a callback for sending a response back to the originating adapter. The Dispatcher sets this when constructing each Engine.

type SessionListOpts added in v0.29.6

type SessionListOpts struct {
	Limit  int // 0 = no limit (return all)
	Offset int
	Agent  string // filter by agent prefix in conversation ID
}

SessionListOpts controls pagination and filtering for session listing.

type SkillUsageRecord added in v0.23.0

type SkillUsageRecord struct {
	ID             int64     `db:"id"              json:"id"`
	MessageID      int64     `db:"message_id"      json:"message_id"`
	ConversationID string    `db:"conversation_id" json:"conversation_id"`
	SkillName      string    `db:"skill_name"      json:"skill_name"`
	MatchType      string    `db:"match_type"      json:"match_type"`
	CreatedAt      time.Time `db:"created_at"      json:"created_at"`
}

SkillUsageRecord represents a skill matched for a user message.

type SkillUsageSummary added in v0.23.0

type SkillUsageSummary struct {
	SkillName  string `db:"skill_name"  json:"skill_name"`
	MatchCount int    `db:"match_count" json:"match_count"`
	MatchTypes string `db:"match_types" json:"match_types"`
}

SkillUsageSummary aggregates skill usage data per skill.

type StoredMessage

type StoredMessage struct {
	ID               int64     `db:"id"`
	ConversationID   string    `db:"conversation_id"`
	Role             string    `db:"role"`
	Content          string    `db:"content"`
	ReasoningContent string    `db:"reasoning_content"`
	TokensUsed       int       `db:"tokens_used"`
	Cost             float64   `db:"cost"`
	Model            string    `db:"model"`
	Provider         string    `db:"provider"`
	TokensPrompt     int       `db:"tokens_prompt"`
	TokensCompletion int       `db:"tokens_completion"`
	TokensCached     int       `db:"tokens_cached"`
	CreatedAt        time.Time `db:"created_at"`
}

StoredMessage represents a message persisted in the memory store.

type TelemetryStore added in v0.23.0

type TelemetryStore interface {
	AddToolCalls(ctx context.Context, convID string, messageID int64, calls []ToolCallRecord) error
	AddSkillUsages(ctx context.Context, convID string, messageID int64, skills []SkillUsageRecord) error
	UpdateConversationStats(ctx context.Context, convID, agent string, msg StoredMessage, toolCallCount, toolErrorCount int) error
	GetConversationStats(ctx context.Context, convID string) (*ConversationStatsRow, error)
	ListConversationsWithStats(ctx context.Context, opts SessionListOpts) ([]ConversationInfoWithStats, int, error)
	GetToolCalls(ctx context.Context, convID string) ([]ToolCallRecord, error)
	GetSkillUsages(ctx context.Context, convID string) ([]SkillUsageRecord, error)
	GetTelemetrySummary(ctx context.Context, since, until *time.Time) (*TelemetrySummary, error)
	GetCostsByAgent(ctx context.Context) ([]AgentCostSummary, error)
	PruneByCount(ctx context.Context, maxConversations int) (int, error)
}

TelemetryStore extends MemoryStore with telemetry persistence methods. Implementations can be obtained by type-asserting a MemoryStore.

type TelemetrySummary added in v0.23.0

type TelemetrySummary struct {
	ByModel []ModelCostSummary  `json:"by_model"`
	ByTool  []ToolUsageSummary  `json:"by_tool"`
	BySkill []SkillUsageSummary `json:"by_skill"`
}

TelemetrySummary holds aggregated telemetry for the summary endpoint.

type ToolCallRecord added in v0.23.0

type ToolCallRecord struct {
	ID             int64     `db:"id"              json:"id"`
	MessageID      int64     `db:"message_id"      json:"message_id"`
	ConversationID string    `db:"conversation_id" json:"conversation_id"`
	ToolName       string    `db:"tool_name"       json:"tool_name"`
	ServerName     string    `db:"server_name"     json:"server_name"`
	Round          int       `db:"round"           json:"round"`
	DurationMs     int64     `db:"duration_ms"     json:"duration_ms"`
	Success        bool      `db:"success"         json:"success"`
	ErrorMsg       string    `db:"error_msg"       json:"error_msg,omitempty"`
	CreatedAt      time.Time `db:"created_at"      json:"created_at"`
}

ToolCallRecord represents a persisted tool call linked to an assistant message.

type ToolUsageSummary added in v0.23.0

type ToolUsageSummary struct {
	ToolName    string  `db:"tool_name"     json:"tool_name"`
	ServerName  string  `db:"server_name"   json:"server_name"`
	CallCount   int     `db:"call_count"    json:"call_count"`
	ErrorCount  int     `db:"error_count"   json:"error_count"`
	AvgDuration float64 `db:"avg_duration"  json:"avg_duration_ms"`
}

ToolUsageSummary aggregates tool call data per tool.

Jump to

Keyboard shortcuts

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