Module: Glancer::Workflow

Defined in:
lib/glancer/workflow.rb,
lib/glancer/workflow/llm.rb,
lib/glancer/workflow/cache.rb,
lib/glancer/workflow/builder.rb,
lib/glancer/workflow/executor.rb,
lib/glancer/workflow/ar_executor.rb,
lib/glancer/workflow/ar_extractor.rb,
lib/glancer/workflow/ar_sanitizer.rb,
lib/glancer/workflow/sql_extractor.rb,
lib/glancer/workflow/sql_sanitizer.rb,
lib/glancer/workflow/sql_validator.rb,
lib/glancer/workflow/prompt_builder.rb,
lib/glancer/workflow/query_enricher.rb,
lib/glancer/workflow/ar_prompt_builder.rb

Defined Under Namespace

Classes: ARExecutor, ARExtractor, ARPromptBuilder, ARSanitizer, Builder, Cache, Executor, LLM, PromptBuilder, QueryEnricher, SQLExtractor, SQLSanitizer, SQLValidator

Class Method Summary collapse

Class Method Details

.run(chat_id, question, cache: true, &status_callback) ⇒ Object



5
6
7
8
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
# File 'lib/glancer/workflow.rb', line 5

def self.run(chat_id, question, cache: true, &status_callback)
  Glancer::Utils::Logger.info("Workflow",
                              "Running workflow for chat_id: #{chat_id.inspect}, " \
                              "question: #{question.inspect}, " \
                              "mode: #{Glancer.configuration.query_mode}, cache: #{cache}")

  if cache && (cached = Workflow::Cache.fetch(question))
    Glancer::Utils::Logger.info("Workflow", "Using cached result for question: #{question.inspect}")
    return cached.merge(from_cache: true)
  end

  chat = Glancer::Chat.find(chat_id)
  history = chat.messages.order(created_at: :desc).limit(Glancer.configuration.history_limit).reverse

  enrichment_enabled = Glancer.configuration.query_enrichment_enabled
  adapter            = Glancer.configuration.query_mode

  status_callback&.call(:enriching) if enrichment_enabled
  effective_question = enrich_question(question, history, adapter: adapter)

  status_callback&.call(:retrieving_context)
  embeddings = Retriever.search(effective_question)
  Glancer::Utils::Logger.debug("Workflow", "Retrieved #{embeddings.size} relevant document(s) for context")

  result = if adapter == :activerecord
             run_activerecord(question, effective_question, embeddings, history, status_callback)
           else
             run_sql(question, effective_question, embeddings, history, status_callback)
           end

  # Always persist the enriched question so the info panel can show it on every message
  result[:enriched_question] = effective_question if enrichment_enabled

  if cache && result[:successful]
    Workflow::Cache.write(question, result)
    Glancer::Utils::Logger.info("Workflow", "Result cached for question: #{question.inspect}")
  end

  result
rescue StandardError => e
  Glancer::Utils::Logger.error("Workflow", "Workflow execution failed: #{e.class} - #{e.message}")
  Glancer::Utils::Logger.debug("Workflow", "Backtrace:\n#{e.backtrace.join("\n")}")
  raise Glancer::Error, "Workflow failed: #{e.message}"
end