agent

package
v0.7.0 Latest Latest
Warning

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

Go to latest
Published: Oct 16, 2026 License: MIT Imports: 7 Imported by: 0

Documentation

Index

Constants

View Source
const DefaultContextWindow = 8192

DefaultContextWindow is the nominal model context in tokens used when neither the provider nor config supplies a value. It is a rough fallback; the status bar and compaction budget prefer the auto- discovered value from the provider (ModelInfo.ContextWindow) or the config value (CompactionConfig.ContextWindow) when available.

Variables

This section is empty.

Functions

func BuildCompactedMessages

func BuildCompactedMessages(history []ai.Message, summary string, keepFirst, keepLast int) []ai.Message

BuildCompactedMessages assembles the compacted message list from a pre-computed summary. Shared by the branch summary feature and the compactor plugin.

func EstimateTokens

func EstimateTokens(history []ai.Message) int

EstimateTokens returns a rough token count for the message history.

func FormatInsights added in v0.5.0

func FormatInsights(in *Insights) string

FormatInsights renders an Insights struct as a plain-text report. Shared by the CLI (omega insights, stdout) and the TUI (/insights slash command, transcript).

func FormatNumber added in v0.5.0

func FormatNumber(n int) string

FormatNumber adds thousands separators to an integer.

func MessageText

func MessageText(m ai.Message) string

MessageText returns the user-visible text of a message, used for token estimation, summary rendering, and export.

func MountAll added in v0.2.0

func MountAll(plugins []Plugin, ctx *Context) error

MountAll sorts plugins by dependencies and mounts each into ctx. Returns an error if:

  • two plugins provide the same exclusive seam (conflict)
  • a required seam is not provided by any plugin (missing dep)
  • a plugin's Mount returns an error

func NewSessionID added in v0.5.1

func NewSessionID() (string, error)

NewSessionID generates a random 32-character hex session ID. Used by the store, TUI, and HTTP channel to avoid duplicating the crypto/rand boilerplate.

Types

type Agent

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

Agent runs the multi-turn conversation loop between a provider and a set of tools. It holds configuration and delegates execution to a LoopProvider. Harness concerns (system prompt, compaction) are injected via interfaces. The loop itself is swappable via SetLoopProvider. The loop is not set by default — the host must wire one (e.g. via the agent-loop plugin in extensions/agent_loop/).

func NewAgent

func NewAgent(provider ai.Provider, tools map[string]Tool, maxTurns int) *Agent

NewAgent creates an Agent. A maxTurns <= 0 uses the default cap. The agent starts with no loop — the host must wire one via SetLoopProvider or by mounting the agent-loop plugin.

func NewFromContext added in v0.3.0

func NewFromContext(ctx *Context, opts AgentOptions) *Agent

NewFromContext creates a fully-wired Agent from a mounted Context. Channels, newAgent, and the TUI use this. The agent gets the loop, tool providers, prompt builder, compactor, injected messages, pending delegations, and logger from ctx. All AgentOptions fields are optional zero-values — setters tolerate zero like the constructor defaults do.

func (*Agent) ListModels

func (a *Agent) ListModels() ([]string, error)

ListModels returns the models available from the agent's provider.

func (*Agent) ModelInfo added in v0.6.0

func (a *Agent) ModelInfo() (ai.ModelInfo, error)

ModelInfo returns the current model's metadata (context window).

func (*Agent) ModelName

func (a *Agent) ModelName() string

ModelName returns the name of the model the agent's provider serves.

func (*Agent) Provider added in v0.7.0

func (a *Agent) Provider() ai.Provider

Provider returns the agent's base provider, so callers can derive per-run copies via WithModel without mutating shared state.

func (*Agent) Run

func (a *Agent) Run(ctx context.Context, messages []ai.Message, tools map[string]Tool) <-chan Event

Run executes the conversation loop and returns a channel of events. The channel is closed when the loop ends. A non-nil tools map overrides the agent's registered tools for this run.

Run always spawns - there is no running guard. The loop is stateless (all state rides LoopOptions) and each Run creates its own events channel, so parallel runs are safe by construction; use RunWithProvider to give a run its own model.

