Class: Ace::PromptPrep::Molecules::EnhancementTracker

Inherits:
Object
  • Object
show all
Defined in:
lib/ace/prompt_prep/molecules/enhancement_tracker.rb

Overview

Tracks enhancement iterations and manages enhancement cache

Constant Summary collapse

DEFAULT_CACHE_DIR =

Default directories (fallback if config unavailable)

Ace::PromptPrep::Defaults::DEFAULT_CACHE_DIR
DEFAULT_ENHANCE_CACHE =
"enhance-cache"
DEFAULT_ARCHIVE_DIR =
"prompts/archive"

Class Method Summary collapse

Class Method Details

.archive_dirString

Get archive directory from config

Returns:

  • (String)

    Archive directory relative to project root



28
29
30
31
32
33
# File 'lib/ace/prompt_prep/molecules/enhancement_tracker.rb', line 28

def self.archive_dir
  config = Ace::PromptPrep.config
  cache_dir = config.dig("paths", "cache_dir") || DEFAULT_CACHE_DIR
  archive = config.dig("paths", "archive_dir") || DEFAULT_ARCHIVE_DIR
  File.join(cache_dir, archive)
end

.cache_key(content, model, system_prompt_content, temperature) ⇒ String

Note:

Uses resolved system prompt content so cache invalidates when prompt changes

Calculate cache key including all parameters that affect output

Parameters:

  • content (String)

    Content to enhance

  • model (String)

    Model identifier

  • system_prompt_content (String)

    Resolved system prompt content (not URI)

  • temperature (Float)

    Temperature for LLM generation

Returns:

  • (String)

    SHA256 hash of combined parameters



43
44
45
46
47
48
# File 'lib/ace/prompt_prep/molecules/enhancement_tracker.rb', line 43

def self.cache_key(content, model, system_prompt_content, temperature)
  # Hash the system prompt content to keep cache key manageable
  system_prompt_hash = Digest::SHA256.hexdigest(system_prompt_content || "")
  key_material = "#{content}|#{model}|#{system_prompt_hash}|#{temperature}"
  Digest::SHA256.hexdigest(key_material)
end

.cached?(hash) ⇒ Boolean

Check if content exists in cache

Parameters:

  • hash (String)

    Content hash

Returns:

  • (Boolean)

    True if cached



63
64
65
66
67
# File 'lib/ace/prompt_prep/molecules/enhancement_tracker.rb', line 63

def self.cached?(hash)
  project_root = Ace::Support::Fs::Molecules::ProjectRootFinder.find_or_current
  cache_path = File.join(project_root, enhance_cache_dir, "#{hash}.md")
  File.exist?(cache_path)
end

.content_hash(content) ⇒ String

Deprecated.

Use cache_key instead for full parameter tracking

Calculate content hash for cache lookup (legacy - content only)

Parameters:

  • content (String)

    Content to hash

Returns:

  • (String)

    SHA256 hash



55
56
57
# File 'lib/ace/prompt_prep/molecules/enhancement_tracker.rb', line 55

def self.content_hash(content)
  Digest::SHA256.hexdigest(content)
end

.enhance_cache_dirString

Get enhance cache directory from config

Returns:

  • (String)

    Enhance cache directory relative to project root



19
20
21
22
23
24
# File 'lib/ace/prompt_prep/molecules/enhancement_tracker.rb', line 19

def self.enhance_cache_dir
  config = Ace::PromptPrep.config
  cache_dir = config.dig("paths", "cache_dir") || DEFAULT_CACHE_DIR
  enhance_cache = config.dig("paths", "enhance_cache") || DEFAULT_ENHANCE_CACHE
  File.join(cache_dir, enhance_cache)
end

.enhancement_filename(session_id, iteration) ⇒ String

Generate enhancement archive filename

Parameters:

  • session_id (String)

    Base36 session ID (e.g., “i50jj3”)

  • iteration (Integer)

    Iteration number

Returns:

  • (String)

    Filename (e.g., “i50jj3_e001.md”)



133
134
135
# File 'lib/ace/prompt_prep/molecules/enhancement_tracker.rb', line 133

def self.enhancement_filename(session_id, iteration)
  "#{session_id}_e#{iteration.to_s.rjust(3, "0")}.md"
end

.get_cached(hash) ⇒ String?

Get cached content

Parameters:

  • hash (String)

    Content hash

Returns:

  • (String, nil)

    Cached content or nil if not found



73
74
75
76
77
78
79
80
81
82
# File 'lib/ace/prompt_prep/molecules/enhancement_tracker.rb', line 73

def self.get_cached(hash)
  project_root = Ace::Support::Fs::Molecules::ProjectRootFinder.find_or_current
  cache_path = File.join(project_root, enhance_cache_dir, "#{hash}.md")
  return nil unless File.exist?(cache_path)

  File.read(cache_path, encoding: "utf-8")
rescue => e
  warn "Warning: Failed to read cache: #{e.message}"
  nil
end

.next_iteration(session_id) ⇒ Integer

Calculate next iteration number for a session ID

Parameters:

  • session_id (String)

    Base36 session ID (e.g., “i50jj3”)

Returns:

  • (Integer)

    Next iteration number (1, 2, 3, etc.)



106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/ace/prompt_prep/molecules/enhancement_tracker.rb', line 106

def self.next_iteration(session_id)
  project_root = Ace::Support::Fs::Molecules::ProjectRootFinder.find_or_current
  archive_dir_path = File.join(project_root, archive_dir)

  return 1 unless Dir.exist?(archive_dir_path)

  # Find all enhancement files for this session ID
  pattern = File.join(archive_dir_path, "#{session_id}_e*.md")
  existing_files = Dir.glob(pattern)

  return 1 if existing_files.empty?

  # Extract iteration numbers and find max
  iterations = existing_files.map do |file|
    basename = File.basename(file, ".md")
    match = basename.match(/_e(\d+)$/)
    match ? match[1].to_i : 0
  end

  iterations.max + 1
end

.store_cache(hash, content) ⇒ Boolean

Store content in cache

Parameters:

  • hash (String)

    Content hash

  • content (String)

    Content to cache

Returns:

  • (Boolean)

    True if successful



89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/ace/prompt_prep/molecules/enhancement_tracker.rb', line 89

def self.store_cache(hash, content)
  project_root = Ace::Support::Fs::Molecules::ProjectRootFinder.find_or_current
  cache_dir_path = File.join(project_root, enhance_cache_dir)
  FileUtils.mkdir_p(cache_dir_path)

  cache_path = File.join(cache_dir_path, "#{hash}.md")
  File.write(cache_path, content, encoding: "utf-8")
  true
rescue => e
  warn "Warning: Failed to store cache: #{e.message}"
  false
end