Class: RubynCode::Memory::Search

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

Overview

Searches memories using SQLite FTS5 full-text search and standard queries. Search methods automatically increment access_count and update last_accessed_at on returned records, reinforcing frequently-accessed memories against decay; #recent accepts touch: false to opt out for passive reads.

Instance Method Summary collapse

Constructor Details

#initialize(db, project_path:) ⇒ Search

Returns a new instance of Search.

Parameters:

  • db (DB::Connection) —

    database connection

  • project_path (String) —

    scoping path for searches



16
17
18
19
# File 'lib/rubyn_code/memory/search.rb', line 16

def initialize(db, project_path:)
  @db = db
  @project_path = project_path
end

Instance Method Details

#by_category(category, limit: 10) ⇒ Array<MemoryRecord>

Returns memories filtered by category.

Parameters:

  • category (String)
  • limit (Integer) (defaults to: 10) —

    maximum results (default 10)

Returns:



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/rubyn_code/memory/search.rb', line 89

def by_category(category, limit: 10)
  rows = @db.query("    SELECT id, project_path, tier, category, content,\n           relevance_score, access_count, last_accessed_at,\n           expires_at, metadata, created_at\n    FROM memories\n    WHERE project_path = ?\n      AND category = ?\n    ORDER BY relevance_score DESC, created_at DESC\n    LIMIT ?\n  SQL\n\n  records = rows.map { |row| build_record(row) }\n  touch_accessed(records)\n  records\nend\n", [@project_path, category, limit]).to_a

#by_tier(tier, limit: 10) ⇒ Array<MemoryRecord>

Returns memories filtered by tier.

Parameters:

  • tier (String)
  • limit (Integer) (defaults to: 10) —

    maximum results (default 10)

Returns:



111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/rubyn_code/memory/search.rb', line 111

def by_tier(tier, limit: 10)
  rows = @db.query("    SELECT id, project_path, tier, category, content,\n           relevance_score, access_count, last_accessed_at,\n           expires_at, metadata, created_at\n    FROM memories\n    WHERE project_path = ?\n      AND tier = ?\n    ORDER BY relevance_score DESC, created_at DESC\n    LIMIT ?\n  SQL\n\n  records = rows.map { |row| build_record(row) }\n  touch_accessed(records)\n  records\nend\n", [@project_path, tier, limit]).to_a

#recent(limit: 10, touch: true) ⇒ Array<MemoryRecord>

Returns the most recently created memories.

Parameters:

  • limit (Integer) (defaults to: 10) —

    maximum results (default 10)

  • touch (Boolean) (defaults to: true) —

    whether to record an access on returned records; pass false for passive reads (e.g. prompt assembly) that shouldn't reinforce memories or issue a write

Returns:



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/rubyn_code/memory/search.rb', line 68

def recent(limit: 10, touch: true)
  rows = @db.query("    SELECT id, project_path, tier, category, content,\n           relevance_score, access_count, last_accessed_at,\n           expires_at, metadata, created_at\n    FROM memories\n    WHERE project_path = ?\n    ORDER BY created_at DESC\n    LIMIT ?\n  SQL\n\n  records = rows.map { |row| build_record(row) }\n  touch_accessed(records) if touch\n  records\nend\n", [@project_path, limit]).to_a

#search(query, tier: nil, category: nil, limit: 10) ⇒ Array<MemoryRecord>

Full-text search across memory content using FTS5.

Parameters:

  • query (String) —

    the search query (FTS5 syntax supported)

  • tier (String, nil) (defaults to: nil) —

    filter by tier

  • category (String, nil) (defaults to: nil) —

    filter by category

  • limit (Integer) (defaults to: 10) —

    maximum results (default 10)

Returns:



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/rubyn_code/memory/search.rb', line 28

def search(query, tier: nil, category: nil, limit: 10)
  conditions = ['m.project_path = ?']
  params = [@project_path]

  if tier
    conditions << 'm.tier = ?'
    params << tier
  end

  if category
    conditions << 'm.category = ?'
    params << category
  end

  params << query
  params << limit

  rows = @db.query("    SELECT m.id, m.project_path, m.tier, m.category, m.content,\n           m.relevance_score, m.access_count, m.last_accessed_at,\n           m.expires_at, m.metadata, m.created_at\n    FROM memories m\n    WHERE \#{conditions.join(' AND ')}\n      AND m.content LIKE '%' || ? || '%'\n    ORDER BY m.relevance_score DESC, m.created_at DESC\n    LIMIT ?\n  SQL\n\n  records = rows.map { |row| build_record(row) }\n  touch_accessed(records)\n  records\nend\n", params).to_a