Class: RubynCode::Memory::SessionPersistence

Inherits:
Object
  • Object
show all
Defined in:
lib/rubyn_code/memory/session_persistence.rb

Overview

Saves and restores full conversation sessions to SQLite, enabling session continuity across process restarts and session browsing.

Constant Summary collapse

JSON_ATTRS =
%i[metadata messages].freeze
SIMPLE_ATTRS =
%i[title status model].freeze

Instance Method Summary collapse

Constructor Details

#initialize(db) ⇒ SessionPersistence

Returns a new instance of SessionPersistence.

Parameters:



12
13
14
15
# File 'lib/rubyn_code/memory/session_persistence.rb', line 12

def initialize(db)
  @db = db
  ensure_table
end

Instance Method Details

#delete_session(session_id) ⇒ void

This method returns an undefined value.

Deletes a session permanently.

Parameters:

  • session_id (String)


112
113
114
# File 'lib/rubyn_code/memory/session_persistence.rb', line 112

def delete_session(session_id)
  @db.execute('DELETE FROM sessions WHERE id = ?', [session_id])
end

#list_sessions(project_path: nil, status: nil, limit: 20) ⇒ Array<Hash>

Lists sessions, optionally filtered by project and/or status.

Parameters:

  • project_path (String, nil) (defaults to: nil)

    filter by project

  • status (String, nil) (defaults to: nil)

    filter by status (“active”, “archived”, “deleted”)

  • limit (Integer) (defaults to: 20)

    maximum results (default 20)

Returns:

  • (Array<Hash>)

    session summaries (without full messages)



75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/rubyn_code/memory/session_persistence.rb', line 75

def list_sessions(project_path: nil, status: nil, limit: 20)
  where_clause, params = build_list_filters(project_path, status)
  params << limit

  rows = @db.query(<<~SQL, params).to_a
    SELECT id, project_path, title, model, status, metadata, created_at, updated_at
    FROM sessions
    #{where_clause}
    ORDER BY updated_at DESC
    LIMIT ?
  SQL

  rows.map { |row| row_to_session_summary(row) }
end

#load_session(session_id) ⇒ Hash?

Loads a session by ID.

Parameters:

  • session_id (String)

Returns:

  • (Hash, nil)

    { messages:, metadata:, title:, model:, status:, project_path: } or nil



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/rubyn_code/memory/session_persistence.rb', line 49

def load_session(session_id)
  rows = @db.query(
    'SELECT * FROM sessions WHERE id = ?',
    [session_id]
  ).to_a
  return nil if rows.empty?

  row = rows.first
  {
    messages: parse_json_array(row['messages']),
    metadata: parse_json_hash(row['metadata']),
    title: row['title'],
    model: row['model'],
    status: row['status'],
    project_path: row['project_path'],
    created_at: row['created_at'],
    updated_at: row['updated_at']
  }
end

#save_session(session_id:, project_path:, messages:, **opts) ⇒ void

This method returns an undefined value.

Persists a complete session snapshot.

Parameters:

  • attrs (Hash)

    session attributes: :session_id, :project_path, :messages (required); :title, :model, :metadata (optional)



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/rubyn_code/memory/session_persistence.rb', line 23

def save_session(session_id:, project_path:, messages:, **opts)
  now = Time.now.utc.strftime('%Y-%m-%d %H:%M:%S')
  messages_json = JSON.generate(messages)
  meta_json = JSON.generate(opts.fetch(:metadata, {}))
  title = opts[:title]
  model = opts[:model]

  insert_params = [session_id, project_path, title, model, messages_json, 'active', meta_json, now, now]
  update_params = [messages_json, title, model, meta_json, now]

  @db.execute(<<~SQL, insert_params + update_params)
    INSERT INTO sessions (id, project_path, title, model, messages, status, metadata, created_at, updated_at)
    VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
    ON CONFLICT(id) DO UPDATE SET
      messages = ?,
      title = COALESCE(?, title),
      model = COALESCE(?, model),
      metadata = ?,
      updated_at = ?
  SQL
end

#update_session(session_id, **attrs) ⇒ void

This method returns an undefined value.

Updates session attributes.

Parameters:

  • session_id (String)
  • attrs (Hash)

    attributes to update (:title, :status, :model, :metadata, :messages)



95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/rubyn_code/memory/session_persistence.rb', line 95

def update_session(session_id, **attrs)
  return if attrs.empty?

  sets, params = build_update_clauses(attrs)
  return if sets.empty?

  sets << 'updated_at = ?'
  params << Time.now.utc.strftime('%Y-%m-%d %H:%M:%S')
  params << session_id

  @db.execute("UPDATE sessions SET #{sets.join(', ')} WHERE id = ?", params)
end