ponytail: the injected-messages channel and pending delegations are shared across concurrent runs, so a delegated message drains into an arbitrary active run - fine at single-user load. Upgrade path: a per-run injected channel (a config-defined agent registry builds on that later).

func (*Agent) RunWithProvider added in v0.7.0

func (a *Agent) RunWithProvider(ctx context.Context, provider ai.Provider, messages []ai.Message, tools map[string]Tool) <-chan Event

RunWithProvider starts a run on the given provider - typically a copy derived from Provider() via WithModel, carrying a per-request model. Returns a channel of events, closed when the run ends.

func (*Agent) SetCWD

func (a *Agent) SetCWD(dir string)

SetCWD sets the working directory passed to extension-built prompts via PromptBuildOptions.

func (*Agent) SetCompactionProvider added in v0.2.0

func (a *Agent) SetCompactionProvider(c CompactionProvider)

SetCompactionProvider installs the compactor. A nil value disables compaction.

func (*Agent) SetExtensionInfos added in v0.2.0

func (a *Agent) SetExtensionInfos(infos []ExtensionInfo)

SetExtensionInfos sets the metadata about loaded extensions, used for prompt building and the /extensions command.

func (*Agent) SetInjectedMessages added in v0.2.0

func (a *Agent) SetInjectedMessages(ch <-chan InjectedMessage)

SetInjectedMessages sets the channel for subagent result injection.

func (*Agent) SetLogger added in v0.2.2

func (a *Agent) SetLogger(l LoggerProvider)

SetLogger installs a logger for the agent loop. A nil value disables logging. The logger is passed to the loop via LoopOptions.

func (*Agent) SetLoopProvider added in v0.2.0

func (a *Agent) SetLoopProvider(loop LoopProvider)

SetLoopProvider installs a custom agent loop. A nil value clears the loop; Run will return an error if called without a loop set.

func (*Agent) SetMaxToolOutput

func (a *Agent) SetMaxToolOutput(n int)

SetMaxToolOutput sets the maximum tool result length in characters. Results exceeding this are truncated. A value <= 0 disables truncation.

func (*Agent) SetPendingDelegations added in v0.2.0

func (a *Agent) SetPendingDelegations(f func() int)

SetPendingDelegations sets the function that returns the count of running subagent tasks.

func (*Agent) SetPromptAppend

func (a *Agent) SetPromptAppend(prompts []string)

SetPromptAppend stores extra prompts from --append-system-prompt. Passed to extensions via PromptBuildOptions.Append.

func (*Agent) SetPromptBuilder added in v0.2.0

func (a *Agent) SetPromptBuilder(pb PromptBuilder)

SetPromptBuilder installs the prompt builder for system prompt assembly.

func (*Agent) SetPromptContext

func (a *Agent) SetPromptContext(s string)

SetPromptContext stores the trust-gated AGENTS.md project context. Passed to extensions via PromptBuildOptions.ProjectContext.

func (*Agent) SetPromptCustom

func (a *Agent) SetPromptCustom(s string)

SetPromptCustom stores the user-supplied custom prompt from config. Passed to extensions via PromptBuildOptions.Custom.

func (*Agent) SetToolProviders added in v0.2.0

func (a *Agent) SetToolProviders(tps []ToolProvider)

SetToolProviders installs additional tool providers (from extensions). Their tools are merged on each Run.

func (*Agent) SetUserInput added in v0.1.2

func (a *Agent) SetUserInput(ch chan string)

SetUserInput sets a channel for receiving user messages while the agent loop is running. The TUI uses this so the user can chat while subagents are running. One-shot mode (omega run) leaves it nil.

type AgentEnd

type AgentEnd struct {
	Type         string       `json:"type"`
	Turns        int          `json:"turns"`
	FinishReason string       `json:"finish_reason"`
	Error        string       `json:"error,omitempty"`
	Message      ai.Assistant `json:"message,omitempty"`
}

AgentEnd is emitted when Run finishes. Message carries the final assistant response (with thinking) so the TUI can persist it without reconstructing from the stream buffer.

type AgentOptions added in v0.3.0

type AgentOptions struct {
	MaxTurns      int
	MaxToolOutput int
	PromptCustom  string
	PromptAppend  []string
	PromptContext string
	CWD           string
}

