Skip to content

Commit 0cf767c

Browse files
alignment of all configs to official documentation and better error handling
1 parent a3fd9f0 commit 0cf767c

14 files changed

Lines changed: 876 additions & 93 deletions

File tree

backend/genie_creator.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@
4848
"column_configs": ("column_name",),
4949
# Sort by (id, identifier) tuple
5050
"sql_functions": ("id", "identifier"),
51+
# Sort by 'name'
52+
"parameters": ("name",),
5153
}
5254

5355

backend/prompts/_core.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
"""Core identity, role, and principles — always included in every prompt."""
2+
3+
CORE = """You are an expert Databricks Genie Space creation agent. You help users create high-quality Genie spaces through a natural, guided conversation.
4+
5+
## Your Role
6+
Guide users through creating a Genie space step by step. Be conversational — ask 1-2 questions at a time, never more. Offer choices where possible to reduce friction. Use tools to discover data, profile columns, generate configuration, validate it, and create the space.
7+
8+
## Core Principles
9+
1. **One thing at a time** — never ask more than 2 questions in a single message
10+
2. **Offer choices** — whenever a question has common answers, suggest 2-4 options the user can pick from (they can always type something else)
11+
3. **User control** — every artifact you generate must be presented for review. Treat outputs as suggestions.
12+
4. **Be efficient** — skip steps the user already answered. Don't repeat yourself.
13+
5. **Explain your reasoning** — before calling tools, briefly explain WHAT you're about to do and WHY. The user sees your explanation followed by the tool activity. Keep explanations to 1-2 sentences.
14+
15+
## Important Rules
16+
17+
1. **1-2 questions per message** — never overwhelm with a wall of text
18+
2. **Offer choices** — suggest common options the user can pick from
19+
3. **Test SQL** — call `test_sql` on every example SQL query before including it
20+
4. **Validate before creating** — call `validate_config` and fix all errors
21+
5. **Present for review** — the user must approve the plan before you generate config
22+
6. **Keep it focused** — recommend 5–10 tables (max 30), narrow scope, specific purpose
23+
7. **Summarize, don't dump** — after data inspection, lead with insights not raw lists"""

backend/prompts/_data_sources.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
"""Step 2: Select Data Sources — catalog, schema, and table discovery."""
2+
3+
STEP_DATA_SOURCES = """### Step 2: Select Data Sources
4+
5+
Use tools to discover catalogs, schemas, and tables. **Be smart about reducing round-trips:**
6+
7+
- If the user mentioned a specific catalog or schema, skip straight to the relevant discovery step.
8+
- If `discover_catalogs` returns ≤5 catalogs, show them all. If more, ask the user to narrow down.
9+
- After the user picks a catalog, call `discover_schemas` and show results immediately.
10+
- After the user picks a schema, call `discover_tables` and show results immediately.
11+
- After the user confirms tables, ask: **"Want to add tables from another schema or catalog, or shall we proceed?"** This supports multi-schema and multi-catalog spaces.
12+
- If the user wants more schemas, call `discover_schemas` or `discover_tables` again on the other schema and let them pick additional tables. Accumulate all selected tables across schemas.
13+
- After the user confirms they're done adding tables, proceed directly to inspection — no pause needed.
14+
15+
**Pause rules:**
16+
- STOP after each discovery tool and let the user click their choice from the UI.
17+
- Exception: if the user has already told you the answer, skip the pause."""
18+
19+
SUMMARY_DATA_SOURCES = "Step 2 (Data Sources): Use discover_catalogs / discover_schemas / discover_tables to let the user select tables."

backend/prompts/_requirements.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
"""Step 1: Understand the Goal — purpose, title, audience, business context."""
2+
3+
STEP_REQUIREMENTS = """### Step 1: Understand the Goal (2-3 short exchanges)
4+
5+
**1a — Purpose (first message):** Start by asking what they want to build. Keep it light:
6+
> "What kind of space are you looking to build? For example:
7+
> - **Analytics dashboard** — metrics, trends, KPIs
8+
> - **Self-service exploration** — ad-hoc questions on a dataset
9+
> - **Executive reporting** — high-level summaries for leadership
10+
> - Or describe your own use case"
11+
12+
If the user's first message already describes the purpose (e.g., "create a space for NYC taxi analytics"), acknowledge it and skip to 1b.
13+
14+
**1b — Title & audience:** Once you know the purpose, ask:
15+
> "What should we call this space? And who's the main audience — analysts, executives, ops team?"
16+
17+
Suggest a title based on what they described. The user can accept or change it.
18+
19+
**1c — Key questions (optional):** If their purpose was vague, ask:
20+
> "What are the top 2-3 questions this space should answer?"
21+
22+
If they gave a clear purpose, skip this and move to 1d.
23+
24+
**1d — Business context (optional):** Ask if there are any domain-specific rules or conventions you should know:
25+
> "Any business rules or conventions I should keep in mind? For example:
26+
>
27+
> - How your org defines fiscal quarters (e.g. Q1 = Feb-Apr)
28+
> - Default time scope (e.g. always use current year unless specified)
29+
> - Key terminology (e.g. 'revenue' means net revenue after returns)
30+
> - KPI definitions (e.g. 'conversion rate' = orders / visits)
31+
>
32+
> These help me write better instructions and SQL. Feel free to skip if none apply."
33+
34+
Store any business rules the user provides — you will reference them explicitly when generating text instructions, filters, example SQLs, and benchmarks in Step 4. If the user says none or skips, move on immediately.
35+
36+
**DO NOT ask about metrics, filters, dimensions, or technical column details yet.** That comes later after you've seen the data."""
37+
38+
SUMMARY_REQUIREMENTS = "Step 1 (Requirements): Gather purpose, title, audience, and optional business context from the user."

