Class: Aidp::Database::Repositories::ModelCacheRepository

Inherits:
Aidp::Database::Repository show all
Defined in:
lib/aidp/database/repositories/model_cache_repository.rb

Overview

Repository for model cache Replaces: ~/.aidp/cache/models.json

Caches discovered models from AI providers with TTL support

Constant Summary collapse

DEFAULT_TTL =

24 hours in seconds

86400

Instance Attribute Summary

Attributes inherited from Aidp::Database::Repository

#project_dir, #table_name

Instance Method Summary collapse

Constructor Details

#initialize(project_dir: Dir.pwd) ⇒ ModelCacheRepository

Returns a new instance of ModelCacheRepository.



15
16
17
# File 'lib/aidp/database/repositories/model_cache_repository.rb', line 15

def initialize(project_dir: Dir.pwd)
  super(project_dir: project_dir, table_name: "model_cache")
end

Instance Method Details

#cache_models(provider_name, models, ttl: DEFAULT_TTL) ⇒ Boolean

Cache models for a provider

Parameters:

  • provider_name (String) —

    Provider name

  • models (Array<Hash>) —

    Models array

  • ttl (Integer) (defaults to: DEFAULT_TTL) —

    Time to live in seconds

Returns:

  • (Boolean) —

    Success status



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/aidp/database/repositories/model_cache_repository.rb', line 25

def cache_models(provider_name, models, ttl: DEFAULT_TTL)
  Aidp.log_debug("model_cache_repo", "cache_models",
    provider: provider_name, count: models.size, ttl: ttl)

  expires_at = Time.now.utc + ttl

  execute("    INSERT INTO \#{table_name} (project_dir, provider_name, models, cached_at, expires_at)\n    VALUES (?, ?, ?, ?, ?)\n    ON CONFLICT(project_dir, provider_name) DO UPDATE SET\n      models = excluded.models,\n      cached_at = excluded.cached_at,\n      expires_at = excluded.expires_at\n  SQL\n\n  Aidp.log_info(\"model_cache_repo\", \"cached_models\",\n    provider: provider_name, count: models.size)\n  true\nrescue => e\n  Aidp.log_error(\"model_cache_repo\", \"cache_models_failed\",\n    provider: provider_name, error: e.message)\n  false\nend\n", [project_dir, provider_name, serialize_json(models), current_timestamp, expires_at.strftime("%Y-%m-%d %H:%M:%S")])

#cached_providers ⇒ Array<String>

Get list of providers with valid cached models

Returns:

  • (Array<String>) —

    Provider names with valid caches



121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/aidp/database/repositories/model_cache_repository.rb', line 121

def cached_providers
  rows = query("    SELECT provider_name, expires_at\n    FROM \#{table_name}\n    WHERE project_dir = ?\n  SQL\n\n  providers = []\n  rows.each do |row|\n    next unless row[\"expires_at\"]\n\n    # Parse as UTC since timestamps are stored in UTC\n    expires_at = Time.parse(row[\"expires_at\"] + \" UTC\")\n    providers << row[\"provider_name\"] if Time.now.utc <= expires_at\n  end\n\n  providers\nend\n", [project_dir])

#cleanup_expired ⇒ Integer

Clean up expired entries

Returns:

  • (Integer) —

    Number of entries deleted



160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
# File 'lib/aidp/database/repositories/model_cache_repository.rb', line 160

def cleanup_expired
  result = query_value("    SELECT COUNT(*) FROM \#{table_name}\n    WHERE project_dir = ?\n      AND expires_at IS NOT NULL\n      AND datetime(expires_at) <= datetime('now')\n  SQL\n\n  execute(<<~SQL, [project_dir])\n    DELETE FROM \#{table_name}\n    WHERE project_dir = ?\n      AND expires_at IS NOT NULL\n      AND datetime(expires_at) <= datetime('now')\n  SQL\n\n  count = result || 0\n  if count > 0\n    Aidp.log_info(\"model_cache_repo\", \"cleanup_expired\",\n      deleted: count)\n  end\n  count\nend\n", [project_dir])

#get_cached_models(provider_name) ⇒ Array<Hash>?

Get cached models for a provider if not expired

Parameters:

  • provider_name (String) —

    Provider name

Returns:

  • (Array<Hash>, nil) —

    Cached models or nil if expired/not found



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/aidp/database/repositories/model_cache_repository.rb', line 53

def get_cached_models(provider_name)
  Aidp.log_debug("model_cache_repo", "get_cached_models",
    provider: provider_name)

  row = query_one("    SELECT models, cached_at, expires_at\n    FROM \#{table_name}\n    WHERE project_dir = ? AND provider_name = ?\n  SQL\n\n  return nil unless row\n\n  # Check expiration\n  if row[\"expires_at\"]\n    # Parse as UTC since timestamps are stored in UTC\n    expires_at = Time.parse(row[\"expires_at\"] + \" UTC\")\n    if Time.now.utc > expires_at\n      Aidp.log_debug(\"model_cache_repo\", \"cache_expired\",\n        provider: provider_name, expires_at: expires_at)\n      return nil\n    end\n  end\n\n  models = deserialize_json(row[\"models\"])\n  Aidp.log_debug(\"model_cache_repo\", \"cache_hit\",\n    provider: provider_name, count: models&.size || 0)\n  models\nend\n", [project_dir, provider_name])

#invalidate(provider_name) ⇒ Boolean

Invalidate cache for a specific provider

Parameters:

  • provider_name (String) —

    Provider name

Returns:

  • (Boolean) —

    Success status



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/aidp/database/repositories/model_cache_repository.rb', line 86

def invalidate(provider_name)
  Aidp.log_debug("model_cache_repo", "invalidate",
    provider: provider_name)

  execute("    DELETE FROM \#{table_name}\n    WHERE project_dir = ? AND provider_name = ?\n  SQL\n\n  Aidp.log_info(\"model_cache_repo\", \"invalidated\",\n    provider: provider_name)\n  true\nrescue => e\n  Aidp.log_error(\"model_cache_repo\", \"invalidate_failed\",\n    provider: provider_name, error: e.message)\n  false\nend\n", [project_dir, provider_name])

#invalidate_all ⇒ Boolean

Invalidate all cached models

Returns:

  • (Boolean) —

    Success status



107
108
109
110
111
112
113
114
115
116
# File 'lib/aidp/database/repositories/model_cache_repository.rb', line 107

def invalidate_all
  Aidp.log_debug("model_cache_repo", "invalidate_all")
  delete_by_project
  Aidp.log_info("model_cache_repo", "invalidated_all")
  true
rescue => e
  Aidp.log_error("model_cache_repo", "invalidate_all_failed",
    error: e.message)
  false
end

#model_count(provider_name) ⇒ Integer

Get model count for a provider

Parameters:

  • provider_name (String) —

    Provider name

Returns:

  • (Integer) —

    Number of cached models



187
188
189
190
# File 'lib/aidp/database/repositories/model_cache_repository.rb', line 187

def model_count(provider_name)
  models = get_cached_models(provider_name)
  models&.size || 0
end

#stats ⇒ Hash

Get cache statistics

Returns:

  • (Hash) —

    Statistics



143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/aidp/database/repositories/model_cache_repository.rb', line 143

def stats
  total = query_value("    SELECT COUNT(*) FROM \#{table_name} WHERE project_dir = ?\n  SQL\n\n  valid_providers = cached_providers\n\n  {\n    total_providers: total || 0,\n    cached_providers: valid_providers,\n    valid_count: valid_providers.size\n  }\nend\n", [project_dir])