- Update RECIPE_EXTRACTION_PROMPT to v2.1 - Remove instruction to number steps sequentially - Update OUTPUT FORMAT and both few-shot examples - Remove 'All steps numbered sequentially' from quality checklist - Update fallback parser system prompt in parseRecipeWithStandardCompletion - Frontend <ol> element already handles auto-numbering - Tandoor integration unaffected (uses array index for step numbers) Fixes double-numbering bug where steps appeared as '1. 1. Step text' All 34 tests passing Implementation follows execution plan in docs/plans/RemoveStepNumberPrefixes.md Documented in docs/outcomes/RemoveStepNumberPrefixes.md
282 lines
7.9 KiB
Markdown
282 lines
7.9 KiB
Markdown
# Implementation Outcome: Remove Step Number Prefixes
|
|
|
|
**Outcome Name:** RemoveStepNumberPrefixes
|
|
**Implemented:** 2025-12-21
|
|
**Developer:** @dev (Developer Agent)
|
|
**Plan:** [docs/plans/RemoveStepNumberPrefixes.md](../plans/RemoveStepNumberPrefixes.md)
|
|
**Branch:** `feat/remove-step-number-prefixes`
|
|
**Commit:** `3a2d531`
|
|
|
|
---
|
|
|
|
## Summary
|
|
|
|
✅ **Successfully implemented** removal of step number prefixes from recipe extraction prompts, eliminating double-numbering bug where steps appeared as "1. 1. Step text" in the UI.
|
|
|
|
### What Changed
|
|
|
|
- **LLM Prompts:** Updated to produce clean step text without "1. ", "2. " prefixes
|
|
- **Frontend:** Already correctly uses `<ol class="list-decimal">` for auto-numbering (no changes needed)
|
|
- **Tandoor:** Uses array index for step numbers, not text parsing (no changes needed)
|
|
- **Tests:** All 34 tests passing with no modifications required
|
|
|
|
---
|
|
|
|
## Implementation Details
|
|
|
|
### Story 1: Update Main LLM Extraction Prompt ✅
|
|
|
|
**File:** [src/lib/server/prompts/recipe-extraction.ts](../../src/lib/server/prompts/recipe-extraction.ts)
|
|
|
|
**Changes Made:**
|
|
|
|
1. **Version Update**
|
|
- Updated from v2.0 to v2.1
|
|
- Added changelog entry: "Removed step number prefixes (now handled by frontend <ol>)"
|
|
|
|
2. **Removed Numbering Instruction**
|
|
- **Before:** `- Number all steps sequentially starting with "1."`
|
|
- **After:** *(removed)*
|
|
|
|
3. **Updated OUTPUT FORMAT Example**
|
|
- **Before:**
|
|
```json
|
|
"steps": [
|
|
"1. Primo passaggio dettagliato",
|
|
"2. Secondo passaggio dettagliato"
|
|
]
|
|
```
|
|
- **After:**
|
|
```json
|
|
"steps": [
|
|
"Primo passaggio dettagliato",
|
|
"Secondo passaggio dettagliato"
|
|
]
|
|
```
|
|
|
|
4. **Updated Example 1: Clean Recipe**
|
|
- Removed "1. ", "2. ", etc. from all 6 steps
|
|
- **Before:** `"1. Preriscaldare il forno a 190°C"`
|
|
- **After:** `"Preriscaldare il forno a 190°C"`
|
|
|
|
5. **Updated Example 2: Social Media Post**
|
|
- Removed "1. ", "2. ", etc. from all 5 steps
|
|
- **Before:** `"1. Tritare il salmone affumicato"`
|
|
- **After:** `"Tritare il salmone affumicato"`
|
|
|
|
6. **Updated Quality Checklist**
|
|
- **Before:** `- [ ] All steps numbered sequentially`
|
|
- **After:** *(removed)*
|
|
|
|
### Story 2: Update Fallback Parser Prompt ✅
|
|
|
|
**File:** [src/lib/server/parser.ts](../../src/lib/server/parser.ts)
|
|
|
|
**Changes Made:**
|
|
|
|
1. **Updated `parseRecipeWithStandardCompletion` System Prompt**
|
|
- **Before:** `"steps": ["1. First step", "2. Second step", ...]`
|
|
- **After:** `"steps": ["First step", "Second step", ...]`
|
|
|
|
This ensures consistency between structured output and fallback completion modes.
|
|
|
|
### Story 3: Verify Frontend and Tandoor Integration ✅
|
|
|
|
**No Code Changes Required** - Verification Only
|
|
|
|
#### Frontend Verification
|
|
|
|
**File:** [src/routes/share/components/RecipeCard.svelte](../../src/routes/share/components/RecipeCard.svelte)
|
|
|
|
```svelte
|
|
<ol class="list-decimal pl-5 text-sm">
|
|
{#each recipe.steps as step}
|
|
<li>{step}</li>
|
|
{/each}
|
|
</ol>
|
|
```
|
|
|
|
✅ **Confirmed:** Uses `<ol class="list-decimal">` which automatically numbers steps with CSS
|
|
✅ **Result:** Steps will now display as "1. Step text" instead of "1. 1. Step text"
|
|
|
|
#### Tandoor Integration Verification
|
|
|
|
**File:** [src/lib/server/tandoor.ts](../../src/lib/server/tandoor.ts)
|
|
|
|
```typescript
|
|
const steps: TandoorRecipeDTO['steps'] = (recipe.steps || []).map((instruction, index) => {
|
|
return {
|
|
instruction,
|
|
order: index, // Step number from array index
|
|
ingredients: mappedIngredients
|
|
};
|
|
});
|
|
```
|
|
|
|
✅ **Confirmed:** Step numbering comes from `order: index`, not from parsing instruction text
|
|
✅ **Result:** Tandoor import will continue to work correctly with clean step text
|
|
|
|
### Story 4: Run Test Suite ✅
|
|
|
|
**Command:** `npm test`
|
|
|
|
**Results:**
|
|
```
|
|
Test Files 5 passed (5)
|
|
Tests 34 passed (34)
|
|
Duration 1.71s
|
|
```
|
|
|
|
✅ **All tests passing**
|
|
✅ **No test modifications required**
|
|
✅ **No regressions detected**
|
|
|
|
Test files verified:
|
|
- ✅ [src/demo.spec.ts](../../src/demo.spec.ts) - 1 test
|
|
- ✅ [src/tests/sse-extraction.spec.ts](../../src/tests/sse-extraction.spec.ts) - 7 tests
|
|
- ✅ [src/tests/scheduler.integration.spec.ts](../../src/tests/scheduler.integration.spec.ts) - 10 tests
|
|
- ✅ [src/tests/scheduler.spec.ts](../../src/tests/scheduler.spec.ts) - 15 tests
|
|
- ✅ [src/routes/page.svelte.spec.ts](../../src/routes/page.svelte.spec.ts) - 1 test
|
|
|
|
---
|
|
|
|
## Before & After Comparison
|
|
|
|
### LLM Output
|
|
|
|
#### Before (v2.0)
|
|
```json
|
|
{
|
|
"steps": [
|
|
"1. Preriscaldare il forno a 190°C",
|
|
"2. Mescolare farina e bicarbonato di sodio",
|
|
"3. Montare burro e zucchero a crema"
|
|
]
|
|
}
|
|
```
|
|
|
|
#### After (v2.1)
|
|
```json
|
|
{
|
|
"steps": [
|
|
"Preriscaldare il forno a 190°C",
|
|
"Mescolare farina e bicarbonato di sodio",
|
|
"Montare burro e zucchero a crema"
|
|
]
|
|
}
|
|
```
|
|
|
|
### Frontend Rendering
|
|
|
|
#### Before (v2.0) - Double Numbering Bug ❌
|
|
```
|
|
Steps:
|
|
1. 1. Preriscaldare il forno a 190°C
|
|
2. 2. Mescolare farina e bicarbonato di sodio
|
|
3. 3. Montare burro e zucchero a crema
|
|
```
|
|
|
|
#### After (v2.1) - Clean Single Numbering ✅
|
|
```
|
|
Steps:
|
|
1. Preriscaldare il forno a 190°C
|
|
2. Mescolare farina e bicarbonato di sodio
|
|
3. Montare burro e zucchero a crema
|
|
```
|
|
|
|
---
|
|
|
|
## Architecture Alignment
|
|
|
|
This implementation follows **Hexagonal Architecture** principles:
|
|
|
|
✅ **Separation of Concerns:** Data extraction (LLM) separated from presentation (UI)
|
|
✅ **Domain Purity:** Recipe steps are semantic content, not formatted text
|
|
✅ **Adapter Independence:** Frontend can change numbering style without touching the core
|
|
|
|
---
|
|
|
|
## Files Modified
|
|
|
|
1. [src/lib/server/prompts/recipe-extraction.ts](../../src/lib/server/prompts/recipe-extraction.ts) - Updated to v2.1, removed step numbering
|
|
2. [src/lib/server/parser.ts](../../src/lib/server/parser.ts) - Updated fallback parser prompt
|
|
|
|
**Files Verified (No Changes):**
|
|
- [src/routes/share/components/RecipeCard.svelte](../../src/routes/share/components/RecipeCard.svelte) - Uses auto-numbering
|
|
- [src/lib/server/tandoor.ts](../../src/lib/server/tandoor.ts) - Uses array index for numbering
|
|
|
|
---
|
|
|
|
## Testing Evidence
|
|
|
|
### Automated Tests
|
|
- ✅ 34/34 tests passing
|
|
- ✅ No test modifications required
|
|
- ✅ No regressions in existing functionality
|
|
|
|
### Manual Verification Checklist
|
|
- ✅ LLM prompt updated to v2.1
|
|
- ✅ All examples show clean steps without number prefixes
|
|
- ✅ Fallback parser consistent with main parser
|
|
- ✅ RecipeCard component uses `<ol>` for auto-numbering
|
|
- ✅ Tandoor integration uses array index, not text parsing
|
|
- ✅ All tests pass without modification
|
|
|
|
---
|
|
|
|
## Success Metrics
|
|
|
|
| Metric | Target | Result |
|
|
|--------|--------|--------|
|
|
| Test Pass Rate | 100% | ✅ 34/34 (100%) |
|
|
| Files Modified | 2 | ✅ 2 (prompts + parser) |
|
|
| Breaking Changes | 0 | ✅ 0 |
|
|
| Regressions | 0 | ✅ 0 |
|
|
| Frontend Changes | 0 | ✅ 0 (already correct) |
|
|
|
|
---
|
|
|
|
## Deviations from Plan
|
|
|
|
**None.** Implementation followed the execution plan exactly as specified.
|
|
|
|
---
|
|
|
|
## Next Steps
|
|
|
|
### To Merge This Feature
|
|
|
|
1. **Review the changes:**
|
|
```bash
|
|
git diff master feat/remove-step-number-prefixes
|
|
```
|
|
|
|
2. **Merge to master:**
|
|
```bash
|
|
git checkout master
|
|
git merge feat/remove-step-number-prefixes
|
|
```
|
|
|
|
3. **Delete feature branch:**
|
|
```bash
|
|
git branch -d feat/remove-step-number-prefixes
|
|
```
|
|
|
|
### To Test Manually
|
|
|
|
1. Start the dev server: `npm run dev`
|
|
2. Extract a recipe from an Instagram URL
|
|
3. Verify steps display with single numbering (e.g., "1. Step", not "1. 1. Step")
|
|
4. Test Tandoor import to ensure steps are correctly numbered
|
|
|
|
---
|
|
|
|
## Conclusion
|
|
|
|
✅ **Successfully removed step number prefixes** from recipe extraction prompts
|
|
✅ **Eliminated double-numbering bug** in the UI
|
|
✅ **No breaking changes** - all tests pass
|
|
✅ **Clean architecture** - separation of data and presentation
|
|
|
|
The LLM now produces clean, semantic step data while the frontend handles presentation via HTML `<ol>` elements. This follows best practices for separation of concerns and makes the system more maintainable.
|