AgentOptions carries the host-level settings NewFromContext cannot get from the Context itself. All fields are optional zero-values.

type AgentStart

type AgentStart struct {
	Type      string `json:"type"`
	ModelName string `json:"model_name"`
}

AgentStart is emitted when Run begins.

type AssistantMessageEvent

type AssistantMessageEvent struct {
	Type    string       `json:"type"`
	Message ai.Assistant `json:"message"`
}

AssistantMessageEvent is emitted after the provider finishes a turn, carrying the assistant message (with thinking and tool calls) so the TUI can persist it to the session store.

type Channel added in v0.3.0

type Channel interface {
	// Start runs the channel until the context is cancelled or Stop
	// is called. Blocks.
	Start(ctx context.Context, deps ChannelDeps) error
	// Stop shuts the channel down. Called by the host after the
	// context is cancelled.
	Stop() error
}

Channel is a delivery transport that connects external clients to the agent. Channels are additive: multiple can run simultaneously (HTTP + Discord + Telegram). The host starts all mounted channels after MountAll and stops them on shutdown.

Start blocks until the channel stops or the context is cancelled. Each channel creates agents from deps.Ctx as needed — HTTP reuses one agent; a chat-platform channel may create one per conversation.

type ChannelDeps added in v0.3.0

type ChannelDeps struct {
	Ctx   *Context
	Store StoreProvider
}

ChannelDeps carries everything a channel needs to run. Ctx is the fully-wired plugin Context — channels create agents from it. Store persists messages.

type CmdAction added in v0.2.0

type CmdAction struct {
	Type  string   // "set_model", "refresh_title", "fetch_model_info", "run_compact", "set_model_list", "set_tool_display", "set_thinking", "new_session", "load_session", "branch_session", "set_label"
	Value string   // primary value (model name, session ID, label text)
	List  []string // list values (model names)
}

CmdAction tells the host to do something after a command runs. Extensions declare intent; the host interprets.

type CommandResult added in v0.2.0

type CommandResult struct {
	Text    string      // what to display (may be empty)
	Actions []CmdAction // optional TUI actions
}

CommandResult is what an extension command returns. Text is printed to the transcript. Actions are TUI directives the host interprets.

type CompactionConfig

type CompactionConfig struct {
	Enabled       bool    `yaml:"enabled"`
	Threshold     float64 `yaml:"threshold"`
	ContextWindow int     `yaml:"context_window"`
	KeepFirst     int     `yaml:"keep_first"`
	KeepLast      int     `yaml:"keep_last"`
	ReserveTokens int     `yaml:"reserve_tokens"`
	MaxToolOutput int     `yaml:"max_tool_output"`
}

CompactionConfig controls when the agent summarizes old messages to stay within the model's context window. It lives in the agent package (not the host so the agent can consume it without importing a layer above itself. The config is passed to the compactor plugin via Context; the plugin owns the compaction logic.

func (CompactionConfig) Budget added in v0.2.0

func (c CompactionConfig) Budget() int

Budget returns the token count at which compaction triggers. ReserveTokens are subtracted from the context window so the model has room for its response after the prompt.

type CompactionProvider added in v0.2.0

type CompactionProvider interface {
	// Compact compacts the message history. Returns the compacted
	// history, or the original if no compaction is needed. A nil
	// CompactionProvider means compaction is disabled.
	Compact(ctx context.Context, messages []ai.Message) ([]ai.Message, error)
}

CompactionProvider handles context compaction when the token budget is exceeded. The compactor-seam extension implements this; when no compactor extension is loaded, compaction is disabled and the agent surfaces a friendly error on context overflow.

type Context added in v0.2.0

type Context struct {
	// Seam slots (exclusive — one plugin per slot).
	Provider      ai.Provider
	Compactor     CompactionProvider
	Store         StoreProvider
	Skills        SkillsProvider
	Loop          LoopProvider
	Logger        LoggerProvider
	Memory        MemoryProvider
	PromptBuilder PromptBuilder

	// Tool providers (additive — multiple plugins contribute).
	ToolProviders []ToolProvider

	// Frontend (exclusive — one frontend at a time). The host calls
	// Run after mounting all extensions.
	Frontend Frontend
	Trust    TrustProvider

	// Channels (additive — multiple plugins contribute delivery
	// transports). The host starts all mounted channels after MountAll.
	Channels []Channel

	// Cross-cutting (set by specific plugins).
	Commands           []ExtensionCommand
	CommandHandler     func(ctx context.Context, name, args string) (CommandResult, error)
	InjectedMessages   <-chan InjectedMessage
	PendingDelegations func() int

	// Shared state.
	CWD     string
	Configs map[string]any // per-plugin typed config, keyed by plugin Name()

	// Metadata (built during MountAll).
	Infos []ExtensionInfo
}

