mikeboone Claude Sonnet 4.6 commited on
Commit
fc9ee34
·
1 Parent(s): 487ba69

feat: run-time settings redesign — right panel accordion

Browse files

TS Environment + AI Model always visible at top. New collapsible
⚙️ Settings accordion contains Liveboard Name, Data Size (Small/
Medium/Standard/Large), and Geographic Scope. Controller reads all
panel values at GO time — no Supabase call during a run.

- Data Size maps to fact/dim row counts (5k/200 default = Standard)
- fact_table_size, dim_table_size, geo_scope hidden in Settings tab
(still saved to Supabase; UI now lives in right panel)
- Page load seeds panel from Supabase defaults via load_session_state_on_startup
- Sprint 4 doc updated: Priority 1 done, Priority 2 in progress

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

Files changed (3) hide show
  1. chat_interface.py +61 -31
  2. sprint_2026_04.md +60 -45
  3. tests/e2e_quality.py +1 -0
chat_interface.py CHANGED
@@ -5119,6 +5119,9 @@ def create_chat_interface():
5119
  use_case = str(settings.get("default_use_case", "")).strip()
5120
  model = (str(settings.get("default_llm", "")).strip() or DEFAULT_LLM_MODEL)
5121
  liveboard_name = str(settings.get("liveboard_name", "")).strip()
 
 
 
5122
  print(f"[LOAD] load_session_state_on_startup OK — model={model}, company={company}")
5123
  return (
5124
  "initialization",
@@ -5128,6 +5131,8 @@ def create_chat_interface():
5128
  liveboard_name,
5129
  gr.update(value=model),
5130
  gr.update(value=liveboard_name),
 
 
5131
  "",
5132
  )
5133
  except Exception as e:
@@ -5135,7 +5140,8 @@ def create_chat_interface():
5135
  print(f"[LOAD ERROR] load_session_state_on_startup failed: {e}\n{traceback.format_exc()}")
5136
  return (
5137
  "initialization", DEFAULT_LLM_MODEL, "", "", "",
5138
- gr.update(value=DEFAULT_LLM_MODEL), gr.update(value=""), "",
 
5139
  )
5140
 
5141
  # Wire up load handler - outputs follow SETTINGS_SCHEMA order
@@ -5156,6 +5162,8 @@ def create_chat_interface():
5156
  current_liveboard_name,
5157
  chat_components["model_dropdown"],
5158
  chat_components["liveboard_name_input"],
 
 
5159
  chat_components["msg"],
5160
  ]
5161
  )
