agent

import "github.com/goppydae/sharur/internal/agent"

Package agent provides the stateful agent with transcript, tools, and events.

Index

Constants

const (
    ThinkingOff    = types.ThinkingOff
    ThinkingLow    = types.ThinkingLow
    ThinkingMedium = types.ThinkingMedium
    ThinkingHigh   = types.ThinkingHigh
)

const SUMMARIZATION_PROMPT = `The messages above are a conversation to summarize. Create a structured context checkpoint summary that another LLM will use to continue the work.

Start your response with the exact string: <!-- sharur-summary -->

Then use this EXACT format:

## Goal
[What is the user trying to accomplish? Can be multiple items if the session covers different tasks.]

## Constraints & Preferences
- [Any constraints, preferences, or requirements mentioned by user]
- [Or "(none)" if none were mentioned]

## Progress
### Done
- [x] [Completed tasks/changes]

### In Progress
- [ ] [Current work]

### Blocked
- [Issues preventing progress, if any]

## Key Decisions
- **[Decision]**: [Brief rationale]

## Next Steps
1. [Ordered list of what should happen next]

## Critical Context
- [Any data, examples, or references needed to continue]
- [Or "(none)" if not applicable]

Keep each section concise. Preserve exact file paths, function names, and error messages.`

const TURN_PREFIX_SUMMARIZATION_PROMPT = `This is the PREFIX of a turn that was too large to keep. The SUFFIX (recent work) is retained.

Summarize the prefix to provide context for the retained suffix:

## Original Request
[What did the user ask for in this turn?]

## Early Progress
- [Key decisions and work done in the prefix]

## Context for Suffix
- [Information needed to understand the retained recent work]

Be concise. Focus on what's needed to understand the kept suffix.`

const UPDATE_SUMMARIZATION_PROMPT = `The messages above are NEW conversation messages to incorporate into the existing summary provided in <previous-summary> tags.

Start your response with the exact string: <!-- sharur-summary -->

Update the existing structured summary with new information. RULES:
- PRESERVE all existing information from the previous summary
- ADD new progress, decisions, and context from the new messages
- UPDATE the Progress section: move items from "In Progress" to "Done" when completed
- UPDATE "Next Steps" based on what was accomplished
- PRESERVE exact file paths, function names, and error messages
- If something is no longer relevant, you may remove it

Use this EXACT format:

## Goal
[Preserve existing goals, add new ones if the task expanded]

## Constraints & Preferences
- [Preserve existing, add new ones discovered]

## Progress
### Done
- [x] [Include previously done items AND newly completed items]

### In Progress
- [ ] [Current work - update based on progress]

### Blocked
- [Current blockers - remove if resolved]

## Key Decisions
- **[Decision]**: [Brief rationale] (preserve all previous, add new)

## Next Steps
1. [Update based on current state]

## Critical Context
- [Preserve important context, add new if needed]

Keep each section concise. Preserve exact file paths, function names, and error messages.`

func EstimateMessageTokens

func EstimateMessageTokens(m Message) int

type Agent

Agent owns the transcript, emits events, and executes tools.

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

func New

func New(provider llm.Provider, registry *tools.ToolRegistry) *Agent

New creates a new agent with the given provider and tools.

func (*Agent) Abort

func (a *Agent) Abort()

Abort signals the agent to stop the current turn.

func (*Agent) Compact

func (a *Agent) Compact(ctx context.Context, keepRecentTokens int)

Compact trims the transcript to stay within approximate token budgets. It implements a pi-mono style summarization and file tracking strategy.

func (*Agent) Continue

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

Continue asks the agent to continue generating.

func (*Agent) EstimateContextTokens

func (a *Agent) EstimateContextTokens() int

EstimateContextTokens returns the estimated total tokens in the current context.

func (*Agent) EventBus

func (a *Agent) EventBus() *events.EventBus

EventBus returns the event bus.

func (*Agent) FollowUp

