Documentation
¶
Overview ¶
Package loop is a controllable agent loop for CloudWeGo Eino, in an interface-first, nested shape. Read in this order:
loop.go the public Loop: what a caller can do wire.go which concrete type fills each role internal/engine/run.go the loop itself, and every role it needs then any internal package wire.go names
Index ¶
- Constants
- func NewToolInfo(name, desc string, params map[string]any) (*schema.ToolInfo, error)
- type CallOptionsBuilder
- type Config
- type ConfigChange
- type CostEstimator
- type ErrorClassifier
- type EventSink
- type HistoryCompactor
- type Loop
- func (l *Loop) Events() <-chan event.Event
- func (l *Loop) Inject(message string) bool
- func (l *Loop) Iteration() int
- func (l *Loop) Messages() []*schema.Message
- func (l *Loop) ModifyConfig(c ConfigChange) bool
- func (l *Loop) Result() (event.DoneData, bool)
- func (l *Loop) Start(ctx context.Context, messages []*schema.Message) <-chan event.Event
- func (l *Loop) State() State
- func (l *Loop) Stop()
- func (l *Loop) Wait()
- type ModelIdentifier
- type ReflectCondition
- type State
- type StopCondition
- type ToolExecutor
Constants ¶
const ( StateIdle = state.Idle StateRunning = state.Running StateDone = state.Done StateStopped = state.Stopped StateError = state.Error )
const FinishToolName = "finish"
FinishToolName is the reserved tool that ends a StopOnFinishTool run. Its arguments become DoneData.FinalContent. It never reaches the ToolExecutor.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type CallOptionsBuilder ¶
CallOptionsBuilder builds the per-call model options. Default: temperature only.
type Config ¶
type Config struct {
MaxIterations int // cap on model calls; the loop never exceeds it
StopCondition StopCondition // when the loop ends on its own
Temperature float64 // below 0: not sent, so the provider's default applies
IterationTimeout time.Duration // bound on one model call; zero: none
TotalTimeout time.Duration // bound on the whole run; zero: none
Reflect ReflectCondition // zero: off; reviews never count toward MaxIterations
IterationReviewPrompt string // ReflectOnIteration judge; empty: built-in
FinishReviewPrompt string // ReflectOnFinish judge; empty: built-in
MaxReopens int // ReflectOnFinish: re-opens after drift; zero: 1
StreamEvents bool // false: only error and done events
EventBuffer int // event channel capacity; zero: 64
EventSink EventSink // optional
DoneDeliveryGrace time.Duration // wait for a reader of the done event; zero: 5s
Pauses map[string]pause.Handler // tool name → handler, in place of the ToolExecutor
StopInstructions string // instructions for the stop condition
AutoNudgeText string // sent after a text-only reply in StopOnFinishTool; empty: built-in
DisableAutoNudge bool
RetryMaxAttempts int // extra attempts after a transient failure; zero: 1; -1: none
ErrorClassifier ErrorClassifier
DisableStreaming bool // call Generate instead of Stream
IdleChunkTimeout time.Duration // longest gap between streamed chunks; zero: 30s
DisableIterationTimeoutDecoupling bool // each call inherits the run's remaining time
HistoryCompactor HistoryCompactor
CallOptions CallOptionsBuilder
ModelIdentity ModelIdentifier
CostEstimator CostEstimator
TranscriptLogLevel slog.Level // level for transcript lines (they contain prompt text)
}
Config configures one Loop. It holds values and interfaces only, no function fields. DefaultConfig returns sensible values.
func DefaultConfig ¶
func DefaultConfig() Config
DefaultConfig suits an interactive assistant: up to 12 model calls, stop when the model answers without a tool call, intermediate events on.
type ConfigChange ¶
ConfigChange changes settings while the loop runs. Nil fields are left unchanged.
type CostEstimator ¶
type CostEstimator interface {
Estimate(provider, model string, inputTokens, outputTokens int) float64
}
CostEstimator prices one turn for LLMTurn events. Default: 0.
type ErrorClassifier ¶
ErrorClassifier decides whether a failed model call is worth retrying. Default: deadline exceeded, EOF, empty reply, idle stream, connection reset.
type EventSink ¶
EventSink receives every event, synchronously, before it is offered to the event channel. It must not block for long.
type HistoryCompactor ¶
HistoryCompactor shapes the history before each model call. Its result is what the model receives; the stored history is not changed.
type Loop ¶
type Loop struct {
// contains filtered or unexported fields
}
Loop runs one agent conversation: call the model, run the tools it asks for, feed the results back, repeat. Start it once; it is safe for concurrent use. New (wire.go) builds it.
func New ¶
func New(cfg Config, llm model.ToolCallingChatModel, tools []*schema.ToolInfo, executor ToolExecutor, logger *slog.Logger) (*Loop, error)
New builds a Loop. It is the only place that picks a concrete type for each role, so this function alone tells you what runs. llm is any Eino tool-calling chat model; when tools is not empty it is bound to them. A nil logger discards log output.
func (*Loop) ModifyConfig ¶
func (l *Loop) ModifyConfig(c ConfigChange) bool
ModifyConfig queues a settings change. It returns false when the queue is full.
func (*Loop) Start ¶
Start begins the run and returns the event channel, which is closed after the done event. The loop keeps its own copy of messages. A second call returns a channel holding one fatal error.
type ModelIdentifier ¶
type ModelIdentifier interface {
Identity() (provider, model string)
}
ModelIdentifier names the provider and model for LLMTurn events. It is asked once per turn, so it may change during a run.
type ReflectCondition ¶
type ReflectCondition int
const ( // ReflectOff never reviews. ReflectOff ReflectCondition = iota // default: no reflection // ReflectOnIteration reviews every iteration, whatever the stop // condition, and feeds any correction into the next iteration. ReflectOnIteration // ReflectOnFinish judges the final answer against the system prompt and // user request. If it drifted, the run re-opens with the judge's notes, // at most MaxReopens times. It only applies when the model finishes. ReflectOnFinish )
type StopCondition ¶
type StopCondition int
StopCondition decides when the loop ends on its own.
const ( // StopOnNoToolFinish ends the loop when the model replies without calling // a tool. Suits chat and question answering. StopOnNoToolFinish StopCondition = iota // StopOnFinishTool runs until the model calls FinishToolName. StopOnFinishTool // StopOnExplicit runs until a stop signal, the iteration cap or a timeout. StopOnExternal )
Directories
¶
| Path | Synopsis |
|---|---|
|
Package event is the vocabulary of a running loop: every event type and payload.
|
Package event is the vocabulary of a running loop: every event type and payload. |
|
internal
|
|
|
audit
Package audit builds the LLMTurn record of each model call that led to tool calls.
|
Package audit builds the LLMTurn record of each model call that led to tool calls. |
|
control
Package control holds the controls sent to a running loop: stop, inject a message, change settings.
|
Package control holds the controls sent to a running loop: stop, inject a message, change settings. |
|
defaults
Package defaults is what runs when the caller supplies nothing: one no-op or built-in implementation per optional interface, so no other package has to check for nil.
|
Package defaults is what runs when the caller supplies nothing: one no-op or built-in implementation per optional interface, so no other package has to check for nil. |
|
dispatch
Package dispatch runs one tool call: through the ToolExecutor, or through the pause handler registered for that tool.
|
Package dispatch runs one tool call: through the ToolExecutor, or through the pause handler registered for that tool. |
|
emitter
Package emitter owns the event channel: it filters, counts dropped events, and guarantees the done event is sent once and waited for.
|
Package emitter owns the event channel: it filters, counts dropped events, and guarantees the done event is sent once and waited for. |
|
engine
Package engine is the loop itself.
|
Package engine is the loop itself. |
|
modelcall
Package modelcall makes one logical model call: iteration timeout, streaming with an idle-chunk watchdog, and retries on transient failure.
|
Package modelcall makes one logical model call: iteration timeout, streaming with an idle-chunk watchdog, and retries on transient failure. |
|
state
Package state holds all mutable state of one loop run behind one mutex.
|
Package state holds all mutable state of one loop run behind one mutex. |
|
stopping_policy
Package stopping holds one stop policy per stop condition.
|
Package stopping holds one stop policy per stop condition. |
|
transcript
Package transcript logs the conversation as it grows.
|
Package transcript logs the conversation as it grows. |
|
Package pause is what a pause handler sees and can do.
|
Package pause is what a pause handler sees and can do. |
|
Package registry tracks running loops by a key of the caller's choice, such as a user or session id, so another goroutine can stop or steer them.
|
Package registry tracks running loops by a key of the caller's choice, such as a user or session id, so another goroutine can stop or steer them. |