Documentation
¶
Overview ¶
Package pi provides a stateful agent loop built on pi-llm-go.
Index ¶
- Constants
- Variables
- func DefaultConvertToLLM(messages []Message) []llm.Message
- func EstimateTokens(messages []Message) int
- func NewSessionID() string
- func ShouldCompact(contextTokens, contextWindow int, settings CompactionSettings) bool
- type AfterCompactCtx
- type AfterProviderResponseCtx
- type AfterToolCallCtx
- type AfterTurnCtx
- type Agent
- func (a *Agent) Close() error
- func (a *Agent) Compact(ctx context.Context, opts CompactOpts) (*CompactResult, error)
- func (a *Agent) Context() context.Context
- func (a *Agent) FollowUp(ctx context.Context, m Message) error
- func (a *Agent) Phase() AgentPhase
- func (a *Agent) Prompt(ctx context.Context, msg Message, opts PromptOpts) (*EventStream, error)
- func (a *Agent) Resume(ctx context.Context, opts PromptOpts) (*EventStream, error)
- func (a *Agent) SetActiveTools(ctx context.Context, names []string) error
- func (a *Agent) SetModel(model string)
- func (a *Agent) SetSkills(skills []Skill)
- func (a *Agent) SetSystemPrompt(prompt string)
- func (a *Agent) SetThinkingLevel(level llm.ThinkingLevel)
- func (a *Agent) SetTools(tools []RegisteredTool) error
- func (a *Agent) State() AgentState
- func (a *Agent) Steer(ctx context.Context, m Message) error
- func (a *Agent) Stop()
- func (a *Agent) Transcript() []Message
- type AgentConfig
- type AgentEndEvent
- type AgentEvent
- type AgentPhase
- type AgentStartEvent
- type AgentState
- type BeforeAgentStartCtx
- type BeforeCompactCtx
- type BeforeProviderRequestCtx
- type BeforeToolCallCtx
- type BranchSummary
- type CompactOpts
- type CompactResult
- type CompactionEndEvent
- type CompactionSettings
- type CompactionStartEvent
- type ConfigField
- type ConfigUpdateCtx
- type ConvertToLLMFn
- type DynamicToolOption
- type EventStream
- type FollowUpInjectedEvent
- type Hooks
- type LLMErrorEvent
- type LLMRetryEvent
- type Message
- func BuildLLMContext(transcript []Message, summaries []BranchSummary) []Message
- func NewActiveToolsChange(names []string) Message
- func NewBranchSummaryMessage(summary string) Message
- func NewSystem(text string) Message
- func NewText(role, text string) Message
- func NewTextWithSignature(role, text string, thoughtSignature []byte) Message
- func NewThinking(role, text string) Message
- func NewThinkingWithSignature(role, text string, thoughtSignature []byte) Message
- func NewToolCall(role string, callID, toolName string, args json.RawMessage) Message
- func NewToolCallWithSignature(role string, callID, toolName string, args json.RawMessage, ...) Message
- func NewToolResult(role string, callID, toolName, content string, data json.RawMessage, ...) Message
- func NewToolResultMsg(callID, toolName string, result ToolResult) Message
- func (m Message) ActiveToolNames() (names []string, ok bool)
- func (m Message) Text() string
- func (m Message) TextThoughtSignature() []byte
- func (m Message) ThinkingText() string
- func (m Message) ThinkingThoughtSignature() []byte
- func (m Message) ToolCall() (callID, toolName string, args json.RawMessage, ok bool)
- func (m Message) ToolCallThoughtSignature() []byte
- func (m Message) ToolResult() (callID, toolName, content string, data json.RawMessage, isError bool, ok bool)
- func (m Message) Usage() *Usage
- func (m Message) WithUsage(u Usage) Message
- type MessageEndEvent
- type MessageStartEvent
- type PendingToolCall
- type PrepareArgumentsFunc
- type PromptOpts
- type PromptResult
- type RegisteredTool
- type SessionID
- type SessionMeta
- type SessionRepo
- type Skill
- type SteerInjectedEvent
- type SummarizationRetryCtx
- type SummarizationRetryPhase
- type SummarizationRetryPolicy
- type TextDeltaEvent
- type ThinkingDeltaEvent
- type ThinkingUnsupportedEvent
- type Tool
- type ToolCallEndEvent
- type ToolCallStartEvent
- type ToolErrorEvent
- type ToolExecutionMode
- type ToolLeakEvent
- type ToolResult
- type ToolUpdateEvent
- type TransformContextCtx
- type TurnEndEvent
- type TurnStartEvent
- type Usage
- type UserMessageEvent
Constants ¶
const ( DefaultSummarizationRetryBaseDelay = time.Second DefaultSummarizationRetryMaxDelay = 60 * time.Second )
Defaults for SummarizationRetryPolicy zero fields.
const SummarizationPrompt = `` /* 879-byte string literal not displayed */
SummarizationPrompt is the user prompt for the first summarization of a conversation prefix. Aligned with upstream 0.79.1 structured template.
const SummarizationSystemPrompt = `` /* 310-byte string literal not displayed */
SummarizationSystemPrompt is the system prompt used for summarization calls. Matches upstream 0.79.1 — neutral "AI assistant" wording so compaction works correctly for non-coding harnesses.
const TurnPrefixSummarizationPrompt = `` /* 440-byte string literal not displayed */
TurnPrefixSummarizationPrompt is used for the turn-prefix summarization in split-turn compaction. Aligned with upstream 0.79.1 structured template.
const UpdateSummarizationPrompt = `` /* 1289-byte string literal not displayed */
UpdateSummarizationPrompt is used when updating an existing summary with new messages. Aligned with upstream 0.79.1 structured template. Adaptation: upstream references "<previous-summary> tags" (injected inline in TS); Go passes the previous summary as a BranchSummary message above, so that phrase is reworded.
Variables ¶
var ( ErrPromptCancelled = errors.New("prompt cancelled by caller context") ErrAgentStopped = errors.New("prompt stopped by caller") // ErrToolLeaked is reserved (ADR-0004); not returned — the leak terminal error is the cancellation cause, ToolLeakEvent is the per-call signal. ErrToolLeaked = errors.New("tool execution leaked goroutine") ErrToolNotFound = errors.New("tool not found") ErrCompactFailed = errors.New("compaction failed") ErrInvalidModel = errors.New("invalid model") ErrInvalidModelRef = errors.New("invalid model reference") ErrAgentBusy = errors.New("agent is busy") // ErrNoPromptInFlight is returned by Steer and FollowUp when no prompt // is currently in flight. It is also the cancel cause of the idle context // returned by Agent.Context(), ensuring any stale nested work tied to // that context exits immediately rather than leaking. ErrNoPromptInFlight = errors.New("no prompt in flight") ErrSessionNotFound = errors.New("session not found") // ErrNothingToResume is returned by Agent.Resume when the transcript tail // is not tool results (or no session was given): there is no suspended // prompt to continue. ErrNothingToResume = errors.New("nothing to resume") ErrUnsupportedFeature = errors.New("unsupported feature") ErrDuplicateToolName = errors.New("duplicate tool name") ErrUnknownActiveTool = errors.New("active tool not registered") )
Sentinel errors for pi-core-agent-go.
var DefaultCompactionSettings = CompactionSettings{ Enabled: true, ReserveTokens: 16384, KeepRecentTokens: 20000, }
DefaultCompactionSettings matches upstream's DEFAULT_COMPACTION_SETTINGS.
Functions ¶
func DefaultConvertToLLM ¶
func DefaultConvertToLLM(messages []Message) []llm.Message
DefaultConvertToLLM converts the built-in agent message types to llm.Message.
func EstimateTokens ¶
EstimateTokens returns a rough token estimate using the chars/4 heuristic. Per ADR-0003, this is a coarse approximation until local tokenizers land. Images count 4800 chars each (upstream 0.76.0 attachment heuristic, AGENT-14); conservative per ADR-0003.
func ShouldCompact ¶
func ShouldCompact(contextTokens, contextWindow int, settings CompactionSettings) bool
ShouldCompact returns true when the context has grown large enough to warrant compaction. It is exported so callers can build their own auto-trigger logic.
Types ¶
type AfterCompactCtx ¶
type AfterCompactCtx struct {
SessionID SessionID
BranchSummary BranchSummary
}
AfterCompactCtx is passed to the AfterCompact hook.
type AfterProviderResponseCtx ¶
type AfterProviderResponseCtx struct {
Provider string
Model string
StatusCode int
Headers map[string]string
}
AfterProviderResponseCtx is passed to the AfterProviderResponse hook.
type AfterToolCallCtx ¶
type AfterToolCallCtx struct {
CallID string
ToolName string
Result ToolResult
}
AfterToolCallCtx is passed to the AfterToolCall hook.
type AfterTurnCtx ¶
type AfterTurnCtx struct {
// Turn is the 1-based index of the turn that just completed.
Turn int
// HadToolCalls reports whether the LLM returned tool calls this turn.
HadToolCalls bool
}
AfterTurnCtx is passed to the ShouldStopAfterTurn hook.
type Agent ¶
type Agent struct {
// contains filtered or unexported fields
}
Agent is the persistent, configurable object that owns tools, hooks, the session backend, default options, and the system prompt.
func NewAgent ¶
func NewAgent(cfg AgentConfig) (*Agent, error)
NewAgent creates an Agent from the given config.
func (*Agent) Compact ¶
func (a *Agent) Compact(ctx context.Context, opts CompactOpts) (*CompactResult, error)
Compact collapses older transcript messages into a BranchSummary. It must be called when the agent is idle (no in-flight run).
func (*Agent) Context ¶
Context returns the in-flight prompt's context. Tools and hooks can use it to forward cancellation into nested goroutines they spawn: when Stop is called (or the caller's context is cancelled), the returned context is cancelled with the same cause, and any goroutine blocking on its Done channel unblocks.
Idle contract: when no prompt is in flight, Context returns a non-nil, already-cancelled context with cause ErrNoPromptInFlight. Callers that hold a reference across a prompt boundary should not start new work from it — its Done channel is already closed.
Concurrent-safe: safe to call from any goroutine while a prompt is starting, running, or stopping.
func (*Agent) Phase ¶
func (a *Agent) Phase() AgentPhase
Phase returns the current (or most recent) prompt's phase.
func (*Agent) Prompt ¶
func (a *Agent) Prompt(ctx context.Context, msg Message, opts PromptOpts) (*EventStream, error)
Prompt starts a new prompt and returns its EventStream. The user message is the second argument; per-prompt overrides are carried on opts.
func (*Agent) Resume ¶ added in v0.11.0
func (a *Agent) Resume(ctx context.Context, opts PromptOpts) (*EventStream, error)
Resume continues the agent loop from the current transcript without appending input — the entry point for prompts suspended on ToolResult.Suspend once their external results have landed (AGENT-25). Precondition: opts.SessionID names a session whose transcript tail is a tool_result message; otherwise ErrNothingToResume. Leave opts.SystemPrompt empty: the override appends a system message before the resume tail check, so the tail is never a tool_result and Resume always returns ErrNothingToResume (after the override has already mutated the session). A SessionID no backend knows is ambiguous: the outcome depends on the backend's Load behavior — memory sessions load empty (ErrNothingToResume), an erroring backend surfaces its own error.
func (*Agent) SetActiveTools ¶
SetActiveTools sets the subset of registered tools offered to the model on subsequent turns; nil means all registered tools are active. The change takes effect on the next turn snapshot, not the in-flight turn. It returns an error without mutating the Agent when a name is not registered or is duplicated.
Persistence follows the bound session: when a session is bound and idle the change is written immediately; when a prompt is in flight it is queued and flushed at the next turn-end safe point. Before the first prompt no session is bound and nothing is persisted — instead the change is recorded at bind time (see Prompt) if the active set differs from the full registered set, so resume still restores it.
func (*Agent) SetModel ¶
SetModel sets the model reference used for subsequent turns. The change takes effect on the next turn snapshot, not the in-flight turn.
func (*Agent) SetSkills ¶
SetSkills replaces the Agent's skill set. The change takes effect on the next turn snapshot.
func (*Agent) SetSystemPrompt ¶
SetSystemPrompt replaces the Agent's system prompt. The change takes effect on the next turn snapshot.
func (*Agent) SetThinkingLevel ¶
func (a *Agent) SetThinkingLevel(level llm.ThinkingLevel)
SetThinkingLevel sets the thinking level used for subsequent turns. The change takes effect on the next turn snapshot, not the in-flight turn.
func (*Agent) SetTools ¶
func (a *Agent) SetTools(tools []RegisteredTool) error
SetTools replaces the Agent's tool set. The change takes effect on the next turn snapshot, not the in-flight turn. It returns an error without mutating the Agent when tool names are not unique, or when the current active set references a tool the new set no longer registers.
func (*Agent) State ¶
func (a *Agent) State() AgentState
State returns a snapshot of the current (or most recent) prompt's state.
func (*Agent) Steer ¶
Steer enqueues a message for injection into the in-flight prompt at the next safe point.
func (*Agent) Stop ¶
func (a *Agent) Stop()
Stop fire-and-forget cancels the in-flight prompt. Idempotent; a no-op when no prompt is in flight.
func (*Agent) Transcript ¶
Transcript returns a copy of the current (or most recent) prompt's transcript.
type AgentConfig ¶
type AgentConfig struct {
Providers []llm.LLMProvider
DefaultModel string
SystemPrompt string
Tools []RegisteredTool
ActiveToolNames []string
Hooks Hooks
Session SessionRepo
ConvertToLLM ConvertToLLMFn
ToolExecution ToolExecutionMode
MaxParallelTools int
ShutdownTimeout time.Duration
EventBufferSize int
SteerBufferSize int
DefaultThinking llm.ThinkingLevel
// ThinkingBudgets optionally sets per-level token caps forwarded to the
// provider on every turn. Nil or empty means "use provider defaults".
ThinkingBudgets map[llm.ThinkingLevel]int
ReserveTokens int
KeepRecentTokens int
// SummarizationRetry configures bounded retries with exponential backoff
// for the summarization calls made by Compact. The zero value disables
// retries, matching pre-0.7.0 behavior. Retry lifecycle is reported
// through Hooks.OnSummarizationRetry. Ported from upstream 0.81.1.
SummarizationRetry SummarizationRetryPolicy
// Transport is the preferred stream transport forwarded to every LLMRequest.
// Zero value behaves as TransportAuto.
Transport llm.TransportPreference
// Skills is the initial skill set offered to the model; hot-reload via SetSkills.
Skills []Skill
}
AgentConfig carries all settings for constructing an Agent.
type AgentEndEvent ¶
type AgentEndEvent struct{ Messages []Message }
AgentEndEvent signals the end of a run.
type AgentEvent ¶
type AgentEvent interface {
// contains filtered or unexported methods
}
AgentEvent is a sealed interface for every event that flows on Run.Events.
type AgentPhase ¶
type AgentPhase int
AgentPhase describes the current phase of a run.
const ( // PhaseIdle is the agent's phase at construction and between prompts, with no prompt in flight. PhaseIdle AgentPhase = iota // PhaseWaitingLLM means the run is blocked on a model response. PhaseWaitingLLM // PhaseExecutingTools means the run is executing tool calls requested by the model. PhaseExecutingTools // PhaseCompacting means the run is compacting the transcript to reclaim context window. PhaseCompacting // PhaseShuttingDown means the run is draining in-flight work after a stop. PhaseShuttingDown // PhaseDone means the prompt has finished. PhaseDone )
type AgentStartEvent ¶
type AgentStartEvent struct{}
AgentStartEvent signals the beginning of a run.
type AgentState ¶
type AgentState struct {
Phase AgentPhase
ActiveModel string
Thinking llm.ThinkingLevel
SessionID SessionID
TurnNumber int
TranscriptLen int
PendingToolCalls []PendingToolCall
LastEvent AgentEvent
LastError error
StartedAt time.Time
LastActivityAt time.Time
}
AgentState is a value-type snapshot of a run's current state.
type BeforeAgentStartCtx ¶
type BeforeAgentStartCtx struct {
PromptOpts PromptOpts
}
BeforeAgentStartCtx is passed to the BeforeAgentStart hook.
type BeforeCompactCtx ¶
BeforeCompactCtx is passed to the BeforeCompact hook.
type BeforeProviderRequestCtx ¶
BeforeProviderRequestCtx is passed to the BeforeProviderRequest hook.
type BeforeToolCallCtx ¶
BeforeToolCallCtx is passed to the BeforeToolCall hook. Args may be rewritten by the hook.
type BranchSummary ¶
type BranchSummary struct {
StartIdx int
EndIdx int
Summary string
CreatedAt time.Time
// Usage is the summarization call usage; nil when the provider reported
// none. Split-turn compaction sums both calls (upstream #6671).
Usage *Usage `json:"Usage,omitempty"`
}
BranchSummary is a persisted compaction artifact.
type CompactOpts ¶
type CompactOpts struct {
KeepRecentTokens int
// SessionID selects the session to compact. Empty means the session
// bound by the most recent prompt — which is also empty on an Agent
// that has never prompted, making Compact a silent no-op there; set
// SessionID explicitly to compact such a session (e.g. a harness
// compacting a durable conversation with a fresh Agent).
SessionID SessionID
}
CompactOpts carries options for a compaction operation.
type CompactResult ¶
type CompactResult struct {
Summary BranchSummary
RemovedCount int
}
CompactResult carries the outcome of a compaction.
type CompactionEndEvent ¶
type CompactionEndEvent struct{}
CompactionEndEvent signals the end of compaction.
type CompactionSettings ¶
CompactionSettings controls when and how compaction runs.
type CompactionStartEvent ¶
type CompactionStartEvent struct{}
CompactionStartEvent signals the start of compaction.
type ConfigField ¶
type ConfigField string
ConfigField identifies which Agent configuration field changed.
const ( // ConfigFieldModel reports a SetModel change. ConfigFieldModel ConfigField = "model" // ConfigFieldThinkingLevel reports a SetThinkingLevel change. ConfigFieldThinkingLevel ConfigField = "thinking_level" // ConfigFieldTools reports a SetTools change. ConfigFieldTools ConfigField = "tools" // ConfigFieldSystemPrompt reports a SetSystemPrompt change. ConfigFieldSystemPrompt ConfigField = "system_prompt" // ConfigFieldSkills reports a SetSkills change. ConfigFieldSkills ConfigField = "skills" // ConfigFieldActiveTools reports a SetActiveTools change. ConfigFieldActiveTools ConfigField = "active_tools" )
type ConfigUpdateCtx ¶
type ConfigUpdateCtx struct {
Field ConfigField
OldModel string
NewModel string
OldThinkingLevel llm.ThinkingLevel
NewThinkingLevel llm.ThinkingLevel
OldTools []RegisteredTool
NewTools []RegisteredTool
OldSystemPrompt string
NewSystemPrompt string
OldSkills []Skill
NewSkills []Skill
OldActiveTools []string
NewActiveTools []string
}
ConfigUpdateCtx is passed to the OnConfigUpdate hook. Only the typed pair matching Field is populated; all other pairs are zero.
type ConvertToLLMFn ¶
type ConvertToLLMFn func(messages []Message) []llm.Message
ConvertToLLMFn transforms agent-side Messages into LLM-shaped messages.
type DynamicToolOption ¶
type DynamicToolOption func(*dynamicTool)
DynamicToolOption configures an optional capability on a dynamic tool.
func WithPrepareArguments ¶
func WithPrepareArguments(fn PrepareArgumentsFunc) DynamicToolOption
WithPrepareArguments attaches a PrepareArgumentsFunc hook to a dynamic tool. The hook transforms raw LLM-supplied arguments before they reach the handler. Returning an error surfaces as a tool error result; the prompt continues.
type EventStream ¶
type EventStream struct {
Events <-chan AgentEvent
Done <-chan PromptResult
}
EventStream is the shared return shape for an Agent prompt. It carries a stream of typed events on Events (closed by the sender when the prompt completes) and exactly one terminal PromptResult on Done.
type FollowUpInjectedEvent ¶
type FollowUpInjectedEvent struct{ Message Message }
FollowUpInjectedEvent signals that a follow-up message has been injected.
type Hooks ¶
type Hooks struct {
BeforeAgentStart func(ctx context.Context, c BeforeAgentStartCtx) error
BeforeToolCall func(ctx context.Context, c BeforeToolCallCtx) error
AfterToolCall func(ctx context.Context, c AfterToolCallCtx) error
BeforeCompact func(ctx context.Context, c BeforeCompactCtx) error
AfterCompact func(ctx context.Context, c AfterCompactCtx) error
TransformContext func(ctx context.Context, c TransformContextCtx) ([]Message, error)
BeforeProviderRequest func(ctx context.Context, c BeforeProviderRequestCtx) error
AfterProviderResponse func(ctx context.Context, c AfterProviderResponseCtx)
// OnSummarizationRetry is called at each retry-lifecycle point when a
// summarization call made by Compact fails transiently and
// AgentConfig.SummarizationRetry allows a retry. It is never called when
// the policy disables retries or the first call succeeds. Calls are
// serial: split-turn summarization runs its two summarization calls in
// sequence, so lifecycle events never interleave. It must not call back
// into the Agent. Nil is a no-op.
OnSummarizationRetry func(ctx context.Context, c SummarizationRetryCtx)
// ShouldStopAfterTurn is called at each turn boundary — after turn_end is
// emitted and tool results are flushed to the session, before the
// steer/follow-up queues are polled or the next LLM call starts. When it
// returns true the loop exits with a clean, nil-error PromptResult. Nil is
// a no-op. Matches upstream pi 0.72.0 shouldStopAfterTurn decision-point
// semantics. It is also invoked on turns that end via ToolResult.Terminate;
// on those turns the return value is ignored — the prompt ends regardless.
// The auto-continue loop imposes no turn cap by design (parity with
// upstream pi); this hook is the mechanism for imposing one.
ShouldStopAfterTurn func(ctx context.Context, c AfterTurnCtx) bool
// OnConfigUpdate is called synchronously by each setter (SetModel,
// SetThinkingLevel, SetTools, SetSystemPrompt, SetSkills, SetActiveTools)
// after the new
// value is committed, on the setter's calling goroutine, without holding
// the Agent's internal mutex. This means the hook may safely call Agent
// getters (e.g. State()) without deadlocking. Because the mutex is released
// before the hook runs, a concurrent setter may write a newer value between
// the commit and the hook invocation — the hook may therefore observe a
// newer Agent state than ConfigUpdateCtx.Old* reflects. Nil is a no-op.
OnConfigUpdate func(ConfigUpdateCtx)
}
Hooks is a flat struct of optional function fields covering every lifecycle point. Nil fields are no-ops.
type LLMErrorEvent ¶
LLMErrorEvent signals an error from the LLM provider.
type LLMRetryEvent ¶
type LLMRetryEvent struct {
Provider string
Model string
Attempt int
NextDelay int64 // milliseconds
Reason string
ServerHint bool
}
LLMRetryEvent signals a retry attempt.
type Message ¶
type Message struct {
Role string
Type string
Body json.RawMessage
// Images carries attachments outside Body so Body stays text-only and token estimation can count images at a flat rate.
Images []llm.ImageContent `json:",omitempty"`
}
Message is the agent-side unit of transcript content. The framework treats Body as opaque bytes for user-defined custom message types.
func BuildLLMContext ¶
func BuildLLMContext(transcript []Message, summaries []BranchSummary) []Message
BuildLLMContext returns a message slice with BranchSummary messages substituted for the ranges they cover. Summaries are sorted by StartIdx and applied in order. Bookkeeping entries (active_tools_change) are stripped — they are state, not conversation, and must never reach the model.
func NewActiveToolsChange ¶
NewActiveToolsChange creates an active_tools_change bookkeeping entry recording the set of active tool names (nil means all registered tools are active). It is never sent to the model — DefaultConvertToLLM and BuildLLMContext both exclude it — and is never chosen as a compaction cut point. On resume, the active set is restored by scanning the transcript for the last such entry.
func NewBranchSummaryMessage ¶
NewBranchSummaryMessage creates a branch_summary message.
func NewTextWithSignature ¶ added in v0.10.0
NewTextWithSignature creates a text message carrying the provider's opaque thought signature (Gemini). With an empty signature it is exactly NewText, so transcripts without signatures keep the plain-string body shape.
func NewThinking ¶
NewThinking creates a thinking message.
func NewThinkingWithSignature ¶ added in v0.10.0
NewThinkingWithSignature creates a thinking message carrying the provider's opaque thought signature (Gemini). With an empty signature it is exactly NewThinking, so transcripts without signatures keep the plain-string body shape.
func NewToolCall ¶
func NewToolCall(role string, callID, toolName string, args json.RawMessage) Message
NewToolCall creates a tool call message.
func NewToolCallWithSignature ¶ added in v0.6.0
func NewToolCallWithSignature(role string, callID, toolName string, args json.RawMessage, thoughtSignature []byte) Message
NewToolCallWithSignature creates a tool call message that also persists the provider's opaque thought signature (Gemini 3), so replaying the transcript carries it back verbatim. A nil signature is equivalent to NewToolCall.
func NewToolResult ¶
func NewToolResult(role string, callID, toolName, content string, data json.RawMessage, isError bool) Message
NewToolResult creates a tool result message.
func NewToolResultMsg ¶ added in v0.8.0
func NewToolResultMsg(callID, toolName string, result ToolResult) Message
NewToolResultMsg is the ToolResult-aware variant of NewToolResult: it takes the tool's ToolResult directly and copies result.Images to Message.Images (images ride the Message, never the JSON Body). Tool results are always authored with role "tool".
func (Message) ActiveToolNames ¶
ActiveToolNames extracts the recorded active tool names from an active_tools_change message. The second return is false for other types.
func (Message) Text ¶
Text extracts the text from a text-typed or branch_summary message. Signature-carrying bodies (NewTextWithSignature) store an object; both shapes read back.
func (Message) TextThoughtSignature ¶ added in v0.10.0
TextThoughtSignature extracts the provider's opaque thought signature from a text message. Nil when absent (pre-existing transcripts, providers without signatures) or when the message is not a text.
func (Message) ThinkingText ¶ added in v0.10.0
ThinkingText extracts the text from a thinking message. Signature-carrying bodies (NewThinkingWithSignature) store an object; both shapes read back.
func (Message) ThinkingThoughtSignature ¶ added in v0.10.0
ThinkingThoughtSignature extracts the provider's opaque thought signature from a thinking message. Nil when absent or when the message is not a thinking.
func (Message) ToolCall ¶
func (m Message) ToolCall() (callID, toolName string, args json.RawMessage, ok bool)
ToolCall extracts fields from a tool_call message.
func (Message) ToolCallThoughtSignature ¶ added in v0.6.0
ToolCallThoughtSignature extracts the provider's opaque thought signature from a tool_call message. Nil when absent (pre-existing transcripts, providers without signatures) or when the message is not a tool_call.
func (Message) ToolResult ¶
func (m Message) ToolResult() (callID, toolName, content string, data json.RawMessage, isError bool, ok bool)
ToolResult extracts fields from a tool_result message.
func (Message) Usage ¶ added in v0.10.0
Usage extracts the provider token usage recorded on the message (WithUsage). Nil when absent — older transcripts, providers that report none — so callers fall back to EstimateTokens.
func (Message) WithUsage ¶ added in v0.10.0
WithUsage returns a copy of the message with provider token usage recorded under the body's usage key, preserving existing fields. Plain-string bodies (unsigned text/thinking) convert to the object form; the Usage is metadata and is never sent to a provider.
type MessageEndEvent ¶
type MessageEndEvent struct{ Message Message }
MessageEndEvent signals the end of a message.
type MessageStartEvent ¶
MessageStartEvent signals the beginning of a message.
type PendingToolCall ¶
PendingToolCall describes an in-flight tool execution.
type PrepareArgumentsFunc ¶
type PrepareArgumentsFunc func(ctx context.Context, raw json.RawMessage) (json.RawMessage, error)
PrepareArgumentsFunc transforms raw LLM-supplied arguments before unmarshalling into P. A typical use case is shimming a deprecated argument shape — e.g. migrating a legacy_value key to the current value key — without requiring callers to update their prompts. Returning an error surfaces as a tool error result; the prompt continues.
type PromptOpts ¶
type PromptOpts struct {
SessionID SessionID
Model string
SystemPrompt string
Thinking llm.ThinkingLevel
ProviderHints llm.ProviderHints
}
PromptOpts carries per-prompt overrides. The user message is passed as the second argument to Agent.Prompt, not on this struct.
type PromptResult ¶
type PromptResult struct {
Messages []Message
Err error
// Suspended reports the prompt ended with at least one Suspend-marked
// tool call pending external resolution (AGENT-25).
Suspended bool
}
PromptResult is the terminal value delivered on EventStream.Done.
type RegisteredTool ¶
type RegisteredTool interface {
Name() string
Description() string
Schema() json.RawMessage
Execute(ctx context.Context, callID string, args json.RawMessage) (ToolResult, error)
IsSequential() bool
}
RegisteredTool is the internal interface that the agent loop uses to invoke tools. Tools built from Tool.ExecuteStream support both call styles: Execute runs them with partial updates discarded, and the unexported streamingTool capability (checked via type assertion) runs them with updates observed.
func NewDynamicTool ¶
func NewDynamicTool(name, description string, schema json.RawMessage, execute func(ctx context.Context, callID string, args json.RawMessage) (ToolResult, error), opts ...DynamicToolOption) RegisteredTool
NewDynamicTool creates a tool from a runtime schema and raw handler. Optional DynamicToolOption values (e.g. WithPrepareArguments) may be appended; existing callers that pass none are unaffected.
func NewTool ¶
func NewTool[P any](t Tool[P]) RegisteredTool
NewTool creates a RegisteredTool from a typed Tool. Exactly one of Execute or ExecuteStream must be set; NewTool panics otherwise, since this is API misuse rather than a runtime condition.
type SessionID ¶
type SessionID string
SessionID is an opaque string that identifies a single session.
type SessionMeta ¶
SessionMeta carries metadata about a session.
type SessionRepo ¶
type SessionRepo interface {
Create(ctx context.Context) (SessionID, error)
Append(ctx context.Context, id SessionID, msgs ...Message) error
Load(ctx context.Context, id SessionID) ([]Message, error)
List(ctx context.Context) ([]SessionMeta, error)
AppendBranchSummary(ctx context.Context, id SessionID, summary BranchSummary) error
LoadBranchSummaries(ctx context.Context, id SessionID) ([]BranchSummary, error)
Delete(ctx context.Context, id SessionID) error
}
SessionRepo is the interface every storage backend implements.
type Skill ¶
type Skill struct {
// Name is the model-visible identifier rendered into the skill index.
// When omitted from the SKILL.md frontmatter it defaults to the parent
// directory name.
Name string
// Description is the one-line summary shown to the model in the skill
// index. It is required; a skill without one is rejected with a Diagnostic.
Description string
// Content holds the full text of the SKILL.md body. The framework does
// not deliver this to the model automatically; the host application must
// supply a tool that resolves FilePath so the model can fetch it on demand.
Content string
// FilePath is the absolute path to the SKILL.md file. It is included in
// the model-visible index so the model can request the file via a
// host-supplied file-reader tool.
FilePath string
// DisableModelInvocation excludes the skill from the model-visible index
// when true. The skill remains accessible to the host application.
DisableModelInvocation bool
}
Skill is a unit of model-invokable expertise carried on the Agent. It is part of the mutable runtime config and the turn snapshot; the model-visible index (name, description, location) is auto-rendered into the system prompt at turn-snapshot time by formatSkillsForSystemPrompt.
Content-reader contract: the framework does NOT ship a tool that reads FilePath. The rendered index exposes only the skill's name, description, and FilePath — never Content — so the model fetches a skill's full instructions on demand through a user-supplied tool (e.g. a file-reader tool registered on the Agent) that resolves FilePath. Carrying Content here is purely informational for the host application; populating it does not make the framework deliver it to the model.
type SteerInjectedEvent ¶
type SteerInjectedEvent struct{ Message Message }
SteerInjectedEvent signals that a steered message has been injected.
type SummarizationRetryCtx ¶ added in v0.7.0
type SummarizationRetryCtx struct {
Phase SummarizationRetryPhase
// Attempt is the 1-indexed retry attempt this point belongs to.
Attempt int
// MaxAttempts is the configured MaxRetries. Set on Scheduled.
MaxAttempts int
// Delay is the backoff about to be slept. Set on Scheduled.
Delay time.Duration
// Success reports the loop outcome. Set on Finished.
Success bool
// Err is the error that triggered this retry on Scheduled, and the final
// error on an unsuccessful Finished. Nil on AttemptStart and on a
// successful Finished.
Err error
}
SummarizationRetryCtx describes one retry-lifecycle point of a failed summarization call (Compact's first summary, summary update, or split-turn pair).
type SummarizationRetryPhase ¶ added in v0.7.0
type SummarizationRetryPhase int
SummarizationRetryPhase identifies which point of the retry lifecycle an OnSummarizationRetry call reports. Mirrors upstream 0.81.1's summarization_retry_scheduled / _attempt_start / _finished events.
const ( // SummarizationRetryScheduled fires before the backoff sleep of each retry. SummarizationRetryScheduled SummarizationRetryPhase // SummarizationRetryAttemptStart fires after the backoff sleep, immediately // before the retried call starts. SummarizationRetryAttemptStart // SummarizationRetryFinished fires once when the retry loop ends, whether // it succeeded, exhausted its budget, or was aborted during backoff. SummarizationRetryFinished )
type SummarizationRetryPolicy ¶ added in v0.7.0
type SummarizationRetryPolicy struct {
// MaxRetries bounds retry attempts; the initial call never counts as a
// retry. 0 disables retries.
MaxRetries int
// BaseDelay is the first retry delay; attempt n waits BaseDelay * 2^(n-1),
// capped at MaxDelay. <= 0 uses DefaultSummarizationRetryBaseDelay.
BaseDelay time.Duration
// MaxDelay caps the per-attempt delay. <= 0 uses DefaultSummarizationRetryMaxDelay.
MaxDelay time.Duration
}
SummarizationRetryPolicy configures bounded retries with exponential backoff for the summarization calls made by Compact (first summary, summary update, and the split-turn pair). The zero value disables retries, matching upstream when no retry policy is configured. Ported from upstream 0.81.1 (resilient compaction and branch summaries, pi#6901).
type TextDeltaEvent ¶
type TextDeltaEvent struct {
Delta string
// ThoughtSignature is the provider's opaque signature for the text part
// this delta belongs to (Gemini). Present on at most some deltas — possibly
// one with an empty Delta — so durable-log consumers retain the last
// non-empty value; empty for providers without signatures.
ThoughtSignature []byte
}
TextDeltaEvent carries a fragment of assistant text.
type ThinkingDeltaEvent ¶
type ThinkingDeltaEvent struct {
Delta string
// ThoughtSignature behaves as on TextDeltaEvent, for thinking parts.
ThoughtSignature []byte
}
ThinkingDeltaEvent carries a fragment of assistant thinking.
type ThinkingUnsupportedEvent ¶
type ThinkingUnsupportedEvent struct {
Requested string
Provider string
Model string
Reason string
}
ThinkingUnsupportedEvent signals that thinking was requested but unsupported.
type Tool ¶
type Tool[P any] struct { Name string Description string Sequential bool Execute func(ctx context.Context, params P) (ToolResult, error) // ExecuteStream is the streaming alternative to Execute: it may call emit // zero or more times with partial results before returning the final // ToolResult. Exactly one of Execute or ExecuteStream must be set; // NewTool panics otherwise. Partial results are ephemeral — the loop // forwards each emit as a ToolUpdateEvent and never persists them to the // transcript. ExecuteStream func(ctx context.Context, params P, emit func(ToolResult)) (ToolResult, error) // PrepareArguments is an optional hook that runs on raw args before // unmarshalling into P. See PrepareArgumentsFunc for details. PrepareArguments PrepareArgumentsFunc }
Tool is the generic, compile-time-typed tool struct.
type ToolCallEndEvent ¶
type ToolCallEndEvent struct {
CallID string
ToolName string
Result ToolResult
}
ToolCallEndEvent signals that a tool call has completed.
type ToolCallStartEvent ¶
type ToolCallStartEvent struct {
CallID string
ToolName string
Args []byte
ThoughtSignature []byte
}
ToolCallStartEvent signals that a tool call has started. v0.9.0 guarantee: fires once per tool call when the call is finalized at the provider's ToolCallEndEvent, always carrying complete arguments. ThoughtSignature is the provider's opaque per-call signature (Gemini 3); nil for providers without one. Event consumers that persist tool calls outside the transcript (e.g. a durable harness) must carry it so replayed calls keep their signature.
type ToolErrorEvent ¶
ToolErrorEvent signals that a tool call errored.
type ToolExecutionMode ¶
type ToolExecutionMode int
ToolExecutionMode controls whether tools execute in parallel or serially.
const ( // ToolExecParallel runs a turn's tool calls concurrently. It is the zero value and the default. ToolExecParallel ToolExecutionMode = iota // ToolExecSequential runs a turn's tool calls one at a time, in the order the model requested them. ToolExecSequential )
type ToolLeakEvent ¶
type ToolLeakEvent struct {
ToolName string
CallID string
// Duration is milliseconds measured from batch start to leak declaration
// (≈ time-to-cancellation + ShutdownTimeout) — not the leaked tool's
// eventual runtime, which is unbounded since the goroutine is still running.
Duration int64
}
ToolLeakEvent signals that a tool ignored context cancellation.
type ToolResult ¶
type ToolResult struct {
Content string
Data json.RawMessage
IsError bool
Terminate bool
// Suspend marks a call that resolves externally (HARNESS-15's task tool):
// the loop persists sibling results, persists NO tool_result for this
// call — the pending call is the suspension point — and ends the prompt
// gracefully after the batch, reporting PromptResult.Suspended.
// Terminate dominates when both are set in an all-terminating batch.
Suspend bool
// Images carries optional image parts of the result (flows to llm.ToolResultContent.Images).
Images []llm.ImageContent
}
ToolResult is the concrete struct returned by a tool's Execute function.
type ToolUpdateEvent ¶ added in v0.8.0
type ToolUpdateEvent struct {
CallID string
Name string
Result ToolResult
}
ToolUpdateEvent carries a partial-result snapshot from a running tool. Zero or more are emitted between ToolCallStartEvent and ToolCallEndEvent. Updates are ephemeral: events only, never persisted to the transcript.
type TransformContextCtx ¶
type TransformContextCtx struct {
Messages []Message
}
TransformContextCtx is passed to the TransformContext hook. The returned messages replace the transcript sent to the LLM.
type TurnEndEvent ¶
type TurnEndEvent struct{ Turn int }
TurnEndEvent signals the end of an agent turn.
type TurnStartEvent ¶
type TurnStartEvent struct{ Turn int }
TurnStartEvent signals the beginning of a new agent turn.
type Usage ¶ added in v0.9.0
Usage records provider token usage for the LLM call(s) that produced an artifact. Values are sums when multiple calls contributed (split-turn compaction runs two).
type UserMessageEvent ¶
type UserMessageEvent struct{ Message Message }
UserMessageEvent signals a user message being processed.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package agenttest provides test helpers for pi-core-agent-go.
|
Package agenttest provides test helpers for pi-core-agent-go. |
|
examples
|
|
|
providers
command
Command providers constructs an agent with Gemini plus the six OpenAI-compatible targets (OpenAI, OpenCode Zen, xAI, Mistral, Qwen, z.ai) and routes one prompt by "<provider>/<model>" ref.
|
Command providers constructs an agent with Gemini plus the six OpenAI-compatible targets (OpenAI, OpenCode Zen, xAI, Mistral, Qwen, z.ai) and routes one prompt by "<provider>/<model>" ref. |
|
internal
|
|
|
harness
Package harness contains the internal agent loop implementation.
|
Package harness contains the internal agent loop implementation. |
|
Package piskills loads pi.Skill values from a directory tree of SKILL.md files.
|
Package piskills loads pi.Skill values from a directory tree of SKILL.md files. |
|
Package session provides pi.SessionRepo implementations for persisting agent transcripts: a JSONL file-backed store and an in-memory store.
|
Package session provides pi.SessionRepo implementations for persisting agent transcripts: a JSONL file-backed store and an in-memory store. |
|
Package tools provides utilities consumed by agent-facing tool implementations.
|
Package tools provides utilities consumed by agent-facing tool implementations. |