func (a *Agent) FollowUp(text string, images ...Image)

FollowUp queues a follow-up message to be processed after the agent finishes.

func (*Agent) GetInfo

func (a *Agent) GetInfo() llm.ProviderInfo

GetInfo returns the current model’s provider info.

func (*Agent) GetSession

func (a *Agent) GetSession() *types.Session

GetSession returns a copy of the current session types.

func (*Agent) GetStats

func (a *Agent) GetStats() AgentStats

GetStats returns token usage statistics from the agent’s events.

func (*Agent) Idle

func (a *Agent) Idle() <-chan struct{}

Idle returns a channel that closes when the agent is idle.

func (*Agent) InvokeTool

func (a *Agent) InvokeTool(ctx context.Context, name string, args string) error

InvokeTool manually triggers a tool call as if it came from the assistant. It executes the tool, records the result, and then starts the agent loop to allow the LLM to react to the invocation.

func (*Agent) IsRunning

func (a *Agent) IsRunning() bool

IsRunning reports whether the agent is currently processing.

func (*Agent) LifecycleState

func (a *Agent) LifecycleState() string

LifecycleState returns the current lifecycle state as a string.

func (*Agent) Messages

func (a *Agent) Messages() []Message

Messages returns a copy of the conversation messages.

func (*Agent) Prompt

func (a *Agent) Prompt(ctx context.Context, text string, images ...Image) error

Prompt sends a user message and runs the agent loop until idle.

func (*Agent) Reset

func (a *Agent) Reset()

Reset clears the conversation history and queues.

func (*Agent) ResetSession

func (a *Agent) ResetSession(id string)

ResetSession clears messages, queues and creates a fresh session ID.

func (*Agent) Session

func (a *Agent) Session() *session.Session

Session returns the current session object.

func (*Agent) SetCompactionConfig

func (a *Agent) SetCompactionConfig(enabled bool, reserve, keepRecent int)

SetCompactionConfig updates the compaction settings.

func (*Agent) SetDryRun

func (a *Agent) SetDryRun(dry bool)

SetDryRun sets the agent’s dry-run mode.

func (*Agent) SetExtensions

func (a *Agent) SetExtensions(exts []Extension)

SetExtensions sets the active extensions for the agent.

func (*Agent) SetMaxTokens

func (a *Agent) SetMaxTokens(n int)

SetMaxTokens sets the maximum tokens for LLM responses.

func (*Agent) SetModel

func (a *Agent) SetModel(model string)

SetModel sets the model name and records it in the session if manager is present.

func (*Agent) SetProvider

func (a *Agent) SetProvider(provider llm.Provider)

SetProvider sets the LLM provider and records it in the session if manager is present.

func (*Agent) SetSession

func (a *Agent) SetSession(mgr *session.Manager, sess *session.Session)

SetSession attaches a session manager and session to the agent.

func (*Agent) SetSessionName

func (a *Agent) SetSessionName(name string)

SetSessionName sets a human-readable name for the current session.

func (*Agent) SetSystemPrompt

func (a *Agent) SetSystemPrompt(prompt string)

SetSystemPrompt updates the system prompt.

func (*Agent) SetThinkingLevel

func (a *Agent) SetThinkingLevel(level ThinkingLevel)

SetThinkingLevel sets the thinking level and records it in the session if manager is present.

func (*Agent) State

func (a *Agent) State() *AgentState

State returns a copy of the current agent state.

func (*Agent) Steer

func (a *Agent) Steer(text string, images ...Image)

Steer queues a steering message to be injected as soon as the current tool execution finishes.

func (*Agent) Subscribe

func (a *Agent) Subscribe(fn func(Event)) func()

Subscribe registers an event listener and returns an unsubscribe function.

func (*Agent) ToolRegistry

func (a *Agent) ToolRegistry() *tools.ToolRegistry

ToolRegistry returns the tool registry.

type AgentState

AgentState holds the full state of an agent instance.

