Class: RubynCode::Context::ContextBudget
- Inherits:
-
Object
- Object
- RubynCode::Context::ContextBudget
- Defined in:
- lib/rubyn_code/context/context_budget.rb
Overview
Budget-aware context loader that prioritizes which related files to load fully vs. as signatures-only. Prevents context bloat by capping auto-loaded context at a configurable token budget.
Constant Summary collapse
- CHARS_PER_TOKEN =
4- DEFAULT_BUDGET =
tokens
4000- PRIORITY_MAP =
Rails convention-based priority for related files. Lower number = higher priority = loaded first.
{ 'spec' => 1, # tests for the file 'factory' => 2, # FactoryBot factories 'service' => 3, # service objects 'model' => 4, # related models 'controller' => 5, # controllers 'serializer' => 6, # serializers 'concern' => 7, # concerns/mixins 'helper' => 8, # helpers 'migration' => 9 # migrations }.freeze
Instance Attribute Summary collapse
-
#loaded_files ⇒ Object
readonly
Returns the value of attribute loaded_files.
-
#signature_files ⇒ Object
readonly
Returns the value of attribute signature_files.
-
#tokens_used ⇒ Object
readonly
Returns the value of attribute tokens_used.
Instance Method Summary collapse
-
#extract_signatures(content) ⇒ Object
Extract method signatures and class structure without method bodies.
-
#initialize(budget: DEFAULT_BUDGET, codebase_index: nil) ⇒ ContextBudget
constructor
A new instance of ContextBudget.
-
#load_for(file_path, related_files: []) ⇒ Object
Load context for a primary file, filling budget with related files.
-
#stats ⇒ Object
Returns budget utilization stats.
Constructor Details
#initialize(budget: DEFAULT_BUDGET, codebase_index: nil) ⇒ ContextBudget
Returns a new instance of ContextBudget.
28 29 30 31 32 33 34 |
# File 'lib/rubyn_code/context/context_budget.rb', line 28 def initialize(budget: DEFAULT_BUDGET, codebase_index: nil) @budget = budget @codebase_index = codebase_index @loaded_files = [] @signature_files = [] @tokens_used = 0 end |
Instance Attribute Details
#loaded_files ⇒ Object (readonly)
Returns the value of attribute loaded_files.
26 27 28 |
# File 'lib/rubyn_code/context/context_budget.rb', line 26 def loaded_files @loaded_files end |
#signature_files ⇒ Object (readonly)
Returns the value of attribute signature_files.
26 27 28 |
# File 'lib/rubyn_code/context/context_budget.rb', line 26 def signature_files @signature_files end |
#tokens_used ⇒ Object (readonly)
Returns the value of attribute tokens_used.
26 27 28 |
# File 'lib/rubyn_code/context/context_budget.rb', line 26 def tokens_used @tokens_used end |
Instance Method Details
#extract_signatures(content) ⇒ Object
Extract method signatures and class structure without method bodies. Much more compact than full source — typically 10-20% of original size.
68 69 70 71 72 73 74 75 76 77 |
# File 'lib/rubyn_code/context/context_budget.rb', line 68 def extract_signatures(content) signatures = [] indent_stack = [] content.lines.each do |line| process_signature_line(line, signatures, indent_stack) end signatures.join end |
#load_for(file_path, related_files: []) ⇒ Object
Load context for a primary file, filling budget with related files. Returns array of { file:, content:, mode: :full|:signatures }
When a codebase_index is available and no related_files are supplied, uses impact_analysis to auto-discover related files (specs, associated models, controllers, etc.).
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/rubyn_code/context/context_budget.rb', line 42 def load_for(file_path, related_files: []) results = [] # Primary file always loads fully primary_content = safe_read(file_path) return results unless primary_content primary_tokens = estimate_tokens(primary_content) @tokens_used = primary_tokens @loaded_files << file_path results << { file: file_path, content: primary_content, mode: :full } # Auto-discover related files from the index when none supplied = (file_path) if .empty? && @codebase_index # Sort related files by priority and fill remaining budget sorted = prioritize() remaining = @budget - @tokens_used remaining = load_full_files(sorted, results, remaining) load_signature_files(sorted, results, remaining) results end |
#stats ⇒ Object
Returns budget utilization stats.
80 81 82 83 84 85 86 87 88 |
# File 'lib/rubyn_code/context/context_budget.rb', line 80 def stats { budget: @budget, tokens_used: @tokens_used, utilization: @budget.positive? ? (@tokens_used.to_f / @budget).round(3) : 0.0, full_files: @loaded_files.size, signature_files: @signature_files.size } end |