1 line
23 KiB
JSON
1 line
23 KiB
JSON
{"repo": "byakuyakutchiki/luna-server", "files": {"tools/agents/deepseek_chat.py": {"25b46e3b004b4bb49d59a9cc1344c8626950a89b": {"t": 1785746411.5186265, "n": 8655, "h": "ce58fbdaa9945123", "c": "#!/usr/bin/env python3\n\"\"\"Terminal DeepSeek interactif pour audit code Luna.\n\nNOUVEAU — Gestion Git automatique :\n- Se place dans REPO_ROOT au démarrage\n- git pull automatique au démarrage\n- Détection auto des fichiers modifiés après chaque réponse\n- Commandes /status, /pull, /commit pour livrer sur GitHub\n\"\"\"\n\nimport os\nimport sys\nimport json\nimport subprocess\nimport urllib.request\nimport urllib.error\nfrom pathlib import Path\n\nREPO_ROOT = Path(__file__).resolve().parent.parent.parent\nDOCS_DIR = REPO_ROOT / \"docs\" / \"AGENTS_COLLABORATION\"\nAPI_URL = \"https://api.deepseek.com/chat/completions\"\nMODEL = \"deepseek-chat\"\n\nCONTEXT_FILES = [\n (\"OBJECTIFS_ACTIFS.md\", \"Objectifs actifs\"),\n (\"QUEUE.md\", \"Queue des tâches\"),\n (\"REGLES_DE_COORDINATION.md\", \"Règles de coordination\"),\n (\"TABLEAU_DE_BORD.md\", \"Tableau de bord\"),\n (\"ETAT_ACTUEL.md\", \"État actuel\"),\n]\n\nSYSTEM_PROMPT = \"\"\"Tu es DeepSeek, agent technique d'audit code Luna.\nTu n'es pas Claude, pas Kimi, pas Codex.\n\nRôle : audit technique, risques code, faisabilité, propositions précises.\n\nRègles absolues :\n- Réponses courtes, concrètes, orientées application.\n- Ne jamais proposer de régression graphique.\n- Ne jamais modifier la production.\n- Ne jamais déclencher SMS, email, appel, paiement, réservation réels.\n- Ne jamais modifier secrets, Cloud, base de données, données utilisateur.\n- Si changement majeur (niveau 2+) : demander validation Ludovic avant tout.\n- Si aucune tâche ouverte : proposer le prochain test bouton/workflow utile.\n- Niveaux : 0=audit/doc, 1=petite correction faible risque, 2+=validation Ludovic obligatoire.\n- DeepSeek = niveau 0 uniquement (audit, avis, documentation, tests non destructifs).\n\nLIVRAISON OBLIGATOIRE :\n- Quand tu produis un rapport, crée le fichier dans docs/AGENTS_COLLABORATION/agents/DEEPSEEK_*.md\n- Après avoir créé/modifié des fichiers, utilise la commande /commit \"message\" pour livrer sur GitHub.\n- Si tu ne fais pas /commit, tes résultats ne sont PAS sur GitHub et Ludovic ne les voit pas.\n- Exemple : /commit \"TASK-017-DEEPSEEK: audit UI mobile — cause CSS trouvée\"\n\nTu peux : lire le repo, analyser le code, proposer des patchs niveau 0/1, répondre à Ludovic.\"\"\"\n\n\ndef _run_git(cmd: list, cwd: Path = REPO_ROOT) -> tuple:\n \"\"\"Exécute une commande git et retourne (returncode, stdout, stderr).\"\"\"\n try:\n result = subprocess.run(\n [\"git\", \"-C\", str(cwd)] + cmd,\n capture_output=True,\n text=True,\n timeout=30,\n )\n return result.returncode, result.stdout.strip(), result.stderr.strip()\n except Exception as e:\n return -1, \"\", str(e)\n\n\ndef git_pull() -> str:\n \"\"\"Fait un git pull et retourne un résumé.\"\"\"\n rc, out, err = _run_git([\"pull\", \"--ff-only\"])\n if rc == 0:\n return f\"✅ Git pull OK : {out[:80]}\" if out else \"✅ Git pull OK (déjà à jour)\"\n return f\"⚠️ Git pull échoue : {err[:120]}\"\n\n\ndef git_status_short() -> str:\n \"\"\"Retourne le git status --short.\"\"\"\n rc, out, _ = _run_git([\"status\", \"--short\"])\n return out if rc == 0 else \"\"\n\n\ndef git_commit_push(message: str) -> str:\n \"\"\"Add, commit, push. Retourne le résultat.\"\"\"\n rc1, _, err1 = _run_git([\"add\", \"-A\"])\n if rc1 != 0:\n return f\"❌ git add échoue : {err1}\"\n rc2, out2, err2 = _run_git([\"commit\", \"-m\", message])\n if rc2 != 0:\n return f\"❌ git commit échoue : {err2}\"\n rc3, out3, err3 = _run_git([\"push\", \"origin\", \"HEAD\"])\n if rc3 != 0:\n return f\"❌ git push échoue : {err3}\"\n return f\"✅ Livré sur GitHub : {out3[:80]}\"\n\n\ndef load_context() -> str:\n \"\"\"Charge le contexte court depuis les fichiers de collaboration.\"\"\"\n parts = []\n for filename, label in CONTEXT_FILES:\n path = DOCS_DIR / filename\n if not path.exists():\n continue\n content = path.read_text(encoding=\"utf-8\").strip()\n if filename == \"ETAT_ACTUEL.md\":\n lines = content.splitlines()\n content = \"\\n\".join(lines[:40])\n parts.append(f\"=== {label} ({filename}) ===\\n{content}\")\n if not parts:\n return \"\"\n return \"\\n\\n\".join(parts)\n\n\ndef call_deepseek(api_key: str, messages: list) -> str:\n \"\"\"Appelle l'API DeepSeek et retourne la réponse texte.\"\"\"\n payload = json.dumps({\n \"model\": MODEL,\n \"messages\": messages,\n \"max_tokens\": 1024,\n \"temperature\": 0.3,\n }).encode(\"utf-8\")\n\n req = urllib.request.Request(\n API_URL,\n data=payload,\n headers={\n \"Content-Type\": \"application/json\",\n \"Authorization\": f\"Bearer {api_key}\",\n },\n method=\"POST\",\n )\n try:\n with urllib.request.urlopen(req, timeout=60) as resp:\n data = json.loads(resp.read().decode(\"utf-8\"))\n return data[\"choices\"][0][\"message\"][\"content\"].strip()\n except urllib.error.HTTPError as e:\n body = e.read().decode(\"utf-8\", errors=\"replace\")\n return f\"[Erreur API {e.code}] {body}\"\n except urllib.error.URLError as e:\n return f\"[Erreur réseau] {e.reason}\"\n\n\ndef check_and_commit():\n \"\"\"Vérifie si des fichiers sont modifiés et propose de committer.\"\"\"\n status = git_status_short()\n if not status:\n return\n print()\n print(\"─\" * 50)\n print(\"📁 Fichiers modifiés/créés détectés :\")\n for line in status.splitlines()[:15]:\n print(f\" {line}\")\n if len(status.splitlines()) > 15:\n print(f\" ... et {len(status.splitlines()) - 15} autres\")\n print()\n try:\n ans = input(\"💾 Committer et push sur GitHub ? [o/N] \").strip().lower()\n except (KeyboardInterrupt, EOFError):\n print(\"⏭️ Commit annulé.\")\n return\n if ans in (\"o\", \"oui\", \"y\", \"yes\"):\n msg = input(\"📝 Message de commit : \").strip()\n if not msg:\n msg = \"DEEPSEEK: mise à jour automatique\"\n result = git_commit_push(msg)\n print(result)\n else:\n print(\"⏭️ Commit annulé. Utilise /commit plus tard.\")\n print(\"─\" * 50)\n\n\ndef handle_command(cmd: str, api_key: str, messages: list) -> bool:\n \"\"\"Gère les commandes spéciales. Retourne True si c'est une commande traitée.\"\"\"\n parts = cmd.split(None, 1)\n if not parts:\n return False\n keyword = parts[0].lower()\n\n if keyword == \"/status\":\n status = git_status_short()\n if status:\n print(\"📁 Fichiers modifiés :\")\n print(status)\n else:\n print(\"✅ Aucun fichier modifié.\")\n return True\n\n if keyword == \"/pull\":\n print(git_pull())\n return True\n\n if keyword == \"/commit\":\n msg = parts[1] if len(parts) > 1 else \"DEEPSEEK: mise à jour\"\n print(git_commit_push(msg))\n return True\n\n if keyword in (\"/help\", \"/aide\"):\n print(\"\"\"\nCommandes disponibles :\n /status → Voir les fichiers modifiés\n /pull → git pull (synchroniser avec GitHub)\n /commit \"msg\" → git add + commit + push\n /help → Cette aide\n exit / quit / q → Quitter\n\"\"\")\n return True\n\n return False\n\n\ndef main():\n api_key = os.environ.get(\"DEEPSEEK_API_KEY\", \"\").strip()\n if not api_key:\n print(\"Clé API manquante. Lance d'abord :\")\n print(' export DEEPSEEK_API_KEY=\"sk-...\"')\n sys.exit(1)\n\n # Se placer dans le repo\n os.chdir(REPO_ROOT)\n print(f\"📂 Repo : {REPO_ROOT}\")\n\n # Git pull au démarrage\n print(git_pull())\n\n context = load_context()\n system_content = SYSTEM_PROMPT\n if context:\n system_content += f\"\\n\\n--- Contexte Luna chargé automatiquement ---\\n{context}\"\n\n messages = [{\"role\": \"system\", \"content\": system_content}]\n\n print(\"=\" * 60)\n print(\" Terminal DeepSeek — Agent audit code Luna\")\n print(\" Tape '/help' pour les commandes, 'exit' pour quitter.\")\n print(\"=\" * 60)\n print()\n\n while True:\n try:\n user_input = input(\"Ludovic > \").strip()\n except (KeyboardInterrupt, EOFError):\n print(\"\\nAu revoir.\")\n break\n\n if not user_input:\n continue\n if user_input.lower() in (\"exit\", \"quit\", \"q\"):\n print(\"Au revoir.\")\n break\n\n # Commandes spéciales\n if handle_command(user_input, api_key, messages):\n continue\n\n messages.append({\"role\": \"user\", \"content\": user_input})\n print(\"DeepSeek > ...\", end=\"\\r\", flush=True)\n\n reply = call_deepseek(api_key, messages)\n print(f\"DeepSeek > {reply}\\n\")\n messages.append({\"role\": \"assistant\", \"content\": reply})\n\n # Détection auto des fichiers modifiés\n check_and_commit()\n\n\nif __name__ == \"__main__\":\n main()\n"}, "5318e5e735615fc16684d8e2d0dd5143dfacef26": {"t": 1785763670.1458275, "n": 8655, "h": "ce58fbdaa9945123", "c": "#!/usr/bin/env python3\n\"\"\"Terminal DeepSeek interactif pour audit code Luna.\n\nNOUVEAU — Gestion Git automatique :\n- Se place dans REPO_ROOT au démarrage\n- git pull automatique au démarrage\n- Détection auto des fichiers modifiés après chaque réponse\n- Commandes /status, /pull, /commit pour livrer sur GitHub\n\"\"\"\n\nimport os\nimport sys\nimport json\nimport subprocess\nimport urllib.request\nimport urllib.error\nfrom pathlib import Path\n\nREPO_ROOT = Path(__file__).resolve().parent.parent.parent\nDOCS_DIR = REPO_ROOT / \"docs\" / \"AGENTS_COLLABORATION\"\nAPI_URL = \"https://api.deepseek.com/chat/completions\"\nMODEL = \"deepseek-chat\"\n\nCONTEXT_FILES = [\n (\"OBJECTIFS_ACTIFS.md\", \"Objectifs actifs\"),\n (\"QUEUE.md\", \"Queue des tâches\"),\n (\"REGLES_DE_COORDINATION.md\", \"Règles de coordination\"),\n (\"TABLEAU_DE_BORD.md\", \"Tableau de bord\"),\n (\"ETAT_ACTUEL.md\", \"État actuel\"),\n]\n\nSYSTEM_PROMPT = \"\"\"Tu es DeepSeek, agent technique d'audit code Luna.\nTu n'es pas Claude, pas Kimi, pas Codex.\n\nRôle : audit technique, risques code, faisabilité, propositions précises.\n\nRègles absolues :\n- Réponses courtes, concrètes, orientées application.\n- Ne jamais proposer de régression graphique.\n- Ne jamais modifier la production.\n- Ne jamais déclencher SMS, email, appel, paiement, réservation réels.\n- Ne jamais modifier secrets, Cloud, base de données, données utilisateur.\n- Si changement majeur (niveau 2+) : demander validation Ludovic avant tout.\n- Si aucune tâche ouverte : proposer le prochain test bouton/workflow utile.\n- Niveaux : 0=audit/doc, 1=petite correction faible risque, 2+=validation Ludovic obligatoire.\n- DeepSeek = niveau 0 uniquement (audit, avis, documentation, tests non destructifs).\n\nLIVRAISON OBLIGATOIRE :\n- Quand tu produis un rapport, crée le fichier dans docs/AGENTS_COLLABORATION/agents/DEEPSEEK_*.md\n- Après avoir créé/modifié des fichiers, utilise la commande /commit \"message\" pour livrer sur GitHub.\n- Si tu ne fais pas /commit, tes résultats ne sont PAS sur GitHub et Ludovic ne les voit pas.\n- Exemple : /commit \"TASK-017-DEEPSEEK: audit UI mobile — cause CSS trouvée\"\n\nTu peux : lire le repo, analyser le code, proposer des patchs niveau 0/1, répondre à Ludovic.\"\"\"\n\n\ndef _run_git(cmd: list, cwd: Path = REPO_ROOT) -> tuple:\n \"\"\"Exécute une commande git et retourne (returncode, stdout, stderr).\"\"\"\n try:\n result = subprocess.run(\n [\"git\", \"-C\", str(cwd)] + cmd,\n capture_output=True,\n text=True,\n timeout=30,\n )\n return result.returncode, result.stdout.strip(), result.stderr.strip()\n except Exception as e:\n return -1, \"\", str(e)\n\n\ndef git_pull() -> str:\n \"\"\"Fait un git pull et retourne un résumé.\"\"\"\n rc, out, err = _run_git([\"pull\", \"--ff-only\"])\n if rc == 0:\n return f\"✅ Git pull OK : {out[:80]}\" if out else \"✅ Git pull OK (déjà à jour)\"\n return f\"⚠️ Git pull échoue : {err[:120]}\"\n\n\ndef git_status_short() -> str:\n \"\"\"Retourne le git status --short.\"\"\"\n rc, out, _ = _run_git([\"status\", \"--short\"])\n return out if rc == 0 else \"\"\n\n\ndef git_commit_push(message: str) -> str:\n \"\"\"Add, commit, push. Retourne le résultat.\"\"\"\n rc1, _, err1 = _run_git([\"add\", \"-A\"])\n if rc1 != 0:\n return f\"❌ git add échoue : {err1}\"\n rc2, out2, err2 = _run_git([\"commit\", \"-m\", message])\n if rc2 != 0:\n return f\"❌ git commit échoue : {err2}\"\n rc3, out3, err3 = _run_git([\"push\", \"origin\", \"HEAD\"])\n if rc3 != 0:\n return f\"❌ git push échoue : {err3}\"\n return f\"✅ Livré sur GitHub : {out3[:80]}\"\n\n\ndef load_context() -> str:\n \"\"\"Charge le contexte court depuis les fichiers de collaboration.\"\"\"\n parts = []\n for filename, label in CONTEXT_FILES:\n path = DOCS_DIR / filename\n if not path.exists():\n continue\n content = path.read_text(encoding=\"utf-8\").strip()\n if filename == \"ETAT_ACTUEL.md\":\n lines = content.splitlines()\n content = \"\\n\".join(lines[:40])\n parts.append(f\"=== {label} ({filename}) ===\\n{content}\")\n if not parts:\n return \"\"\n return \"\\n\\n\".join(parts)\n\n\ndef call_deepseek(api_key: str, messages: list) -> str:\n \"\"\"Appelle l'API DeepSeek et retourne la réponse texte.\"\"\"\n payload = json.dumps({\n \"model\": MODEL,\n \"messages\": messages,\n \"max_tokens\": 1024,\n \"temperature\": 0.3,\n }).encode(\"utf-8\")\n\n req = urllib.request.Request(\n API_URL,\n data=payload,\n headers={\n \"Content-Type\": \"application/json\",\n \"Authorization\": f\"Bearer {api_key}\",\n },\n method=\"POST\",\n )\n try:\n with urllib.request.urlopen(req, timeout=60) as resp:\n data = json.loads(resp.read().decode(\"utf-8\"))\n return data[\"choices\"][0][\"message\"][\"content\"].strip()\n except urllib.error.HTTPError as e:\n body = e.read().decode(\"utf-8\", errors=\"replace\")\n return f\"[Erreur API {e.code}] {body}\"\n except urllib.error.URLError as e:\n return f\"[Erreur réseau] {e.reason}\"\n\n\ndef check_and_commit():\n \"\"\"Vérifie si des fichiers sont modifiés et propose de committer.\"\"\"\n status = git_status_short()\n if not status:\n return\n print()\n print(\"─\" * 50)\n print(\"📁 Fichiers modifiés/créés détectés :\")\n for line in status.splitlines()[:15]:\n print(f\" {line}\")\n if len(status.splitlines()) > 15:\n print(f\" ... et {len(status.splitlines()) - 15} autres\")\n print()\n try:\n ans = input(\"💾 Committer et push sur GitHub ? [o/N] \").strip().lower()\n except (KeyboardInterrupt, EOFError):\n print(\"⏭️ Commit annulé.\")\n return\n if ans in (\"o\", \"oui\", \"y\", \"yes\"):\n msg = input(\"📝 Message de commit : \").strip()\n if not msg:\n msg = \"DEEPSEEK: mise à jour automatique\"\n result = git_commit_push(msg)\n print(result)\n else:\n print(\"⏭️ Commit annulé. Utilise /commit plus tard.\")\n print(\"─\" * 50)\n\n\ndef handle_command(cmd: str, api_key: str, messages: list) -> bool:\n \"\"\"Gère les commandes spéciales. Retourne True si c'est une commande traitée.\"\"\"\n parts = cmd.split(None, 1)\n if not parts:\n return False\n keyword = parts[0].lower()\n\n if keyword == \"/status\":\n status = git_status_short()\n if status:\n print(\"📁 Fichiers modifiés :\")\n print(status)\n else:\n print(\"✅ Aucun fichier modifié.\")\n return True\n\n if keyword == \"/pull\":\n print(git_pull())\n return True\n\n if keyword == \"/commit\":\n msg = parts[1] if len(parts) > 1 else \"DEEPSEEK: mise à jour\"\n print(git_commit_push(msg))\n return True\n\n if keyword in (\"/help\", \"/aide\"):\n print(\"\"\"\nCommandes disponibles :\n /status → Voir les fichiers modifiés\n /pull → git pull (synchroniser avec GitHub)\n /commit \"msg\" → git add + commit + push\n /help → Cette aide\n exit / quit / q → Quitter\n\"\"\")\n return True\n\n return False\n\n\ndef main():\n api_key = os.environ.get(\"DEEPSEEK_API_KEY\", \"\").strip()\n if not api_key:\n print(\"Clé API manquante. Lance d'abord :\")\n print(' export DEEPSEEK_API_KEY=\"sk-...\"')\n sys.exit(1)\n\n # Se placer dans le repo\n os.chdir(REPO_ROOT)\n print(f\"📂 Repo : {REPO_ROOT}\")\n\n # Git pull au démarrage\n print(git_pull())\n\n context = load_context()\n system_content = SYSTEM_PROMPT\n if context:\n system_content += f\"\\n\\n--- Contexte Luna chargé automatiquement ---\\n{context}\"\n\n messages = [{\"role\": \"system\", \"content\": system_content}]\n\n print(\"=\" * 60)\n print(\" Terminal DeepSeek — Agent audit code Luna\")\n print(\" Tape '/help' pour les commandes, 'exit' pour quitter.\")\n print(\"=\" * 60)\n print()\n\n while True:\n try:\n user_input = input(\"Ludovic > \").strip()\n except (KeyboardInterrupt, EOFError):\n print(\"\\nAu revoir.\")\n break\n\n if not user_input:\n continue\n if user_input.lower() in (\"exit\", \"quit\", \"q\"):\n print(\"Au revoir.\")\n break\n\n # Commandes spéciales\n if handle_command(user_input, api_key, messages):\n continue\n\n messages.append({\"role\": \"user\", \"content\": user_input})\n print(\"DeepSeek > ...\", end=\"\\r\", flush=True)\n\n reply = call_deepseek(api_key, messages)\n print(f\"DeepSeek > {reply}\\n\")\n messages.append({\"role\": \"assistant\", \"content\": reply})\n\n # Détection auto des fichiers modifiés\n check_and_commit()\n\n\nif __name__ == \"__main__\":\n main()\n"}, "5d592a1a28492032dc1fa7ab967fda8378a28d7c": {"t": 1785763671.9953694, "n": 4312, "h": "a4d5108c6233fb7c", "c": "#!/usr/bin/env python3\n\"\"\"Terminal DeepSeek interactif pour audit code Luna.\"\"\"\n\nimport os\nimport sys\nimport json\nimport urllib.request\nimport urllib.error\nfrom pathlib import Path\n\nREPO_ROOT = Path(__file__).resolve().parent.parent.parent\nDOCS_DIR = REPO_ROOT / \"docs\" / \"AGENTS_COLLABORATION\"\nAPI_URL = \"https://api.deepseek.com/chat/completions\"\nMODEL = \"deepseek-chat\"\n\nCONTEXT_FILES = [\n (\"OBJECTIFS_ACTIFS.md\", \"Objectifs actifs\"),\n (\"QUEUE.md\", \"Queue des tâches\"),\n (\"REGLES_DE_COORDINATION.md\", \"Règles de coordination\"),\n (\"TABLEAU_DE_BORD.md\", \"Tableau de bord\"),\n (\"ETAT_ACTUEL.md\", \"État actuel\"),\n]\n\nSYSTEM_PROMPT = \"\"\"Tu es DeepSeek, agent technique d'audit code Luna.\nTu n'es pas Claude, pas Kimi, pas Codex.\n\nRôle : audit technique, risques code, faisabilité, propositions précises.\n\nRègles absolues :\n- Réponses courtes, concrètes, orientées application.\n- Ne jamais proposer de régression graphique.\n- Ne jamais modifier la production.\n- Ne jamais déclencher SMS, email, appel, paiement, réservation réels.\n- Ne jamais modifier secrets, Cloud, base de données, données utilisateur.\n- Si changement majeur (niveau 2+) : demander validation Ludovic avant tout.\n- Si aucune tâche ouverte : proposer le prochain test bouton/workflow utile.\n- Niveaux : 0=audit/doc, 1=petite correction faible risque, 2+=validation Ludovic obligatoire.\n- DeepSeek = niveau 0 uniquement (audit, avis, documentation, tests non destructifs).\n\nTu peux : lire le repo, analyser le code, proposer des patchs niveau 0/1, répondre à Ludovic.\"\"\"\n\n\ndef load_context() -> str:\n \"\"\"Charge le contexte court depuis les fichiers de collaboration.\"\"\"\n parts = []\n for filename, label in CONTEXT_FILES:\n path = DOCS_DIR / filename\n if not path.exists():\n continue\n content = path.read_text(encoding=\"utf-8\").strip()\n if filename == \"ETAT_ACTUEL.md\":\n lines = content.splitlines()\n content = \"\\n\".join(lines[:40])\n parts.append(f\"=== {label} ({filename}) ===\\n{content}\")\n if not parts:\n return \"\"\n return \"\\n\\n\".join(parts)\n\n\ndef call_deepseek(api_key: str, messages: list) -> str:\n \"\"\"Appelle l'API DeepSeek et retourne la réponse texte.\"\"\"\n payload = json.dumps({\n \"model\": MODEL,\n \"messages\": messages,\n \"max_tokens\": 1024,\n \"temperature\": 0.3,\n }).encode(\"utf-8\")\n\n req = urllib.request.Request(\n API_URL,\n data=payload,\n headers={\n \"Content-Type\": \"application/json\",\n \"Authorization\": f\"Bearer {api_key}\",\n },\n method=\"POST\",\n )\n try:\n with urllib.request.urlopen(req, timeout=60) as resp:\n data = json.loads(resp.read().decode(\"utf-8\"))\n return data[\"choices\"][0][\"message\"][\"content\"].strip()\n except urllib.error.HTTPError as e:\n body = e.read().decode(\"utf-8\", errors=\"replace\")\n return f\"[Erreur API {e.code}] {body}\"\n except urllib.error.URLError as e:\n return f\"[Erreur réseau] {e.reason}\"\n\n\ndef main():\n api_key = os.environ.get(\"DEEPSEEK_API_KEY\", \"\").strip()\n if not api_key:\n print(\"Clé API manquante. Lance d'abord :\")\n print(' export DEEPSEEK_API_KEY=\"sk-...\"')\n sys.exit(1)\n\n context = load_context()\n system_content = SYSTEM_PROMPT\n if context:\n system_content += f\"\\n\\n--- Contexte Luna chargé automatiquement ---\\n{context}\"\n\n messages = [{\"role\": \"system\", \"content\": system_content}]\n\n print(\"=\" * 60)\n print(\" Terminal DeepSeek — Agent audit code Luna\")\n print(\" Tape 'exit' ou Ctrl+C pour quitter.\")\n print(\"=\" * 60)\n print()\n\n while True:\n try:\n user_input = input(\"Ludovic > \").strip()\n except (KeyboardInterrupt, EOFError):\n print(\"\\nAu revoir.\")\n break\n\n if not user_input:\n continue\n if user_input.lower() in (\"exit\", \"quit\", \"q\"):\n print(\"Au revoir.\")\n break\n\n messages.append({\"role\": \"user\", \"content\": user_input})\n print(\"DeepSeek > ...\", end=\"\\r\", flush=True)\n\n reply = call_deepseek(api_key, messages)\n print(f\"DeepSeek > {reply}\\n\")\n messages.append({\"role\": \"assistant\", \"content\": reply})\n\n\nif __name__ == \"__main__\":\n main()\n"}}}} |