VibecoderMcSwaggins commited on
Commit
b866967
Β·
1 Parent(s): dfdeb30

docs: update UI simplification spec with senior review fixes

Browse files

Incorporates all feedback from senior review:
- Change 6: Fix Advanced mode check (was using removed param)
- Change 7: Remove 'Using your X key' message (would crash)
- Change 8: Remove api_provider from function call
- All 11 changes now explicitly documented with line numbers
- Added GPT-5.1 and Claude Sonnet 4.5 to compatibility matrix
- Added comprehensive testing checklist

Files changed (1) hide show
  1. docs/bugs/FIX_UI_SIMPLIFICATION.md +175 -62
docs/bugs/FIX_UI_SIMPLIFICATION.md CHANGED
@@ -1,8 +1,9 @@
1
- # UI Simplification: Remove Anthropic Provider
2
 
3
  **Issues**: #52, #53
4
  **Priority**: P1 - UX improvement for hackathon demo
5
  **Estimated Time**: 30 minutes
 
6
 
7
  ---
8
 
@@ -18,13 +19,17 @@ The current UI has confusing BYOK (Bring Your Own Key) settings:
18
 
19
  Remove `api_provider` dropdown entirely. Auto-detect provider from key prefix.
20
 
 
 
 
 
21
  ---
22
 
23
  ## Implementation
24
 
25
  ### File: `src/app.py`
26
 
27
- #### 1. Update `configure_orchestrator()` signature
28
 
29
  ```python
30
  # BEFORE
@@ -32,7 +37,7 @@ def configure_orchestrator(
32
  use_mock: bool = False,
33
  mode: str = "simple",
34
  user_api_key: str | None = None,
35
- api_provider: str = "openai", # REMOVE THIS
36
  ) -> tuple[Any, str]:
37
 
38
  # AFTER
@@ -43,29 +48,65 @@ def configure_orchestrator(
43
  ) -> tuple[Any, str]:
44
  ```
45
 
46
- #### 2. Auto-detect provider from key prefix
47
 
48
  ```python
49
- # Inside configure_orchestrator, replace provider logic with:
50
- if user_api_key:
51
- # Auto-detect provider from key prefix
52
- if user_api_key.startswith("sk-ant-"):
53
- # Anthropic key
54
- anthropic_provider = AnthropicProvider(api_key=user_api_key)
55
- model = AnthropicModel(settings.anthropic_model, provider=anthropic_provider)
56
- backend_info = "Paid API (Anthropic)"
57
- elif user_api_key.startswith("sk-"):
58
- # OpenAI key
59
- openai_provider = OpenAIProvider(api_key=user_api_key)
60
- model = OpenAIModel(settings.openai_model, provider=openai_provider)
61
- backend_info = "Paid API (OpenAI)"
62
- else:
63
- raise ValueError("Invalid API key format. Expected sk-... (OpenAI) or sk-ant-... (Anthropic)")
64
 
65
- judge_handler = JudgeHandler(model=model)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
66
  ```
67
 
68
- #### 3. Update `research_agent()` signature
69
 
70
  ```python
71
  # BEFORE
@@ -74,7 +115,7 @@ async def research_agent(
74
  history: list[dict[str, Any]],
75
  mode: str = "simple",
76
  api_key: str = "",
77
- api_provider: str = "openai", # REMOVE THIS
78
  ) -> AsyncGenerator[str, None]:
79
 
80
  # AFTER
@@ -86,116 +127,188 @@ async def research_agent(
86
  ) -> AsyncGenerator[str, None]:
87
  ```
88
 
89
- #### 4. Update warning message for Advanced mode
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90
 
91
  ```python
92
  # BEFORE
93
  if mode == "advanced" and not (has_openai or (has_user_key and api_provider == "openai")):
94
 
95
- # AFTER
96
- is_openai_key = user_api_key and user_api_key.startswith("sk-") and not user_api_key.startswith("sk-ant-")
97
- if mode == "advanced" and not (has_openai or is_openai_key):
98
  yield (
99
  "⚠️ **Advanced mode requires OpenAI API key.** "
100
- "Anthropic keys only work in Simple mode. Falling back to Simple.\\n\\n"
101
  )
102
  mode = "simple"
103
  ```