Context is the shared service container that extensions mount into. Each slot corresponds to a capability seam. The host creates a Context, runs MountAll to populate it, then passes it to the agent loop.

Seam slots (Provider, Compactor, Store, Skills, Loop, PromptBuilder) are exclusive: one plugin per slot. ToolProviders and Channels are additive: multiple plugins contribute.

type DayStat

type DayStat struct {
	Day   string // "Mon", "Tue", etc.
	Count int
	Bar   string // visual bar string
}

DayStat is one row in the daily activity breakdown.

type DefaultToolProvider

type DefaultToolProvider struct {
	ToolsMap map[string]Tool
}

DefaultToolProvider wraps a static tool map. Used by tests to satisfy the ToolProvider interface with a simple map.

func (DefaultToolProvider) Tools

func (d DefaultToolProvider) Tools() map[string]Tool

Tools returns the tool map.

type Event

type Event interface {
	// contains filtered or unexported methods
}

Event is the sealed interface for all agent events.

type ExtensionCommand

type ExtensionCommand struct {
	Name        string `json:"name"` // includes leading slash, e.g. "/mycmd"
	Description string `json:"description"`
}

ExtensionCommand is a slash command registered by an extension.

type ExtensionInfo

type ExtensionInfo struct {
	Name     string
	Tools    int
	Commands int
	Seams    []string   // declared seam types ("prompt_builder", "compactor", etc.)
	ToolList []ToolInfo // tools provided by this extension (name + description)
}

ExtensionInfo is metadata about a loaded extension, for display.

type Frontend added in v0.4.0

type Frontend interface {
	Run(ctx context.Context, pctx *Context, opts FrontendOptions) error
}

Frontend is the user-facing interface seam. The default implementation is the terminal TUI (extensions/tui/). A custom implementation could serve a web UI or any other interactive frontend. The host calls Run after mounting all extensions; Run blocks until the frontend exits.

type FrontendOptions added in v0.4.0

type FrontendOptions struct {
	ModelName     string
	ProviderType  string
	Compaction    *CompactionConfig
	PromptCustom  string
	PromptAppend  []string
	PromptContext string
	Skills        []Skill
	ThemeName     string
	TrustState    string
	Notifications string
	CWD           string
	Version       string
}

FrontendOptions carries host-level settings the frontend needs that are not on the Context itself. All fields are optional zero-values.

type InjectedMessage added in v0.1.2

type InjectedMessage struct {
	Text   string // the message content
	Source string // "delegate:<task_id>" — for display
}

InjectedMessage is a message injected by an extension (e.g. a subagent result) that re-enters the conversation as a new user message, triggering a new turn.

type Insights

type Insights struct {
	Period         string
	PeriodStart    string
	PeriodEnd      string
	Days           int
	Sessions       int
	Messages       int
	UserMessages   int
	ToolCalls      int
	TotalTokens    int
	AvgSessionMsgs float64
	Tools          []ToolStat
	Daily          [7]DayStat
	NotableMsgs    NotableStat
	NotableTokens  NotableStat
	NotableTools   NotableStat
}

Insights is the aggregated cross-session analytics result.

type LoggerProvider added in v0.2.2

type LoggerProvider interface {
	// Printf writes an info-level log entry.
	Printf(format string, args ...any)
	// Errorf writes an error-level log entry.
	Errorf(format string, args ...any)
	// Close flushes and closes the log output.
	Close() error
}

LoggerProvider is the logging seam. Extensions call it to write log entries. The default implementation writes to a file in OMEGA_HOME; a no-op implementation is used when logging is disabled.

type LoopOptions

