feat(desktop): persist agent window history locally across app restarts (T-124) #115

Merged
ahitosly merged 1 commit from feat/T-124-agent-window-history-persistence into main 2026-09-07 21:23:44 +02:00
Owner

Tâche

T-xxx — (titre dans docs/STATUS.md)

Changements

Contrat modifié ?

  • Non
  • Oui : packages/contract / supabase/migrations — docs/API.md / docs/DATA.md mis à jour, label contract, approbation humaine requise

Tests

  • scripts/check.sh vert
  • Test manuel (OS, scénario) :

Impacts cross-domaine

Fichiers hors périmètre de l'agent (et pourquoi) :

Suivi

  • docs/STATUS.md mis à jour (ligne de la tâche)
  • docs/CHANGELOG.md : entrée ajoutée sous Unreleased
  • docs/DECISIONS.md / docs/ECARTS.md mis à jour si décision ou écart
## Tâche T-xxx — (titre dans docs/STATUS.md) ## Changements - ## Contrat modifié ? - [ ] Non - [ ] Oui : `packages/contract` / `supabase/migrations` — `docs/API.md` / `docs/DATA.md` mis à jour, label `contract`, approbation humaine requise ## Tests - [ ] `scripts/check.sh` vert - [ ] Test manuel (OS, scénario) : ## Impacts cross-domaine Fichiers hors périmètre de l'agent (et pourquoi) : ## Suivi - [ ] `docs/STATUS.md` mis à jour (ligne de la tâche) - [ ] `docs/CHANGELOG.md` : entrée ajoutée sous Unreleased - [ ] `docs/DECISIONS.md` / `docs/ECARTS.md` mis à jour si décision ou écart
feat(desktop): persist agent window history locally across app restarts (T-124)
All checks were successful
ci / desktop-ts (pull_request) Successful in 28s
ci / server (pull_request) Successful in 14s
ci / desktop-rust (pull_request) Successful in 2m38s
1bf19b5b84
Restore AgentWindow.tsx turns after a real window/app relaunch (crash, Cmd+Q),
not just a close/reopen (already handled since T-107). Uses tauri-plugin-store
(client-only, no new contract/migration), TTL of 2h mirroring the Hermes
continuity window (ADR-012). Esc still clears both the displayed and
persisted history.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011MSWGSF3VJrGALNM8JsE2u
Author
Owner

Tâche

T-124 — Réactiver la récupération de l'historique de la fenêtre agent après une vraie fermeture/relance (demande directe de l'humain, après clarification : le mode agent d'Aria, pas Claude Code)

Changements

  • Nouveau apps/desktop/src/agent/historyStore.ts : persistance locale des turns d'AgentWindow.tsx via tauri-plugin-store (agent-history.json), avec un TTL de 2h (HISTORY_TTL_MS) miroir de la fenêtre de continuité Hermes (ADR-012).
  • AgentWindow.tsx : restaure l'historique au montage si assez frais, persiste à chaque changement de turns, et efface aussi le persisté sur Esc (en plus de l'affiché, comportement existant inchangé).
  • Aucun changement Rust/contrat/schéma : store:default était déjà accordé à la fenêtre agent (capabilities/default.json), le plugin JS @tauri-apps/plugin-store était déjà une dépendance.

Piste écartée (documentée pour ne pas être réinvestiguée)