type AgentState struct {
    Session       Session       `json:"session"`
    SystemPrompt  string        `json:"systemPrompt"`
    Messages      []Message     `json:"messages"`
    SteerQueue    []Message     `json:"steerQueue,omitempty"`
    FollowUpQueue []Message     `json:"followUpQueue,omitempty"`
    Tools         []ToolInfo    `json:"tools,omitempty"`
    Model         string        `json:"model"`
    Provider      string        `json:"provider"`
    Thinking      ThinkingLevel `json:"thinkingLevel"`
    MaxTokens     int           `json:"maxTokens,omitempty"`
    Temperature   float64       `json:"temperature,omitempty"`
    DryRun        bool          `json:"dryRun,omitempty"`
    Compaction    struct {
        Enabled          bool `json:"enabled"`
        ReserveTokens    int  `json:"reserveTokens"`
        KeepRecentTokens int  `json:"keepRecentTokens"`
    }   `json:"compaction"`
    LatestCompaction *types.CompactionState `json:"latestCompaction,omitempty"`
}

type AgentStats

AgentStats holds session statistics.

type AgentStats struct {
    SessionID      string
    ParentID       string
    SessionFile    string
    Name           string
    CreatedAt      time.Time
    UpdatedAt      time.Time
    Model          string
    Provider       string
    Thinking       string
    UserMessages   int
    AssistantMsgs  int
    ToolCalls      int
    ToolResults    int
    TotalMessages  int
    InputTokens    int
    OutputTokens   int
    CacheRead      int
    CacheWrite     int
    TotalTokens    int
    ContextTokens  int
    ContextWindow  int
    Cost           float64
    QueuedSteer    int
    QueuedFollowUp int
}

type CompactionPrep

CompactionPrep describes the state passed to BeforeCompact.

type CompactionPrep struct {
    MessageCount    int
    EstimatedTokens int
    PreviousSummary string
}

type CompactionResult

CompactionResult can be returned by BeforeCompact to provide a custom summary and skip the default LLM-based summarization.

type CompactionResult struct {
    Summary          string
    FirstKeptEntryID string
}

type Event

Event represents an agent lifecycle event.

type Event struct {
    Type     EventType
    Content  string
    ToolCall *ToolCall
    Usage    *llm.Usage
    Error    error
    // ToolOutput stores the result content of a tool execution.
    // Emitted when type is EventToolOutput.
    ToolOutput *ToolOutput
    // StateChange holds details of a lifecycle state transition.
    // Emitted when type is EventStateChange.
    StateChange *StateTransition
    // Value stores a numeric value (e.g. token count).
    // Emitted when type is EventTokens.
    Value int64
}

type EventType

EventType identifies the kind of agent event.

type EventType string

const (
    EventAgentStart    EventType = "agent_start"
    EventTurnStart     EventType = "turn_start"
    EventMessageStart  EventType = "message_start"
    EventTextDelta     EventType = "text_delta"
    EventThinkingDelta EventType = "thinking_delta"
    EventToolCall      EventType = "tool_call"
    EventToolDelta     EventType = "tool_delta"
    EventToolOutput    EventType = "tool_output"
    EventMessageEnd    EventType = "message_end"
    EventAgentEnd      EventType = "agent_end"
    EventError         EventType = "error"
    EventAbort         EventType = "abort"
    EventQueueUpdate   EventType = "queue_update"
    EventCompactStart  EventType = "compact_start"
    EventCompactEnd    EventType = "compact_end"
    EventStateChange   EventType = "state_change"
    EventTokens        EventType = "tokens"
    EventHeartbeat     EventType = "heartbeat"
)

type Extension

Extension is the unified interface for all extensions (gRPC plugins, Markdown Skills, etc.)

