Documentation
¶
Overview ¶
Package ext provides the extension registration surface for piglet.
App is the central API through which all extensions — both compiled-in and external — register their capabilities. It supports five primitives:
- Inject: add text to the system prompt (App.RegisterPromptSection)
- React: respond to triggers (App.RegisterTool, App.RegisterCommand)
- Intercept: modify or block tool calls (App.RegisterInterceptor)
- Hook: process user messages before the LLM (App.RegisterMessageHook)
- Observe: react to lifecycle events (App.RegisterEventHandler)
Package ext provides the extension API for piglet. Extensions are plain functions that receive *App and register capabilities.
Index ¶
- Constants
- func BoolArg(args map[string]any, key string, fallback bool) bool
- func CompactWithCircuitBreaker(fn func(ctx context.Context, msgs []core.Message) ([]core.Message, error), ...) func(ctx context.Context, msgs []core.Message) ([]core.Message, error)
- func IntArg(args map[string]any, key string, fallback int) int
- func StringArg(args map[string]any, key string) string
- func TextResult(text string) *core.ToolResult
- type Action
- type ActionAttachImage
- type ActionCloseOverlay
- type ActionDetachImage
- type ActionExec
- type ActionNotify
- type ActionQuit
- type ActionRunAsync
- type ActionSendMessage
- type ActionSetSessionTitle
- type ActionSetStatus
- type ActionSetWidget
- type ActionShowMessage
- type ActionShowOverlay
- type ActionShowPicker
- type ActionSwapSession
- type AgentAPI
- type AgentReader
- type AgentWriter
- type App
- func (a *App) AppendCustomMessage(role, content string) error
- func (a *App) AppendSessionEntry(kind string, data any) error
- func (a *App) AvailableModels() []core.Model
- func (a *App) BackgroundSafeTools() []core.Tool
- func (a *App) Bind(agent AgentAPI, opts ...BindOption)
- func (a *App) BranchSession(entryID string) error
- func (a *App) BranchSessionWithSummary(entryID, summary string) error
- func (a *App) CWD() string
- func (a *App) CancelBackground()
- func (a *App) ClearIdle()
- func (a *App) CloseOverlay(key string)
- func (a *App) Commands() map[string]*Command
- func (a *App) Compactor() *Compactor
- func (a *App) ConversationMessages() []core.Message
- func (a *App) CoreTools() []core.Tool
- func (a *App) DispatchEvent(ctx context.Context, evt core.Event)
- func (a *App) EnqueueAction(action Action)
- func (a *App) ExtInfos() []ExtInfo
- func (a *App) FindTool(name string) *core.Tool
- func (a *App) ForkSession() (string, int, error)
- func (a *App) IsBackgroundRunning() bool
- func (a *App) LastAssistantText() string
- func (a *App) LoadSession(path string) error
- func (a *App) Notify(msg string)
- func (a *App) NotifyError(msg string)
- func (a *App) NotifyWarn(msg string)
- func (a *App) NotifyWithLevel(msg, level string)
- func (a *App) PendingActions() []Action
- func (a *App) PromptSections() []PromptSection
- func (a *App) Provider() core.StreamProvider
- func (a *App) Publish(topic string, data any)
- func (a *App) RegisterCommand(c *Command)
- func (a *App) RegisterCompactor(c Compactor)
- func (a *App) RegisterEventHandler(h EventHandler)
- func (a *App) RegisterExtInfo(info ExtInfo)
- func (a *App) RegisterInputTransformer(t InputTransformer)
- func (a *App) RegisterInterceptor(i Interceptor)
- func (a *App) RegisterMessageHook(h MessageHook)
- func (a *App) RegisterPromptSection(s PromptSection)
- func (a *App) RegisterRenderer(typ string, r Renderer)
- func (a *App) RegisterShortcut(s *Shortcut)
- func (a *App) RegisterStatusSection(s StatusSection)
- func (a *App) RegisterStreamProvider(api string, factory StreamProviderFactory)
- func (a *App) RegisterTool(t *ToolDef)
- func (a *App) Renderers() map[string]Renderer
- func (a *App) RequestQuit()
- func (a *App) ResolveModel(id string) (core.Model, core.StreamProvider, error)
- func (a *App) RunBackground(prompt string) error
- func (a *App) RunInputTransformers(ctx context.Context, input string) (string, bool, error)
- func (a *App) RunMessageHooks(ctx context.Context, msg string) ([]string, error)
- func (a *App) SendMessage(content string)
- func (a *App) SessionEntryInfos() []EntryInfo
- func (a *App) SessionFullTree() []TreeNode
- func (a *App) SessionTitle() string
- func (a *App) Sessions() ([]SessionSummary, error)
- func (a *App) SetConversationMessages(msgs []core.Message)
- func (a *App) SetModel(m core.Model)
- func (a *App) SetProvider(p core.StreamProvider)
- func (a *App) SetSessionLabel(targetID, label string) error
- func (a *App) SetSessionTitle(title string) error
- func (a *App) SetStatus(key, text string)
- func (a *App) SetWidget(key, placement, content string)
- func (a *App) Shortcuts() map[string]*Shortcut
- func (a *App) ShowMessage(text string)
- func (a *App) ShowOverlay(key, title, content, anchor, width string)
- func (a *App) ShowPicker(title string, items []PickerItem, onSelect func(PickerItem))
- func (a *App) SignalIdle()
- func (a *App) StatusSections() []StatusSection
- func (a *App) Steer(content string)
- func (a *App) StreamProvider(api string, model core.Model) (core.StreamProvider, bool)
- func (a *App) Subscribe(topic string, fn func(any)) func()
- func (a *App) SwitchModel(id string) error
- func (a *App) SyncModels() (int, error)
- func (a *App) SystemPrompt() string
- func (a *App) ToggleStepMode() bool
- func (a *App) ToolDefs() []*ToolDef
- func (a *App) Tools() []string
- func (a *App) UnregisterExtension(name string)
- func (a *App) WaitForIdle(ctx context.Context) error
- func (a *App) WriteModelsWithOverrides(overrides map[string]ModelOverride) (int, error)
- type BindOption
- type Command
- type Compactor
- type EntryInfo
- type EventHandler
- type ExtInfo
- type Extension
- type InputTransformer
- type Interceptor
- type InterruptBehavior
- type MessageHook
- type ModelManager
- type ModelOverride
- type PickerItem
- type PromptSection
- type Renderer
- type SessionManager
- type SessionSummary
- type Shortcut
- type StatusSection
- type StatusSide
- type StreamProviderFactory
- type ToolDef
- type TreeNode
Constants ¶
const ( StatusKeyApp = "app" StatusKeyModel = "model" StatusKeyMouse = "mouse" StatusKeyBg = "bg" StatusKeyTokens = "tokens" StatusKeyCost = "cost" StatusKeyQueue = "queue" StatusKeyPromptBudget = "prompt-budget" )
Built-in status section keys.
Variables ¶
This section is empty.
Functions ¶
func CompactWithCircuitBreaker ¶ added in v0.17.0
func CompactWithCircuitBreaker( fn func(ctx context.Context, msgs []core.Message) ([]core.Message, error), maxFails int, cooldown time.Duration, ) func(ctx context.Context, msgs []core.Message) ([]core.Message, error)
CompactWithCircuitBreaker wraps a compact function with retry protection. After maxFails consecutive failures, compaction is disabled for cooldown duration.
func IntArg ¶ added in v0.5.0
IntArg extracts an integer argument from a tool call's args map. JSON numbers decode as float64, so both float64 and int are handled.
func TextResult ¶ added in v0.5.0
func TextResult(text string) *core.ToolResult
TextResult builds a ToolResult containing a single text block.
Types ¶
type Action ¶ added in v0.4.0
type Action interface {
// contains filtered or unexported methods
}
Action represents an intent requested by an extension command or shortcut. Commands enqueue actions; the TUI drains and applies them after the handler returns.
type ActionAttachImage ¶ added in v0.5.0
type ActionAttachImage struct{ Image any }
ActionAttachImage attaches an image to the next message. Image is typed as any to avoid importing core.ImageContent.
type ActionCloseOverlay ¶ added in v0.18.0
type ActionCloseOverlay struct {
Key string
}
ActionCloseOverlay removes a named overlay.
type ActionDetachImage ¶ added in v0.5.0
type ActionDetachImage struct{}
ActionDetachImage removes a pending image attachment.
type ActionExec ¶ added in v0.5.0
type ActionExec struct{ Cmd any }
ActionExec hands the terminal to an external process (e.g., $EDITOR). Cmd is typed as any to avoid importing os/exec from ext/. The TUI asserts *exec.Cmd and uses tea.ExecProcess.
type ActionNotify ¶ added in v0.4.0
ActionNotify sends a transient notification. Level controls styling: "" or "info" = muted, "warn" = warning, "error" = error.
type ActionRunAsync ¶ added in v0.5.0
type ActionRunAsync struct{ Fn func() Action }
ActionRunAsync runs Fn in a goroutine. The returned Action (if non-nil) is enqueued when Fn completes. Use for expensive event handler work.
type ActionSendMessage ¶ added in v0.16.8
type ActionSendMessage struct{ Content string }
ActionSendMessage injects a user message into the agent loop.
type ActionSetSessionTitle ¶ added in v0.5.0
type ActionSetSessionTitle struct{ Title string }
ActionSetSessionTitle sets the current session's title.
type ActionSetStatus ¶ added in v0.4.0
type ActionSetStatus struct{ Key, Text string }
ActionSetStatus updates a status bar widget (e.g. "model").
type ActionSetWidget ¶ added in v0.18.0
type ActionSetWidget struct {
Key string
Placement string // "above-input" or "below-status"
Content string // empty = remove widget
}
ActionSetWidget sets or clears persistent multi-line content in a TUI region. Placement: "above-input" (between messages and input) or "below-status" (after status bar). Empty Content removes the widget. Keyed: last-write-wins per key.
type ActionShowMessage ¶ added in v0.4.0
type ActionShowMessage struct{ Text string }
ActionShowMessage displays a message in the conversation view.
type ActionShowOverlay ¶ added in v0.18.0
ActionShowOverlay creates or replaces a named overlay. Anchor: "center" (default), "right", "left". Width: "50%", "80" (chars), "" (auto ~60%).
type ActionShowPicker ¶ added in v0.4.0
type ActionShowPicker struct {
Title string
Items []PickerItem
OnSelect func(PickerItem)
}
ActionShowPicker opens a modal picker.
type ActionSwapSession ¶ added in v0.4.0
type ActionSwapSession struct{ Session any }
ActionSwapSession replaces the active session. Session is typed as any to avoid importing session/ from ext/.
type AgentAPI ¶
type AgentAPI interface {
AgentReader
AgentWriter
}
AgentAPI is the subset of *core.Agent that the extension runtime needs. Using an interface keeps ext/ from depending on agent implementation details.
Removed from interface (used only via *core.Agent in tui/ and cmd/):
- SetTools, SetTurnContext, IsRunning
type AgentReader ¶ added in v0.16.8
type AgentReader interface {
Messages() []core.Message
StepMode() bool
Provider() core.StreamProvider
System() string
}
AgentReader provides read-only access to agent state.
type AgentWriter ¶ added in v0.16.8
type AgentWriter interface {
Steer(msg core.Message)
FollowUp(msg core.Message)
SetModel(m core.Model)
SetProvider(p core.StreamProvider)
SetMessages(msgs []core.Message)
SetStepMode(on bool)
}
AgentWriter provides mutation access to the agent.
type App ¶
type App struct {
// contains filtered or unexported fields
}
App is the single extension API surface. Extensions receive this in their factory function and call methods to register tools, commands, etc.
After registration, Bind() wires the runtime references (agent, session) so runtime methods like SendMessage() and Model() work.
CAPABILITY GATE — before adding a new callback or field to App, answer:
- Can this be a Tool? → RegisterTool (agent-callable action)
- Can this be a Command? → RegisterCommand (user-invoked /slash)
- Can this be a Shortcut? → RegisterShortcut (keyboard binding)
- Can this be a PromptSection? → RegisterPromptSection (system prompt injection)
- Can this be an Interceptor? → RegisterInterceptor (before/after tool hook)
- Can this be a MessageHook? → RegisterMessageHook (before user message reaches LLM)
Only add a new BindOption/callback when NONE of the above apply — typically for TUI-specific lifecycle that extensions cannot express through existing primitives (e.g. session swapping, background agent management). See ext/architecture_test.go for automated boundary enforcement.
func (*App) AppendCustomMessage ¶ added in v0.18.0
AppendCustomMessage writes a message that persists and appears in Messages() on reload. Role must be "user" or "assistant".
func (*App) AppendSessionEntry ¶ added in v0.18.0
AppendSessionEntry writes a custom extension entry to the current session. The kind should be namespaced (e.g., "ext:memory:facts").
func (*App) AvailableModels ¶ added in v0.4.0
AvailableModels returns all registered models.
func (*App) BackgroundSafeTools ¶ added in v0.4.0
BackgroundSafeTools returns core.Tool slice filtered to tools marked BackgroundSafe.
func (*App) Bind ¶
func (a *App) Bind(agent AgentAPI, opts ...BindOption)
Bind wires the runtime references after the agent and session are created. Must be called before runtime methods (SendMessage, Model, etc.) are used.
func (*App) BranchSession ¶ added in v0.18.0
BranchSession moves the current session's leaf to an earlier entry (in-place). The agent's message history and TUI are refreshed via ActionSwapSession.
func (*App) BranchSessionWithSummary ¶ added in v0.18.0
BranchSessionWithSummary moves the leaf and writes a branch_summary entry.
func (*App) CancelBackground ¶ added in v0.4.0
func (a *App) CancelBackground()
CancelBackground stops the running background agent. No-op if not bound or not running.
func (*App) ClearIdle ¶ added in v0.18.4
func (a *App) ClearIdle()
ClearIdle marks the agent as no longer idle. Must be called when the agent starts a new run, before any WaitForIdle callers register.
func (*App) CloseOverlay ¶ added in v0.18.0
CloseOverlay removes a named overlay.
func (*App) ConversationMessages ¶
ConversationMessages returns a snapshot of the conversation history.
func (*App) CoreTools ¶
CoreTools converts registered ToolDefs into core.Tool slice for the agent. Wraps each tool's Execute with the interceptor chain.
func (*App) DispatchEvent ¶ added in v0.5.0
DispatchEvent sends an agent event to all registered event handlers. Called by the TUI or runPrint as events are drained from the agent channel. Handlers run synchronously in priority order. Returned actions are enqueued.
func (*App) EnqueueAction ¶ added in v0.5.0
EnqueueAction adds an action to the pending queue. Used by the TUI to re-enqueue results from ActionRunAsync.
func (*App) FindTool ¶ added in v0.5.0
FindTool looks up a tool by name and returns a core.Tool with interceptors applied. Returns nil if no tool with that name is registered.
func (*App) ForkSession ¶ added in v0.4.0
ForkSession forks the current session into a new branch.
func (*App) IsBackgroundRunning ¶ added in v0.4.0
IsBackgroundRunning returns whether a background agent is currently active.
func (*App) LastAssistantText ¶ added in v0.18.0
LastAssistantText returns the text content of the last assistant message, or empty string if none found. Walks backward through conversation history.
func (*App) LoadSession ¶ added in v0.4.0
LoadSession opens a session by path and enqueues a swap.
func (*App) NotifyError ¶ added in v0.18.0
NotifyError sends an error notification.
func (*App) NotifyWarn ¶ added in v0.18.0
NotifyWarn sends a warning notification.
func (*App) NotifyWithLevel ¶ added in v0.18.0
NotifyWithLevel sends a notification with a severity level.
func (*App) PendingActions ¶ added in v0.4.0
PendingActions returns and clears all queued actions.
func (*App) PromptSections ¶
func (a *App) PromptSections() []PromptSection
PromptSections returns all registered prompt sections, sorted by order.
func (*App) Provider ¶ added in v0.5.0
func (a *App) Provider() core.StreamProvider
Provider returns the current agent's streaming provider.
func (*App) Publish ¶ added in v0.18.0
Publish sends data to all subscribers of a topic. Callbacks run synchronously — keep them fast or use goroutines in the subscriber.
func (*App) RegisterCommand ¶
RegisterCommand adds a slash command. Panics with a descriptive message if c is nil, has empty Name, or nil Handler.
func (*App) RegisterCompactor ¶ added in v0.5.0
RegisterCompactor sets the conversation compactor. Only one compactor is active at a time (last-write-wins).
func (*App) RegisterEventHandler ¶ added in v0.5.0
func (a *App) RegisterEventHandler(h EventHandler)
RegisterEventHandler adds a handler that reacts to agent lifecycle events. Sorted by priority ascending (lower = earlier).
func (*App) RegisterExtInfo ¶ added in v0.2.0
RegisterExtInfo records metadata about a loaded extension.
func (*App) RegisterInputTransformer ¶ added in v0.18.0
func (a *App) RegisterInputTransformer(t InputTransformer)
RegisterInputTransformer adds a transformer that intercepts user input before the agent. Sorted by priority ascending (lower = earlier).
func (*App) RegisterInterceptor ¶
func (a *App) RegisterInterceptor(i Interceptor)
RegisterInterceptor adds a tool interceptor. Sorted by priority descending.
func (*App) RegisterMessageHook ¶ added in v0.5.0
func (a *App) RegisterMessageHook(h MessageHook)
RegisterMessageHook adds a hook that runs before user messages reach the LLM. Sorted by priority ascending (lower = earlier).
func (*App) RegisterPromptSection ¶
func (a *App) RegisterPromptSection(s PromptSection)
RegisterPromptSection adds a section to the system prompt.
func (*App) RegisterRenderer ¶
RegisterRenderer adds a custom message type renderer.
func (*App) RegisterShortcut ¶
RegisterShortcut adds a keyboard shortcut.
func (*App) RegisterStatusSection ¶ added in v0.5.0
func (a *App) RegisterStatusSection(s StatusSection)
RegisterStatusSection adds a status bar section. Overwrites if a section with the same key already exists.
func (*App) RegisterStreamProvider ¶ added in v0.16.11
func (a *App) RegisterStreamProvider(api string, factory StreamProviderFactory)
RegisterStreamProvider registers a factory that creates StreamProviders for the given API type.
func (*App) RegisterTool ¶
RegisterTool adds a tool. Overwrites if name already exists. Panics with a descriptive message if t is nil, has empty Name, or nil Execute.
func (*App) ResolveModel ¶ added in v0.5.0
ResolveModel returns a model and configured provider for the given model ID without switching the main agent. Used by sub-agents to run on different models.
func (*App) RunBackground ¶ added in v0.4.0
RunBackground starts a background agent with the given prompt. Returns an error if not bound or if a background agent is already running.
func (*App) RunInputTransformers ¶ added in v0.18.0
RunInputTransformers executes all input transformers in priority order. Returns the (possibly modified) input text and whether the input was consumed.
func (*App) RunMessageHooks ¶ added in v0.5.0
RunMessageHooks executes all message hooks in priority order. Returns collected non-empty context strings for ephemeral injection.
func (*App) SendMessage ¶
SendMessage enqueues an ActionSendMessage that the TUI will pick up and feed into the agent loop as a follow-up user message.
func (*App) SessionEntryInfos ¶ added in v0.18.0
SessionEntryInfos returns entry info for the current branch (for display/picker).
func (*App) SessionFullTree ¶ added in v0.18.0
SessionFullTree returns the full DAG of the current session for tree rendering.
func (*App) SessionTitle ¶ added in v0.5.0
SessionTitle returns the current session's title (empty if not set).
func (*App) Sessions ¶ added in v0.4.0
func (a *App) Sessions() ([]SessionSummary, error)
Sessions returns all sessions, newest first.
func (*App) SetConversationMessages ¶
SetConversationMessages replaces the conversation history.
func (*App) SetProvider ¶ added in v0.3.0
func (a *App) SetProvider(p core.StreamProvider)
SetProvider swaps the agent's streaming provider.
func (*App) SetSessionLabel ¶ added in v0.18.0
SetSessionLabel sets or clears a bookmark label on a session entry.
func (*App) SetSessionTitle ¶ added in v0.4.0
SetSessionTitle updates the current session's title.
func (*App) SetWidget ¶ added in v0.18.0
SetWidget sets or clears a persistent multi-line widget in a TUI region. Placement: "above-input" or "below-status". Empty content removes the widget.
func (*App) ShowMessage ¶
ShowMessage displays a message in the TUI.
func (*App) ShowOverlay ¶ added in v0.18.0
ShowOverlay creates or replaces a named overlay in the TUI. Anchor: "center" (default), "right", "left". Width: "50%", "80" (chars), "" (auto).
func (*App) ShowPicker ¶
func (a *App) ShowPicker(title string, items []PickerItem, onSelect func(PickerItem))
ShowPicker shows a picker/modal in the TUI.
func (*App) SignalIdle ¶ added in v0.18.0
func (a *App) SignalIdle()
SignalIdle marks the agent as idle and wakes all pending WaitForIdle callers. Called by the shell/TUI when the agent finishes a turn.
func (*App) StatusSections ¶ added in v0.5.0
func (a *App) StatusSections() []StatusSection
StatusSections returns all registered status sections.
func (*App) StreamProvider ¶ added in v0.16.11
StreamProvider returns a provider for the given API type and model, if a factory is registered.
func (*App) Subscribe ¶ added in v0.18.0
Subscribe registers a callback for a topic. Returns an unsubscribe function. Callbacks run synchronously in the publisher's goroutine — keep them fast.
func (*App) SwitchModel ¶ added in v0.4.0
SwitchModel activates a model by its "provider/id" key. Updates the agent's model and provider, and enqueues a status update.
func (*App) SyncModels ¶ added in v0.4.0
SyncModels updates the model catalog from an external source.
func (*App) SystemPrompt ¶ added in v0.5.0
SystemPrompt returns the current agent's system prompt.
func (*App) ToggleStepMode ¶
ToggleStepMode toggles step mode and returns the new state.
func (*App) UnregisterExtension ¶ added in v0.16.11
UnregisterExtension removes all registrations associated with the named extension. Used by the supervisor when restarting a crashed extension process.
func (*App) WaitForIdle ¶ added in v0.18.0
WaitForIdle blocks until SignalIdle is called or the context is cancelled. Returns immediately if the agent is already idle (missed-signal safe).
func (*App) WriteModelsWithOverrides ¶ added in v0.20.0
func (a *App) WriteModelsWithOverrides(overrides map[string]ModelOverride) (int, error)
WriteModelsWithOverrides regenerates models.yaml from the embedded curated list with API-sourced overrides, writes to disk, and reloads the registry.
type BindOption ¶
type BindOption func(*App)
BindOption configures optional runtime callbacks for sync operations that cannot be expressed as fire-and-forget actions.
func WithCancelBackground ¶ added in v0.4.0
func WithCancelBackground(fn func()) BindOption
WithCancelBackground sets the callback to cancel the running background agent.
func WithIsBackgroundRunning ¶ added in v0.4.0
func WithIsBackgroundRunning(fn func() bool) BindOption
WithIsBackgroundRunning sets the callback to check if a background agent is active.
func WithModelManager ¶ added in v0.4.0
func WithModelManager(mm ModelManager) BindOption
WithModelManager binds the model manager.
func WithRunBackground ¶ added in v0.4.0
func WithRunBackground(fn func(prompt string) error) BindOption
WithRunBackground sets the callback to start a background agent.
func WithSessionManager ¶ added in v0.4.0
func WithSessionManager(sm SessionManager) BindOption
WithSessionManager binds the session manager.
type Command ¶
type Command struct {
Name string
Description string
Handler func(args string, app *App) error
Complete func(prefix string) []string // tab completion; nil = no completion
Immediate bool // if true, executes during streaming without queuing
}
Command is a slash command registered by an extension.
type Compactor ¶ added in v0.5.0
type Compactor struct {
Name string
Threshold int // token threshold for auto-compact; 0 = use config default
Compact func(ctx context.Context, messages []core.Message) ([]core.Message, error)
}
Compactor controls conversation compaction (summarization to save tokens). Register one via App.RegisterCompactor. The Compact function receives all messages and returns the compacted set — giving full control over what to keep and how to summarize.
type EntryInfo ¶ added in v0.18.0
EntryInfo is the ext-layer view of a session entry for display. Mirrors session.EntryInfo without importing session/.
type EventHandler ¶ added in v0.5.0
type EventHandler struct {
Name string
Priority int
// Filter limits which events this handler sees. nil = all events.
Filter func(core.Event) bool
// Handle processes the event. Returns an optional Action to enqueue.
// Return nil for no action.
Handle func(ctx context.Context, evt core.Event) Action
}
EventHandler reacts to agent lifecycle events (Observe primitive). Lower priority runs first. Handle must be fast (<50ms) — return ActionRunAsync for expensive work.
type ExtInfo ¶ added in v0.2.0
type ExtInfo struct {
Name string // human-readable name
Version string // semver or empty
Kind string // "builtin" or "external"
Runtime string // "go", "bun", "node", "python", etc.
Tools []string // tool names registered by this extension
Commands []string // command names registered by this extension
Interceptors []string // interceptor names
EventHandlers []string // event handler names
Shortcuts []string // shortcut keys
MessageHooks []string // message hook names
InputTransformers []string // input transformer names
Compactor string // compactor name, empty if none
PromptSections []string // prompt section titles
StreamProviders []string // stream provider API types (e.g. "openai")
}
ExtInfo describes a loaded extension for /extensions listing.
type Extension ¶
Extension is a function that registers tools, commands, interceptors, etc. Built-in tools and external extensions use the same signature.
type InputTransformer ¶ added in v0.18.0
type InputTransformer struct {
Name string
Priority int // lower = earlier
// Transform receives the raw user input and returns the (possibly modified) text.
// If handled is true, the input was fully consumed — do not send to agent.
Transform func(ctx context.Context, input string) (transformed string, handled bool, err error)
}
InputTransformer intercepts user input before it reaches the agent. Transformers run in priority order (ascending). The first transformer that returns handled=true consumes the input — the agent is not invoked.
type Interceptor ¶
type Interceptor struct {
Name string
Priority int
// Before is called before tool execution.
// Return allow=false to block the tool call.
// Return modified args to transform input.
Before func(ctx context.Context, toolName string, args map[string]any) (allow bool, modifiedArgs map[string]any, err error)
// After is called after tool execution.
// Return modified result to transform output.
After func(ctx context.Context, toolName string, result any) (any, error)
}
Interceptor wraps tool execution with before/after hooks. Higher priority runs first. Use priority 2000+ for security, 1000+ for logging.
type InterruptBehavior ¶ added in v0.17.0
type InterruptBehavior int
InterruptBehavior controls how a tool reacts to steering (mid-turn user input).
const ( // InterruptCancel cancels the tool on steer and discards its result (default). InterruptCancel InterruptBehavior = iota // InterruptBlock keeps the tool running when steered; the steer is queued // for after the tool completes. InterruptBlock )
type MessageHook ¶ added in v0.5.0
type MessageHook struct {
Name string
Priority int
// OnMessage sees the user message before the LLM call.
// Returns additional context to inject for this turn only (ephemeral).
// Empty string = no injection. Error = abort the message.
OnMessage func(ctx context.Context, msg string) (string, error)
}
MessageHook runs before a user message is sent to the LLM. Lower priority runs first (same convention as prompt sections).
type ModelManager ¶ added in v0.4.0
type ModelManager interface {
// Available returns all registered models.
Available() []core.Model
// Switch activates a model by its "provider/id" key.
// Returns the model and a configured streaming provider.
// The implementation handles provider creation and auth.
Switch(id string) (core.Model, core.StreamProvider, error)
// Sync updates the model catalog from an external source (e.g. models.dev).
// Returns the number of models updated.
Sync() (updated int, err error)
// WriteWithOverrides regenerates models.yaml from the embedded curated
// list with the given API overrides, writes it to disk, and reloads.
WriteWithOverrides(overrides map[string]ModelOverride) (int, error)
}
ModelManager provides model operations to commands and extensions. Implemented by the wiring layer which imports provider/ and config/.
type ModelOverride ¶ added in v0.20.0
ModelOverride holds API-sourced values that replace curated defaults.
type PickerItem ¶
PickerItem is an item in a picker/modal list. Used by commands to request a selection UI from the TUI.
type PromptSection ¶
type PromptSection struct {
Title string // section heading (e.g. "Code Style")
Content string // markdown content
Order int // lower = earlier in prompt; default 0
TokenHint int // estimated token count; 0 = unknown
}
PromptSection is a block of text injected into the system prompt. Extensions use this to add instructions, guidelines, or context.
type Renderer ¶
Renderer renders a custom message type for display. expanded controls whether the message is shown in full or collapsed.
type SessionManager ¶ added in v0.4.0
type SessionManager interface {
// List returns all sessions, newest first.
List() ([]SessionSummary, error)
// Load opens a session by path.
// Returns an opaque session handle for ActionSwapSession.
Load(path string) (any, error)
// Fork creates a branch of the current session.
// Returns the parent short ID, forked session handle, message count, and any error.
Fork() (parentID string, forked any, count int, err error)
// Branch moves the current session's leaf to an earlier entry (in-place branching).
// Returns the same session handle for refreshing the TUI/agent.
Branch(entryID string) (session any, err error)
// BranchWithSummary moves the leaf and writes a branch_summary entry.
BranchWithSummary(entryID, summary string) (session any, err error)
// EntryInfos returns info about entries on the current branch for display.
EntryInfos() []EntryInfo
// SetTitle updates the current session's title.
SetTitle(title string) error
// Title returns the current session's title (empty if not set).
Title() string
// AppendEntry writes a custom extension entry to the current session.
// The kind should be namespaced (e.g., "ext:memory:facts").
AppendEntry(kind string, data any) error
// AppendCustomMessage writes a message that persists AND appears in Messages().
// Role must be "user" or "assistant".
AppendCustomMessage(role, content string) error
// AppendLabel sets or clears a bookmark label on a session entry.
// Empty label clears the label.
AppendLabel(targetID, label string) error
// FullTree returns every entry in the session for full DAG rendering.
FullTree() []TreeNode
}
SessionManager provides session operations to commands and extensions. Implemented by the wiring layer (main.go/tui) which imports session/.
type SessionSummary ¶ added in v0.4.0
type SessionSummary struct {
ID string
Path string
Title string
Model string
CWD string
CreatedAt time.Time
Messages int
ParentID string
}
SessionSummary is the ext-layer view of a session. Mirrors session.Summary without importing session/.
type Shortcut ¶
type Shortcut struct {
Key string // e.g. "ctrl+g"
Description string
Handler func(app *App) (Action, error)
}
Shortcut is a keyboard shortcut registered by an extension.
type StatusSection ¶ added in v0.5.0
type StatusSection struct {
Key string // unique key (e.g. "model", "tokens", "cost")
Side StatusSide // left or right side of status bar
Order int // lower = rendered first within the side
}
StatusSection defines an extensible status bar segment. Register via App.RegisterStatusSection. The TUI renders all registered sections sorted by Order within each side (left/right).
type StatusSide ¶ added in v0.5.0
type StatusSide int
StatusSide determines which side of the status bar a section appears on.
const ( StatusLeft StatusSide = iota StatusRight )
type StreamProviderFactory ¶ added in v0.16.11
type StreamProviderFactory func(model core.Model) core.StreamProvider
StreamProviderFactory creates a StreamProvider configured for a specific model. Registered per API type; called each time the agent selects a model served by that API.
type ToolDef ¶
type ToolDef struct {
core.ToolSchema
// Execute runs the tool. Same signature as core.ToolExecuteFn.
Execute func(ctx context.Context, id string, args map[string]any) (*core.ToolResult, error)
// PromptHint is a one-liner injected into the system prompt.
// Example: "Read file contents with line numbers"
PromptHint string
// PromptGuides are bullets injected into the system prompt guidelines.
// Example: ["Use offset/limit for files >2000 lines", "Prefer grep to find content"]
PromptGuides []string
// BackgroundSafe marks this tool as safe for background agent use (read-only).
BackgroundSafe bool
// ConcurrencySafe returns true if this tool call is safe to run concurrently
// with other tool calls. Return false for destructive/mutating operations.
// nil means always safe (default: parallel execution).
ConcurrencySafe func(args map[string]any) bool
// InterruptBehavior controls how this tool reacts to steering.
// InterruptBlock keeps the tool running; InterruptCancel (default) cancels it.
InterruptBehavior InterruptBehavior
// Deferred marks this tool as rarely used. Only name+description sent in API schemas.
// Full schema available via tool_search.
Deferred bool
}
ToolDef extends core.ToolSchema with execution and optional UI rendering.
type TreeNode ¶ added in v0.18.0
type TreeNode struct {
ID string
ParentID string
Type string
Timestamp time.Time
Children int
OnActivePath bool
Depth int
Preview string
Label string
}
TreeNode is the ext-layer view of a full tree node for DAG rendering. Mirrors session.TreeNode without importing session/.