104
 
105
- #### 5. Simplify examples (remove provider column)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
106
 
107
  ```python
108
  # BEFORE
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
109
  examples=[
110
  ["What drugs improve female libido post-menopause?", "simple", "", "openai"],
111
- ["Clinical trials for erectile dysfunction alternatives to PDE...", "simple", "", "openai"],
112
  ["Evidence for testosterone therapy in women with HSDD?", "simple", "", "openai"],
113
- ]
114
 
115
- # AFTER
116
  examples=[
117
- ["What drugs improve female libido post-menopause?", "simple", ""],
118
- ["Clinical trials for ED alternatives to PDE5 inhibitors?", "simple", ""],
119
- ["Evidence for testosterone therapy in women with HSDD?", "simple", ""],
120
- ]
121
  ```
122
 
123
- #### 6. Remove provider from additional_inputs
124
 
125
  ```python
126
- # BEFORE
127
  additional_inputs=[
128
  gr.Radio(
129
  choices=["simple", "advanced"],
130
  value="simple",
131
  label="Orchestrator Mode",
132
- ...
133
  ),
134
  gr.Textbox(
135
  label="πŸ”‘ API Key (Optional - BYOK)",
136
- ...
 
 
137
  ),
138
- gr.Radio( # REMOVE THIS ENTIRE BLOCK
139
  choices=["openai", "anthropic"],
140
  value="openai",
141
  label="API Provider",
142
- ...
143
  ),
144
- ]
145
 
146
- # AFTER
147
  additional_inputs=[
148
  gr.Radio(
149
  choices=["simple", "advanced"],
150
  value="simple",
151
  label="Orchestrator Mode",
152
- info="Simple: Works with free tier | Advanced: Requires OpenAI key",
153
  ),
154
  gr.Textbox(
155
  label="πŸ”‘ API Key (Optional)",
156
  placeholder="sk-... (OpenAI) or sk-ant-... (Anthropic)",
157
  type="password",
158
- info="Leave empty for free tier (Llama 3.1). Auto-detects provider from key.",
159
  ),
160
- ]
161
  ```
162
 
163
- #### 7. Update accordion label
164
 
165
  ```python
166
- additional_inputs_accordion=gr.Accordion(
167
- label="βš™οΈ Settings (Free tier works without API key)",
168
- open=False
169
- ),
 
170
  ```
171
 
172
  ---
173
 
174
- ## Testing
175
 
176
  ### Manual Tests
177
- 1. **No key**: Should use free tier (HuggingFace Inference)
178
- 2. **OpenAI key**: Should detect and use OpenAI
179
- 3. **Anthropic key**: Should detect and use Anthropic in Simple mode
180
- 4. **Anthropic key + Advanced**: Should warn and fallback to Simple
 
 
 
 
181
 
182
  ### Unit Test Updates
183
- - Update `tests/unit/test_app_smoke.py` if it checks additional_inputs count
184
 
185
  ---
186
 
187
  ## Definition of Done
188
 
189
- - [ ] `api_provider` parameter removed from both functions
190
- - [ ] Auto-detection logic works for both key types
191
- - [ ] Examples table only shows 2 columns (query, mode)
 
 
 
192
  - [ ] Accordion label updated
193
- - [ ] Placeholder text shows key formats
194
- - [ ] Advanced mode warning works with auto-detection
195
  - [ ] All existing tests pass
 
 
 
 
 
 
 
 
 
 
196
 
197
  ---
198
 
199
  ## Related
200
  - Issue #52: UI Polish - Examples table confusion
201
  - Issue #53: API Provider Simplification
 
 
1
+ # UI Simplification: Remove API Provider Dropdown
2
 
3
  **Issues**: #52, #53
4
  **Priority**: P1 - UX improvement for hackathon demo
5
  **Estimated Time**: 30 minutes
