inmemory.go
Overview
This file implements an in-memory, thread-safe session service as part of the broader Session Management module. It provides a volatile storage backend for sessions, handling creation, retrieval, listing, deletion, and event appending for user-agent interaction sessions. The service maintains session states and event histories entirely in memory, supporting layered state merging at application, user, and session scopes. This implementation is optimized for development, testing, or scenarios requiring fast, ephemeral session storage without external dependencies.
The in-memory service conforms to the Service interface, ensuring compatibility with other session backend implementations such as the database-backed service.
Main Types and Their Responsibilities
inMemoryService
Core struct implementing the session service interface.
Fields:
mu sync.RWMutex: Protects concurrent access to all internal data.sessions omap.Map[string, *session]: Ordered map storing sessions, keyed by encoded composite IDs.userState map[string]map[string]stateMap: Nested map for user-scoped state by app and user IDs.appState map[string]stateMap: Map holding application-wide state per app.
Provides methods for session lifecycle management and event handling (see detailed method descriptions below).
Maintains separate maps for app, user, and session state allowing efficient updates and merges.
session
Represents an individual session.
Fields:
id id: Composite identifier with appName, userID, and sessionID.mu sync.RWMutex: Guards mutable session fields.events []*Event: Ordered list of recorded events in the session.state map[string]any: Current session-level state.updatedAt time.Time: Timestamp of last update.
Methods provide accessors (
ID(),AppName(),UserID()), state and event retrieval, and event appending with state mutation.
id
Represents the composite session identifier.
Fields:
appName stringuserID stringsessionID string
Methods:
Encode() string: Serializes the id into a string key using ordered encoding.Decode(key string) error: Parses a key string back into the id fields.
state
Wraps session state map with a mutex for safe concurrent access.
Methods:
Get(key string) (any, error): Retrieves a value by key.Set(key string, value any) error: Sets a key-value pair.All() iter.Seq2[string, any]: Returns an iterator over all key-value pairs.
events
A slice wrapper for session events.
Methods:
All() iter.Seq[*Event]: Iterates over events.Len() intAt(i int) *Event
Key Methods in inMemoryService
Create(ctx context.Context, req *CreateRequest) (*CreateResponse, error)
Creates a new session with provided
AppName,UserID, and optionally aSessionID.Generates a UUID for
SessionIDif not provided.Validates parameters.
Checks for existing session; returns error if already exists.
Merges initial state with existing app and user states via
sessionutils.ExtractStateDeltasandMergeStates.Stores the new session in
sessionsmap.Returns a deep-copied session including cloned state and event slices.
Usage example:
resp, err := service.Create(ctx, &CreateRequest{
AppName: "myapp",
UserID: "user123",
State: map[string]any{"foo": "bar"},
})
if err != nil {
// handle error
}
session := resp.Session
Get(ctx context.Context, req *GetRequest) (*GetResponse, error)
Retrieves a session by
AppName,UserID, andSessionID.Supports filtering events by:
NumRecentEvents: limits the number of recent events returned.After: returns only events occurring after a timestamp.
Merges session state with current app and user states using
mergeStates.Returns a deep copy of the session including filtered event list.
Usage example:
resp, err := service.Get(ctx, &GetRequest{
AppName: "myapp",
UserID: "user123",
SessionID: "sess456",
NumRecentEvents: 10,
After: time.Date(2025, 1, 1, 0, 0, 0, 0, time.UTC),
})
if err != nil {
// handle error
}
session := resp.Session
List(ctx context.Context, req *ListRequest) (*ListResponse, error)
Lists sessions filtered by
AppNameand optionallyUserID.Uses lexicographical range scans on encoded keys for efficient retrieval.
Returns sessions without event histories but with merged states.
Sessions are deep-copied to avoid external mutation.
Delete(ctx context.Context, req *DeleteRequest) error
Deletes a session by
AppName,UserID, andSessionID.Validates input parameters.
Removes the session from the internal map.
AppendEvent(ctx context.Context, curSession Session, event *Event) error
Appends an event to an existing session.
Validates
curSessionandeventnot nil.Ignores partial events (
event.Partial).Locks the service and updates session state by applying the event’s state delta.
Filters out temporary keys prefixed with
KeyPrefixTempfrom the event state delta.Updates app and user states with extracted deltas.
Updates the session’s
eventsslice andupdatedAttimestamp.
State Management Helpers
updateAppState(appDelta stateMap, appName string) stateMap: Updates application-level state for an app by merging deltas.updateUserState(userDelta stateMap, appName, userID string) stateMap: Updates user-level state for a user in an app.mergeStates(state stateMap, appName, userID string) stateMap: Merges application, user, and session states into a combined state map.
Important Implementation Details and Algorithms
Thread Safety: Uses
sync.RWMutexfor granular locking:The
inMemoryService.muprotects access to the entire sessions map and global states.Each
sessionhas its own mutex for protecting its event slice and state map.
State Delta Extraction and Merging: Utilizes
sessionutils.ExtractStateDeltasto split state changes into app, user, and session scopes based on key prefixes. State maps are merged usingsessionutils.MergeStatesto compose the final state view.Event Filtering: When retrieving events, supports filtering by count (
NumRecentEvents) and timestamp (After). Uses binary search (sort.Search) for efficient timestamp-based filtering.Temporary State Keys: Keys prefixed with
temp:are excluded from persistent state bytrimTempDeltaStatebefore updating session state.Immutable Session Copies: Returned sessions are deep copies without direct references to internal storage structs, ensuring encapsulation and preventing external mutation.
Interaction with Other System Components
Implements the
Serviceinterface defined in Session Management, enabling interchangeable backends.Session events and state managed here feed into the Agent Execution Runner, which depends on session context to execute AI agents.
State merging and event handling logic cooperate with Instruction Template Processing to inject session state into LLM prompts.
The in-memory service is suitable for transient or testing use cases, while production deployments may use the database-backed service (Database Session Service).
Relies on utilities and types from
sessionutilsfor state delta extraction and merging.
Visual Diagram: Class Structure of In-Memory Session Service
classDiagram
class inMemoryService {
- mu: RWMutex
- sessions: omap.Map
- userState: map[string]map[string]stateMap
- appState: map[string]stateMap
+ Create()
+ Get()
+ List()
+ Delete()
+ AppendEvent()
+ updateAppState()
+ updateUserState()
+ mergeStates()
}
class session {
- id: id
- mu: RWMutex
- events: []*Event
- state: map[string]any
- updatedAt: time.Time
+ ID()
+ AppName()
+ UserID()
+ State()
+ Events()
+ LastUpdateTime()
+ appendEvent()
}
class id {
- appName: string
- userID: string
- sessionID: string
+ Encode()
+ Decode()
}
inMemoryService "1" o-- "*" session : manages
session "1" *-- "1" id : identifies
Detailed Explanation of Selected Functions and Methods
func (s *session) appendEvent(event *Event) error
Adds an event to the session.
Skips partial events.
Calls
trimTempDeltaStateto remove temporary keys from the event’s state delta.Updates the session state by applying the filtered delta via updateSessionState.
Appends the event to the session’s event slice.
Updates
updatedAttimestamp to the event’s timestamp.
Auxiliary Functions
trimTempDeltaState(event *Event) *Event
Removes keys starting with the temporary prefix
temp:from the event’s Actions.StateDelta map.Returns the modified event for further processing.
updateSessionState(session *session, event *Event) error
Applies the event’s filtered state delta to the session’s state map.
Skips keys with temporary prefix.
Uses the state.Set method to update keys thread-safely.
copySessionWithoutStateAndEvents(sess *session) *session
Creates a shallow copy of a session without copying state or events.
Used internally to prepare copies for return to callers, avoiding data races or external state mutations.
Data Structures Summary
Type | Description |
|---|---|
| Main service struct managing sessions and states |
| Represents a user-agent session with events and state |
| Composite key struct for appName, userID, sessionID |
| Thread-safe wrapper around session state map |
| Wrapper over event slice with iterator methods |
Usage Context
Primarily used for rapid prototyping, unit testing, or ephemeral session management where persistence beyond the process lifetime is unnecessary.
Serves as a baseline or fallback implementation of the session service interface.
Enables development without dependency on external databases or network storage.
Facilitates local caching of session state and event history with concurrency control.
This file is a crucial component of the overall Session Management system, providing a performant and straightforward in-memory option for session handling aligned with the system’s design principles for session state layering, event-driven updates, and concurrency safety.