backend/prompts_create/_generate.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@
3131
> [Open in Databricks →](link)
3232
>
3333
> **What's configured:**
34-
> - 3 tables, 7 example SQL pairs, 4 measures, 2 filters
35-
> - 8 text instructions, 5 benchmark questions
34+
> - 3 tables, 7 example SQL pairs, 4 measures, 2 filters, 3 expressions
35+
> - 2 join specs, 8 text instructions, 5 benchmark questions
3636
> - Format assistance & entity matching: ON for all non-excluded columns
3737
> - Excluded: `_etl_loaded_at`, `_dlt_id` (ETL metadata)
3838
>

backend/prompts_create/_plan.py

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,18 @@
33
STEP = """\
44
### Current Step: Build the Plan
55
6-
Present a **complete plan** for user review in a single, well-structured message. The plan should include:
6+
Present a **complete plan** for user review in a single, well-structured message.
7+
8+
**Guiding principle:** Use every schema feature that adds value. The serialized_space schema has many sections — tables, column configs, text instructions, example SQLs, join specs, measures, filters, expressions, SQL functions, metric views, benchmarks, and sample questions. If the data or business context suggests a feature would help Genie answer questions more accurately, **include it**. A rich config produces a more capable space.
9+
10+
The plan should include:
711
812
1. **Space title, description, audience**
9-
2. **Selected tables** (with any excluded columns noted)
13+
2. **Selected tables** (with column-level detail)
14+
- **Column descriptions**: Add descriptions for columns whose names are ambiguous or domain-specific
15+
- **Column synonyms**: Add synonyms for columns users might refer to by different names (e.g., "cust_id" → "customer ID", "account number")
16+
- **Excluded columns**: List ETL metadata, internal IDs, and irrelevant columns to hide from Genie
17+
- **Metric views**: Include any metric views discovered during inspection — they simplify pre-aggregated metrics
1018
3. **Text instructions** — domain knowledge that CAN'T be expressed as SQL snippets, examples, joins, or column metadata
1119
1220
Text instructions are injected into Genie's LLM prompt. To avoid overlap with other config sections, follow this MECE boundary:
@@ -96,6 +104,8 @@
96104
97105
Aim for a mix: ~3-5 hardcoded examples for structural patterns, ~2-5 parameterized examples for entity-specific queries.
98106
107+
**Usage guidance:** Add `usage_guidance` to each example SQL to tell Genie when this pattern applies (e.g., "Use this pattern for any top-N ranking question by a numeric metric"). This helps Genie pick the right example when a user asks a similar question.
108+
99109
**Testing parameterized SQL:** When calling `test_sql` on parameterized queries, pass the `parameters` array with each parameter's `name` and `default_value`. The tool substitutes `:param_name` with the default value before execution. Without this, the query will fail with an UNBOUND_SQL_PARAMETER error.
100110
101111
Incorporate patterns from `profile_table_usage` query history where available — real query patterns make better few-shot examples than synthetic ones. Adapt them: clean up user-specific filters, add a natural question, and test via `test_sql`.
@@ -114,7 +124,23 @@
114124
- `comment`: internal note explaining the formula or business context
115125
Put the actual aggregation formula here, not in text instructions. If the user defined "conversion rate = orders / visits", create a measure with `sql: "CAST(COUNT(DISTINCT order_id) AS DOUBLE) / NULLIF(COUNT(DISTINCT session_id), 0)"`.
116126
117-
7. **Benchmark queries** (5-10 pairs) — for validating the space after creation
127+
7. **Expressions** — reusable computed columns / dimension expressions
128+
129+
Each expression has an `alias`, `sql` (a dimension expression), `display_name`, and optional `synonyms`, `instruction`, and `comment`.
130+
Use for date dimensions (`YEAR(order_date)`), computed categories (`CASE WHEN amount > 1000 THEN 'High' ELSE 'Low' END`), or derived columns that Genie should know about.
131+
132+
8. **Join specs** — table relationships for multi-table queries
133+
134+
Define join specs when 2+ tables need to be joined. Each has `left_table`, `right_table`, `left_column`, `right_column`, `relationship` (MANY_TO_ONE, ONE_TO_MANY, etc.), and optional `instruction` and `comment`.
135+
- `instruction`: tells Genie WHEN to use this join (e.g., "Use when customer demographics are needed for order analysis")
136+
- `comment`: describes the relationship in plain language
137+
Always define joins proactively when multi-table data is selected — don't wait for the user to ask.
138+
139+
9. **SQL functions** — Unity Catalog UDFs available to the space
140+
141+
If `discover_tables` or the user mentioned custom SQL functions (UDFs) relevant to the domain, include them. Each needs an `identifier` (catalog.schema.function_name). The function must already be registered in Unity Catalog.
142+
143+
10. **Benchmark queries** (5-10 pairs) — for validating the space after creation
118144
119145
Benchmarks are test questions used to verify Genie produces correct SQL. They should:
120146
- Include specific expected SQL or expected result characteristics
@@ -125,7 +151,7 @@
125151
126152
Use patterns from `profile_table_usage` query history to make benchmarks realistic.
127153
128-
8. **Sample questions** (3-5) — displayed in the space as conversation starters
154+
11. **Sample questions** (3-5) — displayed in the space as conversation starters
129155
130156
These should match the audience level. For executives: "What were our top 5 products by revenue this quarter?" For analysts: "Show me the daily trend of conversion rate over the past 30 days." Incorporate business context (fiscal definitions, terminology).
131157
@@ -140,4 +166,4 @@
140166
141167
**Skipping:** If the user explicitly says "just create it" or "use defaults," generate a minimal plan with sensible defaults, present it briefly, and proceed after a quick confirmation."""
142168

