@@ -962,8 +962,8 @@ func (m *Manager) CreateSession(session *SessionRecord) error {
962962 c := bucket .Cursor ()
963963 for k , v := c .First (); k != nil ; k , v = c .Next () {
964964 keyStr := string (k )
965- // Check if key ends with the session ID (after the underscore)
966- if len ( keyStr ) > len ( session . ID ) && keyStr [ len (keyStr ) - len ( session . ID ):] == session .ID {
965+ // Check if key ends with _{session_id}
966+ if strings . HasSuffix (keyStr , "_" + session .ID ) {
967967 existingKey = k
968968 if err := json .Unmarshal (v , & existingSession ); err != nil {
969969 m .logger .Warnw ("Failed to unmarshal existing session" , "error" , err )
@@ -1033,8 +1033,8 @@ func (m *Manager) CloseSession(sessionID string) error {
10331033 for k , v := c .First (); k != nil ; k , v = c .Next () {
10341034 // Key format: {timestamp_ns}_{session_id}
10351035 keyStr := string (k )
1036- // Check if key ends with the session ID (after the underscore)
1037- if len (keyStr ) > len ( sessionID ) && keyStr [ len ( keyStr ) - len ( sessionID ):] == sessionID {
1036+ // Check if key ends with _{session_id}
1037+ if strings . HasSuffix (keyStr , "_" + sessionID ) {
10381038 sessionKey = k
10391039 if err := json .Unmarshal (v , & session ); err != nil {
10401040 return fmt .Errorf ("failed to unmarshal session: %w" , err )
@@ -1115,8 +1115,8 @@ func (m *Manager) GetSessionByID(sessionID string) (*SessionRecord, error) {
11151115 c := bucket .Cursor ()
11161116 for k , v := c .First (); k != nil ; k , v = c .Next () {
11171117 keyStr := string (k )
1118- // Check if key ends with the session ID (after the underscore)
1119- if len (keyStr ) > len ( sessionID ) && keyStr [ len ( keyStr ) - len ( sessionID ):] == sessionID {
1118+ // Check if key ends with _{session_id}
1119+ if strings . HasSuffix (keyStr , "_" + sessionID ) {
11201120 var s SessionRecord
11211121 if err := json .Unmarshal (v , & s ); err != nil {
11221122 return fmt .Errorf ("failed to unmarshal session: %w" , err )
@@ -1200,8 +1200,8 @@ func (m *Manager) UpdateSessionStats(sessionID string, tokens int) error {
12001200 c := bucket .Cursor ()
12011201 for k , v := c .First (); k != nil ; k , v = c .Next () {
12021202 keyStr := string (k )
1203- // Check if key ends with the session ID (after the underscore)
1204- if len (keyStr ) > len ( sessionID ) && keyStr [ len ( keyStr ) - len ( sessionID ):] == sessionID {
1203+ // Check if key ends with _{session_id}
1204+ if strings . HasSuffix (keyStr , "_" + sessionID ) {
12051205 sessionKey = k
12061206 if err := json .Unmarshal (v , & session ); err != nil {
12071207 return fmt .Errorf ("failed to unmarshal session: %w" , err )
@@ -1228,6 +1228,38 @@ func (m *Manager) UpdateSessionStats(sessionID string, tokens int) error {
12281228 })
12291229}
12301230
1231+ // UpdateSessionActivity updates LastActivity without incrementing tool call counts.
1232+ // Call this on any MCP message to keep the session alive.
1233+ func (m * Manager ) UpdateSessionActivity (sessionID string ) error {
1234+ m .mu .Lock ()
1235+ defer m .mu .Unlock ()
1236+
1237+ return m .db .db .Update (func (tx * bbolt.Tx ) error {
1238+ bucket := tx .Bucket ([]byte (SessionsBucket ))
1239+ if bucket == nil {
1240+ return nil
1241+ }
1242+
1243+ c := bucket .Cursor ()
1244+ for k , v := c .First (); k != nil ; k , v = c .Next () {
1245+ keyStr := string (k )
1246+ if strings .HasSuffix (keyStr , "_" + sessionID ) {
1247+ var session SessionRecord
1248+ if err := json .Unmarshal (v , & session ); err != nil {
1249+ return err
1250+ }
1251+ session .LastActivity = time .Now ()
1252+ data , err := json .Marshal (session )
1253+ if err != nil {
1254+ return err
1255+ }
1256+ return bucket .Put (k , data )
1257+ }
1258+ }
1259+ return nil // Session not found is not an error - may not be persisted yet
1260+ })
1261+ }
1262+
12311263// CloseInactiveSessions closes sessions that haven't had activity for the specified duration
12321264func (m * Manager ) CloseInactiveSessions (inactivityTimeout time.Duration ) (int , error ) {
12331265 m .mu .Lock ()
0 commit comments