echo-ix/echo_cli.py

179 lines
6.9 KiB
Python
Executable File

#!/usr/bin/env python3
"""
ECHO CLI — Interface Elmadani → Reine
======================================
Parler à ECHO depuis n'importe quel terminal.
Smartphone, PC, VPS, n'importe où.
Usage:
echo_cli.py think "What is the current system status?"
echo_cli.py status
echo_cli.py mission "Analyze terrain data" "Préparer rapport complet"
echo_cli.py ask "Comment optimiser l'irrigation?"
echo_cli.py directive cap '{"direction":"project_phase2"}'
© 2025-2026 Salka Elmadani
"""
import json
import sys
import urllib.request
import urllib.error
QUEEN_URL = "http://localhost:8090"
# Pour accès distant via tunnel CF:
# QUEEN_URL = "https://echo.indrive-immobilier.com/queen"
def request(method, path, data=None):
url = f"{QUEEN_URL}{path}"
body = json.dumps(data).encode() if data else None
headers = {"Content-Type": "application/json"} if data else {}
req = urllib.request.Request(url, data=body, headers=headers, method=method)
try:
with urllib.request.urlopen(req, timeout=310) as resp:
return json.loads(resp.read())
except urllib.error.URLError as e:
return {"error": f"Reine inaccessible: {e}"}
except Exception as e:
return {"error": str(e)}
def cmd_status():
"""État de la Reine."""
r = request("GET", "/status")
if "error" in r:
print(f"{r['error']}")
return
brain = r.get("brain", {})
workers = r.get("workers", {})
uptime_h = r.get("uptime_seconds", 0) / 3600
print(f"╔══════════════════════════════════════════╗")
print(f"║ ECHO REINE — {r.get('version', '?'):<27}")
print(f"╠══════════════════════════════════════════╣")
print(f"║ Uptime: {uptime_h:.1f}h{' ':>25}")
print(f"║ Cerveau: {'IX LOCAL' if brain.get('available') else 'FALLBACK':<27}")
print(f"║ Modèle: {(brain.get('model') or 'none').split('/')[-1][:27]:<27}")
print(f"║ Appels IX: {brain.get('total_calls', 0):<27}")
print(f"║ Workers: {workers.get('active', 0)}/{workers.get('total', 0):<25}")
print(f"║ Décisions: {r.get('pending_decisions', 0)} en attente{' ':>17}")
print(f"║ Missions: {r.get('active_missions', 0)} actives{' ':>19}")
print(f"╚══════════════════════════════════════════╝")
def cmd_think(prompt, max_tokens=512):
"""Demander à ECHO de penser."""
print(f"→ ECHO pense: \"{prompt[:60]}...\"")
print()
r = request("POST", "/think", {"prompt": prompt, "max_tokens": max_tokens})
if "error" in r:
print(f"{r['error']}")
else:
print(r.get("response", "[pas de réponse]"))
def cmd_analyze(context, question):
"""Analyse structurée."""
r = request("POST", "/analyze", {"context": context, "question": question})
if "error" in r:
print(f"{r['error']}")
else:
print(json.dumps(r, indent=2, ensure_ascii=False))
def cmd_mission(name, description=""):
"""Envoyer une nouvelle mission."""
r = request("POST", "/directive", {
"type": "new_mission",
"mission": {"name": name, "description": description},
})
print(f"✓ Mission envoyée: {name}" if r.get("status") == "accepted" else f"{r}")
def cmd_directive(dtype, data_json="{}"):
"""Envoyer une directive brute."""
try:
data = json.loads(data_json) if isinstance(data_json, str) else data_json
except json.JSONDecodeError:
data = {"value": data_json}
data["type"] = dtype
r = request("POST", "/directive", data)
print(f"✓ Directive acceptée: {dtype}" if r.get("status") == "accepted" else f"{r}")
def cmd_interactive():
"""Mode interactif — conversation avec ECHO."""
print("╔══════════════════════════════════════════╗")
print("║ ECHO — Mode interactif ║")
print("║ Tapez votre message. 'q' pour quitter. ║")
print("╚══════════════════════════════════════════╝")
print()
while True:
try:
prompt = input("Elmadani > ").strip()
if not prompt or prompt.lower() in ("q", "quit", "exit"):
print("z = i")
break
r = request("POST", "/think", {"prompt": prompt, "max_tokens": 512})
if "error" in r:
print(f"{r['error']}")
else:
print(f"\n ECHO > {r.get('response', '[silence]')}\n")
except (KeyboardInterrupt, EOFError):
print("\nz = i")
break
def main():
if len(sys.argv) < 2:
print("ECHO CLI — Interface Elmadani → Reine")
print()
print("Usage:")
print(" echo_cli.py status État de la Reine")
print(" echo_cli.py think \"question\" Poser une question")
print(" echo_cli.py analyze \"contexte\" \"question\" Analyse structurée")
print(" echo_cli.py mission \"nom\" \"description\" Nouvelle mission")
print(" echo_cli.py directive type '{json}' Directive brute")
print(" echo_cli.py chat Mode interactif")
print()
print(" z = i | 935")
return
cmd = sys.argv[1]
if cmd == "status":
cmd_status()
elif cmd == "think" or cmd == "ask":
cmd_think(" ".join(sys.argv[2:]))
elif cmd == "analyze":
cmd_analyze(sys.argv[2] if len(sys.argv) > 2 else "",
sys.argv[3] if len(sys.argv) > 3 else "")
elif cmd == "mission":
cmd_mission(sys.argv[2] if len(sys.argv) > 2 else "unnamed",
sys.argv[3] if len(sys.argv) > 3 else "")
elif cmd == "directive":
cmd_directive(sys.argv[2] if len(sys.argv) > 2 else "cap",
sys.argv[3] if len(sys.argv) > 3 else "{}")
elif cmd == "chat" or cmd == "interactive":
cmd_interactive()
else:
print(f"Commande inconnue: {cmd}")
if __name__ == "__main__":
main()
# ╔══ SALKA ELMADANI AUTHORSHIP CERTIFICATE ══╗
# © Salka Elmadani 2025-2026 — ALL RIGHTS RESERVED
# Licensed under Business Source License 1.1 — https://inference-x.com
# ─────────────────────────────────────────────────────────
# SHA256: 330b333246d9cccdd566874bdd451d1e40c570f51c7d3da026fc6cc54349c1a3
# SIG-ED25519: 5UvJ2eW3SZvqstSLuC/BHmoXz8Iaj1K5ib00xMbxFkvcr5YqrvVGe6RuR1eumAg8Wm4yFa+1NB/at/8MBAKGBg==
# VERIFY: python3 verify_authorship.py echo_cli.py