agent

package module
v0.1.4 Latest Latest
Warning

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

Go to latest
Published: Jun 5, 2026 License: MIT Imports: 5 Imported by: 0

Documentation

Overview

Package agent provides the L3 Agent: a stateful, in-memory session manager that owns the transcript, model, tools, and queues. It delegates execution to L2 (AgentLoop) and provides compaction primitives.

The Agent does NOT:

  • Decide when to compact (that's PiCompaction in the App)
  • Call an LLM to generate summaries (that's PiCompaction)
  • Persist the compaction result (that's PiSession)
  • Fire hooks before/after compaction (that's PiHooks)

It only applies the mechanical transformation and emits an event.

Key types:

  • Agent: Prompt, Continue, Abort, Steer, FollowUp, Compact
  • AgentState: model, system prompt, thinking level, tools, messages
  • EventBus: typed subscribe/unsubscribe event dispatch
  • MessageQueue: steering + follow-up queues with DrainAll/DrainOne modes
  • MessageRegistry: runtime message type conversion
  • Compaction: EstimateTokens, ShouldCompact, CompactMessages, Agent.Compact

Layer map:

L0: Protocol       — pure types
L1: LLM Gateway    — depends on protocol
L2: Agent Loop     — depends on protocol only (L1 via StreamFn parameter)
L3: Agent          (this package) — depends on protocol, loop

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CompactMessages

func CompactMessages(messages []protocol.Message, summary string, firstKeptIndex int, tokensBefore int, tokensAfter int, fileOps *protocol.FileOperations) ([]protocol.Message, error)

CompactMessages takes messages, a summary, and a cut point. Returns the compacted message list. No side effects. No LLM call. This is the mechanical part of compaction. Returns an error if firstKeptIndex is out of bounds.

func EstimateTokens

func EstimateTokens(messages []protocol.Message) int

EstimateTokens estimates the token count for a message list. This is a rough heuristic: ~4 characters per token.

func ShouldCompact

func ShouldCompact(messages []protocol.Message, settings CompactionSettings, model protocol.ModelDescriptor) bool

ShouldCompact checks whether compaction is needed based on token count and settings.

Types

type Agent

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

Agent is a stateful, in-memory session manager. It owns the transcript, model, tools, and queues. It delegates execution to L2.

func NewAgent

func NewAgent(config AgentConfig) *Agent

NewAgent creates a new Agent from the given config.

func (*Agent) Abort

func (a *Agent) Abort()

Abort cancels the current run. Callers should call WaitForIdle() after Abort to ensure the run has fully stopped before starting a new one.

func (*Agent) ClearAllQueues

func (a *Agent) ClearAllQueues()

ClearAllQueues removes all queued messages.

func (*Agent) ClearFollowUpQueue

func (a *Agent) ClearFollowUpQueue()

ClearFollowUpQueue removes all follow-up messages.

func (*Agent) ClearSteeringQueue

func (a *Agent) ClearSteeringQueue()

ClearSteeringQueue removes all steering messages.

func (*Agent) Compact

func (a *Agent) Compact(summary string, firstKeptIndex int, tokensBefore int, fileOps *protocol.FileOperations) error

Compact applies compaction to the agent's message list. Emits CompactEvent on the event bus. Returns an error if firstKeptIndex is out of bounds.

func (*Agent) Continue

func (a *Agent) Continue(ctx context.Context) error

Continue continues the loop from the current transcript.

func (*Agent) EventBus

func (a *Agent) EventBus() *EventBus

EventBus returns the agent's event bus for subscribing to events.

func (*Agent) FollowUp

func (a *Agent) FollowUp(msg protocol.Message)

FollowUp enqueues a message to be processed after the agent would otherwise stop.

func (*Agent) HasQueuedMessages

func (a *Agent) HasQueuedMessages() bool

HasQueuedMessages returns true if any messages are queued.

func (*Agent) Prompt

func (a *Agent) Prompt(ctx context.Context, input string, images ...protocol.ImageContent) error

Prompt sends a prompt to the agent and runs the loop until completion.

func (*Agent) Registry

func (a *Agent) Registry() *MessageRegistry

Registry returns the agent's message registry for registering custom message types.

func (*Agent) Reset

func (a *Agent) Reset()

Reset clears the transcript, runtime state, and queued messages.

func (*Agent) SetModel

func (a *Agent) SetModel(model protocol.ModelDescriptor)

SetModel changes the model for subsequent turns.

func (*Agent) SetSystemPrompt

func (a *Agent) SetSystemPrompt(prompt string)

SetSystemPrompt changes the system prompt for subsequent turns.

func (*Agent) SetThinkingLevel

func (a *Agent) SetThinkingLevel(level *protocol.ThinkingLevel)

SetThinkingLevel changes the thinking level for subsequent turns. Pass nil to use the model's DefaultThinkingLevel; pass a non-nil value (including &protocol.ThinkingOff) to explicitly set it.

func (*Agent) SetTools

func (a *Agent) SetTools(tools []loop.AgentTool)

SetTools changes the available tools for subsequent turns.

func (*Agent) State

func (a *Agent) State() AgentState

State returns a copy of the current agent state.

func (*Agent) Steer

func (a *Agent) Steer(msg protocol.Message)

Steer enqueues a message to be injected after the current assistant turn.

func (*Agent) WaitForIdle

func (a *Agent) WaitForIdle()

WaitForIdle blocks until the current run completes.

type AgentConfig

type AgentConfig struct {
	InitialState    *AgentState
	StreamFn        loop.StreamFn
	ConvertToLlm    loop.MessageTransformer
	QueueConfig     *QueueConfig
	SessionID       string
	ThinkingBudgets *protocol.ThinkingBudgets
	Transport       protocol.Transport
	MaxRetryDelayMs *int
	ToolExecution   loop.ToolExecutionPolicy
	BeforeToolCall  func(ctx loop.BeforeToolCallContext, signal <-chan struct{}) *loop.BeforeToolCallResult
	AfterToolCall   func(ctx loop.AfterToolCallContext, signal <-chan struct{}) *loop.AfterToolCallResult
	PrepareNextTurn func(ctx loop.PrepareNextTurnContext) *loop.TurnUpdate
}

AgentConfig configures the creation of an Agent.

type AgentEvent

type AgentEvent struct {
	LoopEvent    *loop.LoopEvent
	CompactEvent *CompactEvent
}

AgentEvent is the union of loop events + agent-specific events.

type AgentState

type AgentState struct {
	SystemPrompt     string
	Model            protocol.ModelDescriptor
	ThinkingLevel    *protocol.ThinkingLevel // nil = use model's DefaultThinkingLevel; non-nil = explicit (including "off")
	Tools            []loop.AgentTool
	Messages         []protocol.Message
	IsStreaming      bool
	StreamingMessage *protocol.AssistantMessage
	PendingToolCalls map[string]bool
	LastError        error
}

AgentState holds the current state of the agent.

func (*AgentState) Copy

func (s *AgentState) Copy() AgentState

Copy returns a shallow copy of the state to prevent external mutation. Note: this is a shallow copy. The Messages and Tools slices are copied, but individual Message and AgentTool values may contain shared mutable data (e.g., maps, slices, or pointers within Tool.Parameters). Callers must not modify individual message or tool values from the copy.

type CompactEvent

type CompactEvent struct {
	Summary      string
	FirstKeptID  string
	TokensBefore int
	TokensAfter  int
	FileOps      *protocol.FileOperations
}

CompactEvent is emitted when compaction is applied to the agent's messages.

type CompactionSettings

type CompactionSettings struct {
	Enabled       bool
	ReserveTokens int // tokens to keep free after compaction
}

CompactionSettings controls when compaction should be triggered.

type DrainMode

type DrainMode int

DrainMode controls how messages are drained from a queue.

const (
	DrainAll DrainMode = iota // drain every queued message at once
	DrainOne                  // drain only the oldest message
)

type EventBus

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

EventBus is a typed, ordered event bus for the agent.

func NewEventBus

func NewEventBus() *EventBus

NewEventBus creates a new event bus.

func (*EventBus) Emit

func (b *EventBus) Emit(event AgentEvent)

Emit sends an event to all listeners in order.

func (*EventBus) Subscribe

func (b *EventBus) Subscribe(listener Listener) func()

Subscribe registers a listener and returns an unsubscribe function.

type Listener

type Listener func(event AgentEvent)

Listener is a function that receives agent events.

type MessageQueue

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

MessageQueue is a thread-safe queue of messages.

func NewMessageQueue

func NewMessageQueue(mode DrainMode) *MessageQueue

NewMessageQueue creates a new message queue.

func (*MessageQueue) Clear

func (q *MessageQueue) Clear()

Clear removes all messages from the queue.

func (*MessageQueue) Drain

func (q *MessageQueue) Drain() []protocol.Message

Drain removes and returns messages from the queue.

func (*MessageQueue) Enqueue

func (q *MessageQueue) Enqueue(msg protocol.Message)

Enqueue adds a message to the queue.

func (*MessageQueue) HasItems

func (q *MessageQueue) HasItems() bool

HasItems returns true if the queue has messages.

type MessageRegistry

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

MessageRegistry replaces declaration merging with an explicit, runtime-validated registry.

func NewMessageRegistry

func NewMessageRegistry() *MessageRegistry

NewMessageRegistry creates a new registry with built-in types pre-registered.

func (*MessageRegistry) Convert

func (r *MessageRegistry) Convert(msg protocol.Message) *protocol.Message

Convert converts a single message to an LLM message (or filters it out).

func (*MessageRegistry) ConvertAll

func (r *MessageRegistry) ConvertAll(messages []protocol.Message) []protocol.Message

ConvertAll converts all messages to LLM messages.

func (*MessageRegistry) Register

func (r *MessageRegistry) Register(role string, converter ToLlmConverter)

Register adds a custom message type with its conversion logic.

func (*MessageRegistry) Roles

func (r *MessageRegistry) Roles() []string

Roles returns all registered message role names.

type QueueConfig

type QueueConfig struct {
	SteeringMode DrainMode
	FollowUpMode DrainMode
}

QueueConfig controls how the steering and follow-up queues drain.

type ToLlmConverter

type ToLlmConverter func(msg protocol.Message) *protocol.Message

ToLlmConverter converts an AgentMessage to an LLM Message. Return nil to filter the message out.

Jump to

Keyboard shortcuts

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