6
+ **Senior Review**: βœ… Approved with changes (incorporated below)
7
 
8
  ---
9
 
 
19
 
20
  Remove `api_provider` dropdown entirely. Auto-detect provider from key prefix.
21
 
22
+ **Functionality preserved:**
23
+ - Simple mode: Free tier, OpenAI, OR Anthropic (all work)
24
+ - Advanced mode: OpenAI only (Magentic multi-agent requires `OpenAIChatClient`)
25
+
26
  ---
27
 
28
  ## Implementation
29
 
30
  ### File: `src/app.py`
31
 
32
+ #### Change 1: Update `configure_orchestrator()` signature (lines 23-28)
33
 
34
  ```python
35
  # BEFORE
 
37
  use_mock: bool = False,
38
  mode: str = "simple",
39
  user_api_key: str | None = None,
40
+ api_provider: str = "openai", # ← REMOVE
41
  ) -> tuple[Any, str]:
42
 
43
  # AFTER
 
48
  ) -> tuple[Any, str]:
49
  ```
50
 
51
+ #### Change 2: Update docstring (lines 29-40)
52
 
53
  ```python
54
+ # AFTER
55
+ """
56
+ Create an orchestrator instance.
57
+
58
+ Args:
59
+ use_mock: If True, use MockJudgeHandler (no API key needed)
60
+ mode: Orchestrator mode ("simple" or "advanced")
61
+ user_api_key: Optional user-provided API key (BYOK) - auto-detects provider
62
+
63
+ Returns:
64
+ Tuple of (Orchestrator instance, backend_name)
65
+ """
66
+ ```
67
+
68
+ #### Change 3: Replace provider logic with auto-detection (lines 62-88)
69
 
70
+ ```python
71
+ # BEFORE (lines 62-88) - complex provider checking with api_provider param
72
+
73
+ # AFTER - auto-detect from key prefix
74
+ # 2. Paid API Key (User provided or Env)
75
+ elif user_api_key and user_api_key.strip():
76
+ # Auto-detect provider from key prefix
77
+ model: AnthropicModel | OpenAIModel
78
+ if user_api_key.startswith("sk-ant-"):
79
+ # Anthropic key
80
+ anthropic_provider = AnthropicProvider(api_key=user_api_key)
81
+ model = AnthropicModel(settings.anthropic_model, provider=anthropic_provider)
82
+ backend_info = "Paid API (Anthropic)"
83
+ elif user_api_key.startswith("sk-"):
84
+ # OpenAI key
85
+ openai_provider = OpenAIProvider(api_key=user_api_key)
86
+ model = OpenAIModel(settings.openai_model, provider=openai_provider)
87
+ backend_info = "Paid API (OpenAI)"
88
+ else:
89
+ raise ValueError(
90
+ "Invalid API key format. Expected sk-... (OpenAI) or sk-ant-... (Anthropic)"
91
+ )
92
+ judge_handler = JudgeHandler(model=model)
93
+
94
+ # 3. Environment API Keys (fallback)
95
+ elif os.getenv("OPENAI_API_KEY"):
96
+ judge_handler = JudgeHandler(model=None) # Uses env key
97
+ backend_info = "Paid API (OpenAI from env)"
98
+
99
+ elif os.getenv("ANTHROPIC_API_KEY"):
100
+ judge_handler = JudgeHandler(model=None) # Uses env key
101
+ backend_info = "Paid API (Anthropic from env)"
102
+
103
+ # 4. Free Tier (HuggingFace Inference)
104
+ else:
105
+ judge_handler = HFInferenceJudgeHandler()
106
+ backend_info = "Free Tier (Llama 3.1 / Mistral)"
107
  ```
108
 
109
+ #### Change 4: Update `research_agent()` signature (lines 105-111)
110
 
111
  ```python
112
  # BEFORE
 
115
  history: list[dict[str, Any]],
116
  mode: str = "simple",
117
  api_key: str = "",
118
+ api_provider: str = "openai", # ← REMOVE
119
  ) -> AsyncGenerator[str, None]:
120
 
121
  # AFTER
 
127
  ) -> AsyncGenerator[str, None]:
128
  ```
