Class: Strata::CLI::AI::Services::TableGenerator

Inherits:
Object
  • Object
show all
Defined in:
lib/strata/cli/ai/services/table_generator.rb

Overview

Generates semantic model fields from database table metadata using AI. Returns structured JSON for use in the field editor.

Constant Summary collapse

SYSTEM_PROMPT =
<<~PROMPT
  You are a semantic modeling expert for analytics and BI systems.
  Analyze database columns and generate semantic field definitions.

  For each column, determine:
  - name: Human-friendly field name (e.g., "customer_id" → "Customer ID")
  - description: Brief description of what this field represents
  - schema_type: "dimension" for categorical/text, "measure" for numeric aggregations
  - data_type: string, integer, bigint, decimal, date, date_time, boolean
  - expression: SQL expression (for measures include aggregation like "sum(amount)")
  - synonyms: Array of 2-4 alternative names users might use to refer to this field.
    These help AI search and natural language queries find the right field.
    Example: "Customer ID" → ["cust id", "client id", "buyer id"]

  Output ONLY valid JSON array, no explanations.
PROMPT

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(client: Client.new) ⇒ TableGenerator

Returns a new instance of TableGenerator.



32
33
34
# File 'lib/strata/cli/ai/services/table_generator.rb', line 32

def initialize(client: Client.new)
  @client = client
end

Instance Attribute Details

#clientObject (readonly)

Returns the value of attribute client.



30
31
32
# File 'lib/strata/cli/ai/services/table_generator.rb', line 30

def client
  @client
end

Instance Method Details

#ai_available?Boolean

Check if AI is available

Returns:

  • (Boolean)


96
97
98
# File 'lib/strata/cli/ai/services/table_generator.rb', line 96

def ai_available?
  @client.enabled?
end

#call(table_name:, columns:, datasource:, user_context: nil) ⇒ Hash?

Generate field definitions from table metadata

Parameters:

  • table_name (String)

    Full table name (schema.table)

  • columns (Array<Hash>)

    Column metadata with :name, :type

  • datasource (String)

    Datasource key

  • user_context (Hash, nil) (defaults to: nil)

    Optional user-provided context with :description

Returns:

  • (Hash, nil)

    Generated model data or nil if AI disabled



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/strata/cli/ai/services/table_generator.rb', line 42

def call(table_name:, columns:, datasource:, user_context: nil)
  unless ai_available?
    warn "AI not available - using rule-based fallback"
    return fallback_fields(columns)
  end

  existing_models = load_existing_models_context
  prompt = build_prompt(
    table_name: table_name,
    columns: columns,
    existing_models_context: existing_models,
    user_context: user_context
  )

  begin
    response = @client.complete(prompt, system_prompt: SYSTEM_PROMPT)
    parse_response(response, columns)
  rescue => e
    # Fallback to basic field generation on AI error
    warn "AI failed to generate fields: #{e.message} - performing basic field generation"
    fallback_fields(columns)
  end
end

#call_with_prompt(table_name:, columns:, datasource:, user_prompt:, current_fields:) ⇒ Array<Hash>

Generate fields with user prompt for modification/regeneration

Parameters:

  • table_name (String)

    Full table name

  • columns (Array<Hash>)

    Column metadata

  • datasource (String)

    Datasource key

  • user_prompt (String)

    User’s natural language prompt

  • current_fields (Array<Hash>)

    Current field definitions

Returns:

  • (Array<Hash>)

    Regenerated fields



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/strata/cli/ai/services/table_generator.rb', line 73

def call_with_prompt(table_name:, columns:, datasource:, user_prompt:, current_fields:)
  unless ai_available?
    warn "AI not available - could not use prompt mode"
    return nil
  end

  prompt = build_prompt_with_user_input(
    table_name: table_name,
    columns: columns,
    user_prompt: user_prompt,
    current_fields: current_fields
  )

  begin
    response = @client.complete(prompt, system_prompt: SYSTEM_PROMPT)
    parse_response(response, columns)
  rescue => e
    warn "AI failed to generate fields: #{e.message}"
    nil
  end
end