type Extension interface {
    // Name returns the extension's unique identifier.
    Name() string

    // Tools returns additional tools to register with the agent.
    Tools() []tools.Tool

    // BeforePrompt is called before each LLM request.
    // Return a modified state to change the request.
    BeforePrompt(ctx context.Context, state *AgentState) *AgentState

    // BeforeToolCall is called before each tool execution.
    // Return (result, true) to intercept and prevent the tool from running.
    // Return (nil, false) to allow normal execution.
    BeforeToolCall(ctx context.Context, call *ToolCall, args json.RawMessage) (*tools.ToolResult, bool)

    // AfterToolCall is called after each tool call completes.
    // Return a modified result to change the outcome.
    AfterToolCall(ctx context.Context, call *ToolCall, result *tools.ToolResult) *tools.ToolResult

    // ModifySystemPrompt is called to augment the system prompt.
    ModifySystemPrompt(prompt string) string

    // SessionStart is called when a session is attached or the first prompt begins.
    SessionStart(ctx context.Context, sessionID string, reason SessionStartReason)

    // SessionEnd is called when a session is reset or the agent is torn down.
    SessionEnd(ctx context.Context, sessionID string, reason SessionEndReason)

    // AgentStart is called when the agent begins processing a user prompt.
    AgentStart(ctx context.Context)

    // AgentEnd is called when the agent loop finishes (success, error, or abort).
    AgentEnd(ctx context.Context)

    // TurnStart is called at the start of each LLM request turn.
    TurnStart(ctx context.Context)

    // TurnEnd is called after each turn's tool calls have been processed.
    TurnEnd(ctx context.Context)

    // ModifyInput is called with raw user input before it is added to the transcript.
    // Return InputHandled to consume the message without further processing.
    // Return InputTransform to replace the text.
    // Return InputContinue (or zero value) to proceed unchanged.
    ModifyInput(ctx context.Context, text string) InputResult

    // ModifyContext is called with the message slice just before building each LLM
    // request. The returned slice replaces what is sent to the LLM (not the stored
    // transcript). Extensions are chained; each receives the previous result.
    ModifyContext(ctx context.Context, messages []types.Message) []types.Message

    // BeforeProviderRequest is called with the assembled CompletionRequest before
    // it is sent to the LLM provider. Return a modified copy to alter the request.
    BeforeProviderRequest(ctx context.Context, req *llm.CompletionRequest) *llm.CompletionRequest

    // AfterProviderResponse is called after the LLM stream is fully consumed.
    AfterProviderResponse(ctx context.Context, content string, numToolCalls int)

    // BeforeCompact is called before the compaction summarization LLM call.
    // Return a non-nil *CompactionResult to provide a custom summary and skip the
    // default LLM-based summarization entirely.
    BeforeCompact(ctx context.Context, prep CompactionPrep) *CompactionResult

    // AfterCompact is called after compaction completes.
    AfterCompact(ctx context.Context, freedTokens int)
}

type Image

Image is an alias for types.Image.

type Image = types.Image

type InputAction

InputAction controls how ModifyInput’s result is applied.

type InputAction string

const (
    // InputContinue passes the original text through unchanged.
    InputContinue InputAction = "continue"
    // InputTransform replaces the user text with InputResult.Text.
    InputTransform InputAction = "transform"
    // InputHandled marks the input as consumed; the message is not appended to the transcript.
    InputHandled InputAction = "handled"
)

type InputResult

InputResult is returned by ModifyInput to describe how to process the user input.

type InputResult struct {
    Action InputAction
    Text   string
}

type LifecycleState

LifecycleState identifies the current operational state of the agent.

type LifecycleState string

const (
    StateIdle       LifecycleState = "idle"
    StateThinking   LifecycleState = "thinking"
    StateExecuting  LifecycleState = "executing"
    StateCompacting LifecycleState = "compacting"
    StateAborting   LifecycleState = "aborting"
    StateError      LifecycleState = "error"
)

type Message

Message is an alias for types.Message.

type Message = types.Message

type NoopExtension

NoopExtension is an extension that does nothing — useful as a base embed.

type NoopExtension struct {
    NameStr string
}

