You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
247 lines
7.6 KiB
Markdown
247 lines
7.6 KiB
Markdown
# Configurable Summary Length — Implementation Plan
|
|
|
|
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
|
|
|
**Goal:** Add a `summary_length` setting (1=court, 2=moyen, 3=detaille) that controls how detailed article summaries are and how much article body is sent to the LLM.
|
|
|
|
**Architecture:** New integer setting (1-3) following the existing settings pattern. Affects the classify prompt instruction and body snippet size in the pipeline. Frontend slider with 3 positions.
|
|
|
|
**Tech Stack:** Rust (sqlx), SolidJS, PostgreSQL
|
|
|
|
**Spec:** `docs/superpowers/specs/2026-03-26-summary-length-design.md`
|
|
|
|
---
|
|
|
|
### Task 1: Migration + backend setting
|
|
|
|
**Files:**
|
|
- Create: `backend/migrations/20260326000023_add_summary_length.sql`
|
|
- Modify: `backend/src/models/settings.rs`
|
|
- Modify: `backend/src/db/settings.rs`
|
|
- Modify: `backend/src/services/prompts.rs` (test fixture)
|
|
- Modify: `backend/tests/api_syntheses_test.rs` (test fixture)
|
|
- Modify: `backend/tests/pipeline_test.rs` (test fixture)
|
|
- Modify: `CLAUDE.md`
|
|
|
|
Follow the exact same pattern as `batch_size` was added. This is mechanical.
|
|
|
|
- [ ] **Step 1: Create migration**
|
|
|
|
```sql
|
|
ALTER TABLE settings ADD COLUMN summary_length INTEGER NOT NULL DEFAULT 3;
|
|
```
|
|
|
|
- [ ] **Step 2: Add `summary_length: i32` to all Rust settings structs**
|
|
|
|
In `backend/src/models/settings.rs`:
|
|
- Add `pub summary_length: i32` to `UserSettings` and `UpdateSettingsRequest` (after `batch_size`)
|
|
- Add to `Default for UserSettings`: `summary_length: 3,`
|
|
- Add to `valid_request()` test fixture: `summary_length: 3,`
|
|
- Add validation:
|
|
```rust
|
|
if !(1..=3).contains(&self.summary_length) {
|
|
return Err("summary_length must be between 1 and 3".into());
|
|
}
|
|
```
|
|
|
|
- [ ] **Step 3: Update DB queries in `db/settings.rs`**
|
|
|
|
Add `summary_length` to `SettingsRow`, `TryFrom` impl, both SQL queries (INSERT columns, VALUES, ON CONFLICT SET, RETURNING), and `.bind()` calls.
|
|
|
|
- [ ] **Step 4: Update test fixtures**
|
|
|
|
Add `summary_length: 3,` to:
|
|
- `backend/src/services/prompts.rs` → `test_settings()`
|
|
- `backend/tests/api_syntheses_test.rs` → settings JSON payload
|
|
- `backend/tests/pipeline_test.rs` → `setup_user_with_settings` JSON payload
|
|
|
|
- [ ] **Step 5: Update CLAUDE.md**
|
|
|
|
Change `## Database (22 migrations)` to `## Database (23 migrations)`.
|
|
|
|
- [ ] **Step 6: Build and test**
|
|
|
|
Run: `cd backend && cargo build && cargo test --lib`
|
|
Expected: All pass
|
|
|
|
- [ ] **Step 7: Commit**
|
|
|
|
```bash
|
|
git add backend/migrations/20260326000023_add_summary_length.sql \
|
|
backend/src/models/settings.rs backend/src/db/settings.rs \
|
|
backend/src/services/prompts.rs backend/tests/api_syntheses_test.rs \
|
|
backend/tests/pipeline_test.rs CLAUDE.md
|
|
git commit -m "feat: add summary_length setting (1=court, 2=moyen, 3=detaille)"
|
|
```
|
|
|
|
---
|
|
|
|
### Task 2: Prompt and pipeline changes
|
|
|
|
**Files:**
|
|
- Modify: `backend/src/services/prompts.rs`
|
|
- Modify: `backend/src/services/synthesis.rs`
|
|
|
|
- [ ] **Step 1: Update `build_article_classify_prompt` to accept `summary_length`**
|
|
|
|
In `backend/src/services/prompts.rs`, add `summary_length: i32` as a new parameter:
|
|
|
|
```rust
|
|
pub fn build_article_classify_prompt(
|
|
title: &str,
|
|
body_snippet: &str,
|
|
categories: &[String],
|
|
summary_length: i32,
|
|
) -> (String, String) {
|
|
```
|
|
|
|
Change the instruction line from:
|
|
```
|
|
"Genere un titre clair et un resume de 4 a 5 lignes."
|
|
```
|
|
To:
|
|
```rust
|
|
let summary_instruction = match summary_length {
|
|
1 => "Genere un titre clair et un resume de 3 a 4 lignes.",
|
|
2 => "Genere un titre clair et un resume de 6 a 8 lignes.",
|
|
_ => "Genere un titre clair et un resume detaille de 12 a 15 lignes.",
|
|
};
|
|
```
|
|
|
|
Use `summary_instruction` in the format string instead of the hardcoded line.
|
|
|
|
- [ ] **Step 2: Update all call sites in `synthesis.rs`**
|
|
|
|
Find all calls to `build_article_classify_prompt` in `synthesis.rs`. There are 2 (Phase 1 and Phase 2 Brave classify loops). Add `settings.summary_length` as the new argument.
|
|
|
|
Also update the body snippet size from hardcoded 500 to dynamic:
|
|
|
|
```rust
|
|
let snippet_size = match settings.summary_length {
|
|
1 => 500,
|
|
2 => 2000,
|
|
_ => 4000,
|
|
};
|
|
let body_snippet: String = body_text.chars().take(snippet_size).collect();
|
|
```
|
|
|
|
Apply this in both Phase 1 (~line 487) and Phase 2 Brave (~line 665) classify loops.
|
|
|
|
- [ ] **Step 3: Update prompt tests**
|
|
|
|
In `prompts.rs` tests, update existing `article_classify_prompt_*` tests to pass `summary_length: 3`. Add a new test:
|
|
|
|
```rust
|
|
#[test]
|
|
fn article_classify_prompt_short_summary() {
|
|
let (_, user) = build_article_classify_prompt(
|
|
"Title", "Content", &["AI".into()], 1,
|
|
);
|
|
assert!(user.contains("3 a 4 lignes"));
|
|
}
|
|
|
|
#[test]
|
|
fn article_classify_prompt_detailed_summary() {
|
|
let (_, user) = build_article_classify_prompt(
|
|
"Title", "Content", &["AI".into()], 3,
|
|
);
|
|
assert!(user.contains("12 a 15 lignes"));
|
|
}
|
|
```
|
|
|
|
- [ ] **Step 4: Build and test**
|
|
|
|
Run: `cd backend && cargo build && cargo test --lib`
|
|
Expected: All pass
|
|
|
|
- [ ] **Step 5: Commit**
|
|
|
|
```bash
|
|
git add backend/src/services/prompts.rs backend/src/services/synthesis.rs
|
|
git commit -m "feat: dynamic summary length and body snippet size based on setting"
|
|
```
|
|
|
|
---
|
|
|
|
### Task 3: Frontend slider + i18n + types
|
|
|
|
**Files:**
|
|
- Modify: `frontend/src/types.ts`
|
|
- Modify: `frontend/src/i18n/fr.ts`
|
|
- Modify: `frontend/src/pages/Settings.tsx`
|
|
- Modify: `e2e/tests/generation-live.spec.ts`
|
|
|
|
- [ ] **Step 1: Update frontend types**
|
|
|
|
In `frontend/src/types.ts`:
|
|
- Add `summary_length: number;` to `UserSettings` (after `batch_size`)
|
|
- Add `summary_length: 3,` to `DEFAULT_SETTINGS`
|
|
|
|
- [ ] **Step 2: Add i18n labels**
|
|
|
|
In `frontend/src/i18n/fr.ts`, add:
|
|
|
|
```typescript
|
|
'settings.summaryLength': 'Niveau de detail des resumes',
|
|
'settings.summaryLengthHelp': 'Controle la longueur des resumes generes pour chaque article.',
|
|
'settings.summaryShort': 'Court',
|
|
'settings.summaryMedium': 'Moyen',
|
|
'settings.summaryDetailed': 'Detaille',
|
|
```
|
|
|
|
- [ ] **Step 3: Add slider to Settings.tsx**
|
|
|
|
In `frontend/src/pages/Settings.tsx`, add a slider in the main settings section (near `max_items_per_category`). Use an `<input type="range">` with min=1, max=3, step=1:
|
|
|
|
```tsx
|
|
<div>
|
|
<label for="summaryLength" class="block text-sm font-medium text-gray-700">
|
|
{t('settings.summaryLength')}
|
|
</label>
|
|
<p class="text-xs text-gray-500 mb-2">{t('settings.summaryLengthHelp')}</p>
|
|
<div class="flex items-center gap-4">
|
|
<span class="text-xs text-gray-500">{t('settings.summaryShort')}</span>
|
|
<input
|
|
type="range"
|
|
id="summaryLength"
|
|
min="1"
|
|
max="3"
|
|
step="1"
|
|
class="flex-1 h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer accent-indigo-600"
|
|
value={settings().summary_length}
|
|
onInput={(e) =>
|
|
setSettings((prev) => ({
|
|
...prev,
|
|
summary_length: parseInt(e.currentTarget.value) || 3,
|
|
}))
|
|
}
|
|
/>
|
|
<span class="text-xs text-gray-500">{t('settings.summaryDetailed')}</span>
|
|
</div>
|
|
<div class="text-center text-xs text-gray-500 mt-1">
|
|
{settings().summary_length === 1
|
|
? t('settings.summaryShort')
|
|
: settings().summary_length === 2
|
|
? t('settings.summaryMedium')
|
|
: t('settings.summaryDetailed')}
|
|
</div>
|
|
</div>
|
|
```
|
|
|
|
- [ ] **Step 4: Update E2E test fixture**
|
|
|
|
In `e2e/tests/generation-live.spec.ts`, add `summary_length: 3,` to the settings payload.
|
|
|
|
- [ ] **Step 5: TypeScript check**
|
|
|
|
Run: `cd frontend && npx tsc --noEmit`
|
|
Expected: No errors
|
|
|
|
- [ ] **Step 6: Commit**
|
|
|
|
```bash
|
|
git add frontend/src/types.ts frontend/src/i18n/fr.ts \
|
|
frontend/src/pages/Settings.tsx e2e/tests/generation-live.spec.ts
|
|
git commit -m "feat: add summary length slider to Settings page"
|
|
```
|