129
 
130
+ #### Change 5: Update docstring (lines 112-124)
131
+
132
+ ```python
133
+ # AFTER
134
+ """
135
+ Gradio chat function that runs the research agent.
136
+
137
+ Args:
138
+ message: User's research question
139
+ history: Chat history (Gradio format)
140
+ mode: Orchestrator mode ("simple" or "advanced")
141
+ api_key: Optional user-provided API key (BYOK - auto-detects provider)
142
+
143
+ Yields:
144
+ Markdown-formatted responses for streaming
145
+ """
146
+ ```
147
+
148
+ #### Change 6: Fix Advanced mode check (line 139)
149
 
150
  ```python
151
  # BEFORE
152
  if mode == "advanced" and not (has_openai or (has_user_key and api_provider == "openai")):
153
 
154
+ # AFTER - auto-detect OpenAI key from prefix
155
+ is_openai_user_key = user_api_key and user_api_key.startswith("sk-") and not user_api_key.startswith("sk-ant-")
156
+ if mode == "advanced" and not (has_openai or is_openai_user_key):
157
  yield (
158
  "⚠️ **Advanced mode requires OpenAI API key.** "
159
+ "Anthropic keys only work in Simple mode. Falling back to Simple.\n\n"
160
  )
161
  mode = "simple"
162
  ```
163
 
164
+ #### Change 7: Remove premature "Using your key" message (lines 146-151)
165
+
166
+ ```python
167
+ # BEFORE - uses api_provider which no longer exists
168
+ if has_user_key:
169
+ yield (
170
+ f"πŸ”‘ **Using your {api_provider.upper()} API key** - "
171
+ "Your key is used only for this session and is never stored.\n\n"
172
+ )
173
+
174
+ # AFTER - remove this block entirely
175
+ # The backend_name from configure_orchestrator already shows "Paid API (OpenAI)" or "Paid API (Anthropic)"
176
+ # No need for duplicate messaging
177
+ ```
178
+
179
+ #### Change 8: Update configure_orchestrator call (lines 165-170)
180
 
181
  ```python
182
  # BEFORE
183
+ orchestrator, backend_name = configure_orchestrator(
184
+ use_mock=False,
185
+ mode=mode,
186
+ user_api_key=user_api_key,
187
+ api_provider=api_provider, # ← REMOVE
188
+ )
189
+
190
+ # AFTER
191
+ orchestrator, backend_name = configure_orchestrator(
192
+ use_mock=False,
193
+ mode=mode,
194
+ user_api_key=user_api_key,
195
+ )
196
+ ```
197
+
198
+ #### Change 9: Simplify examples (lines 210-229)
199
+
200
+ ```python
201
+ # BEFORE - 4 items per example
202
  examples=[
203
  ["What drugs improve female libido post-menopause?", "simple", "", "openai"],
204
+ ["Clinical trials for erectile dysfunction alternatives to PDE5 inhibitors?", "simple", "", "openai"],
205
  ["Evidence for testosterone therapy in women with HSDD?", "simple", "", "openai"],
206
+ ],
207
 
208
+ # AFTER - 2 items per example (query, mode) - API key always empty in examples
209
  examples=[
210
+ ["What drugs improve female libido post-menopause?", "simple"],
211
+ ["Clinical trials for ED alternatives to PDE5 inhibitors?", "simple"],
212
+ ["Evidence for testosterone therapy in women with HSDD?", "simple"],
213
+ ],
214
  ```
215
 
216
+ #### Change 10: Update additional_inputs (lines 231-252)
217
 
