context

package
v0.100.1 Latest Latest
Warning

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

Go to latest
Published: Feb 17, 2026 License: MIT Imports: 15 Imported by: 0

README

AI Context Management (ai/context)

context 包是 AI Agent 的核心组件之一,负责构建、管理和优化发送给 LLM 的上下文窗口 (Context Window)。它实现了动态 Token 预算分配、增量上下文更新 (Delta Update) 和长短期记忆管理。

架构设计

classDiagram
    class ContextBuilder {
        <<interface>>
        +Build(ctx, req)
    }
    class IncrementalBuilder {
        -baseBuilder Service
        -deltaBuilder DeltaBuilder
        +BuildIncremental()
    }
    class BudgetAllocator {
        +Allocate(total, hasRetrieval)
        +AllocateForAgent(total, type)
    }
    class EpisodicProvider {
        <<interface>>
        +SearchEpisodes()
    }
    
    ContextBuilder <|.. Service : implements
    Service --> BudgetAllocator : uses
    Service --> EpisodicProvider : uses
    IncrementalBuilder --> Service : decorates
    IncrementalBuilder --> DeltaBuilder : uses

该包包含以下核心模块:

  1. BudgetAllocator (预算分配器): 负责根据 Agent 类型和配置,计算各类信息(系统提示词、短期记忆、长期记忆、检索内容)的 Token 配额。
  2. ContextBuilder (上下文构建器): 编排整个构建流程,从不同源(Memory, RAG, User Profile)拉取数据并组装。
  3. DeltaBuilder (增量构建器): 实现高效的上下文更新策略,计算前后两次请求的差异,支持 System Prompt Caching。
  4. EpisodicProvider (情景记忆提供者): 基于向量搜索的长短期记忆检索接口。

算法设计

1. 动态 Token 预算分配

根据 TokenBudget 结构进行分配。

  • 基础分配: 预留 System Prompt 和 User Preferences。
  • 剩余分配: 根据是否有检索结果 (RAG),动态调整 Short-term Memory (STM) 和 Long-term Memory (LTM) 的比例。
    • 有 RAG: 侧重 RAG 内容 (45%),减少 STM (40%)。
    • 无 RAG: 侧重 STM (55%)。
  • 长对话自适应: 当对话轮数超过阈值 (HistoryLengthThreshold=20),自动压缩 STM 的比例,增加 LTM 配额,以应对超长上下文产生的“遗忘”问题。
2. 增量上下文更新 (Incremental Update)

为了配合支持 Context Caching 的 LLM (如 DeepSeek, Claude),实现了多种更新策略:

  • ComputeDelta: 计算并仅发送变化的部分(如新增的 Retrieval Items, 新的 Query)。
  • AppendOnly: 仅追加新消息,复用之前的 System Prompt 前缀 Hash。
  • UpdateConversationOnly: 当 System Prompt 未变时,仅更新对话列表部分。
  • 通过 SHA256 Hash 比对 System Prompt、User Prefs 等静态区块,决定使用哪种策略。
3. 多级记忆检索
  • 短期记忆: 也就是最近的 N 轮对话历史。
  • 长期记忆 (Episodic): 使用向量相似度 (Embedding + Vector Search) 从历史 Memo 或 Episode 中检索与当前 Query 相关的片段。

业务流程

sequenceDiagram
    participant User
    participant Handler
    participant ContextBuilder
    participant Budget
    participant Store
    
    User->>Handler: Send Message
    Handler->>ContextBuilder: Build(Request)
    ContextBuilder->>Budget: Allocate()
    Budget-->>ContextBuilder: TokenBudget
    
    par Parallel Fetch
        ContextBuilder->>Store: Get History (STM)
        ContextBuilder->>Store: Vector Search (LTM/RAG)
        ContextBuilder->>Store: Get User Profile
    end
    
    ContextBuilder->>ContextBuilder: Prune & Assemble
    ContextBuilder-->>Handler: ContextResult (Prompt)
  1. 请求接入: 接收 ContextRequest,包含 SessionID, Query, UserID 等。
  2. 预算计算: BudgetAllocator 计算当前请求的 Token 分布。
  3. 策略选择: DeltaBuilder 检查是否有可复用的上一轮 Snapshot,选择更新策略。
  4. 内容组装:
    • 获取 System Prompt (可能包含 Template 渲染)。
    • 获取 User Preferences (时区、语言风格)。
    • 获取短期对话历史 (Pruning 到预算范围内)。
    • 执行 RAG / Episodic Search 获取相关背景信息。
  5. 输出生成: 返回 ContextResult,包含最终拼接好的 Prompt 字符串和各部分 Token 统计。

依赖

  • ai/core/embedding: 用于向量化。
  • store: 用于向量存储访问。

Documentation

Overview

Package context provides context building for LLM prompts.

Package context provides budget profiles for dynamic token allocation. Issue #93: 动态 Token 预算分配 - 按意图类型自适应调整

Package context provides context building for LLM prompts. It orchestrates short-term memory, long-term memory, and retrieval results into an optimized context window for LLM inference.

Package context provides context building for LLM prompts.

Package context provides incremental context building for multi-turn conversations. This module implements Issue #94: Incremental context updates with 70% reduction in round 2 and 82% reduction in round 5.

Package context provides context building for LLM prompts.

Package context provides context building for LLM prompts.

Package context provides context building for LLM prompts.

Package context provides context building for LLM prompts.

Index

Constants

View Source
const (
	DefaultMaxTokens      = 4096
	DefaultSystemPrompt   = 500
	DefaultUserPrefsRatio = 0.10
	DefaultRetrievalRatio = 0.45 // Updated per best practices
	MinSegmentTokens      = 100
)

Default token budget values.

Token allocation strategy (with retrieval): - System Prompt: 500 tokens (fixed) - User Preferences: 10% - Short-term Memory: 40% - Long-term Memory: 15% - Retrieval Results: 45%

Reference: docs/agent-engineering/AGENT_PROMPT_BEST_PRACTICES.md