Lire l'historique directement depuis l'API Hermes plutôt que le persister côté client : GET /v1/responses/{id} ne renvoie que le tour final (pas d'équivalent input_items façon OpenAI pour dérouler la chaîne previous_response_id) ; un mécanisme de « sessions » Hermes existe (GET /api/sessions/{id}/messages) mais est un concept distinct qu'Aria n'utilise pas aujourd'hui (ADR-012/hermes.py utilisent previous_response_id, pas de session_id) — y basculer changerait le contrat serveur et potentiellement le schéma Supabase (approbation humaine bloquante, règle 1/3b), hors scope d'une tâche purement client. Hermes borne en plus son stockage à 100 réponses en LRU, sans garantie de rétention dans le temps.

Contrat modifié ?

  • Non

Tests

  • scripts/check.sh vert (--desktop : tsc --noEmit + eslint ; --rust : cargo clippy -D warnings + cargo test, 133/133, aucun changement Rust donc résultat identique à avant)
  • Test manuel (macOS) : cf. docs/STATUS.md → Vérifications manuelles en attente (T-124) — crash/Cmd+Q réel puis relance dans/hors la fenêtre de 2h, non simulable dans cet environnement agent.

Impacts cross-domaine

Aucun — uniquement apps/desktop/src + apps/desktop/CLAUDE.md (périmètre app-front), et les fichiers de suivi (docs/STATUS.md, docs/CHANGELOG.md).

Suivi

  • docs/STATUS.md mis à jour (T-124, done)
  • docs/CHANGELOG.md : entrée ajoutée sous Unreleased
  • Pas de nouvelle ADR nécessaire (ne contredit aucune décision existante, prolonge ADR-012 en la dupliquant côté client, documenté comme tel) ; pas d'écart introduit
## Tâche T-124 — Réactiver la récupération de l'historique de la fenêtre agent après une vraie fermeture/relance (demande directe de l'humain, après clarification : le mode agent d'Aria, pas Claude Code) ## Changements - Nouveau `apps/desktop/src/agent/historyStore.ts` : persistance locale des `turns` d'`AgentWindow.tsx` via `tauri-plugin-store` (`agent-history.json`), avec un TTL de 2h (`HISTORY_TTL_MS`) miroir de la fenêtre de continuité Hermes (ADR-012). - `AgentWindow.tsx` : restaure l'historique au montage si assez frais, persiste à chaque changement de `turns`, et efface aussi le persisté sur `Esc` (en plus de l'affiché, comportement existant inchangé). - Aucun changement Rust/contrat/schéma : `store:default` était déjà accordé à la fenêtre `agent` (`capabilities/default.json`), le plugin JS `@tauri-apps/plugin-store` était déjà une dépendance. ## Piste écartée (documentée pour ne pas être réinvestiguée) Lire l'historique directement depuis l'API Hermes plutôt que le persister côté client : `GET /v1/responses/{id}` ne renvoie que le tour final (pas d'équivalent `input_items` façon OpenAI pour dérouler la chaîne `previous_response_id`) ; un mécanisme de « sessions » Hermes existe (`GET /api/sessions/{id}/messages`) mais est un concept distinct qu'Aria n'utilise pas aujourd'hui (ADR-012/`hermes.py` utilisent `previous_response_id`, pas de `session_id`) — y basculer changerait le contrat serveur et potentiellement le schéma Supabase (approbation humaine bloquante, règle 1/3b), hors scope d'une tâche purement client. Hermes borne en plus son stockage à 100 réponses en LRU, sans garantie de rétention dans le temps. ## Contrat modifié ? - [x] Non ## Tests - [x] `scripts/check.sh` vert (`--desktop` : `tsc --noEmit` + `eslint` ; `--rust` : `cargo clippy -D warnings` + `cargo test`, 133/133, aucun changement Rust donc résultat identique à avant) - [ ] Test manuel (macOS) : cf. `docs/STATUS.md` → Vérifications manuelles en attente (T-124) — crash/`Cmd+Q` réel puis relance dans/hors la fenêtre de 2h, non simulable dans cet environnement agent. ## Impacts cross-domaine Aucun — uniquement `apps/desktop/src` + `apps/desktop/CLAUDE.md` (périmètre `app-front`), et les fichiers de suivi (`docs/STATUS.md`, `docs/CHANGELOG.md`). ## Suivi - [x] `docs/STATUS.md` mis à jour (T-124, done) - [x] `docs/CHANGELOG.md` : entrée ajoutée sous Unreleased - [x] Pas de nouvelle ADR nécessaire (ne contredit aucune décision existante, prolonge ADR-012 en la dupliquant côté client, documenté comme tel) ; pas d'écart introduit
Author
Owner

Review qa-regression — T-124

Diff relu en entier (scripts/pr.sh --diff 115), scripts/check.sh --desktop et --rust revérifiés dans ce même worktree (133/133 tests Rust, tsc/eslint verts) — aucun changement Rust, résultat attendu identique à avant la PR.

Points vérifiés :

  • Aucun secret/donnée serveur persisté : historyStore.ts ne stocke que les turns déjà affichés à l'écran (texte transcrit + réponses agent + noms d'outils utilisés), rien qui ne soit déjà visible/copiable dans l'UI. Stocké en clair dans agent_data_dir/agent-history.json, cohérent avec le reste de la persistance locale existante (aria.config.json, non chiffré non plus) — pas une régression de sécurité, mais bien une donnée conversationnelle qui reste désormais sur disque au lieu de purement en mémoire ; TTL de 2h limite la fenêtre d'exposition, cohérent avec l'objectif (éviter d'afficher un historique visuel qui ne correspond plus à une conversation réellement poursuivie côté Hermes).
  • TTL correct et cohérent avec ADR-012 : HISTORY_TTL_MS = 2 * 60 * 60 * 1000 = 2h, documenté comme politique miroir côté client (le client ne lit jamais aria_agent_sessions, RLS deny-all) — pas une lecture de la table serveur, bien précisé dans les 3 endroits (en-tête AgentWindow.tsx, historyStore.ts, apps/desktop/CLAUDE.md).
  • Esc toujours prioritaire : efface l'affiché et le persisté (clearPersistedTurns), comportement UX existant non contourné.
  • Pas de régression sur le close/reopen (T-107) : la fenêtre agent étant créée eagerly (visible: false dans tauri.conf.json) et jamais détruite par la croix (install_agent_close_guard), le composant ne remonte pas sur un simple hide/show — l'hydratation ne s'exécute qu'une fois par vrai cycle de vie du process, pas de double-restauration ni d'écrasement d'un historique en cours.
  • Aucun changement de contrat/capacité : store:default déjà accordé à la fenêtre agent, @tauri-apps/plugin-store déjà une dépendance — confirmé en relisant capabilities/default.json/package.json avant la review, pas seulement pris pour argent comptant depuis la description de la PR.
  • Nit non bloquant : sur Esc, setTurns([]) déclenche aussi l'effet de persistance générique (écrit {turns: [], updatedAt: now}) en plus de l'appel explicite clearPersistedTurns() — ordre d'exécution non garanti entre les deux, mais convergent (les deux aboutissent à "pas d'historique à restaurer"), aucun comportement utilisateur incorrect dans aucun entrelacement. Pas de correctif demandé.

