Documentation
¶
Overview ¶
Package engine drives the agent loop: send messages → consume the streamed response → execute requested tools → loop until the model stops on its own.
Two surfaces:
- Run executes one task to completion in a fresh conversation. Use this for `agent run` and other one-shot callers.
- Session keeps message history across calls. Use this for `agent chat` or any caller that needs multi-turn memory.
Index ¶
- Constants
- func Run(ctx context.Context, cfg Config, task string) error
- type Config
- type PolicyViolationError
- type Session
- func (s *Session) LastInputTokens() int
- func (s *Session) Messages() []llm.Message
- func (s *Session) Model() string
- func (s *Session) Reset()
- func (s *Session) RestoreMessages(msgs []llm.Message)
- func (s *Session) SetModel(p llm.Provider, model string)
- func (s *Session) SetSystem(system string)
- func (s *Session) SetUsage(u llm.Usage)
- func (s *Session) Step(ctx context.Context, task string) error
- func (s *Session) Truncate(maxExchanges int)
- func (s *Session) Usage() llm.Usage
Constants ¶
const ( // DefaultMaxTurns caps tool-use loops. A productive agent rarely needs more // than a handful; this exists to stop runaway loops eating tokens forever. DefaultMaxTurns = 15 // DefaultContextBudget is the default context window size when not specified. // 128K is a conservative default that works for most models. DefaultContextBudget = 128_000 // DefaultCompactionThreshold is the percentage of context budget at which // auto-compaction triggers. 80% leaves room for the response. DefaultCompactionThreshold = 80 // DefaultCompactionTarget is the percentage of context budget to compact to. // 50% provides headroom for continued conversation. DefaultCompactionTarget = 50 // DefaultMaxConcurrentTools limits how many tools can run simultaneously. // This prevents resource exhaustion when a model requests many tool calls. // 10 is a reasonable balance between parallelism and resource usage. DefaultMaxConcurrentTools = 10 )
Default configuration values. These can be overridden via Config fields.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type Config ¶
type Config struct {
Provider llm.Provider
Model string
System string
Tools *tools.Registry
Temperature *float64
MaxTokens int
// PIIGuard scans outgoing messages for PII and redacts/warns.
// nil means no PII scanning.
PIIGuard *tools.PIIGuard
// MaxContextTokens is the model's context window size. When estimated
// input tokens exceed 80% of this, the session auto-compacts. Zero
// means use a conservative default (128K).
MaxContextTokens int
// FallbackModels is a list of "provider/model" strings to try when
// the primary model returns a rate-limit (429) or overload error.
// Tried in order; the session switches to the first one that works.
FallbackModels []string
// ResolveModel resolves a "provider/model" string into a Provider and
// bare model name. Required when FallbackModels is set. Typically
// wired to llm.Resolve.
ResolveModel func(model string) (llm.Provider, string, error)
// ResponseSchema constrains the model to produce valid JSON matching
// this schema. Nil means unconstrained text output.
ResponseSchema json.RawMessage
// Out receives streamed assistant text. nil means discard.
Out io.Writer
// Status receives tool-call indicators ("→ shell ls", "← 12 lines").
// nil means discard. Typically wired to stderr.
Status io.Writer
// MaxTurns bounds the tool-use loop within a single Step. Zero uses
// defaultMaxTurns.
MaxTurns int
// ToolConfirm is called before executing any destructive tool.
// Return true to proceed, false to skip. Nil means auto-approve.
ToolConfirm func(ctx context.Context, toolName string, input json.RawMessage) (bool, error)
// PolicyCheck runs before any tool execution. Returning a non-empty
// deny reason blocks execution and fails the current step.
PolicyCheck func(ctx context.Context, toolName string, input json.RawMessage) (denyReason string, err error)
// ContinueConfirm is called when MaxTurns is reached. Return true
// to continue for another MaxTurns rounds, false to stop.
// Nil means stop immediately.
ContinueConfirm func(ctx context.Context, turns int) (bool, error)
// ErrorIntervention is called when a tool execution fails. The callback
// receives the tool name and the error message. It may return a hint
// string that is appended to the error sent back to the LLM, helping
// steer the model away from repeated failures. Return "" to let the
// model retry on its own. Nil means no intervention (original behavior).
ErrorIntervention func(ctx context.Context, toolName string, errMsg string) string
// MaxConcurrentTools limits how many tools can run simultaneously.
// Zero uses DefaultMaxConcurrentTools. This prevents resource exhaustion
// when a model requests many tool calls in a single turn.
MaxConcurrentTools int
// Audit receives structured metadata events. Nil means disabled.
Audit ports.AuditSink
// AuditSessionID groups events for one run/chat session.
AuditSessionID string
}
Config configures a Run or Session. The zero value is not usable: Provider and Model must be set.
type PolicyViolationError ¶ added in v0.1.1
PolicyViolationError is returned when policy denies a tool call.
func (*PolicyViolationError) Error ¶ added in v0.1.1
func (e *PolicyViolationError) Error() string
type Session ¶
type Session struct {
// contains filtered or unexported fields
}
Session is a stateful, multi-turn conversation driver. Step appends a user turn and runs the engine loop; the resulting message history is retained on the Session and reused on subsequent Steps.
func NewSession ¶
NewSession constructs a Session. It validates required Config fields lazily on the first Step call (so a Session can be built before all dependencies are wired, e.g. in tests).
func (*Session) LastInputTokens ¶
LastInputTokens returns the input_tokens from the most recent provider call. This approximates the current context window consumption.
func (*Session) Messages ¶
Messages returns a snapshot of the rolling history. The outer slice and each Message's Content slice are fresh copies; the ContentBlock values themselves (and any contained byte slices) are shared, so callers shouldn't mutate field-level data either.
func (*Session) Reset ¶
func (s *Session) Reset()
Reset clears the conversation history. Tool registry and provider remain configured.
func (*Session) RestoreMessages ¶
RestoreMessages replaces the message history with saved messages. Used to resume a previous session from persistent storage.
func (*Session) SetModel ¶
SetModel hot-swaps the provider and model for subsequent Steps. Existing message history is preserved.
func (*Session) SetSystem ¶ added in v0.1.0
SetSystem replaces the system prompt for subsequent Steps.
func (*Session) Step ¶
Step appends task as a user turn and runs the engine loop until the model stops naturally (or hits MaxTurns). The assistant's response streams to s.cfg.Out; full message turns are appended to the history.
func (*Session) Truncate ¶
Truncate keeps at most the last maxExchanges user-initiated exchanges. A user-initiated exchange begins at a user message containing only text blocks (i.e., not a tool_result-bearing follow-up). All messages from that point through the next exchange-start are retained as a unit, so an assistant turn's tool_use is never split from its matching tool_result. maxExchanges <= 0 is a no-op.