Files
IdeA/.ideai/memory/session-limit-handling-design.md
Blomios 6969dc7988 chore(wip): état runtime .ideai (conversations, layouts, mémoire, skills)
Snapshot de l'état runtime accumulé sur develop : logs/handoffs de
conversations, layouts, notes mémoire (dont git-owns-commit-merge-decisions)
et catalogue de skills.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 09:14:01 +02:00

5.7 KiB

name, description, metadata
name description metadata
session-limit-handling-design Design valide pour la detection des limites de session des agents et la reprise auto a la levee.
type
project

Feature : detecter quand un agent IA est en limite de session (et jusqu'a quelle heure), puis reprendre ou il en etait une fois la limite levee. Cadree le 2026-06-16.

Constat dur : l'heure exacte de reset n'existe nulle part de facon universelle (ni OS, ni code de sortie, ni API inter-modeles) — elle est fabriquee par le fournisseur et seulement exposee dans le flux de sa CLI. Donc « 100% fiable + zero dependance modele + heure exacte » sont incompatibles simultanement ; on vise le meilleur compromis via un detecteur hierarchique.

Solution retenue — detecteur hierarchique calque sur la hierarchie de readiness existante (remaining-work-idea-agent-control-ide) :

  • Niveau 1 (solide) : l'adapter structure extrait limite + reset du flux machine. Pour Claude, rate_limit_event.rate_limit_info est DEJA parse dans infrastructure/session/claude.rs mais jete (reduit a Heartbeat) — il suffit de lire resetsAt.
  • Niveau 2 (configurable) : champ de profil rate_limit_pattern (regex + capture heure) pour agents PTY/TUI sans adapter structure, dans la lignee des profils declaratifs §9.
  • Niveau 3 (filet humain) : si rien ne matche mais agent Stalled (deja prevu dans domain/readiness.rs), IdeA DEMANDE a l'utilisateur. Garantit le « 100% meme pour un novice » : jamais d'inaction silencieuse.

Model-agnostic tenu AU DOMAINE : le domaine ne connait que RateLimited { until: Option<Instant> }. Le savoir specifique modele est confine aux adapters/profils (philosophie §9).

Reprise = partie facile et deja model-agnostique : pivot sur conversation_id du moteur + --resume natif (deja cable dans session/claude.rs + agent/resume.rs) qui portent tout l'historique. Pas de reconstruction manuelle fragile.

Decisions produit verrouillees (2026-06-16) :

  • Reprise : AUTOMATIQUE a l'heure de reset, ANNULABLE (fenetre + notification).
  • Couverture : les TROIS niveaux d'emblee (incl. repli regex niveau 2).
  • Etat : EN MEMOIRE uniquement (pas de persistance de SessionLimit). Consequence assumee : le reveil auto ne joue que tant qu'IdeA reste ouvert ; si l'IDE est ferme/rouvert apres le reset, le chemin existant ListResumableAgents (agent_was_running/conversation_id) prend le relais.

Decoupage (cycle dev/test §3) : 1) domaine (variante ReplyEvent::RateLimited, ReadinessSignal::RateLimited, etat SessionLimit) ; 2) adapter Claude (extraire resetsAt) ; 3) profil (rate_limit_pattern) ; 4) application (planificateur de reprise sur le port Clock) ; 5) UI (badge « limite jusqu'a HH:MM » + filet humain).

Avancement (committe sur feature/agent-session-limits) :

  • LS1 domaine, LS2 adapter Claude niveau 1, LS3 port Scheduler + TokioScheduler, LS4 service application + reconciliation T4 : DONE.
  • LS5 (98bfcf4) detecteur niveau 2 declaratif RateLimitParser (regex confinee infra) + module timeparse pur partage niveau 1/2 (epoch s/ms, RFC3339, heure murale avec passage de minuit) : DONE, 221 tests infra verts.
  • LS6 (ea94e75) cablage : 5 variantes DomainEvent (AgentRateLimited/ResumeScheduled/ResumeCancelled/Resumed/RateLimitSuspected) + ReplyEvent::RateLimited relayees en DomainEventDto (events.rs) ; chunk_from_event traite RateLimited -> None (non terminal, comme Heartbeat) : DONE, workspace vert.
  • LS7-backend (9df5923) cablage app-tauri : LaunchAgentOutput.profile expose (lifecycle.rs), StructuredSessions::meta_for_session (registry.rs, lookup N1), ResumeContext/AppAgentResumer (impl port AgentResumer au-dessus de LaunchAgent) + instanciation/drain du SessionLimitService (TokioScheduler) dans AppState::build (state.rs), taps N1 (agent_send) & N2 (launch_agent, parser regex confine) + commande cancel_resume (commands.rs/lib.rs), dep async-trait. 2 tests d'integration (session_limit_wiring.rs) verts, suites app-tauri+application vertes. Git : reste sur feature/agent-session-limits, PAS de merge develop avant LS7-front.
  • LS7-front (4fad042) : 5 variantes au union DomainEvent (src/domain/index.ts) ; etat limitByAgent dans useAgents (patron delegationSourceByRequester) ; AgentLimitBadge.tsx (badge « limite jusqu'a HH:MM » + compte a rebours + bouton « Annuler la reprise » -> port InputGateway.cancelResume -> commande cancel_resume) ; cable dans AgentsPanel. 24 tests front. Champs wire reels = suffixe Ms : resetsAtMs/fireAtMs (PAS resetsAt/fireAt).
  • LS8 (filet humain niveau 3, decision Architect = B « demander = armer, pas juste informer ») :
    • backend (c480d28) : SessionLimitService::confirm_human_resume(agent, node, conv, resets_at_ms) (source Human, refactor privé arm_scheduled partagé avec on_rate_limited, reutilise branche Scheduled, annulable, AUCUN evenement nouveau) ; commande set_resume_at(agent_id, resets_at_ms) (resout node_id via node_for_agent + conv best-effort, NOT_FOUND si pas de cellule vivante). 15+4 tests (clamp passe, dedup croise, parite auto/humain).
    • front (5d9dd32) : InputGateway.setResumeAt -> set_resume_at ; formulaire de saisie d'heure sur l'etat suspected-sans-heure (helper pur timeInputToEpochMs) -> arme la reprise -> badge bascule auto via agentResumeScheduled. TODO LS7 retire.
    • fix hygiene (3f3504e) : compteur gateways mock 13->14 (permission).
  • STATUT : FEATURE TERMINEE, 3 niveaux complets, tout vert (Rust domain/application/app-tauri + front agents/adapters 109 tests). MERGEE --no-ff dans develop (merge d7041c5, 0 conflit). Branche feature/agent-session-limits conservee (non supprimee). Etat = EN MEMOIRE uniquement (pas de persistance SessionLimit, cf. decision verrouillee). Aucun push (develop local en avance sur origin ; action sortante en attente de validation).