218
  ```python
219
+ # BEFORE - 3 inputs (mode, api_key, api_provider)
220
  additional_inputs=[
221
  gr.Radio(
222
  choices=["simple", "advanced"],
223
  value="simple",
224
  label="Orchestrator Mode",
225
+ info="Simple: Linear (Free Tier Friendly) | Advanced: Multi-Agent (Requires OpenAI)",
226
  ),
227
  gr.Textbox(
228
  label="πŸ”‘ API Key (Optional - BYOK)",
229
+ placeholder="sk-... or sk-ant-...",
230
+ type="password",
231
+ info="Enter your own API key. Never stored.",
232
  ),
233
+ gr.Radio( # ← REMOVE THIS ENTIRE BLOCK
234
  choices=["openai", "anthropic"],
235
  value="openai",
236
  label="API Provider",
237
+ info="Select the provider for your API key",
238
  ),
239
+ ],
240
 
241
+ # AFTER - 2 inputs (mode, api_key)
242
  additional_inputs=[
243
  gr.Radio(
244
  choices=["simple", "advanced"],
245
  value="simple",
246
  label="Orchestrator Mode",
247
+ info="Simple: Works with any key or free tier | Advanced: Requires OpenAI key",
248
  ),
249
  gr.Textbox(
250
  label="πŸ”‘ API Key (Optional)",
251
  placeholder="sk-... (OpenAI) or sk-ant-... (Anthropic)",
252
  type="password",
253
+ info="Leave empty for free tier. Auto-detects provider from key prefix.",
254
  ),
255
+ ],
256
  ```
257
 
258
+ #### Change 11: Update accordion label (line 230)
259
 
260
  ```python
261
+ # BEFORE
262
+ additional_inputs_accordion=gr.Accordion(label="βš™οΈ Settings", open=False),
263
+
264
+ # AFTER
265
+ additional_inputs_accordion=gr.Accordion(label="βš™οΈ Settings (Free tier works without API key)", open=False),
266
  ```
267
 
268
  ---
269
 
270
+ ## Testing Checklist
271
 
272
  ### Manual Tests
273
+ - [ ] **No key**: Shows "Free Tier (Llama 3.1 / Mistral)" in backend
274
+ - [ ] **OpenAI key (sk-...)**: Shows "Paid API (OpenAI)" in backend
275
+ - [ ] **Anthropic key (sk-ant-...)**: Shows "Paid API (Anthropic)" in backend
276
+ - [ ] **Invalid key format**: Shows error message
277
+ - [ ] **Anthropic key + Advanced mode**: Falls back to Simple with warning
278
+ - [ ] **OpenAI key + Advanced mode**: Uses full Magentic multi-agent
279
+ - [ ] **Examples table**: Shows only 2 columns (query, mode)
280
+ - [ ] **MCP server**: Still accessible at `/gradio_api/mcp/`
281
 
282
  ### Unit Test Updates
283
+ - [ ] `tests/unit/test_app_smoke.py` - may need update if checking input count
284
 
285
  ---
286
 
287
  ## Definition of Done
288
 
289
+ - [ ] `api_provider` parameter removed from `configure_orchestrator()`
290
+ - [ ] `api_provider` parameter removed from `research_agent()`
291
+ - [ ] Auto-detection logic works for `sk-` and `sk-ant-` prefixes
292
+ - [ ] Advanced mode check uses auto-detection (not removed param)
293
+ - [ ] "Using your X key" message removed (backend_name handles this)
294
+ - [ ] Examples table shows 2 columns
295
  - [ ] Accordion label updated
296
+ - [ ] Placeholder text shows both key formats
 
297
  - [ ] All existing tests pass
298
+ - [ ] MCP server still works
299
+
300
+ ---
301
+
302
+ ## Mode Compatibility Matrix (Unchanged)
303
+
304
+ | Mode | No Key | OpenAI Key | Anthropic Key |
305
+ |------|--------|------------|---------------|
306
+ | **Simple** | βœ… Free tier | βœ… GPT-5.1 | βœ… Claude Sonnet 4.5 |
307
+ | **Advanced** | ⚠️ Falls back | βœ… Full Magentic | ⚠️ Falls back to Simple |
308
 
309
  ---
310
 
311
  ## Related
312
  - Issue #52: UI Polish - Examples table confusion
313
  - Issue #53: API Provider Simplification
314
+ - Senior Review: Approved 2025-11-28