188 lines
6.4 KiB
Go
188 lines
6.4 KiB
Go
package session
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
|
|
"github.com/simonfxr/pubsub"
|
|
"ollie/backend"
|
|
)
|
|
|
|
// WatchField names supported by Core.WaitChange.
|
|
const (
|
|
WatchState = "state"
|
|
WatchUsage = "usage"
|
|
WatchCtxSz = "ctxsz"
|
|
WatchCWD = "cwd"
|
|
WatchAgent = "agent"
|
|
)
|
|
|
|
// ErrInterrupted is returned when the user cancels an agent turn (Ctrl-C).
|
|
var ErrInterrupted = errors.New("interrupted")
|
|
|
|
// Event is a typed output event emitted during an agent turn or in response
|
|
// to a command.
|
|
type Event struct {
|
|
Role string
|
|
Name string
|
|
Content string
|
|
ResponseID string
|
|
}
|
|
|
|
// EventHandler receives events from the agent.
|
|
type EventHandler func(Event)
|
|
|
|
// Session is the interface between a frontend (TUI, HTTP handler, etc.) and the
|
|
// agent engine. All output from the agent is delivered via the event bus.
|
|
type Session interface {
|
|
// Submit processes one line of user input. Slash commands and shell
|
|
// shortcuts are dispatched synchronously; any other input starts an agent
|
|
// turn that publishes events to the bus until the turn is complete.
|
|
// After the turn, any queued prompts are drained sequentially.
|
|
Submit(ctx context.Context, input string)
|
|
|
|
// Interrupt cancels the current in-progress agent turn.
|
|
// Returns true if an action was running and was cancelled.
|
|
Interrupt(cause error) bool
|
|
|
|
// Inject sends a message that will be appended to the next tool result
|
|
// as a user interruption. If no turn is running, it is silently dropped.
|
|
Inject(prompt string)
|
|
|
|
// Queue pushes a prompt onto the FIFO for execution after the current
|
|
// turn completes.
|
|
Queue(prompt string)
|
|
|
|
// Bus returns the session event bus.
|
|
Bus() *pubsub.Bus
|
|
|
|
// PopQueue removes and returns the next queued prompt.
|
|
// Returns ("", false) if the queue is empty.
|
|
PopQueue() (string, bool)
|
|
|
|
// IsRunning returns true if an agent turn is currently in progress.
|
|
IsRunning() bool
|
|
|
|
// State returns the current agent state: "idle", "thinking", or "calling: <tool>".
|
|
State() string
|
|
|
|
// Reply returns the assistant text from the most recently completed turn.
|
|
// Cleared when a new prompt is submitted.
|
|
Reply() string
|
|
|
|
// AgentName returns the name of the active agent.
|
|
AgentName() string
|
|
|
|
// BackendName returns the name of the active backend (e.g. "anthropic", "ollama").
|
|
BackendName() string
|
|
|
|
// ModelName returns the name of the active model.
|
|
ModelName() string
|
|
|
|
// CtxSz returns the estimated context size as a one-line summary.
|
|
CtxSz() string
|
|
|
|
// Usage returns billed token counts as a one-line summary.
|
|
Usage() string
|
|
|
|
// Cost returns per-turn and session cost as a two-line key=value summary.
|
|
Cost() string
|
|
|
|
// ListModels returns available model names, one per line.
|
|
ListModels() string
|
|
|
|
// CWD returns the current working directory used for tool execution.
|
|
CWD() string
|
|
|
|
// SetCWD changes the working directory for tool execution and
|
|
// updates the system prompt. Returns an error if the path does not exist.
|
|
SetCWD(dir string) error
|
|
|
|
// SetSessionID renames the session: updates the in-memory ID, renames
|
|
// persisted files on disk, and propagates to the execute server env.
|
|
SetSessionID(newID string) error
|
|
|
|
// Context returns the current message history as it would be sent to the
|
|
// backend: system prompt prepended, stale reads pruned. Does not include
|
|
// tool definitions (see Tools) or generation params (see GenerationParams).
|
|
Context() []backend.Message
|
|
|
|
// SystemPrompt returns the fully rendered system prompt for this session.
|
|
SystemPrompt() string
|
|
|
|
// GenerationParams returns the current sampling parameters.
|
|
GenerationParams() backend.GenerationParams
|
|
|
|
// SetGenerationParams replaces the current sampling parameters.
|
|
// Returns an error if the agent is currently running.
|
|
SetGenerationParams(params backend.GenerationParams) error
|
|
|
|
// CompactionModel returns the model override used for context compaction.
|
|
CompactionModel() string
|
|
|
|
// SetCompactionModel changes the model used for context compaction.
|
|
SetCompactionModel(model string)
|
|
|
|
// SetEnv injects a session-scoped environment variable into the shell
|
|
// subprocesses. Does not affect the daemon process environment.
|
|
SetEnv(key, value string)
|
|
|
|
// WaitChange blocks until the named field changes from current, then returns
|
|
// the new value. Returns ("", false) if ctx is cancelled before a change.
|
|
// Supported fields: WatchState, WatchUsage, WatchCtxSz, WatchCWD.
|
|
WaitChange(ctx context.Context, field, current string) (string, bool)
|
|
|
|
// ToolCallCount returns the total number of tool calls executed in this
|
|
// session since the agent was created. The counter is monotonically
|
|
// increasing and never resets. Blocked calls (pre-tool hook exit 2) are
|
|
// not counted. Timed-out or erroring calls are counted because execution
|
|
// was attempted. Use modulo arithmetic in hooks to fire every N calls:
|
|
// [ $(($(cat tcct) % 10)) -eq 0 ] && ...
|
|
ToolCallCount() int64
|
|
|
|
// SaveSession writes the current session state to the given path.
|
|
// The file includes all messages, agent/backend/model metadata, and task state.
|
|
SaveSession(path string) error
|
|
|
|
// Close releases resources associated with the session, including its
|
|
// temporary directory under /tmp/ollie/.
|
|
Close()
|
|
|
|
// Detach detaches the currently running process from the agent.
|
|
// The process continues running; returns false if nothing is executing.
|
|
Detach() bool
|
|
|
|
// ListDetached returns info about all detached processes.
|
|
ListDetached() []DetachedInfo
|
|
|
|
// SignalDetached sends a signal to a detached process by PID.
|
|
SignalDetached(pid, signal int) error
|
|
|
|
// GetDetachedOutput returns the ring buffer output for a detached process.
|
|
GetDetachedOutput(pid int) (string, error)
|
|
|
|
// DismissDetached removes an exited process from the list.
|
|
DismissDetached(pid int) bool
|
|
|
|
// InjectSystemEvent appends a system-originated message to the session
|
|
// context and emits it on the event bus. The agent sees it on its next
|
|
// turn; it appears in the chat log immediately.
|
|
InjectSystemEvent(content string)
|
|
|
|
// React records an emoji reaction to the most recent assistant response.
|
|
React(emoji string)
|
|
// ReactTo records an emoji reaction to a specific assistant response.
|
|
ReactTo(responseID, emoji string) error
|
|
// Reactions returns the current response ID to emoji mapping.
|
|
Reactions() map[string]string
|
|
}
|
|
|
|
// DetachedInfo describes a detached process for external consumers.
|
|
type DetachedInfo struct {
|
|
PID int
|
|
Command string
|
|
Started int64 // unix timestamp
|
|
Exited bool
|
|
ExitCode int
|
|
}
|