func (*NoopExtension) AfterCompact

func (n *NoopExtension) AfterCompact(_ context.Context, _ int)

func (*NoopExtension) AfterProviderResponse

func (n *NoopExtension) AfterProviderResponse(_ context.Context, _ string, _ int)

func (*NoopExtension) AfterToolCall

func (n *NoopExtension) AfterToolCall(_ context.Context, _ *ToolCall, result *tools.ToolResult) *tools.ToolResult

func (*NoopExtension) AgentEnd

func (n *NoopExtension) AgentEnd(_ context.Context)

func (*NoopExtension) AgentStart

func (n *NoopExtension) AgentStart(_ context.Context)

func (*NoopExtension) BeforeCompact

func (n *NoopExtension) BeforeCompact(_ context.Context, _ CompactionPrep) *CompactionResult

func (*NoopExtension) BeforePrompt

func (n *NoopExtension) BeforePrompt(_ context.Context, state *AgentState) *AgentState

func (*NoopExtension) BeforeProviderRequest

func (n *NoopExtension) BeforeProviderRequest(_ context.Context, req *llm.CompletionRequest) *llm.CompletionRequest

func (*NoopExtension) BeforeToolCall

func (n *NoopExtension) BeforeToolCall(_ context.Context, _ *ToolCall, _ json.RawMessage) (*tools.ToolResult, bool)

func (*NoopExtension) ModifyContext

func (n *NoopExtension) ModifyContext(_ context.Context, messages []types.Message) []types.Message

func (*NoopExtension) ModifyInput

func (n *NoopExtension) ModifyInput(_ context.Context, _ string) InputResult

func (*NoopExtension) ModifySystemPrompt

func (n *NoopExtension) ModifySystemPrompt(prompt string) string

func (*NoopExtension) Name

func (n *NoopExtension) Name() string

func (*NoopExtension) SessionEnd

func (n *NoopExtension) SessionEnd(_ context.Context, _ string, _ SessionEndReason)

func (*NoopExtension) SessionStart

func (n *NoopExtension) SessionStart(_ context.Context, _ string, _ SessionStartReason)

func (*NoopExtension) Tools

func (n *NoopExtension) Tools() []tools.Tool

func (*NoopExtension) TurnEnd

func (n *NoopExtension) TurnEnd(_ context.Context)

func (*NoopExtension) TurnStart

func (n *NoopExtension) TurnStart(_ context.Context)

type Session

Session is an alias for types.Session.

type Session = types.Session

type SessionEndReason

SessionEndReason identifies why a session is ending.

type SessionEndReason string

const (
    SessionEndReset SessionEndReason = "reset"
)

type SessionStartReason

SessionStartReason identifies why a session is starting.

type SessionStartReason string

const (
    SessionStartNew    SessionStartReason = "new"
    SessionStartResume SessionStartReason = "resume"
)

type StateMachine

StateMachine manages agent states and transitions.

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

func NewStateMachine

func NewStateMachine(initial LifecycleState, onTransition func(StateTransition)) *StateMachine

NewStateMachine creates a new state machine.

func (*StateMachine) Current

func (s *StateMachine) Current() LifecycleState

Current returns the current lifecycle state.

func (*StateMachine) Transition

func (s *StateMachine) Transition(to LifecycleState) error

Transition moves the state machine to a new state.

type StateTransition

StateTransition represents a transition between two states.

type StateTransition struct {
    From LifecycleState
    To   LifecycleState
}

type ThinkingLevel

ThinkingLevel is an alias for types.ThinkingLevel.

type ThinkingLevel = types.ThinkingLevel

type ToolCall

ToolCall is an alias for types.ToolCall.

type ToolCall = types.ToolCall

type ToolInfo

ToolInfo is an alias for types.ToolInfo.

type ToolInfo = types.ToolInfo

type ToolOutput

ToolOutput is an alias for types.ToolOutput.

type ToolOutput = types.ToolOutput

Generated by gomarkdoc