agent

package
v0.2.12 Latest Latest
Warning

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

Go to latest
Published: Jul 24, 2026 License: MIT Imports: 13 Imported by: 0

Documentation

Overview

Package agent runs the conversation loop: send the history, stream the reply, execute whatever tools the model called, feed the results back, and repeat until the model ends its turn.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func SystemPrompt

func SystemPrompt(now time.Time, workspace, persona, memoryIndex, skillsIndex string) string

SystemPrompt assembles tomo's identity plus whatever memory and skills indexes the caller has. Kept small on purpose: memory topics and skill bodies load on demand, not here. A non-empty persona sets a specialist worker's role on top of the shared identity. A non-empty workspace tells the model where its file and shell tools are rooted, so it stops guessing a home dir.

Types

type Agent

type Agent struct {
	Provider provider.Provider
	Model    string
	System   string
	Tools    *tool.Registry
	Gate     Gate
	// Workspace is the working directory of the file and shell tools. When it
	// is a git repo, the loop uses it to notice a turn that rewrote a test
	// instead of fixing the code and nudge the model back on track. Empty
	// disables that check.
	Workspace string
	// MaxRounds caps the model calls in one turn. Zero means unbounded, the normal
	// mode: the convergence governor, not a fixed length, decides when a productive
	// run ends. A positive value is a hard budget, used to bound a probe or A/B run
	// so the loop stops after a set number of rounds instead of playing out in full.
	MaxRounds int
	// CompactTail sets the recent-window floor for send-time history compaction:
	// the last CompactTail tool-result rounds are always sent verbatim. A coding
	// loop re-sends the whole transcript every round, so a large tool result
	// stays on the wire long after the model has moved past it, and on a provider
	// that does not cache the prefix that re-send is the biggest share of a long
	// run's cost. With CompactBudgetTokens zero, a positive CompactTail elides
	// every result above CompactMinBytes older than the window. With both zero,
	// the default, the full history is sent and the loop behaves exactly as
	// before. The stored transcript is never changed: this shapes only the wire.
	CompactTail int
	// CompactBudgetTokens keys compaction to the model's context length: while
	// the estimated transcript fits the budget nothing is elided, so a short task
	// or a large-context model pays no quality cost; only the overflow is shed,
	// oldest-first. Set it to a fraction of the model's context window, leaving
	// room for the reply and the next few tool results. Zero disables the budget
	// (see CompactTail for unconditional shedding).
	CompactBudgetTokens int
	// CompactMinBytes is the size a tool result must exceed before an older copy
	// of it is elided, so small results a model often refers back to are kept.
	// Zero falls back to defaultCompactMinBytes when compaction is on.
	CompactMinBytes int
}

Agent binds a provider, a toolset, and the policy gate for the turn loop.

func (*Agent) Turn

func (a *Agent) Turn(ctx context.Context, history []provider.Message, user provider.Message, sink Sink) ([]provider.Message, error)

Turn runs one user turn to completion and returns every message it generated, the user message first, so the caller can persist them. On error the messages so far come back too, so a partial turn is not lost.

type Gate

type Gate interface {
	// Allow decides whether a call may run, blocking for approval if needed.
	// When it returns false the reason is fed back to the model as the tool
	// result, so a refusal becomes something the model can work around.
	Allow(ctx context.Context, name string, class tool.Class, input json.RawMessage) (bool, string)
	// Ingested is called after a tool ran so the gate can track taint.
	Ingested(name string, class tool.Class, isErr bool)
}

Gate is the policy check the loop consults before and after every tool run. A nil Gate means allow everything, which is only appropriate for tests.

type Sink

type Sink interface {
	Text(s string)
	ToolStart(name string, input json.RawMessage)
	ToolEnd(name, result string, isErr bool)
}

Sink receives progress while a turn runs: text deltas as they stream and tool activity as it happens. Channels and the REPL implement this.

Jump to

Keyboard shortcuts

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