View Source
const (
	// HistoryLengthThreshold is the number of turns after which dynamic adjustment kicks in
	// Triggers when historyLength > 20 (i.e., at 21+ turns)
	HistoryLengthThreshold = 20
	// ShortTermReductionRatio is how much to reduce ShortTerm when conversation is long
	ShortTermReductionRatio = 0.375 // Reduce from 40% to 25% (40% * 0.375 = 15% reduction)
	// LongTermIncreaseRatio is how much to increase LongTerm/Retrieval when conversation is long
	LongTermIncreaseRatio = 0.333 // Increase from 15% to 20% (15% * 0.333 ≈ 5% increase)
)

Dynamic budget adjustment thresholds (Issue #211: Phase 3)

View Source
const (
	// ServiceBlockStore is the AIBlock storage service
	ServiceBlockStore = "block_store"
	// ServiceVectorSearch is the vector search service
	ServiceVectorSearch = "vector_search"
	// ServiceEmbedding is the embedding generation service
	ServiceEmbedding = "embedding"
	// ServiceMetadataMgr is the metadata manager
	ServiceMetadataMgr = "metadata_manager"
	// ServiceContextBuilder is the main context builder
	ServiceContextBuilder = "context_builder"
	// ServiceMessageProvider is the message provider
	ServiceMessageProvider = "message_provider"
	// ServiceEpisodicProvider is the episodic memory provider
	ServiceEpisodicProvider = "episodic_provider"
)

Service name constants for type-safe access.

Variables

View Source
var DefaultBudgetProfiles = map[string]*BudgetProfile{
	"memo_search": {
		Name:           "memo_search",
		Description:    "Memo search intent - prioritize retrieval results",
		ShortTermRatio: 0.30,
		LongTermRatio:  0.10,
		RetrievalRatio: 0.60,
		UserPrefsRatio: 0.10,
	},
	"schedule_create": {
		Name:           "schedule_create",
		Description:    "Schedule creation - moderate conversation, low retrieval",
		ShortTermRatio: 0.55,
		LongTermRatio:  0.25,
		RetrievalRatio: 0.20,
		UserPrefsRatio: 0.10,
	},
	"schedule_query": {
		Name:           "schedule_query",
		Description:    "Schedule query - moderate conversation, low retrieval",
		ShortTermRatio: 0.55,
		LongTermRatio:  0.25,
		RetrievalRatio: 0.20,
		UserPrefsRatio: 0.10,
	},
	"amazing": {
		Name:           "amazing",
		Description:    "Amazing parrot - balanced allocation",
		ShortTermRatio: 0.40,
		LongTermRatio:  0.15,
		RetrievalRatio: 0.45,
		UserPrefsRatio: 0.10,
	},
	"geek": {
		Name:           "geek",
		Description:    "Geek parrot - no LLM budget (Claude Code CLI manages context)",
		ShortTermRatio: 0.00,
		LongTermRatio:  0.00,
		RetrievalRatio: 0.00,
		UserPrefsRatio: 0.00,
	},
	"evolution": {
		Name:           "evolution",
		Description:    "Evolution parrot - no LLM budget (Claude Code CLI manages context)",
		ShortTermRatio: 0.00,
		LongTermRatio:  0.00,
		RetrievalRatio: 0.00,
		UserPrefsRatio: 0.00,
	},
	"default": {
		Name:           "default",
		Description:    "Fallback profile - balanced allocation",
		ShortTermRatio: 0.40,
		LongTermRatio:  0.15,
		RetrievalRatio: 0.45,
		UserPrefsRatio: 0.10,
	},
}

DefaultBudgetProfiles returns the built-in profile registry.

Functions

func EstimateTokens

func EstimateTokens(content string) int

EstimateTokens estimates the token count for a string. Uses heuristic: Chinese chars count as ~2 tokens, ASCII as ~0.3 tokens per char.

func FormatConversation

func FormatConversation(messages []*Message) string

FormatConversation formats messages into conversation context.

func FormatEpisodes

func FormatEpisodes(episodes []*EpisodicMemory) string

FormatEpisodes formats episodic memories into context.

func FormatPreferences

func FormatPreferences(prefs *UserPreferences) string

FormatPreferences formats user preferences into context.

func GetAgentType added in v0.100.1

func GetAgentType(ctx context.Context) string

GetAgentType extracts agent type from orchestrator context. Returns empty string if not set.

func GetBlockID added in v0.100.1

func GetBlockID(ctx context.Context) (int64, bool)

GetBlockID extracts block ID from orchestrator context. Returns 0 and false if not set.

func GetConversationID added in v0.100.1

func GetConversationID(ctx context.Context) (int32, bool)

GetConversationID extracts conversation ID from orchestrator context. Returns 0 and false if not set.

func GetHistory added in v0.100.1

func GetHistory(ctx context.Context) []string

GetHistory extracts conversation history from orchestrator context. Returns an empty slice if not set.

func GetSessionID added in v0.100.1

func GetSessionID(ctx context.Context) string

GetSessionID extracts session ID from orchestrator context. Returns empty string if not set.

func GetUserID added in v0.100.1

func GetUserID(ctx context.Context) (int32, bool)

GetUserID extracts user ID from orchestrator context. Returns 0 and false if not set.

func InitializeContextEngine added in v0.100.0

func InitializeContextEngine(
	blockStore store.AIBlockStore,
	cfg *ContextEngineConfig,
	userID int32,
) (*Service, *MetadataManager, *Container, error)

InitializeContextEngine sets up the entire context building infrastructure. This is the main entry point for context engine initialization.

func ParseSessionID added in v0.100.0

func ParseSessionID(sessionID string) (int32, error)

ParseSessionID extracts conversationID from sessionID. Supported formats:

  • "conv_<conversationID>" (e.g., "conv_123")
  • Direct conversationID as string (e.g., "123")

func WithOrchestratorContext added in v0.100.1

func WithOrchestratorContext(ctx context.Context, oc *OrchestratorContext) context.Context

WithOrchestratorContext returns a new context with orchestrator data. This follows the standard Go context pattern for request-scoped values.

Types

type Block added in v0.100.0

type Block struct {
	ID               int64
	ConversationID   int32
	RoundNumber      int32
	UserInputs       []UserInputView
	AssistantContent string
	AssistantTs      int64
	Metadata         map[string]any
	CreatedTs        int64
}

Block represents a minimal view of AIBlock for context building. This decouples the context package from the full store package.

type BlockStore added in v0.100.0

type BlockStore interface {
	// ListBlocks retrieves blocks for a conversation
	ListBlocks(ctx context.Context, conversationID int32) ([]*Block, error)

	// GetLatestBlock retrieves the most recent block for a conversation
	GetLatestBlock(ctx context.Context, conversationID int32) (*Block, error)
}

BlockStore defines the minimal block storage operations needed by context builder. This follows Interface Segregation Principle (ISP) - only the methods we need.

type BlockStoreMessageProvider added in v0.100.0

type BlockStoreMessageProvider struct {
	// contains filtered or unexported fields
}

BlockStoreMessageProvider implements MessageProvider using AIBlockStore. This decouples frontend from history management, following the "Backend as Source of Truth" principle from context-engineering.md.

func NewBlockStoreMessageProvider added in v0.100.0

func NewBlockStoreMessageProvider(store BlockStore, userID int32) *BlockStoreMessageProvider

NewBlockStoreMessageProvider creates a new block-based message provider.

func (*BlockStoreMessageProvider) GetBlockCount added in v0.100.0

func (p *BlockStoreMessageProvider) GetBlockCount(ctx context.Context, conversationID int32) (int, error)

GetBlockCount returns the number of blocks for a conversation. Used by GetHistoryLength for accurate conversation turn counting.

func (*BlockStoreMessageProvider) GetRecentMessages added in v0.100.0

func (p *BlockStoreMessageProvider) GetRecentMessages(
	ctx context.Context,
	sessionID string,
	limit int,
) ([]*Message, error)

GetRecentMessages retrieves recent messages from block store. Implements MessageProvider interface.

type BudgetAllocator

type BudgetAllocator struct {
	// contains filtered or unexported fields
}

BudgetAllocator allocates token budgets.

func NewBudgetAllocator

func NewBudgetAllocator() *BudgetAllocator

NewBudgetAllocator creates a new budget allocator with defaults.

func (*BudgetAllocator) Allocate

func (a *BudgetAllocator) Allocate(total int, hasRetrieval bool) *TokenBudget

Allocate allocates token budget based on total and whether retrieval is needed.

func (*BudgetAllocator) AllocateForAgent added in v0.94.0

func (a *BudgetAllocator) AllocateForAgent(total int, hasRetrieval bool, agentType string) *TokenBudget

AllocateForAgent allocates token budget based on agent type (profile-based). Issue #93: 动态 Token 预算分配 - 按意图类型自适应调整

func (*BudgetAllocator) AllocateForAgentWithHistory added in v0.100.0

func (a *BudgetAllocator) AllocateForAgentWithHistory(total int, hasRetrieval bool, agentType string, historyLength int) *TokenBudget

AllocateForAgentWithHistory allocates token budget based on agent type and conversation length. Issue #211: Phase 3 - Dynamic budget adjustment based on conversation turns When conversation exceeds 20 turns (historyLength > 20, i.e., 21+ turns), it compresses ShortTerm and increases LongTerm/Retrieval to handle long conversations more efficiently. Note: Has a maximum adjustment cap to prevent over-compression for extremely long conversations.

func (*BudgetAllocator) LoadProfileFromEnv added in v0.94.0

func (a *BudgetAllocator) LoadProfileFromEnv()

LoadProfileFromEnv loads profile overrides from environment variables.

func (*BudgetAllocator) WithIntentResolver added in v0.94.0

func (a *BudgetAllocator) WithIntentResolver(resolver *IntentResolver) *BudgetAllocator

WithIntentResolver sets a custom intent resolver.

func (*BudgetAllocator) WithProfileRegistry added in v0.94.0

func (a *BudgetAllocator) WithProfileRegistry(registry *ProfileRegistry) *BudgetAllocator

WithProfileRegistry sets a custom profile registry.

type BudgetProfile added in v0.94.0

type BudgetProfile struct {
	Name        string
	Description string

	// Token allocation ratios for the remaining budget (after SystemPrompt + UserPrefs)
	// Must sum to 1.0
	ShortTermRatio float64
	LongTermRatio  float64
	RetrievalRatio float64

	// Fixed ratios
	UserPrefsRatio float64 // Default: 0.10
}

BudgetProfile defines token allocation ratios for different intents.

type CacheProvider

type CacheProvider interface {
	Get(ctx context.Context, key string) ([]byte, bool)
	Set(ctx context.Context, key string, value []byte, ttl time.Duration) error
}

CacheProvider provides caching functionality.

type Config

type Config struct {
	MaxTurns    int           // Max conversation turns (default: 10)
	MaxEpisodes int           // Max episodic memories (default: 3)
	MaxTokens   int           // Default max tokens (default: 4096)
	CacheTTL    time.Duration // Cache TTL (default: 5 minutes)
}

Config configures the context builder service.

func DefaultConfig

func DefaultConfig() Config

DefaultConfig returns default configuration.

type Container added in v0.100.0

type Container struct {
	// contains filtered or unexported fields
}

Container manages dependencies for context building. This implements Dependency Injection following the Dependency Inversion Principle (DIP). High-level modules (context building) depend on abstractions (interfaces), not concrete implementations.

func NewContainer added in v0.100.0

func NewContainer() *Container

NewContainer creates a new dependency container.

func (*Container) Clear added in v0.100.0

func (c *Container) Clear()

Clear removes all services from the container.

func (*Container) Get added in v0.100.0

func (c *Container) Get(name string) (interface{}, bool)

Get retrieves a service by name. P0 fix: use double-checked locking to prevent race condition in lazy initialization.

func (*Container) Has added in v0.100.0

func (c *Container) Has(name string) bool

Has checks if a service is registered.

func (*Container) MustGet added in v0.100.0

func (c *Container) MustGet(name string) interface{}

MustGet retrieves a service or panics.

func (*Container) Register added in v0.100.0

func (c *Container) Register(name string, service interface{})

Register registers a service instance.

func (*Container) RegisterBuilder added in v0.100.0

func (c *Container) RegisterBuilder(name string, builder func() interface{})

RegisterBuilder registers a lazy service builder. The builder is called on first Get() and the result is cached.

func (*Container) Remove added in v0.100.0

func (c *Container) Remove(name string)

Remove removes a service from the container.

type ContextBuilder

type ContextBuilder interface {
	// Build constructs the full context from various sources.
	Build(ctx context.Context, req *ContextRequest) (*ContextResult, error)

	// BuildHistory constructs history in []string format for ParrotAgent.Execute.
	// Returns alternating user/assistant messages: [user1, assistant1, user2, assistant2, ...]
	// This enables backend-driven context construction (context-engineering.md Phase 1).
	BuildHistory(ctx context.Context, req *ContextRequest) ([]string, error)

	// GetStats returns context building statistics.
	GetStats() *ContextStats
}

ContextBuilder builds optimized context for LLM inference.

type ContextEngineConfig added in v0.100.0

type ContextEngineConfig struct {
	// MaxTurns is the maximum conversation turns to include
	MaxTurns int
	// MaxEpisodes is the maximum episodic memories to retrieve
	MaxEpisodes int
	// MaxTokens is the default token budget
	MaxTokens int
	// CacheTTL is the cache time-to-live
	CacheTTL int // seconds
	// MetadataCacheTTL is the metadata cache TTL in seconds
	MetadataCacheTTL int
	// StickyConfig is the sticky routing configuration
	StickyConfig *StickyConfig
}

ContextEngineConfig holds configuration for the context engine.

func DefaultContextEngineConfig added in v0.100.0

func DefaultContextEngineConfig() *ContextEngineConfig

DefaultContextEngineConfig returns the default configuration.

type ContextPriority

type ContextPriority int

ContextPriority represents the priority level of a context segment.

const (
	PrioritySystem      ContextPriority = 100 // System prompt - highest
	PriorityUserQuery   ContextPriority = 90  // Current user query
	PriorityRecentTurns ContextPriority = 80  // Most recent 3 turns
	PriorityRetrieval   ContextPriority = 70  // RAG retrieval results
	PriorityEpisodic    ContextPriority = 60  // Episodic memory
	PriorityPreferences ContextPriority = 50  // User preferences
	PriorityOlderTurns  ContextPriority = 40  // Older conversation turns
)

type ContextRequest

type ContextRequest struct {
	SessionID        string
	CurrentQuery     string
	AgentType        string
	RetrievalResults []*RetrievalItem
	MaxTokens        int
	UserID           int32
	HistoryLength    int // Number of conversation turns for dynamic budget adjustment
}

ContextRequest contains parameters for context building.

type ContextRequestWithMessages added in v0.94.0

type ContextRequestWithMessages struct {
	ContextRequest
	Messages []*Message
}

ContextRequestWithMessages extends ContextRequest with message history.

type ContextResult

type ContextResult struct {
	TokenBreakdown      *TokenBreakdown
	SystemPrompt        string
	ConversationContext string
	RetrievalContext    string
	UserPreferences     string
	TotalTokens         int
	BuildTime           time.Duration
}

ContextResult contains the built context.

type ContextSegment

type ContextSegment struct {
	Content   string
	Source    string
	Priority  ContextPriority
	TokenCost int
}

ContextSegment represents a piece of context with priority.

func PrioritizeAndTruncate

func PrioritizeAndTruncate(segments []*ContextSegment, budget int) []*ContextSegment

PrioritizeAndTruncate is a convenience function.

type ContextSnapshot added in v0.94.0

type ContextSnapshot struct {
	// Messages in the conversation.
	Messages []*Message

	// Retrieval results.
	RetrievalResults []*RetrievalItem

	// System prompt hash.
	SystemPromptHash string

	// User preferences hash.
	UserPrefsHash string

	// Episodic memories hash.
	EpisodicHash string

	// Timestamp of the snapshot.
	Timestamp time.Time

	// Token count at time of snapshot.
	TokenCount int

	// Query that was processed.
	Query string

	// Agent type used.
	AgentType string
}

ContextSnapshot captures a snapshot of the context for comparison.

func CreateSnapshot added in v0.94.0

func CreateSnapshot(req *ContextRequest, result *ContextResult) *ContextSnapshot

CreateSnapshot creates a snapshot from a context result.

func (*ContextSnapshot) ToJSON added in v0.94.0

func (s *ContextSnapshot) ToJSON() (string, error)

ToJSON converts a snapshot to JSON for debugging.

type ContextStats

type ContextStats struct {
	TotalBuilds      int64
	AverageTokens    float64
	CacheHits        int64
	AverageBuildTime time.Duration
}

ContextStats tracks context building metrics.

type Delta added in v0.94.0

type Delta struct {
	// NewMessages are messages added since last build.
	NewMessages []*Message

	// ModifiedSections are sections that changed.
	ModifiedSections []string

	// RemovedSections are sections that were removed.
	RemovedSections []string

	// NewRetrievalItems are new retrieval results.
	NewRetrievalItems []*RetrievalItem

	// PreviousHash is the hash of the previous context.
	PreviousHash string

	// CurrentHash is the hash of the current context.
	CurrentHash string

	// Strategy used for this delta.
	Strategy UpdateStrategy
}

Delta represents the changes between two context builds.

func (*Delta) ToJSON added in v0.94.0

func (d *Delta) ToJSON() (string, error)

ToJSON converts a delta to JSON for debugging.

type DeltaBuilder added in v0.94.0

type DeltaBuilder struct {
	// contains filtered or unexported fields
}

DeltaBuilder computes deltas between context builds.

func NewDeltaBuilder added in v0.94.0

func NewDeltaBuilder() *DeltaBuilder

NewDeltaBuilder creates a new delta builder.

func (*DeltaBuilder) Clear added in v0.94.0

func (d *DeltaBuilder) Clear()

Clear removes all cached snapshots.

func (*DeltaBuilder) ComputeDelta added in v0.94.0

func (d *DeltaBuilder) ComputeDelta(sessionID string, req *ContextRequest, prevSnapshot *ContextSnapshot) *Delta

ComputeDelta computes the delta between the current request and the previous snapshot.

func (*DeltaBuilder) GetSnapshot added in v0.94.0

func (d *DeltaBuilder) GetSnapshot(sessionID string) *ContextSnapshot

GetSnapshot retrieves the snapshot for a session.

func (*DeltaBuilder) GetStats added in v0.94.0

func (d *DeltaBuilder) GetStats() *DeltaStats

GetStats returns delta building statistics.

func (*DeltaBuilder) SaveSnapshot added in v0.94.0

func (d *DeltaBuilder) SaveSnapshot(sessionID string, snapshot *ContextSnapshot)

SaveSnapshot saves a snapshot for a session.

func (*DeltaBuilder) SelectStrategy added in v0.94.0

func (d *DeltaBuilder) SelectStrategy(req *ContextRequest, prevSnapshot *ContextSnapshot) UpdateStrategy

SelectStrategy selects the optimal update strategy based on the request and previous snapshot.

type DeltaStats added in v0.94.0

type DeltaStats struct {
	TotalDeltas          int64
	DeltaHits            int64
	FullRebuilds         int64
	AppendOnlyHits       int64
	ConversationOnlyHits int64
	AverageDeltaMs       int64
	SavedTokens          int64
	HitRate              float64
}

DeltaStats contains delta building statistics.

type EmbeddingProviderAdapter added in v0.100.0

type EmbeddingProviderAdapter struct {
	// contains filtered or unexported fields
}

EmbeddingProviderAdapter adapts *embedding.Provider to EmbeddingService interface. This allows the core embedding.Provider to be used with EpisodicProviderImpl.

func NewEmbeddingProviderAdapter added in v0.100.0

func NewEmbeddingProviderAdapter(p *embedding.Provider) *EmbeddingProviderAdapter

NewEmbeddingProviderAdapter creates a new adapter.

func (*EmbeddingProviderAdapter) Embed added in v0.100.0

func (a *EmbeddingProviderAdapter) Embed(ctx context.Context, text string) ([]float32, error)

Embed implements EmbeddingService interface.

type EmbeddingService added in v0.100.0

type EmbeddingService interface {
	// Embed generates a vector embedding for the given text.
	// Returns a float32 slice representing the semantic vector.
	Embed(ctx context.Context, text string) ([]float32, error)
}

EmbeddingService defines the interface for text embedding generation. This interface abstracts the embedding provider, allowing different implementations (e.g., SiliconFlow, OpenAI) to be used interchangeably. Following Interface Segregation Principle (ISP), this interface only exposes the essential embedding operation needed for episodic retrieval.

type EpisodicConfig added in v0.100.0

type EpisodicConfig struct {
	// Enabled controls whether episodic memory is enabled for this agent
	Enabled bool `yaml:"enabled"`
	// MaxEpisodes is the maximum number of episodes to retrieve
	MaxEpisodes int `yaml:"max_episodes"`
	// MinSimilarity is the minimum similarity threshold for retrieval
	MinSimilarity float32 `yaml:"min_similarity"`
	// EmbeddingModel is the embedding model to use
	EmbeddingModel string `yaml:"embedding_model"`
}

EpisodicConfig configures episodic memory retrieval behavior. This is loaded from agent YAML configuration.

func DefaultEpisodicConfig added in v0.100.0

func DefaultEpisodicConfig() *EpisodicConfig

DefaultEpisodicConfig returns the default episodic configuration.

type EpisodicMemory

type EpisodicMemory struct {
	Timestamp time.Time
	Summary   string
	AgentType string
	Outcome   string
	ID        int64
}

EpisodicMemory represents a stored episode.

type EpisodicProvider

type EpisodicProvider interface {
	SearchEpisodes(ctx context.Context, userID int32, query string, limit int) ([]*EpisodicMemory, error)
}

EpisodicProvider provides episodic memory search.

type EpisodicProviderImpl added in v0.100.0

type EpisodicProviderImpl struct {
	// contains filtered or unexported fields
}

EpisodicProviderImpl implements EpisodicProvider using vector search. This enables long-term memory for agents as described in context-engineering.md.

func NewEpisodicProvider added in v0.100.0

func NewEpisodicProvider(
	store VectorSearchStore,
	embedder EmbeddingService,
	config *EpisodicConfig,
	agentType string,
) *EpisodicProviderImpl

NewEpisodicProvider creates a new episodic memory provider.

func (*EpisodicProviderImpl) IsEnabled added in v0.100.0

func (p *EpisodicProviderImpl) IsEnabled() bool

IsEnabled returns whether episodic memory is enabled for this provider.

func (*EpisodicProviderImpl) SearchEpisodes added in v0.100.0

func (p *EpisodicProviderImpl) SearchEpisodes(
	ctx context.Context,
	userID int32,
	query string,
	limit int,
) ([]*EpisodicMemory, error)

SearchEpisodes searches for relevant episodic memories. Implements context.EpisodicProvider interface.

type EpisodicVectorSearcher added in v0.100.0

type EpisodicVectorSearcher interface {
	EpisodicVectorSearch(ctx context.Context, opts *store.EpisodicVectorSearchOptions) ([]*store.EpisodicMemoryWithScore, error)
}

EpisodicVectorSearcher defines the interface for episodic vector search. This follows Interface Segregation Principle (ISP).

type IncrementalBuilder added in v0.94.0

type IncrementalBuilder struct {
	// contains filtered or unexported fields
}

IncrementalBuilder provides incremental context building.

func NewIncrementalBuilder added in v0.94.0

func NewIncrementalBuilder(base *Service) *IncrementalBuilder

NewIncrementalBuilder creates a new incremental context builder.

func (*IncrementalBuilder) BuildIncremental added in v0.94.0

func (b *IncrementalBuilder) BuildIncremental(ctx context.Context, req *ContextRequest) (*ContextResult, error)

BuildIncremental builds context incrementally based on the optimal strategy.

func (*IncrementalBuilder) ClearCache added in v0.94.0

func (b *IncrementalBuilder) ClearCache()

ClearCache clears the incremental builder cache.

func (*IncrementalBuilder) GetDeltaStats added in v0.94.0

func (b *IncrementalBuilder) GetDeltaStats() *DeltaStats

GetDeltaStats returns delta building statistics.

type IntentResolver added in v0.94.0

type IntentResolver struct {
}

IntentResolver infers task intent from AgentType.

func NewIntentResolver added in v0.94.0

func NewIntentResolver() *IntentResolver

NewIntentResolver creates a new intent resolver.

func (*IntentResolver) Resolve added in v0.94.0

func (r *IntentResolver) Resolve(agentType string) string

Resolve infers intent from AgentType (thread-safe). Returns intent name (e.g., "memo_search", "schedule_create").

type LongTermContext

type LongTermContext struct {
	Preferences *UserPreferences
	Episodes    []*EpisodicMemory
}

LongTermContext contains extracted long-term context.

type LongTermExtractor

type LongTermExtractor struct {
	// contains filtered or unexported fields
}

LongTermExtractor extracts episodic memories and user preferences.

func NewLongTermExtractor

func NewLongTermExtractor(maxEpisodes int) *LongTermExtractor

NewLongTermExtractor creates a new long-term memory extractor.

func (*LongTermExtractor) Extract

func (e *LongTermExtractor) Extract(
	ctx context.Context,
	episodicProvider EpisodicProvider,
	prefProvider PreferenceProvider,
	userID int32,
	query string,
) (*LongTermContext, error)

Extract extracts long-term context for the user.

type MemoBasedEpisodicProvider added in v0.100.0

type MemoBasedEpisodicProvider struct {
	// contains filtered or unexported fields
}

MemoBasedEpisodicProvider adapts the existing memo vector search for episodic memory. This bridges the existing memo_embedding infrastructure without requiring a new table.

func NewMemoBasedEpisodicProvider added in v0.100.0

func NewMemoBasedEpisodicProvider(
	embedder *embedding.Provider,
	memoStore MemoVectorSearchStore,
	config *EpisodicConfig,
	userID int32,
) *MemoBasedEpisodicProvider

NewMemoBasedEpisodicProvider creates a new memo-based episodic provider.

func (*MemoBasedEpisodicProvider) SearchEpisodes added in v0.100.0

func (p *MemoBasedEpisodicProvider) SearchEpisodes(
	ctx context.Context,
	userID int32,
	query string,
	limit int,
) ([]*EpisodicMemory, error)

SearchEpisodes searches for relevant episodic memories using memo vector search.

type MemoVectorSearchOptions added in v0.100.0

type MemoVectorSearchOptions struct {
	Vector []float32
	UserID int32
	Limit  int
}

MemoVectorSearchOptions specifies options for memo vector search.

type MemoVectorSearchStore added in v0.100.0

type MemoVectorSearchStore interface {
	// VectorSearch performs a similarity search against memo embeddings.
	// Returns memos ordered by similarity score (highest first).
	VectorSearch(ctx context.Context, opts *MemoVectorSearchOptions) ([]*MemoWithScore, error)
}

MemoVectorSearchStore defines the interface for memo vector search. This interface abstracts the memo storage's vector search capability, allowing MemoBasedEpisodicProvider to search through historical memos for relevant context. Following ISP, it only exposes the vector search operation needed for episodic memory retrieval.

type MemoWithScore added in v0.100.0

type MemoWithScore struct {
	ID      int64
	Content string
	Score   float32
}

MemoWithScore represents a memo with its similarity score.

type Message

type Message struct {
	Timestamp time.Time
	Role      string
	Content   string
}

Message represents a conversation message.

func SplitByRecency

func SplitByRecency(messages []*Message, recentCount int) (recent, older []*Message)

SplitByRecency splits messages into recent (high priority) and older (lower priority).

type MessageProvider

type MessageProvider interface {
	GetRecentMessages(ctx context.Context, sessionID string, limit int) ([]*Message, error)
}

MessageProvider provides recent messages for a session.

type MetadataManager added in v0.100.0

type MetadataManager struct {
	// contains filtered or unexported fields
}

MetadataManager manages block metadata for session state. It provides type-safe access to metadata fields and caches recent values for performance optimization.

func NewMetadataManager added in v0.100.0

func NewMetadataManager(store store.AIBlockStore, cacheTTL time.Duration) *MetadataManager

NewMetadataManager creates a new metadata manager.

func (*MetadataManager) CalculateStickyWindow added in v0.100.0

func (m *MetadataManager) CalculateStickyWindow(confidence float64) time.Duration

CalculateStickyWindow calculates the sticky window duration based on confidence. Higher confidence = longer sticky window.

func (*MetadataManager) GetLastAgent added in v0.100.0

func (m *MetadataManager) GetLastAgent(
	ctx context.Context,
	conversationID int32,
) (string, error)

GetLastAgent retrieves the last agent for a conversation. Uses cache to avoid database queries for recent sessions.

func (*MetadataManager) GetSessionMetadata added in v0.100.0

func (m *MetadataManager) GetSessionMetadata(
	ctx context.Context,
	conversationID int32,
) (*SessionMetadata, error)

GetSessionMetadata retrieves the full session metadata for sticky routing.

func (*MetadataManager) Invalidate added in v0.100.0

func (m *MetadataManager) Invalidate(conversationID int32)

Invalidate clears the cache for a conversation.

func (*MetadataManager) IsStickyValid added in v0.100.0

func (m *MetadataManager) IsStickyValid(
	ctx context.Context,
	conversationID int32,
) (bool, *SessionMetadata)

IsStickyValid checks if the sticky routing is still valid for a conversation.

func (*MetadataManager) SetCurrentAgent added in v0.100.0

func (m *MetadataManager) SetCurrentAgent(
	ctx context.Context,
	conversationID int32,
	blockID int64,
	agent string,
	intent string,
	confidence float32,
) error

SetCurrentAgent stores the current agent for a conversation. This should be called after a successful routing decision.

func (*MetadataManager) UpdateCacheOnly added in v0.100.0

func (m *MetadataManager) UpdateCacheOnly(
	conversationID int32,
	agent string,
	intent string,
	confidence float32,
)

UpdateCacheOnly updates the in-memory cache without persisting to database. This should be called immediately after routing to enable sticky routing for the next request without waiting for block completion. Phase 2 fix: enables sticky routing across consecutive requests.

func (*MetadataManager) WithStickyConfig added in v0.100.0

func (m *MetadataManager) WithStickyConfig(cfg *StickyConfig) *MetadataManager

WithStickyConfig sets a custom sticky configuration.

type OrchestratorContext added in v0.100.1

type OrchestratorContext struct {
	UserID         int32
	ConversationID int32
	BlockID        int64
	History        []string
	AgentType      string
	SessionID      string
}

OrchestratorContext holds context data for orchestrator execution. This is used to pass request-level data through the call chain without modifying function signatures.

type OrchestratorContextKey added in v0.100.1

type OrchestratorContextKey string

OrchestratorContextKey is the key type for orchestrator context values. Using a custom type prevents collisions with other packages.

const (
	// KeyUserID stores the user ID for orchestrator execution.
	KeyUserID OrchestratorContextKey = "orchestrator_user_id"

	// KeyConversationID stores the conversation ID for orchestrator execution.
	KeyConversationID OrchestratorContextKey = "orchestrator_conversation_id"

	// KeyBlockID stores the current block ID for orchestrator execution.
	KeyBlockID OrchestratorContextKey = "orchestrator_block_id"

	// KeyHistory stores the conversation history for orchestrator execution.
	KeyHistory OrchestratorContextKey = "orchestrator_history"

	// KeySessionID stores the session ID for orchestrator execution.
	KeySessionID OrchestratorContextKey = "orchestrator_session_id"

	// KeyAgentType stores the agent type for orchestrator execution.
	KeyAgentType OrchestratorContextKey = "orchestrator_agent_type"
)

type PreferenceProvider

type PreferenceProvider interface {
	GetPreferences(ctx context.Context, userID int32) (*UserPreferences, error)
}

PreferenceProvider provides user preferences.

type PriorityRanker

type PriorityRanker struct{}

PriorityRanker ranks and truncates context segments by priority.

func NewPriorityRanker

func NewPriorityRanker() *PriorityRanker

NewPriorityRanker creates a new priority ranker.

func (*PriorityRanker) RankAndTruncate

func (r *PriorityRanker) RankAndTruncate(segments []*ContextSegment, budget int) []*ContextSegment

RankAndTruncate sorts segments by priority and truncates to fit budget.

type ProfileRegistry added in v0.94.0

type ProfileRegistry struct {
	// contains filtered or unexported fields
}

ProfileRegistry manages budget profiles with override support.

func NewProfileRegistry added in v0.94.0

func NewProfileRegistry() *ProfileRegistry

NewProfileRegistry creates a new profile registry with defaults.

func (*ProfileRegistry) Get added in v0.94.0

func (r *ProfileRegistry) Get(name string) (*BudgetProfile, bool)

Get returns a profile by name (thread-safe). Returns the profile and whether it was found directly (not using fallback).

func (*ProfileRegistry) LoadFromEnv added in v0.94.0

func (r *ProfileRegistry) LoadFromEnv()

LoadFromEnv overrides profiles from environment variables. Format: DIVINESENSE_BUDGET_<PROFILE>_<FIELD>=<value> Example: DIVINESENSE_BUDGET_MEMO_SEARCH_SHORT_TERM=0.35

func (*ProfileRegistry) Set added in v0.94.0

func (r *ProfileRegistry) Set(name string, profile *BudgetProfile)

Set adds or overrides a profile (thread-safe).

type RetrievalItem

type RetrievalItem struct {
	ID      string
	Content string
	Source  string
	Score   float32
}

RetrievalItem represents a single retrieval result.

type Service

type Service struct {
	// contains filtered or unexported fields
}

Service implements ContextBuilder with caching support.

func NewService

func NewService(cfg Config) *Service

NewService creates a new context builder service.

func (*Service) Build

func (s *Service) Build(ctx context.Context, req *ContextRequest) (*ContextResult, error)

Build constructs the context for LLM inference.

func (*Service) BuildHistory added in v0.100.0

func (s *Service) BuildHistory(ctx context.Context, req *ContextRequest) ([]string, error)

BuildHistory constructs history in []string format for ParrotAgent.Execute. Returns alternating user/assistant messages: [user1, assistant1, user2, assistant2, ...] This enables backend-driven context construction (context-engineering.md Phase 1).

func (*Service) GetHistoryLength added in v0.100.0

func (s *Service) GetHistoryLength(ctx context.Context, sessionID string) (int, error)

GetHistoryLength returns the number of conversation blocks for a session. Used for dynamic budget adjustment (Issue #211: Phase 3).

Note: This method tries to get the actual block count if the messageProvider is a BlockStoreMessageProvider, otherwise falls back to message count / 2.

func (*Service) GetStats

func (s *Service) GetStats() *ContextStats

GetStats returns context building statistics.

func (*Service) WithCache

func (s *Service) WithCache(c CacheProvider) *Service

WithCache sets the cache provider.

func (*Service) WithEpisodicProvider

func (s *Service) WithEpisodicProvider(p EpisodicProvider) *Service

WithEpisodicProvider sets the episodic memory provider.

func (*Service) WithMessageProvider

func (s *Service) WithMessageProvider(p MessageProvider) *Service

WithMessageProvider sets the message provider.

func (*Service) WithPreferenceProvider

func (s *Service) WithPreferenceProvider(p PreferenceProvider) *Service

WithPreferenceProvider sets the preference provider.

type SessionMetadata added in v0.100.0

type SessionMetadata struct {
	LastAgent            string
	LastIntent           string
	LastIntentConfidence float32
	StickyUntil          time.Time
	LastUpdated          time.Time
	// contains filtered or unexported fields
}

SessionMetadata caches metadata for a session.

type ShortTermExtractor

type ShortTermExtractor struct {
	// contains filtered or unexported fields
}

ShortTermExtractor extracts recent conversation turns.

func NewShortTermExtractor

func NewShortTermExtractor(maxTurns int) *ShortTermExtractor

NewShortTermExtractor creates a new short-term memory extractor.

func (*ShortTermExtractor) Extract

func (e *ShortTermExtractor) Extract(ctx context.Context, provider MessageProvider, sessionID string) ([]*Message, error)

Extract extracts recent messages from the session.

type StickyConfig added in v0.100.0

type StickyConfig struct {
	// InitialWindow is the base sticky window duration
	InitialWindow time.Duration
	// MaxExtensions is the maximum number of times sticky can be extended
	MaxExtensions int
	// DecayFactor is applied to the window for each extension
	DecayFactor float64
	// MinConfidence is the minimum confidence required for sticky routing
	MinConfidence float64
}

StickyConfig configures the sticky routing behavior. This implements the decay strategy from context-engineering.md.

func DefaultStickyConfig added in v0.100.0

func DefaultStickyConfig() *StickyConfig

DefaultStickyConfig returns the default sticky configuration.

type StoreAdapter added in v0.100.0

type StoreAdapter struct {
	// contains filtered or unexported fields
}

StoreAdapter adapts store.AIBlockStore to BlockStore interface. This follows the Adapter pattern, allowing the context package to remain decoupled from the full store package.

func NewStoreAdapter added in v0.100.0

func NewStoreAdapter(s store.AIBlockStore) *StoreAdapter

NewStoreAdapter creates a new store adapter.

func (*StoreAdapter) GetLatestBlock added in v0.100.0

func (a *StoreAdapter) GetLatestBlock(ctx context.Context, conversationID int32) (*Block, error)

GetLatestBlock retrieves the most recent block for a conversation.

func (*StoreAdapter) ListBlocks added in v0.100.0

func (a *StoreAdapter) ListBlocks(ctx context.Context, conversationID int32) ([]*Block, error)

ListBlocks retrieves blocks for a conversation.

type TokenBreakdown

type TokenBreakdown struct {
	SystemPrompt    int
	ShortTermMemory int
	LongTermMemory  int
	Retrieval       int
	UserPrefs       int
}

TokenBreakdown shows how tokens are distributed.

type TokenBudget

type TokenBudget struct {
	Total           int
	SystemPrompt    int
	ShortTermMemory int
	LongTermMemory  int
	Retrieval       int
	UserPrefs       int
}

TokenBudget represents the token allocation plan.

func AllocateBudget

func AllocateBudget(total int, hasRetrieval bool) *TokenBudget

AllocateBudget is a convenience function.

type UpdateStrategy added in v0.94.0

type UpdateStrategy int

UpdateStrategy defines the strategy for updating context.

const (
	// ComputeDelta computes only the changes since last build.
	ComputeDelta UpdateStrategy = iota

	// AppendOnly appends new messages without recomputing.
	AppendOnly

	// UpdateConversationOnly updates only conversation context.
	UpdateConversationOnly

	// FullRebuild performs a full context rebuild.
	FullRebuild
)

func (UpdateStrategy) String added in v0.94.0

func (s UpdateStrategy) String() string

String returns the string representation of the strategy.

type UserInputView added in v0.100.0

type UserInputView struct {
	Content   string
	Timestamp int64
}

UserInputView represents a user input for context building.

type UserPreferences

type UserPreferences struct {
	Timezone           string
	CommunicationStyle string
	PreferredTimes     []string
	DefaultDuration    int
}

UserPreferences represents user preferences.

func DefaultUserPreferences

func DefaultUserPreferences() *UserPreferences

DefaultUserPreferences returns default preferences.

type VectorSearchEpisodicOptions added in v0.100.0

type VectorSearchEpisodicOptions struct {
	UserID    int32
	AgentType string
	Vector    []float32
	Limit     int
	MinScore  float32
}

VectorSearchEpisodicOptions specifies options for episodic vector search.

type VectorSearchStore added in v0.100.0

type VectorSearchStore interface {
	// VectorSearchEpisodic searches for episodic memories using vector similarity
	VectorSearchEpisodic(ctx context.Context, opts *VectorSearchEpisodicOptions) ([]*store.EpisodicMemory, error)
}

VectorSearchStore defines the interface for vector search operations. This follows Interface Segregation Principle (ISP).

type VectorSearchStoreAdapter added in v0.100.0

type VectorSearchStoreAdapter struct {
	// contains filtered or unexported fields
}

VectorSearchStoreAdapter adapts store.Driver to VectorSearchStore interface. This enables EpisodicProviderImpl to use the store's vector search capabilities.

func NewVectorSearchStoreAdapter added in v0.100.0

func NewVectorSearchStoreAdapter(s EpisodicVectorSearcher) *VectorSearchStoreAdapter

NewVectorSearchStoreAdapter creates a new adapter.

func (*VectorSearchStoreAdapter) VectorSearchEpisodic added in v0.100.0

func (a *VectorSearchStoreAdapter) VectorSearchEpisodic(
	ctx context.Context,
	opts *VectorSearchEpisodicOptions,
) ([]*store.EpisodicMemory, error)

VectorSearchEpisodic implements VectorSearchStore interface. It adapts context.VectorSearchEpisodicOptions to store.EpisodicVectorSearchOptions and filters results by minimum similarity score.

Jump to

Keyboard shortcuts

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