Documentation
¶
Index ¶
- Constants
- Variables
- func CalculateContextTokens(usage ai.Usage) int64
- func ConvertToLLM(messages []agent.AgentMessage) []ai.Message
- func DecodeCompactionDetails[T any](raw json.RawMessage) (details T, ok bool, err error)
- func EstimateContextTokens(messages []agent.AgentMessage) contextUsageEstimate
- func EstimateTokens(message agent.AgentMessage) int64
- func FindInitialModel(registry *ModelRegistry) (ai.Model[ai.API], bool)
- func FindTurnStartIndex(entries []SessionEntry, entryIndex, startIndex int) int
- func GenerateSummary(ctx context.Context, currentMessages []agent.AgentMessage, ...) (string, error)
- func GetLastAssistantUsage(entries []SessionEntry) *ai.Usage
- func MarshalSessionEntry(entry SessionEntry) ([]byte, error)
- func RegisterMessageDecoder(role string, decoder MessageDecoder)
- func ShouldTriggerCompaction(contextTokens int64, contextWindow int64, settings CompactionSettings) bool
- func UnmarshalAgentMessage(data []byte) (agent.AgentMessage, error)
- func UserMessageText(message ai.UserMessage) string
- type AgentSession
- func (s *AgentSession) AbortCompaction()
- func (s *AgentSession) Compact(ctx context.Context, options *ManualCompactionOptions) (*CompactionResult, error)
- func (s *AgentSession) GetActiveToolNames() ([]string, error)
- func (s *AgentSession) GetCompactionSettings() CompactionSettings
- func (s *AgentSession) GetFollowUpMode() (string, error)
- func (s *AgentSession) GetMessages() ([]agent.AgentMessage, error)
- func (s *AgentSession) GetModel() (ai.Model[ai.API], error)
- func (s *AgentSession) GetSessionID() (string, error)
- func (s *AgentSession) GetSessionName() (*string, error)
- func (s *AgentSession) GetState() (agent.AgentState, error)
- func (s *AgentSession) GetSteeringMode() (string, error)
- func (s *AgentSession) GetSystemPrompt() (string, error)
- func (s *AgentSession) GetThinkingLevel() (ai.ModelThinkingLevel, error)
- func (s *AgentSession) IsCompacting() bool
- func (s *AgentSession) IsStreaming() bool
- func (s *AgentSession) Prompt(ctx context.Context, text string, options *PromptOptions) error
- func (s *AgentSession) SetCompactionHook(hook CompactionHook)
- func (s *AgentSession) SetCompactionSettings(settings CompactionSettings)
- func (s *AgentSession) Subscribe(listener AgentSessionEventListener) func()
- type AgentSessionEvent
- type AgentSessionEventListener
- type AuthStore
- type BranchSummaryEntry
- type BranchSummaryMessage
- type CompactFunc
- type CompactOptions
- type CompactionEndEvent
- type CompactionEntry
- type CompactionHook
- type CompactionPreparation
- type CompactionReason
- type CompactionRequest
- type CompactionResult
- type CompactionSettings
- type CompactionStartEvent
- type CompactionSummaryMessage
- type CreateAgentSessionOptions
- type CreateAgentSessionResult
- type CustomEntry
- type CustomMessage
- type CustomMessageEntry
- type CutPointResult
- type EnvAuthStore
- type GenerateSummaryOptions
- type LabelEntry
- type LoadedSession
- type ManualCompactionOptions
- type MessageDecoder
- type ModelChangeEntry
- type ModelRegistry
- func (r *ModelRegistry) APIKeyAndHeaders(model ai.Model[ai.API]) (RequestAuth, error)
- func (r *ModelRegistry) APIKeyForProvider(provider ai.Provider) (string, bool)
- func (r *ModelRegistry) All() []ai.Model[ai.API]
- func (r *ModelRegistry) Available() []ai.Model[ai.API]
- func (r *ModelRegistry) Find(provider ai.Provider, modelID string) (ai.Model[ai.API], bool)
- func (r *ModelRegistry) HasConfiguredAuth(model ai.Model[ai.API]) bool
- func (r *ModelRegistry) ProviderDisplayName(provider ai.Provider) string
- type PromptOptions
- type ReadonlySessionManager
- type RequestAuth
- type SessionBranch
- type SessionContext
- type SessionEntry
- type SessionEntryBase
- type SessionHeader
- type SessionInfo
- type SessionInfoEntry
- type SessionManager
- func (s *SessionManager) AppendCompaction(ctx context.Context, summary, first string, tokens int64, details any, ...) (string, error)
- func (s *SessionManager) AppendCustomEntry(ctx context.Context, t string, data any) (string, error)
- func (s *SessionManager) AppendCustomMessageEntry(ctx context.Context, t string, c []ai.UserContent, display bool, details any) (string, error)
- func (s *SessionManager) AppendLabelChange(ctx context.Context, target string, label *string) (string, error)
- func (s *SessionManager) AppendMessage(ctx context.Context, m agent.AgentMessage) (string, error)
- func (s *SessionManager) AppendMessageWithID(ctx context.Context, id string, m agent.AgentMessage) (string, error)
- func (s *SessionManager) AppendModelChange(ctx context.Context, p, m string) (string, error)
- func (s *SessionManager) AppendSessionInfo(ctx context.Context, name string) (string, error)
- func (s *SessionManager) AppendThinkingLevelChange(ctx context.Context, v string) (string, error)
- func (s *SessionManager) BranchWithSummary(ctx context.Context, from *string, summary string, details any, fromHook *bool) (string, error)
- func (s *SessionManager) BuildSessionContext() SessionContext
- func (s *SessionManager) Fork(ctx context.Context, leafID *string) (*SessionManager, error)
- func (s *SessionManager) GetBranch(from ...string) []SessionEntry
- func (s *SessionManager) GetBranches() []SessionBranch
- func (s *SessionManager) GetChildren(parentID string) []SessionEntry
- func (s *SessionManager) GetEntries() []SessionEntry
- func (s *SessionManager) GetEntry(id string) SessionEntry
- func (s *SessionManager) GetHeader() *SessionHeader
- func (s *SessionManager) GetLabel(id string) *string
- func (s *SessionManager) GetLeafEntry() SessionEntry
- func (s *SessionManager) GetLeafID() *string
- func (s *SessionManager) GetSessionID() string
- func (s *SessionManager) GetSessionName() *string
- func (s *SessionManager) GetTree() []*SessionTreeNode
- func (s *SessionManager) IsPersisted() bool
- func (s *SessionManager) LoadSession(ctx context.Context, id string) error
- func (s *SessionManager) NewSession(ctx context.Context, header *SessionHeader, metadata map[string]any) error
- func (s *SessionManager) Reload(ctx context.Context) error
- func (s *SessionManager) ResetLeaf(ctx context.Context) error
- func (s *SessionManager) SetLeaf(ctx context.Context, id string) error
- type SessionMessageEntry
- type SessionModel
- type SessionQuery
- type SessionStore
- type SessionTreeNode
- type StreamingBehavior
- type SummaryPrompts
- type ThinkingLevelChangeEntry
Constants ¶
const ( MessageRoleCustom = "custom" MessageRoleBranchSummary = "branchSummary" MessageRoleCompactionSummary = "compactionSummary" BranchSummaryPrefix = `The following is a summary of a branch that this conversation came back from: <summary> ` BranchSummarySuffix = `</summary>` CompactionSummaryPrefix = `The conversation history before this point was compacted into the following summary: <summary> ` CompactionSummarySuffix = ` </summary>` )
const ( EntryTypeMessage = "message" EntryTypeThinkingLevelChange = "thinking_level_change" EntryTypeModelChange = "model_change" EntryTypeCompaction = "compaction" EntryTypeBranchSummary = "branch_summary" EntryTypeCustom = "custom" EntryTypeCustomMessage = "custom_message" EntryTypeLabel = "label" EntryTypeSessionInfo = "session_info" )
Session entry types, as stored in SessionEntryBase.Type.
const CurrentSessionVersion = 1
const DefaultThinkingLevel = ai.ThinkingLevelMedium
const SUMMARIZATION_PROMPT = `` /* 879-byte string literal not displayed */
const SUMMARIZATION_SYSTEM_PROMPT = `` /* 310-byte string literal not displayed */
const TURN_PREFIX_SUMMARIZATION_PROMPT = `` /* 440-byte string literal not displayed */
const UPDATE_SUMMARIZATION_PROMPT = `` /* 1257-byte string literal not displayed */
Variables ¶
var ( // ErrSessionNotFound is returned when a session ID has no stored session. ErrSessionNotFound = errors.New("session not found") // ErrSessionExists is returned by CreateSession when the header ID is taken. ErrSessionExists = errors.New("session already exists") // ErrSessionConflict is returned when another writer moved the session's // current position. Reload the session before writing again. ErrSessionConflict = errors.New("session changed by another writer") )
var DEFAULT_COMPACTION_SETTINGS = CompactionSettings{ Enabled: true, ReservedTokens: 16384, KeepRecentTokens: 20000, }
var ErrCompactionCancelled = errors.New("compaction cancelled")
ErrCompactionCancelled is returned by a CompactionHook to cancel compaction. It is reported as an aborted compaction; automatic compaction lets the prompt continue.
var ErrNothingToCompact = errors.New("nothing to compact")
ErrNothingToCompact is returned when everything since the last compaction fits in KeepRecentTokens, so compacting would not shrink the context. Threshold compaction treats it as a no-op rather than a failure.
Functions ¶
func CalculateContextTokens ¶ added in v0.3.0
*
- Calculate total context tokens from usage.
- Uses the native totalTokens field when available, falls back to computing from components.
func ConvertToLLM ¶
func ConvertToLLM(messages []agent.AgentMessage) []ai.Message
func DecodeCompactionDetails ¶ added in v0.3.0
func DecodeCompactionDetails[T any](raw json.RawMessage) (details T, ok bool, err error)
DecodeCompactionDetails decodes details stored by a previous compaction. ok is false when the previous compaction stored no details.
func EstimateContextTokens ¶ added in v0.3.0
func EstimateContextTokens(messages []agent.AgentMessage) contextUsageEstimate
*
- Estimate context tokens from messages, using the last assistant usage when available.
- If there are messages after the last usage, estimate their tokens with estimateTokens.
func EstimateTokens ¶ added in v0.3.0
func EstimateTokens(message agent.AgentMessage) int64
func FindInitialModel ¶
func FindTurnStartIndex ¶ added in v0.3.0
func FindTurnStartIndex(entries []SessionEntry, entryIndex, startIndex int) int
*
- Find the user message that starts the turn containing the given entry index.
- Returns -1 if no turn start found before the index.
func GenerateSummary ¶ added in v0.3.0
func GenerateSummary( ctx context.Context, currentMessages []agent.AgentMessage, model ai.Model[ai.API], reserveTokens int64, apiKey string, options *GenerateSummaryOptions, ) (string, error)
*
- Generate a summary of the conversation using the LLM.
- If previousSummary is provided, uses the update prompt to merge.
func GetLastAssistantUsage ¶ added in v0.3.0
func GetLastAssistantUsage(entries []SessionEntry) *ai.Usage
*
- Find the last non-aborted assistant message usage from session entries.
func MarshalSessionEntry ¶ added in v0.3.0
func MarshalSessionEntry(entry SessionEntry) ([]byte, error)
MarshalSessionEntry encodes an entry for storage. It rejects entries that UnmarshalSessionEntry could not decode back into the same type.
func RegisterMessageDecoder ¶ added in v0.3.0
func RegisterMessageDecoder(role string, decoder MessageDecoder)
RegisterMessageDecoder lets UnmarshalSessionEntry decode messages of a custom role, matched against the message's "role" field. Call it during initialization. It panics if role is empty, built in, or already registered.
func ShouldTriggerCompaction ¶ added in v0.3.0
func ShouldTriggerCompaction(contextTokens int64, contextWindow int64, settings CompactionSettings) bool
*
- Check if compaction should trigger based on context usage.
- An unknown (non-positive) context window never triggers.
func UnmarshalAgentMessage ¶ added in v0.3.0
func UnmarshalAgentMessage(data []byte) (agent.AgentMessage, error)
UnmarshalAgentMessage decodes a built-in or registered agent message.
func UserMessageText ¶ added in v0.3.0
func UserMessageText(message ai.UserMessage) string
UserMessageText joins a user message's text blocks with spaces.
Types ¶
type AgentSession ¶
type AgentSession struct {
// Use Prompt for session orchestration. Direct Agent runs bypass automatic
// compaction; their persisted messages are checked on the next session prompt.
Agent *agent.Agent
SessionManager *SessionManager
// contains filtered or unexported fields
}
func NewAgentSession ¶
func NewAgentSession(a *agent.Agent, sm *SessionManager) *AgentSession
func (*AgentSession) AbortCompaction ¶ added in v0.3.0
func (s *AgentSession) AbortCompaction()
func (*AgentSession) Compact ¶ added in v0.3.0
func (s *AgentSession) Compact(ctx context.Context, options *ManualCompactionOptions) (*CompactionResult, error)
Compact manually compacts the active session branch and replaces the agent context.
An active run is aborted first. Messages queued for it with Steer or FollowUp are not sent: they are removed and reported in the compaction_end event's RestoredMessages. Prompts that arrive during compaction wait for it to finish and then run on the compacted context.
func (*AgentSession) GetActiveToolNames ¶
func (s *AgentSession) GetActiveToolNames() ([]string, error)
* Get the names of currently active tools. * Returns the names of tools currently set on the agent.
func (*AgentSession) GetCompactionSettings ¶ added in v0.3.0
func (s *AgentSession) GetCompactionSettings() CompactionSettings
func (*AgentSession) GetFollowUpMode ¶
func (s *AgentSession) GetFollowUpMode() (string, error)
* Current follow-up mode
func (*AgentSession) GetMessages ¶
func (s *AgentSession) GetMessages() ([]agent.AgentMessage, error)
* Current messages in the conversation
func (*AgentSession) GetSessionID ¶
func (s *AgentSession) GetSessionID() (string, error)
* Current session ID
func (*AgentSession) GetSessionName ¶
func (s *AgentSession) GetSessionName() (*string, error)
* Current session name
func (*AgentSession) GetState ¶
func (s *AgentSession) GetState() (agent.AgentState, error)
* Return full agent state
func (*AgentSession) GetSteeringMode ¶
func (s *AgentSession) GetSteeringMode() (string, error)
* Current steering mode
func (*AgentSession) GetSystemPrompt ¶
func (s *AgentSession) GetSystemPrompt() (string, error)
* Current effective system prompt
func (*AgentSession) GetThinkingLevel ¶
func (s *AgentSession) GetThinkingLevel() (ai.ModelThinkingLevel, error)
* Current thinking level
func (*AgentSession) IsCompacting ¶ added in v0.3.0
func (s *AgentSession) IsCompacting() bool
func (*AgentSession) IsStreaming ¶
func (s *AgentSession) IsStreaming() bool
* Whether agent is currently streaming a response
func (*AgentSession) Prompt ¶
func (s *AgentSession) Prompt(ctx context.Context, text string, options *PromptOptions) error
*
- Send a prompt to the agent.
- - During streaming, queues via steer() or followUp() based on streamingBehavior option
- - Validates model and API key before sending (when not streaming)
- Error if streaming and no streamingBehavior specified
- Error if no model selected or no API key available (when not streaming)
func (*AgentSession) SetCompactionHook ¶ added in v0.3.0
func (s *AgentSession) SetCompactionHook(hook CompactionHook)
SetCompactionHook replaces the compaction hook. Nil restores the default.
func (*AgentSession) SetCompactionSettings ¶ added in v0.3.0
func (s *AgentSession) SetCompactionSettings(settings CompactionSettings)
func (*AgentSession) Subscribe ¶ added in v0.3.0
func (s *AgentSession) Subscribe(listener AgentSessionEventListener) func()
Subscribe receives both forwarded agent events and session-specific events. The returned function removes this registration and is safe to call repeatedly. Changes to subscriptions during an emission apply to subsequent emissions.
type AgentSessionEvent ¶ added in v0.3.0
type AgentSessionEvent interface {
agent.AgentEvent
}
AgentSessionEvent includes ordinary agent events and session-specific events. Consumers can use EventType or a type switch to distinguish them.
type AgentSessionEventListener ¶ added in v0.3.0
type AgentSessionEventListener func(event AgentSessionEvent)
AgentSessionEventListener receives synchronous session notifications. Listeners should return promptly and must not synchronously start or wait for session operations. They may subscribe, unsubscribe, inspect state, or cancel compaction. Queueing with Prompt's StreamingBehavior is also supported.
type BranchSummaryEntry ¶
type BranchSummaryEntry struct {
SessionEntryBase
FromID string `json:"fromId"`
Summary string `json:"summary"`
Details any `json:"details,omitempty"`
FromHook *bool `json:"fromHook,omitempty"`
}
func (*BranchSummaryEntry) GetBase ¶
func (e *BranchSummaryEntry) GetBase() *SessionEntryBase
type BranchSummaryMessage ¶
type BranchSummaryMessage struct {
Role string `json:"role"`
Summary string `json:"summary"`
FromID string `json:"fromId"`
Timestamp int64 `json:"timestamp"`
}
func CreateBranchSummaryMessage ¶
func CreateBranchSummaryMessage(summary, fromID string, timestamp int64) BranchSummaryMessage
func (BranchSummaryMessage) AgentMessageType ¶
func (BranchSummaryMessage) AgentMessageType() string
type CompactFunc ¶ added in v0.3.0
type CompactFunc func(ctx context.Context, req CompactionRequest) (*CompactionResult, error)
CompactFunc produces the compaction result for a request.
type CompactOptions ¶ added in v0.3.0
type CompactOptions struct {
Headers map[string]string
CustomInstructions string
ThinkingLevel ai.ModelThinkingLevel
Prompts SummaryPrompts
}
CompactOptions contains the optional parameters for Compact.
type CompactionEndEvent ¶ added in v0.3.0
type CompactionEndEvent struct {
Type string `json:"type"`
Reason CompactionReason `json:"reason"`
Result *CompactionResult `json:"result,omitempty"`
Aborted bool `json:"aborted"`
// WillRetry refers to overflow recovery, not queued-message continuation.
WillRetry bool `json:"willRetry"`
ErrorMessage string `json:"errorMessage,omitempty"`
// RestoredMessages are steering and follow-up messages, steering first, that
// were queued for the run a manual compaction aborted. They are removed from
// the agent and will not be sent; resend them with Prompt to deliver them.
RestoredMessages []agent.AgentMessage `json:"restoredMessages,omitempty"`
}
CompactionEndEvent is emitted after persistence and context replacement on success, before any retry starts. Result is nil when no compaction completed. Exhausted overflow recovery emits an end event without another start event.
func (CompactionEndEvent) EventType ¶ added in v0.3.0
func (CompactionEndEvent) EventType() string
type CompactionEntry ¶
type CompactionEntry struct {
SessionEntryBase
Summary string `json:"summary"`
FirstKeptEntryID string `json:"firstKeptEntryId"`
TokensBefore int64 `json:"tokensBefore"`
Details any `json:"details,omitempty"`
FromHook *bool `json:"fromHook,omitempty"`
}
func GetLatestCompactionEntry ¶
func GetLatestCompactionEntry(entries []SessionEntry) *CompactionEntry
func (*CompactionEntry) GetBase ¶
func (e *CompactionEntry) GetBase() *SessionEntryBase
type CompactionHook ¶ added in v0.3.0
type CompactionHook func(ctx context.Context, req CompactionRequest, next CompactFunc) (*CompactionResult, error)
CompactionHook wraps manual and automatic compaction. It can call next for the default summary and adjust the result, return its own result, or return ErrCompactionCancelled to skip compaction.
The hook runs with session operations blocked and the agent idle. It must not call AgentSession methods other than AbortCompaction and IsCompacting, and must not write to the session; req.Session gives it read access.
type CompactionPreparation ¶ added in v0.3.0
type CompactionPreparation struct {
FirstKeptEntryID string
MessagesToSummarize []agent.AgentMessage
TurnPrefixMessages []agent.AgentMessage
IsSplitTurn bool
TokensBefore int64
PreviousSummary *string
// PreviousDetails is the previous compaction's Details as JSON, so it reads
// the same before and after a reload. Decode it with DecodeCompactionDetails.
PreviousDetails json.RawMessage
Settings CompactionSettings
}
func PrepareCompaction ¶ added in v0.3.0
func PrepareCompaction( pathEntries []SessionEntry, settings CompactionSettings, ) *CompactionPreparation
type CompactionReason ¶ added in v0.3.0
type CompactionReason string
const ( CompactionReasonManual CompactionReason = "manual" CompactionReasonThreshold CompactionReason = "threshold" CompactionReasonOverflow CompactionReason = "overflow" )
type CompactionRequest ¶ added in v0.3.0
type CompactionRequest struct {
Reason CompactionReason
Preparation *CompactionPreparation
BranchEntries []SessionEntry
// Session is the session being compacted, for reading only.
Session ReadonlySessionManager
CustomInstructions string
// Prompts starts as DefaultSummaryPrompts.
Prompts SummaryPrompts
}
CompactionRequest describes one compaction of the active branch. Hooks may change a copy before passing it to next, but must not modify the entries.
type CompactionResult ¶ added in v0.3.0
type CompactionResult struct {
Summary string
FirstKeptEntryID string
TokensBefore int64
// Details is stored on the CompactionEntry and must marshal to JSON. The next
// compaction receives it as CompactionPreparation.PreviousDetails.
Details any
}
func Compact ¶ added in v0.3.0
func Compact( ctx context.Context, preparation *CompactionPreparation, model ai.Model[ai.API], apiKey string, options *CompactOptions, ) (*CompactionResult, error)
Compact generates summaries from prepared compaction data.
type CompactionSettings ¶ added in v0.3.0
type CompactionStartEvent ¶ added in v0.3.0
type CompactionStartEvent struct {
Type string `json:"type"`
Reason CompactionReason `json:"reason"`
}
func (CompactionStartEvent) EventType ¶ added in v0.3.0
func (CompactionStartEvent) EventType() string
type CompactionSummaryMessage ¶
type CompactionSummaryMessage struct {
Role string `json:"role"`
Summary string `json:"summary"`
TokensBefore int64 `json:"tokensBefore"`
Timestamp int64 `json:"timestamp"`
}
func CreateCompactionSummaryMessage ¶
func CreateCompactionSummaryMessage(summary string, tokensBefore, timestamp int64) CompactionSummaryMessage
func (CompactionSummaryMessage) AgentMessageType ¶
func (CompactionSummaryMessage) AgentMessageType() string
type CreateAgentSessionOptions ¶
type CreateAgentSessionOptions struct {
Model ai.Model[ai.API]
ThinkingLevel ai.ModelThinkingLevel
SessionManager *SessionManager
ModelRegistry *ModelRegistry
AuthStore AuthStore
CompactionSettings *CompactionSettings
// CompactionHook wraps manual and automatic compaction. See CompactionHook.
CompactionHook CompactionHook
SystemPrompt *string
Tools []agent.AgentTool[any, any]
ToolExecutionMode *agent.ToolExecutionMode
/* Optional func to call before each tool call is executed. */
BeforeToolCall func(
ctx context.Context,
call agent.BeforeToolCallContext,
) (*agent.BeforeToolCallResult, error)
/* Optional func to call after each tool call is executed. */
AfterToolCall func(
ctx context.Context,
call agent.AfterToolCallContext[any],
) (*agent.AfterToolCallResult, error)
/* Optional func to call before each payload is sent to the provider. */
OnPayload func(
payload any,
model ai.Model[ai.API],
) (any, error)
/* Optional func to call after each response is received from the provider. */
OnResponse func(
response ai.ProviderResponse,
model ai.Model[ai.API],
) error
}
type CreateAgentSessionResult ¶
type CreateAgentSessionResult struct {
Session *AgentSession
ModelFallbackMessage *string
}
func CreateAgentSession ¶
func CreateAgentSession(ctx context.Context, options CreateAgentSessionOptions) (*CreateAgentSessionResult, error)
CreateAgentSession creates a minimal, generic agent session with no tools.
type CustomEntry ¶
type CustomEntry struct {
SessionEntryBase
CustomType string `json:"customType"`
Data any `json:"data,omitempty"`
}
func (*CustomEntry) GetBase ¶
func (e *CustomEntry) GetBase() *SessionEntryBase
type CustomMessage ¶
type CustomMessage struct {
Role string `json:"role"`
CustomType string `json:"customType"`
Content []ai.UserContent `json:"content"`
Display bool `json:"display"`
Details any `json:"details,omitempty"`
Timestamp int64 `json:"timestamp"`
}
func CreateCustomMessage ¶
func CreateCustomMessage(customType string, content []ai.UserContent, display bool, details any, timestamp int64) CustomMessage
func (CustomMessage) AgentMessageType ¶
func (CustomMessage) AgentMessageType() string
type CustomMessageEntry ¶
type CustomMessageEntry struct {
SessionEntryBase
CustomType string `json:"customType"`
Content []ai.UserContent `json:"content"`
Details any `json:"details,omitempty"`
Display bool `json:"display"`
}
func (*CustomMessageEntry) GetBase ¶
func (e *CustomMessageEntry) GetBase() *SessionEntryBase
type CutPointResult ¶ added in v0.3.0
func FindCutPoint ¶ added in v0.3.0
func FindCutPoint(entries []SessionEntry, startIndex, endIndex int, keepRecentTokens int64) CutPointResult
FindCutPoint finds the entry that keeps approximately keepRecentTokens.
type EnvAuthStore ¶
type EnvAuthStore struct{}
EnvAuthStore resolves API keys from environment variables.
type GenerateSummaryOptions ¶ added in v0.3.0
type GenerateSummaryOptions struct {
Headers map[string]string
CustomInstructions string
PreviousSummary string
ThinkingLevel ai.ModelThinkingLevel
Prompts SummaryPrompts
}
type LabelEntry ¶
type LabelEntry struct {
SessionEntryBase
TargetID string `json:"targetId"`
Label *string `json:"label,omitempty"`
}
func (*LabelEntry) GetBase ¶
func (e *LabelEntry) GetBase() *SessionEntryBase
type LoadedSession ¶ added in v0.3.0
type LoadedSession struct {
Header SessionHeader
// Entries holds every branch, in append order.
Entries []SessionEntry
// CurrentEntryID is the current position: the entry the next append
// attaches to. Nil with entries present means "before the first entry",
// so the next append starts a new root.
CurrentEntryID *string
}
LoadedSession is a stored session with every entry it has.
type ManualCompactionOptions ¶ added in v0.3.0
type ManualCompactionOptions struct {
CustomInstructions string
}
type MessageDecoder ¶ added in v0.3.0
type MessageDecoder func(data []byte) (agent.AgentMessage, error)
MessageDecoder decodes the JSON of an agent message with a registered role.
type ModelChangeEntry ¶
type ModelChangeEntry struct {
SessionEntryBase
Provider string `json:"provider"`
ModelID string `json:"modelId"`
}
func (*ModelChangeEntry) GetBase ¶
func (e *ModelChangeEntry) GetBase() *SessionEntryBase
type ModelRegistry ¶
type ModelRegistry struct {
// contains filtered or unexported fields
}
ModelRegistry provides model lookup and request auth resolution.
func NewModelRegistry ¶
func NewModelRegistry(auth AuthStore) *ModelRegistry
NewModelRegistry creates a registry using the built-in ai.Models list.
func NewModelRegistryWithModels ¶
func NewModelRegistryWithModels(auth AuthStore, models map[ai.Provider]map[string]ai.Model[ai.API]) *ModelRegistry
NewModelRegistryWithModels creates a registry using an explicit model set.
func (*ModelRegistry) APIKeyAndHeaders ¶
func (r *ModelRegistry) APIKeyAndHeaders(model ai.Model[ai.API]) (RequestAuth, error)
APIKeyAndHeaders resolves the API key and headers to use for a model request.
func (*ModelRegistry) APIKeyForProvider ¶
func (r *ModelRegistry) APIKeyForProvider(provider ai.Provider) (string, bool)
APIKeyForProvider resolves a provider API key.
func (*ModelRegistry) All ¶
func (r *ModelRegistry) All() []ai.Model[ai.API]
All returns every model in deterministic provider/id order.
func (*ModelRegistry) Available ¶
func (r *ModelRegistry) Available() []ai.Model[ai.API]
Available returns models whose provider has configured auth.
func (*ModelRegistry) HasConfiguredAuth ¶
HasConfiguredAuth reports whether a model's provider has an API key.
func (*ModelRegistry) ProviderDisplayName ¶
func (r *ModelRegistry) ProviderDisplayName(provider ai.Provider) string
ProviderDisplayName returns a human-friendly provider name.
type PromptOptions ¶
type PromptOptions struct {
Images []ai.ImageContent
/** When streaming, how to queue the message: "steer" (interrupt) or "followUp" (wait). Required if streaming. */
StreamingBehavior StreamingBehavior
}
type ReadonlySessionManager ¶ added in v0.3.0
type ReadonlySessionManager interface {
GetSessionID() string
GetHeader() *SessionHeader
GetSessionName() *string
GetLeafID() *string
GetLeafEntry() SessionEntry
GetEntry(id string) SessionEntry
GetChildren(parentID string) []SessionEntry
GetLabel(id string) *string
GetBranch(from ...string) []SessionEntry
GetBranches() []SessionBranch
GetEntries() []SessionEntry
GetTree() []*SessionTreeNode
BuildSessionContext() SessionContext
}
ReadonlySessionManager is the read side of SessionManager, for code such as hooks that may inspect the session but must not write to it.
type RequestAuth ¶
RequestAuth is the request-level auth and headers resolved for a model.
type SessionBranch ¶ added in v0.3.0
type SessionBranch struct {
// LeafID is the branch's last entry. SetLeaf(LeafID) switches to it.
LeafID string
// BranchPointID is the nearest entry above the leaf with more than one
// child, where this branch splits from its siblings. It is nil when the
// branch splits from another root, or the session has a single branch.
BranchPointID *string
// FirstEntryID is the first entry after BranchPointID. The branch's own
// entries run from it to LeafID.
FirstEntryID string
// Label is the label nearest the leaf on the branch's own entries.
Label *string
// FirstMessage is the text of the first user message on the branch's own
// entries. If they have none, as when a reply was regenerated, it is the
// last user message before them.
FirstMessage string
// Active reports whether the current position is on the branch's own
// entries. At a branch point, before the next append, no branch is active.
Active bool
}
SessionBranch is one branch of a session's entry tree: the path from the root to a leaf, an entry with no children.
type SessionContext ¶
type SessionContext struct {
Messages []agent.AgentMessage
ThinkingLevel string
Model *SessionModel
}
func BuildSessionContext ¶
func BuildSessionContext(entries []SessionEntry, leafID *string, byID map[string]SessionEntry) SessionContext
type SessionEntry ¶
type SessionEntry interface{ GetBase() *SessionEntryBase }
func UnmarshalSessionEntry ¶ added in v0.3.0
func UnmarshalSessionEntry(data []byte) (SessionEntry, error)
UnmarshalSessionEntry decodes an entry encoded by MarshalSessionEntry. Unknown entry types, message roles, and content types are errors, so a partially decoded entry never reaches the agent's context.
type SessionEntryBase ¶
type SessionHeader ¶
type SessionHeader struct {
Type string `json:"type"`
Version int `json:"version,omitempty"`
ID string `json:"id"`
Timestamp string `json:"timestamp"`
ParentSession *string `json:"parentSession,omitempty"`
Name *string `json:"name,omitempty"`
Metadata map[string]any `json:"metadata,omitempty"`
}
func NewDefaultSessionHeader ¶
func NewDefaultSessionHeader(parentSession *string, metadata map[string]any) *SessionHeader
NewDefaultSessionHeader returns a header for a new session with a fresh ID.
type SessionInfo ¶
type SessionInfo struct {
ID string
// Name is the latest session_info entry's name, or nil if that entry
// cleared it. Without any session_info entry a store may supply its own
// name, such as one generated from the first message.
Name *string
ParentSessionID *string
// Created is the header timestamp.
Created time.Time
// Modified is when the store last appended an entry, or Created if it
// has none.
Modified time.Time
// MessageCount counts message entries across every branch.
MessageCount int
// FirstMessage is the text of the first user message with any text, in
// append order, or "" if there is none.
FirstMessage string
Metadata map[string]any
}
SessionInfo summarizes a stored session for listing.
func BuildSessionInfo ¶ added in v0.3.0
func BuildSessionInfo(header SessionHeader, entries []SessionEntry, modified time.Time) SessionInfo
BuildSessionInfo derives SessionInfo from a session's header and entries in append order. modified is the store's time of the last append; pass the zero time when there are no entries. Stores that keep these values in columns should update them the same way on each append.
func FindMostRecentSession ¶ added in v0.3.0
func FindMostRecentSession(ctx context.Context, store SessionStore, metadata map[string]any) (*SessionInfo, error)
FindMostRecentSession returns the most recently modified session matching metadata, or nil if there is none.
type SessionInfoEntry ¶
type SessionInfoEntry struct {
SessionEntryBase
Name *string `json:"name,omitempty"`
}
func (*SessionInfoEntry) GetBase ¶
func (e *SessionInfoEntry) GetBase() *SessionEntryBase
type SessionManager ¶
type SessionManager struct {
// contains filtered or unexported fields
}
SessionManager holds a session's entry tree and current position, and saves changes through a SessionStore when persisted. It is safe for concurrent use.
Its methods only lock mu and delegate to state. Writes hold mu across their store call, so each entry's parent is the position the previous write left, and reads wait for an in-flight write rather than see the state before it.
func InMemorySessionManager ¶
func InMemorySessionManager(ctx context.Context) (*SessionManager, error)
func NewSessionManager ¶
func NewSessionManager(ctx context.Context, header *SessionHeader, sessionID *string, persist bool, store SessionStore, metadata map[string]any) (*SessionManager, error)
NewSessionManager loads the stored session sessionID, or creates a new session when sessionID is nil. A new session uses header, with any empty fields filled in: pass &SessionHeader{ID: id} for a custom session ID. metadata is used when header has none.
func (*SessionManager) AppendCompaction ¶
func (*SessionManager) AppendCustomEntry ¶
func (*SessionManager) AppendCustomMessageEntry ¶
func (s *SessionManager) AppendCustomMessageEntry(ctx context.Context, t string, c []ai.UserContent, display bool, details any) (string, error)
func (*SessionManager) AppendLabelChange ¶
func (s *SessionManager) AppendLabelChange(ctx context.Context, target string, label *string) (string, error)
AppendLabelChange sets the label of an entry, or clears it when label is nil or empty.
func (*SessionManager) AppendMessage ¶
func (s *SessionManager) AppendMessage(ctx context.Context, m agent.AgentMessage) (string, error)
func (*SessionManager) AppendMessageWithID ¶ added in v0.1.3
func (s *SessionManager) AppendMessageWithID(ctx context.Context, id string, m agent.AgentMessage) (string, error)
AppendMessageWithID appends a message with the given entry ID, or a fresh one when id is empty.
func (*SessionManager) AppendModelChange ¶
func (*SessionManager) AppendSessionInfo ¶
func (*SessionManager) AppendThinkingLevelChange ¶
func (*SessionManager) BranchWithSummary ¶ added in v0.3.0
func (s *SessionManager) BranchWithSummary(ctx context.Context, from *string, summary string, details any, fromHook *bool) (string, error)
BranchWithSummary moves the current position to from, or before the first entry when from is nil, and appends a summary there of the branch being left.
func (*SessionManager) BuildSessionContext ¶
func (s *SessionManager) BuildSessionContext() SessionContext
func (*SessionManager) Fork ¶ added in v0.3.0
func (s *SessionManager) Fork(ctx context.Context, leafID *string) (*SessionManager, error)
Fork creates a new session from the path from the root to leafID, which then continues independently of this one. The entries keep their IDs. Labels on the path are carried over as new label entries after it, keeping their timestamps. A nil leafID forks from the root, giving a session with no entries. The fork is saved through this manager's store when persisted.
func (*SessionManager) GetBranch ¶
func (s *SessionManager) GetBranch(from ...string) []SessionEntry
GetBranch returns the path from the root to from, or to the current position when from is omitted.
func (*SessionManager) GetBranches ¶ added in v0.3.0
func (s *SessionManager) GetBranches() []SessionBranch
GetBranches returns every branch of the entry tree, in tree order: depth first, with children in append order.
func (*SessionManager) GetChildren ¶
func (s *SessionManager) GetChildren(parentID string) []SessionEntry
GetChildren returns the entries whose parent is parentID, in append order.
func (*SessionManager) GetEntries ¶
func (s *SessionManager) GetEntries() []SessionEntry
GetEntries returns every entry across all branches, in append order.
func (*SessionManager) GetEntry ¶
func (s *SessionManager) GetEntry(id string) SessionEntry
func (*SessionManager) GetHeader ¶
func (s *SessionManager) GetHeader() *SessionHeader
GetHeader returns a copy of the session header.
func (*SessionManager) GetLabel ¶
func (s *SessionManager) GetLabel(id string) *string
func (*SessionManager) GetLeafEntry ¶
func (s *SessionManager) GetLeafEntry() SessionEntry
func (*SessionManager) GetLeafID ¶
func (s *SessionManager) GetLeafID() *string
func (*SessionManager) GetSessionID ¶
func (s *SessionManager) GetSessionID() string
func (*SessionManager) GetSessionName ¶
func (s *SessionManager) GetSessionName() *string
func (*SessionManager) GetTree ¶
func (s *SessionManager) GetTree() []*SessionTreeNode
GetTree returns the entry tree, with children in append order.
func (*SessionManager) IsPersisted ¶
func (s *SessionManager) IsPersisted() bool
func (*SessionManager) LoadSession ¶
func (s *SessionManager) LoadSession(ctx context.Context, id string) error
LoadSession switches the manager to a stored session, resuming at its saved position. On error the manager is unchanged.
func (*SessionManager) NewSession ¶
func (s *SessionManager) NewSession(ctx context.Context, header *SessionHeader, metadata map[string]any) error
NewSession switches the manager to a new, empty session. See NewSessionManager for header and metadata. On error the manager is unchanged.
func (*SessionManager) Reload ¶ added in v0.3.0
func (s *SessionManager) Reload(ctx context.Context) error
Reload replaces the manager's state with the stored session, such as after ErrSessionConflict reports that another writer changed it.
type SessionMessageEntry ¶
type SessionMessageEntry struct {
SessionEntryBase
Message agent.AgentMessage `json:"message"`
}
func (*SessionMessageEntry) GetBase ¶
func (e *SessionMessageEntry) GetBase() *SessionEntryBase
type SessionModel ¶
type SessionModel struct{ Provider, ModelID string }
type SessionQuery ¶ added in v0.3.0
type SessionQuery struct {
// Metadata matches sessions whose header metadata has every key with an
// equal value. Nil or empty matches every session.
Metadata map[string]any
// Limit caps the number of sessions returned. Zero means no limit.
Limit int
}
SessionQuery selects sessions for ListSessions.
type SessionStore ¶
type SessionStore interface {
CreateSession(ctx context.Context, header SessionHeader, entries []SessionEntry) error
AppendEntry(ctx context.Context, sessionID string, entry SessionEntry) error
SetCurrentEntry(ctx context.Context, sessionID string, expected, entryID *string) error
LoadSession(ctx context.Context, sessionID string) (LoadedSession, error)
ListSessions(ctx context.Context, query SessionQuery) ([]SessionInfo, error)
}
SessionStore persists sessions. baseAgent ships no implementation, so any database can back it. sessionstoretest.Run checks an implementation against the rules below, and MarshalSessionEntry and UnmarshalSessionEntry encode entries for storage.
Ordering and scope:
- Entries come back in append order. Use an insertion sequence, not entry timestamps or IDs, which do not sort in append order.
- LoadSession returns all of a session's entries across every branch. baseAgent works out the active path itself.
- Entry IDs are unique per session, not globally: key entries by (session ID, entry ID). Forks keep their source entries' IDs.
Position and conflicts:
- Every session has a current position, which AppendEntry and SetCurrentEntry move. It is how baseAgent detects another writer.
- AppendEntry is safe to retry. Appending an entry whose ID the session already has succeeds without changing anything; check this before the conflict check, so a retry of a write that landed is not a conflict.
- Otherwise AppendEntry returns ErrSessionConflict unless entry.ParentID equals the current position (both nil counts as equal). On success the entry becomes the current position.
- SetCurrentEntry returns ErrSessionConflict unless expected equals the current position. Branching within a session has no method of its own: it is SetCurrentEntry followed by AppendEntry.
- The conflict check is a safety net, not a scheduler. Deployments should keep one live AgentSession per session, through sticky routing or a lease.
Creating and forking:
- CreateSession is all-or-nothing. It returns ErrSessionExists if the header ID is taken, and fails without storing anything if any entry cannot be stored, such as one with a duplicate ID. The current position is the last entry, or nil without entries.
- A fork is CreateSession with header.ParentSession set and the copied entries, which keep their IDs. Its entries are empty for a fork from the root. A fork is independent of its source once created.
Session info: stores derive SessionInfo themselves, as BuildSessionInfo does. ListSessions sorts by Modified, newest first.
Methods given an unknown session ID return an error wrapping ErrSessionNotFound. Stores must not modify the headers and entries passed to them.
type SessionTreeNode ¶
type SessionTreeNode struct {
Entry SessionEntry `json:"entry"`
Children []*SessionTreeNode `json:"children"`
Label *string `json:"label,omitempty"`
LabelTimestamp *string `json:"labelTimestamp,omitempty"`
}
type StreamingBehavior ¶
type StreamingBehavior string
const ( StreamingBehaviorSteer StreamingBehavior = "steer" StreamingBehaviorFollowUp StreamingBehavior = "followUp" )
type SummaryPrompts ¶ added in v0.3.0
type SummaryPrompts struct {
System string
// Initial asks for a new summary; Update merges into <previous-summary>.
Initial string
Update string
TurnPrefix string
}
SummaryPrompts are the prompts used to generate compaction summaries. Empty fields use the defaults from DefaultSummaryPrompts.
func DefaultSummaryPrompts ¶ added in v0.3.0
func DefaultSummaryPrompts() SummaryPrompts
type ThinkingLevelChangeEntry ¶
type ThinkingLevelChangeEntry struct {
SessionEntryBase
ThinkingLevel string `json:"thinkingLevel"`
}
func (*ThinkingLevelChangeEntry) GetBase ¶
func (e *ThinkingLevelChangeEntry) GetBase() *SessionEntryBase
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package sessionstoretest checks baseAgent.SessionStore implementations against the contract documented on baseAgent.SessionStore.
|
Package sessionstoretest checks baseAgent.SessionStore implementations against the contract documented on baseAgent.SessionStore. |