type LoopOptions struct {
	Provider           ai.Provider
	Messages           []ai.Message
	Tools              map[string]Tool
	ToolProviders      []ToolProvider // additive tool sources (extensions)
	CompactionProvider CompactionProvider
	PromptBuilder      PromptBuilder   // builds system prompt + guidelines
	ExtensionInfos     []ExtensionInfo // for prompt building context
	MaxTurns           int
	MaxToolOutput      int
	CWD                string
	PromptCustom       string   // user-supplied prompt from config, for extension-built prompts
	PromptAppend       []string // extra prompts from --append-system-prompt
	PromptContext      string   // trust-gated AGENTS.md project context
	Events             chan<- Event
	InjectedMessages   <-chan InjectedMessage // subagent results (nil if no delegate extension)
	UserInput          <-chan string          // user messages while running (nil for one-shot mode)
	PendingDelegations func() int             // returns count of running subagent tasks
	Logger             LoggerProvider         // optional logger; nil = no logging
}

LoopOptions carries everything the loop needs to run one agent session. The Agent struct builds this from its configured fields.

type LoopProvider added in v0.2.0

type LoopProvider interface {
	Run(ctx context.Context, opts LoopOptions) error
}

LoopProvider drives the multi-turn conversation. The default implementation (agent_loop.Loop in extensions/agent_loop/) runs the standard turn loop: stream provider responses, execute tool calls, feed results back. A custom implementation can replace the entire loop logic.

type MemoryProvider added in v0.2.2

type MemoryProvider interface {
	// Snapshot returns the formatted prompt block for system prompt
	// injection. Reads files fresh on each call.
	Snapshot() string

	// Add appends a new entry to the target store ("memory" or "user").
	// Returns the new usage string and an error if the entry would
	// exceed the char limit or is an exact duplicate.
	Add(target, content string) (usage string, err error)

	// Replace finds the entry matching oldText (unique substring) and
	// replaces it with content. Returns usage string and error.
	Replace(target, oldText, content string) (usage string, err error)

	// Remove finds the entry matching oldText (unique substring) and
	// deletes it. Returns usage string and error.
	Remove(target, oldText string) (usage string, err error)

	// List returns all entries for the target.
	List(target string) ([]string, error)
}

MemoryProvider manages persistent memory across sessions. The prompt builder calls Snapshot to inject current memory into the system prompt. The memory tool calls Add/Replace/Remove to mutate entries during a session.

type NotableStat

type NotableStat struct {
	Value  int
	Detail string // date or session label
}

NotableStat holds the most extreme session for a given metric.

type Plugin added in v0.2.0

type Plugin interface {
	// Name is shown in the /extensions listing.
	Name() string
	// Provides lists seam names this plugin mounts (e.g. "provider",
	// "store", "tools"). Exclusive seams conflict if two plugins
	// provide the same one. The "tools" seam is additive.
	Provides() []string
	// Requires lists seam names that must be mounted before this
	// plugin. MountAll uses these for topological ordering.
	Requires() []string
	// Mount populates Context slots. Called once, in dependency order.
	Mount(ctx *Context) error
}

Plugin is the contract every extension implements. The host collects plugins, sorts them by dependencies, and mounts each into a Context.

type PromptBuildOptions

type PromptBuildOptions struct {
	CWD            string
	Messages       []ai.Message
	Extensions     []ExtensionInfo
	ProjectContext string   // AGENTS.md contents, already trust-gated by Go
	Custom         string   // user-supplied prompt from config, may be empty
	Append         []string // extra prompts from --append-system-prompt, may be nil
}

PromptBuildOptions carries context for extension-built system prompts.

type PromptBuilder added in v0.2.0

type PromptBuilder interface {
	// BuildPrompt assembles the full system prompt. Returns ok=false
	// if the builder does not want to provide a prompt; the agent gets
	// no system prompt in that case.
	BuildPrompt(ctx context.Context, opts PromptBuildOptions) (string, bool)
	// Guidelines returns extra lines appended under
	// "## Extension Guidelines" in the system prompt.
	Guidelines() []string
}

PromptBuilder builds the system prompt and supplies guideline lines appended to it. The default implementation is provided via the prompt extension. When no prompt extension is loaded, both methods return zero values.

type SearchResult

type SearchResult struct {
	SessionID string `json:"session_id"`
	Snippet   string `json:"snippet"`
}

