Class: Strata::CLI::AI::Services::TableGenerator
- Inherits:
-
Object
- Object
- Strata::CLI::AI::Services::TableGenerator
- 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 the Strata Business Intelligence platform. Analyze database columns and generate semantic field definitions. You must understand that Names are extremely important in the Strata application. When the same named dimension is mapped to multiple tables, Strata treats them as the same entity but with multiple potential tables. Strata will at query generation time choose the best table. Therefore it is extremely important to consider whether a potential dimension or measure is the same as an existing one. You can try and infer that based on the table name, column name, and the existing fields. In general, you should use existing names for the same schema type if it makes sense. The edge case is when you have a Dimension table like Customer with column first_name and another Dimension table called Billed Customer with first_name, then they are likely not the same. A dimension created from Billed Customer should be given an appropriately prefixed name: Billed Customer First Name. Next, if the column is something highly ambigous and the current table is likely a dimension table, we should prefix then dimension name with approprite prefix based on the name of the dimension table. Example: table name: item_dim column name: color dimension name: Item Color Example: table name: customer column name: first name dimension name: Customer First Name Given the above 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. These are the data types supported by strata. They do not have precision nor scale. Simply the types listed here. Do not apply any other data types. - expression: SQL expression (for measures include aggregation like "sum(amount)") - synonyms: Array of 0-3 alternative names users might use to refer to this field. These help AI search and natural language queries find the right field. Example: "Revenue" → ["sales"] Example: "Created At" → ["created date", "date"] Example: "State" in a geography table → ["province"] Example: "Customer Return Date" → [] -- name has high specificity already so no synonyms needed In cases where a dimension already exists (i.e. a dimension with same name exists), omit everything except the following fields: name, schema_type, data_type, expression. Output ONLY valid JSON array, no explanations. PROMPT
Instance Attribute Summary collapse
-
#client ⇒ Object
readonly
Returns the value of attribute client.
Instance Method Summary collapse
-
#ai_available? ⇒ Boolean
Check if AI is available.
-
#call(table_name:, columns:, datasource:, user_context: nil) ⇒ Hash?
Generate field definitions from table metadata.
-
#call_with_prompt(table_name:, columns:, datasource:, user_prompt:, current_fields:) ⇒ Array<Hash>
Generate fields with user prompt for modification/regeneration.
-
#initialize(client: Client.new) ⇒ TableGenerator
constructor
A new instance of TableGenerator.
Constructor Details
#initialize(client: Client.new) ⇒ TableGenerator
Returns a new instance of TableGenerator.
59 60 61 |
# File 'lib/strata/cli/ai/services/table_generator.rb', line 59 def initialize(client: Client.new) @client = client end |
Instance Attribute Details
#client ⇒ Object (readonly)
Returns the value of attribute client.
57 58 59 |
# File 'lib/strata/cli/ai/services/table_generator.rb', line 57 def client @client end |
Instance Method Details
#ai_available? ⇒ Boolean
Check if AI is available
123 124 125 |
# File 'lib/strata/cli/ai/services/table_generator.rb', line 123 def ai_available? @client.enabled? end |
#call(table_name:, columns:, datasource:, user_context: nil) ⇒ Hash?
Generate field definitions from table metadata
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/strata/cli/ai/services/table_generator.rb', line 69 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.} - 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
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/strata/cli/ai/services/table_generator.rb', line 100 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.}" nil end end |