Class: CodeToQuery::Planner

Inherits:
Object
  • Object
show all
Defined in:
lib/code_to_query/planner.rb

Instance Method Summary collapse

Constructor Details

#initialize(config) ⇒ Planner

Returns a new instance of Planner.



5
6
7
# File 'lib/code_to_query/planner.rb', line 5

def initialize(config)
  @config = config
end

Instance Method Details

#plan(prompt:, schema:, allow_tables:) ⇒ Object



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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
# File 'lib/code_to_query/planner.rb', line 9

def plan(prompt:, schema:, allow_tables:)
  schema ||= load_context_pack
  allow_tables = Array(allow_tables).compact

  attempt = 0
  last_error = nil
  feedback = nil
  provider = build_provider
  max_attempts = @config.planner_max_attempts || 1

  while attempt < max_attempts
    attempt += 1
    begin
      intent = provider.extract_intent(
        prompt: build_prompt_with_feedback(prompt, feedback),
        schema: schema,
        allow_tables: allow_tables
      )

      # Optional schema strictness pass: drop filters referencing unknown columns
      if @config.planner_feedback_mode.to_s == 'schema_strict'
        intent = strip_unknown_columns(intent, schema)
      end

      # Expose provider metrics if available
      if provider.respond_to?(:metrics) && provider.metrics.is_a?(Hash)
        intent = intent.merge('_metrics' => provider.metrics)
      end

      # Heuristic backfill of missing params from the prompt (IDs and enum-like labels)
      intent = backfill_params_from_prompt(prompt, intent, schema)

      return intent
    rescue StandardError => e
      last_error = e
      feedback = generate_feedback(e)
      @config.logger.warn("[code_to_query] Planning attempt #{attempt} failed: #{e.message}")
    end
  end

  @config.logger.warn("[code_to_query] Query planning failed after #{max_attempts} attempts: #{last_error&.message}")
  fallback_intent(allow_tables)
rescue StandardError => e
  @config.logger.warn("[code_to_query] Query planning failed: #{e.message}")
  fallback_intent(allow_tables)
end