Documentation
¶
Overview ¶
Package agenttest holds test doubles and helpers for code built on package agent: a scripted model that plays back the turns you give it, so an agent runs with no provider or API key (ScriptedModel, NewScriptedModel, ToolTurn, TextTurn, ErrorTurn); a Store that counts its round trips (CountingStore); and constructors that panic instead of returning an error (MemJournal, MustJournal, MustNew, Must), for tests whose setup cannot fail.
Index ¶
- func Answer(res *agent.Result, err error) (agent.Message, error)
- func IdentityContext(ctx context.Context, id agent.Identity) context.Context
- func MemJournal() *agent.Journal
- func Must[T any](v T, err error) T
- func MustJournal(s agent.Store) *agent.Journal
- func MustNew(model agent.Model, j *agent.Journal, opts ...agent.Option) *agent.Agent
- func NotifyTrailContract(t *testing.T, newStore func() func() agent.NotifyTrail)
- type CountingStore
- func (s *CountingStore) Counts() Counts
- func (s *CountingStore) Get(ctx context.Context, runID, name string) (agent.Entry, bool, error)
- func (s *CountingStore) Insert(ctx context.Context, runID, name string, data []byte) (agent.Entry, bool, error)
- func (s *CountingStore) Load(ctx context.Context, runID string, after int64) iter.Seq2[agent.Entry, error]
- func (s *CountingStore) Reset() Counts
- func (s *CountingStore) Unwrap() agent.Store
- type Counts
- type ScriptedModel
- type ScriptedTurn
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Answer ¶ added in v0.11.0
Answer returns the answer of a run's Result and the run's error, as the string entry points returned them: Answer(a.Run(ctx, runID, agent.UserText(input))). A nil Result (a run ID that fails agent.ValidateRunID, or a session turn refused before it starts) has the zero Message.
func IdentityContext ¶ added in v0.11.0
IdentityContext returns ctx carrying id as the acting identity, as a run binds its WithIdentity option for its tool calls: for a test that calls a tool directly, outside a run, and checks what it does with agent.IdentityFrom.
func MemJournal ¶ added in v0.11.0
MemJournal returns a Journal over a new, empty agent.MemStore.
func Must ¶ added in v0.11.0
Must returns v, and panics with err if it is not nil: Must(agent.NewJournal(s)), say, in a test whose setup cannot fail.
func MustJournal ¶ added in v0.11.0
MustJournal returns agent.NewJournal(s), and panics if that fails (a nil store).
func MustNew ¶ added in v0.11.0
MustNew returns agent.New(model, j, opts...), and panics if it fails.
func NotifyTrailContract ¶ added in v0.16.0
func NotifyTrailContract(t *testing.T, newStore func() func() agent.NotifyTrail)
NotifyTrailContract runs the agent.NotifyTrail contract. newStore returns a new, empty store as a function that returns a view of it: every call of the function is a NotifyTrail over the same store, as two processes' would be, so the concurrent case races views.
Types ¶
type CountingStore ¶
type CountingStore struct {
// contains filtered or unexported fields
}
CountingStore wraps a Store and counts the round trips it serves, for tests that hold the engine to a budget of store calls per operation. It passes run IDs and names through unchanged, so it implements Unwrap, and agent.Capability finds the wrapped store's Lister and Leaser through it (their calls are not counted).
func NewCountingStore ¶
func NewCountingStore(inner agent.Store) *CountingStore
NewCountingStore returns a CountingStore over inner.
func (*CountingStore) Counts ¶
func (s *CountingStore) Counts() Counts
Counts returns the counts so far.
func (*CountingStore) Insert ¶
func (s *CountingStore) Insert(ctx context.Context, runID, name string, data []byte) (agent.Entry, bool, error)
Insert implements agent.Store.
func (*CountingStore) Load ¶
func (s *CountingStore) Load(ctx context.Context, runID string, after int64) iter.Seq2[agent.Entry, error]
Load implements agent.Store.
func (*CountingStore) Reset ¶
func (s *CountingStore) Reset() Counts
Reset zeroes the counts and returns the ones it cleared.
func (*CountingStore) Unwrap ¶
func (s *CountingStore) Unwrap() agent.Store
Unwrap returns the wrapped store.
type Counts ¶
type Counts struct {
Insert, Get, Load int
// Inserted is how many Inserts stored their entry (the rest found one already there).
Inserted int
// EntriesRead is how many entries every Load yielded, in all.
EntriesRead int
// Names lists the name of every Insert and Get, in order, as "insert <name>" or "get <name>".
Names []string
}
Counts is how many round trips a CountingStore served, and how many entries its Loads yielded.
type ScriptedModel ¶ added in v0.11.0
type ScriptedModel struct {
// contains filtered or unexported fields
}
ScriptedModel is a deterministic, LLM-free Model that replays a fixed script of turns, one turn per model call. It is the batteries-included version of the model fakes people otherwise reverse-engineer from agent.ToolCallDelta + agent.Finish for tests, examples, and local dev, so you can drive the whole agent loop offline.
It is replay-safe: it selects the turn to emit by counting the assistant messages already in the request, not by an internal cursor. On a durable resume the agent loop replays journaled assistant turns without calling the model, so a cursor would drift; counting the transcript instead lines the script back up with the live turn every time, including after a crash and re-run. Once the script is exhausted it repeats its last turn, so an over-long conversation does not panic.
Build turns with ToolTurn, TextTurn, and ErrorTurn:
m := agenttest.NewScriptedModel(
agenttest.ToolTurn("call-1", "lookup", `{"q":"weather"}`),
agenttest.TextTurn("it is sunny"),
)
a, err := agent.New(m, j, agent.WithTools(lookupTool))
...
res, err := a.Run(ctx, "run-1", agent.UserText("what's the weather?"))
A ScriptedModel is safe for the sequential agent loop; it is not intended for concurrent Stream calls from multiple runs at once.
func NewScriptedModel ¶ added in v0.11.0
func NewScriptedModel(turns ...ScriptedTurn) *ScriptedModel
NewScriptedModel builds a ScriptedModel that replays turns in order, one per model call.
type ScriptedTurn ¶ added in v0.11.0
type ScriptedTurn struct {
// contains filtered or unexported fields
}
ScriptedTurn is one scripted model output. Construct one with ToolTurn, TextTurn, or ErrorTurn rather than building it directly.
func ErrorTurn ¶ added in v0.11.0
func ErrorTurn(err error) ScriptedTurn
ErrorTurn scripts a turn that fails the model call with err, so a test can exercise the loop's error path (a mid-run "crash" before the next step is journaled, say).
func TextTurn ¶ added in v0.11.0
func TextTurn(text string) ScriptedTurn
TextTurn scripts a turn in which the model emits a final text answer, ending the run.
func ToolTurn ¶ added in v0.11.0
func ToolTurn(id, name, args string) ScriptedTurn
ToolTurn scripts a turn in which the model calls one tool: id is the tool-use ID the journal keys the call under, name is the tool, and args is its JSON arguments.