SearchResult is a single search hit from SearchMessages.

type Session

type Session struct {
	ID        string `json:"id"`
	ParentID  string `json:"parent_id,omitempty"`
	Label     string `json:"label,omitempty"`
	CreatedAt string `json:"created_at"`
	UpdatedAt string `json:"updated_at"`
}

Session is a persisted conversation with optional parent linking for branching.

type SessionNode

type SessionNode struct {
	Session
	Children []*SessionNode
}

SessionNode is one node in the session tree returned by GetSessionTree.

type Skill

type Skill struct {
	Name        string
	Description string
	Content     string
	Dir         string
}

Skill is a loaded skill from a skill directory. The YAML frontmatter in the skill file provides name and description; the markdown body is the skill content injected into the system prompt when invoked. Dir is the path to the skill's directory, so the skill can reference its own files (scripts, references, templates) by relative path.

type SkillsProvider

type SkillsProvider interface {
	LoadSkills(dir string) ([]Skill, error)
}

SkillsProvider is the skill loading seam. The default implementation scans a directory for <name>/<name>.md files, provided via the skills plugin. The host uses this to populate the skill list for autocomplete, inline invocation, and @skill: mentions.

type StoreProvider

type StoreProvider interface {
	Open(dsn string) error
	Close() error
	CreateSession(ctx context.Context, id, parentID, label string) error
	GetSession(ctx context.Context, id string) (Session, error)
	ListSessions(ctx context.Context) ([]Session, error)
	DeleteSession(ctx context.Context, id string) error
	UpdateSession(ctx context.Context, id, label string) error
	AppendMessage(ctx context.Context, sessionID string, msg ai.Message) error
	GetMessages(ctx context.Context, sessionID string) ([]ai.Message, error)
	GetSessionTree(ctx context.Context) ([]*SessionNode, error)
	GetAncestorMessages(ctx context.Context, sessionID string) ([]ai.Message, error)
	SearchMessages(ctx context.Context, query string) ([]SearchResult, error)
	ComputeInsights(ctx context.Context, days int) (*Insights, error)
	CountMessages(ctx context.Context, sessionID string) (int, error)
}

StoreProvider is the session persistence seam. The default implementation is SQLite (store.Store in extensions/store/), provided via the store plugin. All session and message operations go through this interface.

type StreamEvent

type StreamEvent struct {
	Event ai.StreamEvent `json:"-"`
}

StreamEvent wraps an ai stream event forwarded from the provider.

type Tool

type Tool struct {
	Description string
	Parameters  map[string]any
	Run         func(ctx context.Context, args map[string]any) (string, error)
}

Tool is a callable the model may invoke. The map key is the tool name.

type ToolInfo

type ToolInfo struct {
	Name        string
	Description string
}

ToolInfo is a tool name and description pair, for display in the system prompt and /tools listing.

type ToolProvider

type ToolProvider interface {
	Tools() map[string]Tool
}

ToolProvider supplies tools to the agent. Called once per Run to build the tool set. Extension-provided tools are merged on top.

type ToolResultEvent

type ToolResultEvent struct {
	Type    string        `json:"type"`
	Message ai.ToolResult `json:"message"`
}

ToolResultEvent is emitted after a tool executes, carrying the result message so the TUI can persist it to the session store.

type ToolStat

type ToolStat struct {
	Name  string
	Count int
}

ToolStat is one row in the tool breakdown.

type TrustProvider added in v0.5.0

type TrustProvider interface {
	ResolveContext(cwd string, approve, noApprove, interactive bool) string
	State(cwd string, approve, noApprove bool) string
}

TrustProvider gates project context (AGENTS.md) behind a trust check. The default implementation reads trust.yaml from omega home. The host calls ResolveContext before building the agent; State is used for the TUI status bar.

type TurnEnd

type TurnEnd struct {
	Type      string `json:"type"`
	Turn      int    `json:"turn"`
	ToolCalls int    `json:"tool_calls"`
}

TurnEnd is emitted after a turn completes, including tool execution.

type TurnStart

type TurnStart struct {
	Type string `json:"type"`
	Turn int    `json:"turn"`
}

TurnStart is emitted before each provider call.

Jump to

Keyboard shortcuts

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