Vérification manuelle réelle (crash/Cmd+Q puis relance dans/hors la fenêtre de 2h) non exécutable dans cet environnement — correctement consignée dans docs/STATUS.md → Vérifications manuelles en attente, ne bloque pas (CLAUDE.md règle 3b).

Verdict : APPROVE

**Review qa-regression — T-124** Diff relu en entier (`scripts/pr.sh --diff 115`), `scripts/check.sh --desktop` et `--rust` revérifiés dans ce même worktree (133/133 tests Rust, `tsc`/`eslint` verts) — aucun changement Rust, résultat attendu identique à avant la PR. Points vérifiés : - **Aucun secret/donnée serveur persisté** : `historyStore.ts` ne stocke que les `turns` déjà affichés à l'écran (texte transcrit + réponses agent + noms d'outils utilisés), rien qui ne soit déjà visible/copiable dans l'UI. Stocké en clair dans `agent_data_dir/agent-history.json`, cohérent avec le reste de la persistance locale existante (`aria.config.json`, non chiffré non plus) — pas une régression de sécurité, mais bien une donnée conversationnelle qui reste désormais sur disque au lieu de purement en mémoire ; TTL de 2h limite la fenêtre d'exposition, cohérent avec l'objectif (éviter d'afficher un historique visuel qui ne correspond plus à une conversation réellement poursuivie côté Hermes). - **TTL correct et cohérent avec ADR-012** : `HISTORY_TTL_MS = 2 * 60 * 60 * 1000` = 2h, documenté comme politique miroir côté client (le client ne lit jamais `aria_agent_sessions`, RLS deny-all) — pas une lecture de la table serveur, bien précisé dans les 3 endroits (en-tête `AgentWindow.tsx`, `historyStore.ts`, `apps/desktop/CLAUDE.md`). - **`Esc` toujours prioritaire** : efface l'affiché et le persisté (`clearPersistedTurns`), comportement UX existant non contourné. - **Pas de régression sur le close/reopen (T-107)** : la fenêtre `agent` étant créée eagerly (`visible: false` dans `tauri.conf.json`) et jamais détruite par la croix (`install_agent_close_guard`), le composant ne remonte pas sur un simple hide/show — l'hydratation ne s'exécute qu'une fois par vrai cycle de vie du process, pas de double-restauration ni d'écrasement d'un historique en cours. - **Aucun changement de contrat/capacité** : `store:default` déjà accordé à la fenêtre `agent`, `@tauri-apps/plugin-store` déjà une dépendance — confirmé en relisant `capabilities/default.json`/`package.json` avant la review, pas seulement pris pour argent comptant depuis la description de la PR. - Nit non bloquant : sur `Esc`, `setTurns([])` déclenche aussi l'effet de persistance générique (écrit `{turns: [], updatedAt: now}`) en plus de l'appel explicite `clearPersistedTurns()` — ordre d'exécution non garanti entre les deux, mais convergent (les deux aboutissent à "pas d'historique à restaurer"), aucun comportement utilisateur incorrect dans aucun entrelacement. Pas de correctif demandé. Vérification manuelle réelle (crash/`Cmd+Q` puis relance dans/hors la fenêtre de 2h) non exécutable dans cet environnement — correctement consignée dans `docs/STATUS.md` → Vérifications manuelles en attente, ne bloque pas (CLAUDE.md règle 3b). **Verdict : APPROVE**
ahitosly scheduled this pull request to auto merge when all checks succeed 2026-09-07 21:21:41 +02:00
ahitosly deleted branch feat/T-124-agent-window-history-persistence 2026-09-07 21:23:44 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
cloud-rennais/aria!115
No description provided.