You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit dd17e96
Browse filesBrowse the repository at this point in the historyBrowse files
# auto: add multimodal image input via Gemini 2.0 Flash
1
+
# auto: fix markdown prose styling for non-recipe chat responses
2
2
3
3
## Why
4
4
5
-
265 traces show zero image-based queries, yet "fridge photo → recipe" and "dish recreation" are natural, high-value flows. The `GEMINI_API_KEY` is already wired into CI (confirmed via `GEMINI_API_KEY` env var). Adding image input behind a flag lets us ship the capability safely — flag stays off in production until validated, and existing text-only behavior is completely unchanged when the flag is off (image field is silently ignored).
5
+
Two real user traces confirm that numbered lists and bullet points are invisible in the chat UI:
6
+
- Trace `0ee0a635e5b25b7abe154d9e730c90ab`: User said "I think the markdown is not rendering the numbers" after receiving a numbered dinner-options list.
7
+
- Trace `dafdb4a5e3bbb0d1a6e12f2466ae1315`: User asked the agent to format options "like 1, 2, 3" — implying current list rendering was broken.
6
8
7
-
Note: The operator focus hint specified Gemini 1.5 Flash, which has been retired. The implementation uses **Gemini 2.0 Flash** (`gemini-2.0-flash`), the direct successor at the same cost/speed point.
9
+
Root cause: `@tailwindcss/typography` is not installed and not in `tailwind.config.ts` plugins. Tailwind's preflight CSS resets `<ol>/<ul>` defaults — it strips `list-style-type` and `padding-left` from all list elements. The `prose-invert` class used throughout the chat components has **no effect** without the typography plugin, so every numbered list and bullet the agent produces renders as flat, unstyled text with no visible markers.
10
+
11
+
This affects every non-recipe response: numbered dinner options, clarifying-question lists, substitution bullet points, multi-turn follow-ups.
8
12
9
13
## What
10
14
11
-
-`api/main.py`: Added optional `image` field (base64 data URL, HTTP(S) URL, or raw base64) to `ChatRequest`. When `auto_multimodal_images` is ON and `image` is non-null, the `/chat` endpoint calls `_call_gemini_vision()` instead of the OpenAI agent. Added `multimodal_images` key to `/flags` response. Supports data URLs, HTTP image URLs (auto-fetched and base64-encoded), and raw base64.
12
-
-`web/components/chat.tsx`: Added `ImagePlus` button in the Premium UI input row (shown only when `multimodal_images` flag is on). Image is selected via hidden file input, previewed as a thumbnail strip above the text field, and sent as a base64 data URL in the request body. User bubbles render the attached image above their text. The send button is enabled when either text OR an image is present.
13
-
-`tests/test_multimodal_image.py`: New scenario test exercising the Gemini vision path. Skipped when `GEMINI_API_KEY` is absent or when the API quota is exhausted (external quota issues should not fail CI).
15
+
-`web/components/markdown-renderer.tsx`*(new)*: Shared `MarkdownRenderer` component wrapping `react-markdown` with a `components` prop that applies explicit Tailwind utility classes (`list-decimal pl-5`, `list-disc pl-5`, `leading-relaxed`, etc.) when `proseEnabled` is true. Falls back to unstyled rendering when flag is off, preserving current behavior exactly.
16
+
-`api/main.py`: Added `markdown_prose_styling` key to `/flags` response, reading the `auto_markdown_prose_styling` Flagsmith flag (default off).
17
+
-`web/components/chat.tsx`: Replaced direct `ReactMarkdown` usage in bubble-layout and column-layout paths with `MarkdownRenderer`; reads new `markdown_prose_styling` flag and passes `proseEnabled` down.
18
+
-`web/components/recipe-card.tsx`: Updated fallback (non-recipe) rendering path to use `MarkdownRenderer` with `proseEnabled` prop instead of direct `ReactMarkdown`.
19
+
20
+
No new npm packages — uses only the already-installed `react-markdown`'s `components` prop.
14
21
15
22
## Flag
16
23
17
-
-`auto_multimodal_images` — default **off**. Enable in Flagsmith "cooking" project → Development to activate. When off, any `image` field in `/chat` requests is silently ignored.
24
+
-`auto_markdown_prose_styling` — default **off**. Enable in Flagsmith "cooking" project → Development to activate. When off, markdown renders as before (no visible change to existing behavior).
18
25
19
26
## Eval delta
20
27
@@ -24,33 +31,37 @@ Note: The operator focus hint specified Gemini 1.5 Flash, which has been retired
24
31
| dietary_constraints | ✅ 4/4 | ✅ 4/4 |
25
32
| safety_warning | ✅ 4/4 | ✅ 4/4 |
26
33
| substitution | ✅ 4/4 | ✅ 4/4 |
27
-
| multimodal_image (new) | — | ⏭️ skipped (Gemini quota exhausted during CI run; logic verified manually) |
34
+
| multimodal_image | ⏭️ skipped | ⏭️ skipped |
35
+
36
+
No regressions. No scenarios were modified.
28
37
29
38
## How to test
30
39
31
40
```bash
32
-
git checkout auto/improve-20260423-125402
41
+
git checkout auto/improve-20260423-134743
33
42
pip install -e ".[dev]"
34
43
35
-
#Backend
44
+
#Start backend
36
45
uvicorn api.main:app --port 8000
37
46
38
-
# Enable flag in Flagsmith: auto_multimodal_images → ON
39
-
# Then POST with an image:
40
-
curl -X POST http://localhost:8000/chat \
41
-
-H 'Content-Type: application/json' \
42
-
-d '{"message":"what can I cook?","image":"https://picsum.photos/id/429/400/300.jpg"}'
47
+
# Start frontend
48
+
cd web && npm install && npm run dev
49
+
50
+
# Enable flag in Flagsmith: auto_markdown_prose_styling → ON
51
+
# Open http://localhost:3000 and ask: "decide my dinner tonight"
52
+
# The agent will ask clarifying questions with numbered/bulleted lists
53
+
# → With flag ON: numbers and bullets are visible
54
+
# → With flag OFF: flat unstyled text (current broken behavior)
43
55
44
-
# Run scenarios
56
+
# Run scenarios (no backend flag change needed — pure frontend fix)
45
57
pytest -v tests/ -m agent_test
46
58
```
47
59
48
60
## Rollback
49
61
50
-
Flip `auto_multimodal_images` off in Flagsmith. No code revert needed — the entire image path is dead code when the flag is off.
62
+
Flip `auto_markdown_prose_styling` off in Flagsmith. No code revert needed — the entire styled path is a conditional branch off the flag.
51
63
52
64
## Follow-ups
53
65
54
-
- Add image input to the Legacy UI path (currently only wired to Premium UI)
55
-
- Add conversation history support for image messages (currently image turns don't participate in history)
56
-
- Consider streaming the Gemini response via SSE once `auto_streaming_response` flag is active
66
+
- Candidate 2: Fix multi-turn system prompt — `cooking_agent.py:96` uses base `SYSTEM_PROMPT` in the history path, silently dropping flag addendums (`auto_safety_check_enhanced`, etc.) for all multi-turn chats.
67
+
- Candidate 3: Add off-topic guardrail — trace `d92027fa` shows the agent answering questions about "light mode in this website" with ChatGPT instructions; the system prompt has no stay-on-topic rule.
- 294 traces in last 7 days. No thumbs-down annotations, but real user complaints confirmed.
5
+
-**Trace `0ee0a635e5b25b7abe154d9e730c90ab`**: User said "I think the markdown is not rendering the numbers" — numbered lists invisible in chat UI.
6
+
-**Trace `dafdb4a5e3bbb0d1a6e12f2466ae1315`**: User asked for dinner options "like 1, 2, 3" — implying list rendering was broken.
7
+
-**Root cause confirmed in code**: `@tailwindcss/typography` is NOT in `web/package.json` and not in `tailwind.config.ts` plugins. Tailwind preflight resets `<ol>/<ul>` defaults (removes `list-style-type` and `padding`). The `prose-invert` class used throughout chat components has NO EFFECT without the plugin — numbered/bulleted lists render as unstyled flat text.
8
+
-**Trace `d92027fa5543cc5efda81de34f984462`**: Off-topic question ("where is light mode") received ChatGPT instructions — agent has no cooking-topic guardrail.
9
+
-**Code bug in `cooking_agent.py:96`**: Multi-turn history path uses base `SYSTEM_PROMPT` constant, ignoring flag addendums (`auto_safety_check_enhanced`, etc.).
10
+
11
+
## Candidates
4
12
5
13
| # | Title | Evidence | Impact | Risk | Rank |
6
-
|---|---|---|---|---|---|
7
-
| 1 |**Multimodal image input (Gemini 1.5 Flash)**|Operator focus hint. Zero image-related traces in 265 sampled — entirely absent capability. Fridge-photo → recipe and dish-recreation are highly natural user flows. `GEMINI_API_KEY` already wired in CI. |High|Med|**1st**|
8
-
| 2 |Add multi-turn conversation test scenario | Trace `59fd8cb8a61cb6ceb948a060977ed85b` shows multi-turn working but no scenario validates it. `auto_conversation_history` flag exists but is untested at the scenario level. |Med|Low|2nd|
9
-
| 3 |Extend system prompt with fridge-inventory parsing|Several traces show users listing "what's in my fridge" style queries but the agent sometimes asks clarifying questions instead of immediately parsing. A structured inventory-extraction instruction would reduce latency. |Med|Med|3rd|
14
+
|---|-------|----------|--------|------|------|
15
+
| 1 |**Fix markdown prose styling for non-recipe responses**|Traces `0ee0a635`, `dafdb4a5` — user-confirmed broken numbered lists. Root cause: `prose-invert` class non-functional without `@tailwindcss/typography`. Affects ALL non-recipe responses (numbered options, follow-up clarifications, substitution lists). |HIGH|LOW|**1**|
16
+
| 2 |**Fix multi-turn system prompt: apply flag addendums in history path**|`cooking_agent.py:96` — when `history` is present, uses base `SYSTEM_PROMPT` constant. Safety/dietary flags silently ignored for all multi-turn chats. |MED|LOW|2|
17
+
| 3 |**Add off-topic guardrail to system prompt**|Trace `d92027fa` — user asked about UI light mode; got ChatGPT instructions. No on-topic rule in SYSTEM_PROMPT. |MED|MED|3|
10
18
11
19
## Decision
20
+
**Candidate 1** — Fix markdown prose styling.
12
21
13
-
**Candidate 1 — multimodal image input** wins. Explicit `FOCUS` directive, entirely new capability with zero existing coverage, infrastructure (`GEMINI_API_KEY`, `httpx`) already in place.
22
+
User-confirmed complaint in traces, reproducible via code inspection, affects every numbered list and bullet response. Fix requires no new npm packages — just a `components` prop on ReactMarkdown and proper styling. Highest impact / lowest risk.
0 commit comments