@@ -5255,7 +5263,7 @@ def create_chat_tab(chat_controller_state, settings, current_stage, current_mode
5255
 
5256
  # Right column - Status & Settings
5257
  with gr.Column(scale=2):
5258
- # TS Environment selector
5259
  ts_env_choices = get_ts_environments()
5260
  ts_env_dropdown = gr.Dropdown(
5261
  label="TS Environment",
@@ -5264,7 +5272,7 @@ def create_chat_tab(chat_controller_state, settings, current_stage, current_mode
5264
  interactive=True,
5265
  )
5266
 
5267
- # AI Model selector
5268
  model_dropdown = gr.Dropdown(
5269
  label="AI Model",
5270
  choices=list(UI_MODEL_CHOICES),
@@ -5273,14 +5281,34 @@ def create_chat_tab(chat_controller_state, settings, current_stage, current_mode
5273
  allow_custom_value=True
5274
  )
5275
 
5276
- # Liveboard name (quick access same setting as in Settings tab)
5277
- liveboard_name_input = gr.Textbox(
5278
- label="Liveboard Name",
5279
- placeholder="Auto-generated if blank",
5280
- value=settings.get('liveboard_name', ''),
5281
- lines=1,
5282
- interactive=True,
5283
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5284
 
5285
  gr.Markdown("### 📈 Progress")
5286
 
@@ -5432,6 +5460,7 @@ def create_chat_tab(chat_controller_state, settings, current_stage, current_mode
5432
  # Defined tab: GO button handler
5433
  def defined_go(controller, vertical, line, function, url, use_url, additional_info,
5434
  history, stage, model, company, usecase, env_label, lb_name,
 
5435
  request: gr.Request = None):
5436
  import traceback
5437
  function_clean = (function or "").strip()
@@ -5450,6 +5479,18 @@ def create_chat_tab(chat_controller_state, settings, current_stage, current_mode
5450
  controller.settings['liveboard_name'] = lb_name
5451
  if model:
5452
  controller.settings['model'] = model
 
 
 
 
 
 
 
 
 
 
 
 
5453
 
5454
  # Derive company name from URL or line+function label
5455
  if use_url and url.strip():
@@ -5527,7 +5568,8 @@ def create_chat_tab(chat_controller_state, settings, current_stage, current_mode
5527
  _go_inputs = [
5528
  chat_controller_state, vertical_dd, line_dd, function_dd, url_input, use_url_cb,
5529
  additional_info_input, chatbot, current_stage, current_model,
5530
- current_company, current_usecase, ts_env_dropdown, liveboard_name_input
 
5531
  ]
5532
  _go_outputs = [
5533
  chat_controller_state, chatbot, current_stage, current_model,
@@ -5599,6 +5641,8 @@ def create_chat_tab(chat_controller_state, settings, current_stage, current_mode
5599
  'send_btn': send_btn,
5600
  'ts_env_dropdown': ts_env_dropdown,
5601
  'liveboard_name_input': liveboard_name_input,
 
 
5602
  'progress_html': progress_html,
5603
  'phase_log_display': phase_log_display,
5604
  'phase_log_timer': phase_log_timer,
@@ -5803,19 +5847,9 @@ def create_settings_tab():
5803
  info="Tag to apply to all ThoughtSpot objects (connection, tables, model, liveboard)"
5804
  )
5805
 
5806
- fact_table_size = gr.Dropdown(
5807
- label="Fact Table Size",
5808
- choices=["1000", "10000", "100000"],
5809
- value="1000",
5810
- info="Number of rows in fact table"
5811
- )
5812
-
5813
- dim_table_size = gr.Dropdown(
5814
- label="Dim Table Size",
5815
- choices=["50", "100", "1000"],
5816
- value="100",
5817
- info="Number of rows in dimension tables"
5818
- )
5819
 
5820
  with gr.Column():
5821
  object_naming_prefix = gr.Textbox(
@@ -5841,12 +5875,8 @@ def create_settings_tab():
5841
 
5842
  with gr.Row():
5843
  with gr.Column():
5844
- geo_scope = gr.Dropdown(
5845
- label="Geographic Scope",
5846
- choices=["USA Only", "International"],
5847
- value="USA Only",
5848
- info="USA Only: US states/cities, USD currency. International: Global locations, multiple currencies."
5849
- )
5850
 
5851
 
5852
 
 
5119
  use_case = str(settings.get("default_use_case", "")).strip()
5120
  model = (str(settings.get("default_llm", "")).strip() or DEFAULT_LLM_MODEL)
5121
  liveboard_name = str(settings.get("liveboard_name", "")).strip()
5122
+ _ft_to_size = {"100": "Small", "1000": "Medium", "5000": "Standard", "10000": "Large"}
5123
+ saved_size = _ft_to_size.get(str(settings.get("fact_table_size", "5000")), "Standard")
5124
+ saved_geo = str(settings.get("geo_scope", "USA Only")).strip() or "USA Only"
5125
  print(f"[LOAD] load_session_state_on_startup OK — model={model}, company={company}")
5126
  return (
5127
  "initialization",
 
5131
  liveboard_name,
5132
  gr.update(value=model),
5133
  gr.update(value=liveboard_name),
5134
+ gr.update(value=saved_size),
5135
+ gr.update(value=saved_geo),
5136
  "",
5137
  )
5138
  except Exception as e:
 
5140
  print(f"[LOAD ERROR] load_session_state_on_startup failed: {e}\n{traceback.format_exc()}")
5141
  return (
5142
  "initialization", DEFAULT_LLM_MODEL, "", "", "",
5143
+ gr.update(value=DEFAULT_LLM_MODEL), gr.update(value=""),
5144
+ gr.update(value="Standard"), gr.update(value="USA Only"), "",
5145
  )
5146
 
5147
  # Wire up load handler - outputs follow SETTINGS_SCHEMA order
 
5162
  current_liveboard_name,
5163
  chat_components["model_dropdown"],
5164
  chat_components["liveboard_name_input"],
5165
+ chat_components["data_size_dropdown"],
5166
+ chat_components["geo_scope_dropdown"],
5167
  chat_components["msg"],
5168
  ]
5169
  )
 
5263
 
5264
  # Right column - Status & Settings
5265
  with gr.Column(scale=2):
5266
+ # TS Environment selector (always visible)
5267
  ts_env_choices = get_ts_environments()
5268
  ts_env_dropdown = gr.Dropdown(
5269
  label="TS Environment",
 
5272
  interactive=True,
5273
  )
5274
 
5275
+ # AI Model selector (always visible)
5276
  model_dropdown = gr.Dropdown(
5277
  label="AI Model",
5278
  choices=list(UI_MODEL_CHOICES),
 
5281
  allow_custom_value=True
5282
  )
5283
 
5284
+ # Run-time settingscollapsible, all pipeline knobs here
5285
+ with gr.Accordion("⚙️ Settings", open=False):
5286
+ liveboard_name_input = gr.Textbox(
5287
+ label="Liveboard Name",
5288
+ placeholder="Auto from company URL if blank",
5289
+ value=settings.get('liveboard_name', ''),
5290
+ lines=1,
5291
+ interactive=True,
5292
+ )
5293
+
5294
+ # Map saved fact_table_size → Data Size label
5295
+ _ft_to_size = {"100": "Small", "1000": "Medium", "5000": "Standard", "10000": "Large"}
5296
+ _saved_ft = str(settings.get('fact_table_size', '5000'))
5297
+ _init_data_size = _ft_to_size.get(_saved_ft, "Standard")
5298
+
5299
+ data_size_dropdown = gr.Dropdown(
5300
+ label="Data Size",
5301
+ choices=["Small", "Medium", "Standard", "Large"],
5302
+ value=_init_data_size,
5303
+ interactive=True,
5304
+ info="Small 100 rows · Medium 1k · Standard 5k · Large 10k",
5305
+ )
5306
+ geo_scope_dropdown = gr.Dropdown(
5307
+ label="Geographic Scope",
5308
+ choices=["USA Only", "International"],
5309
+ value=settings.get('geo_scope', 'USA Only'),
5310
+ interactive=True,
5311
+ )
5312
 
5313
  gr.Markdown("### 📈 Progress")
5314
 
 
5460
  # Defined tab: GO button handler
5461
  def defined_go(controller, vertical, line, function, url, use_url, additional_info,
5462
  history, stage, model, company, usecase, env_label, lb_name,
5463
+ data_size, geo_scope,
5464
  request: gr.Request = None):
5465
  import traceback
5466
  function_clean = (function or "").strip()
 
5479
  controller.settings['liveboard_name'] = lb_name
5480
  if model:
5481
  controller.settings['model'] = model
5482
+ if data_size:
5483
+ _size_map = {
5484
+ "Small": ("100", "20"),
5485
+ "Medium": ("1000", "100"),
5486
+ "Standard": ("5000", "200"),
5487
+ "Large": ("10000", "500"),
5488
+ }
5489
+ _ft, _dt = _size_map.get(data_size, ("5000", "200"))
5490
+ controller.settings['fact_table_size'] = _ft
5491
+ controller.settings['dim_table_size'] = _dt
5492
+ if geo_scope:
5493
+ controller.settings['geo_scope'] = geo_scope
5494
 
5495
  # Derive company name from URL or line+function label
5496
  if use_url and url.strip():
 
5568
  _go_inputs = [
5569
  chat_controller_state, vertical_dd, line_dd, function_dd, url_input, use_url_cb,
5570
  additional_info_input, chatbot, current_stage, current_model,
5571
+ current_company, current_usecase, ts_env_dropdown, liveboard_name_input,
5572
+ data_size_dropdown, geo_scope_dropdown,
5573
  ]
5574
  _go_outputs = [
5575
  chat_controller_state, chatbot, current_stage, current_model,
 
5641
  'send_btn': send_btn,
5642
  'ts_env_dropdown': ts_env_dropdown,
5643
  'liveboard_name_input': liveboard_name_input,
5644
+ 'data_size_dropdown': data_size_dropdown,
5645
+ 'geo_scope_dropdown': geo_scope_dropdown,
5646
  'progress_html': progress_html,
5647
  'phase_log_display': phase_log_display,
5648
  'phase_log_timer': phase_log_timer,
 
5847
  info="Tag to apply to all ThoughtSpot objects (connection, tables, model, liveboard)"
5848
  )
5849
 
5850
+ # fact_table_size and dim_table_size moved to right panel (Data Size dropdown)
5851
+ fact_table_size = gr.Textbox(visible=False, value="5000")
5852
+ dim_table_size = gr.Textbox(visible=False, value="100")
 
 
 
 
 
 
 
 
 
 
5853
 
5854
  with gr.Column():
5855
  object_naming_prefix = gr.Textbox(
 
5875
 
5876
  with gr.Row():
5877
  with gr.Column():
5878
+ # geo_scope moved to right panel Settings accordion
5879
+ geo_scope = gr.Textbox(visible=False, value="USA Only")
 
 
 
 
5880
 
5881
 
5882
 
sprint_2026_04.md CHANGED
@@ -26,55 +26,85 @@ expanding the user base further.
26
 
27
  ## Sprint Priorities
28
 
29
- ### Priority 1 — Branching / Release Strategy ✅ (set up at sprint start)
30
 
31
  - [x] Define `main` / `develop` / hotfix workflow — documented in CLAUDE.md
32
- - [ ] Create `develop` branch from current `main`
33
- - [ ] Update CI/push targets: sprint work → `hf-test` via `develop`; prod fixes `hf` via `main`
34
- - [ ] Add git tag for current prod release (`v1.0.0` or similar) before new sprint work begins
 
35
 
36
  ---
37
 
38
  ### Priority 2 — Run-Time Settings Redesign
39
 
40
- **Goal:** All pipeline control knobs are live on the app screen. No save/reload cycle.
41
- Setting a value takes effect for the next run immediately. Defaults come from Supabase
42
- admin settings, but can be overridden at runtime without touching the database.
43
 
44
- **Right panel layout:**
45
  ```
46
  ┌─────────────────────────────┐
47
  │ TS Environment [dropdown] │ ← always visible
48
  │ AI Model [dropdown] │ ← always visible
49
  ├─────────────────────────────┤
50
- Advanced Settings │ ← accordion, collapsed by default
51
- │ Liveboard Name [text] │
52
- │ Data Size [dropdown] (Small / Medium / Standard / Large)
53
- │ Geo Scope [dropdown] (USA Only / International)
54
  │ [other knobs as added] │
55
- ─────────────────────────────
56
- │ Pipeline Status / Progress │ ← below settings
57
  │ [stage indicators] │
58
  └─────────────────────────────┘
59
  ```
60
 
61
- **Rules:**
62
- - Values shown are loaded from user's saved settings (Supabase) at page load
63
- - Changing a value in the panel takes effect immediately for the current session — no Save button needed
64
- - "Save as default" option (optional, later) writes back to Supabase
65
- - Eliminates the separate Settings tab for pipeline-control settings (those move here)
66
- - Settings tab becomes admin/account settings only (TS credentials, user preferences)
 
 
 
 
 
 
 
67
 
68
  **Tasks:**
69
- - [ ] Audit all Settings tab fields — categorize as (a) run-time knobs or (b) admin/account
70
- - [ ] Move run-time knobs to right panel with accordion
71
- - [ ] Wire values to controller at run time (not just at session init)
72
- - [ ] Remove save/reload dependency for pipeline settings
73
- - [ ] Update `fact_table_size`, `dim_table_size`, `geo_scope`, `liveboard_name` to read from panel state
 
 
 
 
74
 
75
  ---
76
 
77
- ### Priority 3 — Data Narrative Layer
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
 
79
  **Goal:** Generated data tells the right story. Numbers reflect KPI targets, business context,
80
  and the outlier patterns the liveboard is designed to highlight.
@@ -92,27 +122,12 @@ should tell. KPI targets, growth trends, and anomaly patterns live in the matrix
92
 
93
  ---
94
 
95
- ### Priority 4 — 10k Row Test
96
-
97
- **Goal:** Confirm the "large" preset (10k fact rows) works end-to-end and produces better liveboard quality.
98
-
99
- **Known issues to solve in test:**
100
- - Settings cached at controller init — test must change setting → trigger fresh session → run pipeline
101
- - 10k runs will be ~3–4x slower — bump test timeout for large-preset tests
102
- - Validate that `is_fact_table` name-based detection correctly assigns 10k rows (not 500)
103
-
104
- **Tasks:**
105
- - [ ] Add `fact_table_size=10000` variant to test suite (separate test case or flag)
106
- - [ ] Implement session reset between setting change and run in test harness
107
- - [ ] Increase timeout for large-preset test cases
108
- - [ ] Compare data/liveboard quality scores: 1k vs 10k on same company/use case
109
-
110
- ---
111
-
112
- ## Next Priorities (from status report "Working On Next")
113
 
114
  - [ ] **Async pipeline** — data population + TS model creation currently sequential; run in parallel to cut total pipeline time
115
- - [ ] **Enablement** — HTML user guide (full page on HF doc space, not just the markdown draft); demo videos
 
 
116
  - [ ] **Matrix field input** — story definitions need field review; liveboard makeup and key outlier questions per vertical
117
 
118
  ---
 
26
 
27
  ## Sprint Priorities
28
 
29
+ ### Priority 1 — Branching / Release Strategy ✅
30
 
31
  - [x] Define `main` / `develop` / hotfix workflow — documented in CLAUDE.md
32
+ - [x] `develop` branch exists and tracks `origin/develop`
33
+ - [x] `hf-test` remote exists for test deploys
34
+ - [x] Tagged `v1.0.0` on `main` marks sprint 4 start ✅
35
+ - [ ] Update CI/push targets: sprint work → `hf-test` via `develop`; prod fixes → `hf` via `main` (document in team workflow)
36
 
37
  ---
38
 
39
  ### Priority 2 — Run-Time Settings Redesign
40
 
41
+ **Goal:** All pipeline control knobs live on the main app screen. No save/reload cycle.
42
+ Values take effect immediately for the current run. Defaults come from Supabase admin
43
+ settings (loaded to screen at page load) the app then reads exclusively from the screen.
44
 
45
+ **Right panel layout (updated):**
46
  ```
47
  ┌─────────────────────────────┐
48
  │ TS Environment [dropdown] │ ← always visible
49
  │ AI Model [dropdown] │ ← always visible
50
  ├─────────────────────────────┤
51
+ Settings (collapsible) │
52
+ │ Liveboard Name [text] │ ← blank = auto from company URL
53
+ │ Data Size [dropdown]Small/Medium/Standard/Large
54
+ │ Geo Scope [dropdown]USA Only / International
55
  │ [other knobs as added] │
56
+ ─────────────────────────────
57
+ │ Pipeline Status / Progress │ ← below settings block
58
  │ [stage indicators] │
59
  └─────────────────────────────┘
60
  ```
61
 
62
+ **Architecture:**
63
+ - Supabase loads default values to screen controls at page load — that's its only job here
64
+ - From page load onward, the app reads exclusively from the screen (no mid-run DB calls)
65
+ - Controller reads `env_dropdown.value`, `model_dropdown.value`, `data_size.value`, etc. at GO time
66
+ - Admin page gets a "reset defaults" panel lets you set new default values without affecting a live run
67
+ - Settings tab retains only TS credentials + user account settings; pipeline knobs move here
68
+ - Liveboard Name blank → auto-derives from company URL (strip TLD, capitalize)
69
+
70
+ **Data Size presets:**
71
+ - Small: 100 fact / 20 dim
72
+ - Medium: 1,000 fact / 100 dim
73
+ - Standard: 5,000 fact / 200 dim
74
+ - Large: 10,000 fact / 500 dim
75
 
76
  **Tasks:**
77
+ - [x] Audit all Settings tab fields — categorize as (a) run-time knobs or (b) admin/account
78
+ - [x] Move run-time knobs to right panel (always-visible + collapsible accordion) ✅ — Liveboard Name, Data Size, Geo Scope in `⚙️ Settings` accordion
79
+ - [x] Wire controller to read live panel values at GO time `defined_go` maps Data Size → fact/dim row counts, passes geo_scope directly
80
+ - [x] Remove save/reload dependency for pipeline settings ✅ — panel values override at run time
81
+ - [x] `fact_table_size`/`dim_table_size`/`geo_scope` hidden in Settings tab (still saved to Supabase, but UI lives in right panel)
82
+ - [x] Supabase defaults seed right panel at page load via `load_session_state_on_startup` ✅
83
+ - [ ] Auto-derive liveboard name from company URL when field is blank
84
+ - [ ] Add "reset defaults" section to Admin page
85
+ - [ ] Remove orphaned Password field from Settings tab (never wired to SETTINGS_SCHEMA)
86
 
87
  ---
88
 
89
+ ### Priority 3 — 10k Row Test
90
+
91
+ **Goal:** Confirm the "large" preset (10k fact rows) works end-to-end and produces better liveboard quality.
92
+ Do this after the settings redesign — no sense testing row count behavior against the old settings flow.
93
+
94
+ **Known issues to solve in test:**
95
+ - Settings cached at controller init — test must change setting → trigger fresh session → run pipeline
96
+ - 10k runs will be ~3–4x slower — bump test timeout for large-preset tests
97
+ - Validate that `is_fact_table` name-based detection correctly assigns 10k rows (not 500)
98
+
99
+ **Tasks:**
100
+ - [ ] Add `fact_table_size=10000` variant to test suite (separate test case or flag)
101
+ - [ ] Implement session reset between setting change and run in test harness
102
+ - [ ] Increase timeout for large-preset test cases
103
+ - [ ] Compare data/liveboard quality scores: 1k vs 10k on same company/use case
104
+
105
+ ---
106
+
107
+ ### Priority 4 — Data Narrative Layer (deferred)
108
 
109
  **Goal:** Generated data tells the right story. Numbers reflect KPI targets, business context,
110
  and the outlier patterns the liveboard is designed to highlight.
 
122
 
123
  ---
124
 
125
+ ## Next Priorities
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
126
 
127
  - [ ] **Async pipeline** — data population + TS model creation currently sequential; run in parallel to cut total pipeline time
128
+ - [ ] **Dev database** — dedicated Snowflake dev schema/database so test runs don't land in prod schema; isolate dev/test/prod data cleanly
129
+ - [ ] **LLM costs tracking** — log token usage and estimated cost per pipeline run to Supabase; surface in Admin tab so we can monitor spend
130
+ - [ ] **Enablement** — HTML user guide (full page on HF doc space); demo videos. *Note: HTML guide is the concrete deliverable — not just the markdown draft.*
131
  - [ ] **Matrix field input** — story definitions need field review; liveboard makeup and key outlier questions per vertical
132
 
133
  ---
tests/e2e_quality.py CHANGED
@@ -1226,6 +1226,7 @@ def run_quality_suite(max_tests: int = None):
1226
 
1227
  print(f"\n{'='*62}")
1228
  print(f" DemoPrep Quality Run — {datetime.now().strftime('%Y-%m-%d %H:%M')}")
 
1229
  print(f" {len(suite)} tests | "
1230
  f"{sum(1 for t in suite if t['type']=='fixed')} fixed "
1231
  f"{sum(1 for t in suite if t['type']=='random')} random "
 
1226
 
1227
  print(f"\n{'='*62}")
1228
  print(f" DemoPrep Quality Run — {datetime.now().strftime('%Y-%m-%d %H:%M')}")
1229
+ print(f" Target: {BASE_URL}")
1230
  print(f" {len(suite)} tests | "
1231
  f"{sum(1 for t in suite if t['type']=='fixed')} fixed "
1232
  f"{sum(1 for t in suite if t['type']=='random')} random "