9.8 KiB
9.8 KiB
MiroFish — Fork Context (Private Impact Feature)
Branche de travail
feature/private-impact
Remotes
origin→ https://github.com/CyrilDEVIA/MiroResult.git (fork perso)upstream→ https://github.com/666ghj/MiroFish.git (repo original)
Historique des sessions
2026-04-16 — Session 1
Étapes terminées
- Prompt N°01 — Lecture complète du code source (audit, zéro modification)
- Prompt N°02 — Setup Git : fork + remote + branche
feature/private-impact - Prompt N°03 — Création
backend/scripts/run_private_simulation.py - Prompt N°04 — Création
backend/app/services/private_impact_profile_generator.py - Prompt N°05 — Création
backend/app/services/private_impact_config_generator.py - Prompt N°06 — Création
backend/app/services/private_impact_runner.py - Prompt N°07 — Blueprint
backend/app/api/private.py+ enregistrement (api/__init__.py,app/__init__.py) - Prompt N°08 — Modification
backend/app/services/simulation_runner.py(7 zones : champs private_*, start, monitor, read_log, check_completed, get_actions, cleanup) - Prompt N°09 — Frontend :
api/private.js+ModeSelector.vue+PrivateImpactView.vue+ route/private/:projectId - Prompt N°10 —
action_logger.py: ajoutget_private_logger()+ suppression fallbackrun_private_simulation.py+ intégrationModeSelectordansHome.vue
Fichiers créés / modifiés
| Fichier | Action |
|---|---|
backend/scripts/run_private_simulation.py |
Créé — moteur de simulation privé |
backend/scripts/private/ |
Créé — répertoire de sortie actions.jsonl |
backend/app/services/private_impact_profile_generator.py |
Créé — générateur de profils relationnels |
backend/app/services/private_impact_config_generator.py |
Créé — générateur de paramètres comportementaux |
backend/app/services/private_impact_runner.py |
Créé — orchestrateur subprocess + monitoring |
CONTEXT.md |
Créé — ce fichier |
backend/app/api/private.py |
Créé — blueprint Flask /api/private-impact (7 routes) |
backend/app/api/__init__.py |
Modifié — ajout private_bp + import private |
backend/app/__init__.py |
Modifié — enregistrement private_bp |
backend/app/services/simulation_runner.py |
Modifié — 7 zones private (champs, start, monitor, read_log, check, get_actions, cleanup) |
frontend/src/api/private.js |
Créé — client API private impact (7 fonctions) |
frontend/src/components/ModeSelector.vue |
Créé — sélecteur Public / Private Impact (2 cartes) |
frontend/src/views/PrivateImpactView.vue |
Créé — wizard 5 étapes (form → prepare → run → report → chat) |
frontend/src/router/index.js |
Modifié — route /private/:projectId ajoutée |
backend/scripts/action_logger.py |
Modifié — ajout get_private_logger() à SimulationLogManager |
backend/scripts/run_private_simulation.py |
Modifié — suppression fallback hasattr, appel direct log_manager.get_private_logger() |
frontend/src/views/Home.vue |
Modifié — intégration ModeSelector (right panel) + handleModeSelected + sessionStorage pendingSimMode |
Décisions d'architecture prises
- Pas d'env OASIS (pas de Twitter/Reddit/PlatformConfig)
- Appels LLM directs via
camel-ai ChatAgent+asyncio.to_thread() - Graphe relationnel construit depuis
cascade_influencedans agent_configs REACT_PRIVATELY= invisible → ne propage pas l'exposition- Tous les autres actions (sauf
DO_NOTHING) cascade verscascade_influencetargets zep_graph_memory_updater.pyréutilisé sans modification (platform="private")- IPC
PrivateIPCHandler: interviews via LLM direct (pas de SQLite) - Output :
private/actions.jsonl(même format JSONL que twitter/reddit) RelationalAgentProfilehérite deOasisAgentProfile— 8 champs relationnels ajoutés- Encodage des dimensions relationnelles dans le champ
persona(texte naturel) - Fallback rule-based par type : Employee, Manager, Client, Competitor, Partner, FamilyMember
to_private_format()retourne le dict lu parrun_private_simulation.pyPrivateImpactConfigGenerator.generate_config(): entrée = liste de dicts agents (issue de profile_generator), pas d'EntityNode directPrivateTimeConfig: jours + rounds/jour (matin/midi/soir) — pas d'heures ni timezonePrivateEventConfig: injection pardecision_statement— pas de posts sociauxRelationalActivityConfig.exposure_round: round 0 = exposition directe (distance 1)- Fallback rule-based : table
RELATIONAL_FALLBACKSdans le générateur (6 types) PrivateImpactRunner: même pattern classmethods queSimulationRunner(états en mémoire de classe)- Config lue depuis
private_simulation_config.json(≠simulation_config.jsonOASIS) - Log unique :
{sim_dir}/private/actions.jsonl(une seule plateforme) PrivateRunnerStatus: enum séparé — pas de réutilisation deRunnerStatusprivate_simulated_dayslu depuis le champsimulated_dayduround_endevent- Frontend : CSS plain (pas Tailwind — non présent dans package.json) — même style que les vues existantes
ModeSelector.vue: composant standalone, émet@mode-selectedavec"public"ou"private", à intégrer manuellement dansHome.vueouProcess.vuePrivateImpactView.vue: route/private/:projectId— charge le projet viagetProject()pour récupérergraph_id- Step 3 : polling
/api/private-impact/status/{simId}toutes les 3s + affichagerecent_actionsdepuisto_detail_dict() - Step 4 : report via
generatePrivateReport()→ task_id → pollinggetReportStatus(reportId)→getReport(reportId)(réutilise le ReportManager existant) - Step 5 :
chatAgentsreconstruit depuis la liste d'actions (agent_id + agent_name) ; chat viainterviewAgents()(réutilise simulation.js) SimulationRunState: 5 champsprivate_*ajoutés (current_round, simulated_days, running, actions_count, completed)add_action(): elif platform=="private" → private_actions_count (évite comptage dans reddit)to_dict(): private_* inclus dans total_actions_countstart_simulation(): elif platform=="private" → run_private_simulation.py + private_running=True_monitor_simulation(): lectureprivate/actions.jsonldans la boucle ET en final ; private_running=False à la fin_read_action_log(): simulation_end → private_completed=True ; round_end → private_current_round + private_simulated_days (depuis simulated_day)_check_all_platforms_completed(): private_log + private_enabled + check private_completedget_all_actions(): bloc private après reddit (même pattern)cleanup_simulation_logs(): private_simulation.db + dirs_to_clean inclut "private"- Blueprint
private_bpenregistré sans url_prefix (les routes déclarent/api/private-impact/...en entier) /preparestocke les métadonnées (graph_id, sim_requirement, agent_count…) dansprivate_meta.jsondans le sim_dir/prepareappelleZepEntityReader.get_entities_by_type()en boucle sur les types relationnels puisPrivateImpactProfileGenerator.generate_profiles_from_entities()/startlitprivate_simulation_config.jsonviaPrivateImpactRunner.start_simulation()/statusretourneto_detail_dict()(inclutrecent_actions)/reportréutiliseReportAgentavecsimulation_id=sim_idetgraph_idlu depuisprivate_meta.json/cleanupdélègue entièrement àPrivateImpactRunner.cleanup()get_private_logger()ajouté àSimulationLogManager— même pattern queget_twitter_logger()/get_reddit_logger(); fallback supprimé dansrun_private_simulation.pyModeSelectorintégré dansHome.vue(right panel, au-dessus de.console-box) ; mode stocké danssessionStorage(pendingSimMode) —MainView.vue(N°11) doit lire ce flag et rediriger vers/private/:projectIdaprès création du projet
Prochaines étapes
| Prompt | Fichier cible | Action |
|---|---|---|
| N°04 | backend/app/services/private_impact_profile_generator.py |
✅ Terminé |
| N°05 | backend/app/services/private_impact_config_generator.py |
✅ Terminé |
| N°06 | backend/app/services/private_impact_runner.py |
✅ Terminé |
| N°07 | backend/app/api/private.py |
✅ Terminé |
| N°07 | backend/app/api/__init__.py |
✅ Terminé |
| N°07 | backend/app/__init__.py |
✅ Terminé |
| N°08 | backend/app/services/simulation_runner.py |
✅ Terminé |
| N°09 | frontend/src/views/PrivateImpactView.vue |
✅ Terminé |
| N°09 | frontend/src/components/ModeSelector.vue |
✅ Terminé |
| N°10 | backend/scripts/action_logger.py |
✅ Terminé — get_private_logger() ajouté |
| N°10 | backend/scripts/run_private_simulation.py |
✅ Terminé — fallback supprimé |
| N°10 | frontend/src/views/Home.vue |
✅ Terminé — ModeSelector intégré |
| N°11 | frontend/src/views/MainView.vue |
Lire sessionStorage.pendingSimMode après création du projet → rediriger vers /private/:projectId si 'private' |
| N°11 | Test end-to-end | Préparer → Lancer → Observer actions.jsonl |
Point d'attention — MainView.vue (N°11)
Status : ⏳ PENDING
Home.vue stocke sessionStorage.pendingSimMode = 'private' quand l'utilisateur sélectionne Private Impact.
MainView.vue doit être modifié pour lire ce flag après la création du projet + le build du graphe Zep, et rediriger vers /private/:projectId au lieu de rester sur la vue OASIS standard.
Action requise dans MainView.vue — après la séquence upload → create_project → build_graph :
const pendingMode = sessionStorage.getItem('pendingSimMode')
if (pendingMode === 'private') {
sessionStorage.removeItem('pendingSimMode')
router.push(`/private/${projectId}`)
}