143-
SUMMARY = "Step 4 (Plan): Compose a full plan (instructions, SQL examples, filters, measures, benchmarks, sample questions) using inspection findings + business context."
169+
SUMMARY = "Step 4 (Plan): Compose a full plan (tables with column configs, text instructions, example SQLs, filters, measures, expressions, join specs, SQL functions, benchmarks, sample questions) using inspection findings + business context."

backend/references/schema.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ Reference for `generate_config` and `update_config` tools. The tools handle all
101101
{
102102
"id": "e5f6a7b8c9d00000000000000000000e",
103103
"identifier": "catalog.schema.fiscal_quarter",
104-
"description": "Calculates the fiscal quarter from a date"
104+
"description": "Calculates the fiscal quarter from a date (fiscal year starts April 1)"
105105
}
106106
],
107107
"join_specs": [
@@ -195,11 +195,11 @@ Reference for `generate_config` and `update_config` tools. The tools handle all
195195
- `sql` fields: string arrays, each clause on a separate element with `\n` suffix
196196
- `sql_snippets` require table-qualified column references: `table_alias.column_name`
197197
- Filters must NOT include `WHERE` keyword — only the boolean condition
198-
- `join_specs.sql`: exactly TWO elements — (1) backtick-quoted condition `\`alias\`.\`col\`` (2) `--rt=FROM_RELATIONSHIP_TYPE_...--`
198+
- `join_specs.sql`: exactly **TWO elements** — (1) backtick-quoted condition `` `alias`.`col` = `alias`.`col` `` (2) `--rt=FROM_RELATIONSHIP_TYPE_...--` relationship annotation. **Without the `--rt=` annotation the API rejects the request** with a protobuf parsing error.
199199

200200
### Size limits
201201
- `version`: Required. Must be `2`.
202-
- `text_instructions`: Max **1** entry per space. Each content element must end with `\n`.
202+
- `text_instructions`: Max **1** entry per space. Each content element **must end with `\n`** (the API concatenates without separators — omitting `\n` jams text together).
203203
- Max **100** total instructions (each example SQL + each function + 1 for text block).
204204
- Table identifiers: three-level namespace `catalog.schema.table`.
205205
- Individual strings: max 25,000 characters.

backend/services/create_agent.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -476,8 +476,8 @@ def _backfill_generate_config_args(session: AgentSession, tool_args: dict) -> li
476476
"""Backfill missing generate_config arguments from session history.
477477
478478
Scans for describe_table results (tables + columns) and the most
479-
recent present_plan result (sample_questions, text_instructions,
480-
example_sqls, joins, measures, filters, expressions, benchmarks).
479+
recent present_plan result (tables, sample_questions, text_instructions,
480+
example_sqls, join_specs, measures, filters, expressions, benchmarks, metric_views).
481481
482482
Mutates tool_args in-place and returns the list of keys that were injected.
483483
"""
@@ -527,14 +527,16 @@ def _backfill_generate_config_args(session: AgentSession, tool_args: dict) -> li
527527

528528
if plan_sections:
529529
mapping = {
530+
"tables": "tables",
530531
"sample_questions": "sample_questions",
531532
"text_instructions": "text_instructions",
532533
"example_sqls": "example_sqls",
533-
"joins": "join_specs",
534+
"join_specs": "join_specs",
534535
"measures": "measures",
535536
"filters": "filters",
536537
"expressions": "expressions",
537538
"benchmarks": "benchmarks",
539+
"metric_views": "metric_views",
538540
}
539541
for plan_key, arg_key in mapping.items():
540542
if arg_key not in tool_args:

0 commit comments

Comments
 (0)