#!/usr/bin/env python3
"""Hermes Web Chat Server — Full Agent Mode via Hermes API Server.
Copy to ~/.hermes/webchat/server.py and customize PASSWORD and API_KEY below.

Architecture:
  Browser → Nginx → This server (8888) → Hermes API Server (8080) → Full AIAgent

Prerequisites:
  1. Hermes gateway running with API_SERVER_ENABLED=true
  2. Nginx reverse proxy on port 80/443 → 8888
  3. Firewall allowing port 80/443

Start:
  python3 ~/.hermes/webchat/server.py &
"""

import http.server
import json
import hashlib
import os
import time
import threading
import urllib.request
import urllib.error

# === CONFIGURATION ===
PASSWORD = "CHANGE_ME!"
PORT = 8888
HOST = "0.0.0.0"
USE_SSL = False

# Hermes API Server
API_SERVER_URL = "http://127.0.0.1:8080"
API_KEY = "YOUR_API_SERVER_KEY"

sessions = {}
sessions_lock = threading.Lock()
MAX_HISTORY = 30

def gen_session_id():
    return hashlib.sha256(os.urandom(32) + str(time.time()).encode()).hexdigest()[:32]

def load_memory_context():
    """Load terminal agent's memory files to inject as system prompt."""
    context_parts = []
    memories_dir = os.path.expanduser("~/.hermes/memories")
    user_md = os.path.join(memories_dir, "USER.md")
    if os.path.exists(user_md):
        try:
            with open(user_md, 'r') as f:
                content = f.read().strip()
                if content:
                    context_parts.append(f"## 用户信息\n{content}")
        except:
            pass
    memory_md = os.path.join(memories_dir, "MEMORY.md")
    if os.path.exists(memory_md):
        try:
            with open(memory_md, 'r') as f:
                content = f.read().strip()
                if content:
                    if len(content) > 2000:
                        content = "...(truncated)\n" + content[-2000:]
                    context_parts.append(f"## 记忆\n{content}")
        except:
            pass
    if context_parts:
        return "\n\n".join(context_parts)
    return None

def call_hermes_api(messages, session_id="webchat-main", max_tokens=2000):
    """Call Hermes API Server. Returns (ok, response_or_error)."""
    memory_context = load_memory_context()
    if memory_context:
        messages = [{"role": "system", "content": memory_context}] + messages
    payload = json.dumps({
        "model": "hermes-agent",
        "messages": messages,
        "max_tokens": max_tokens
    }).encode()
    req = urllib.request.Request(
        f"{API_SERVER_URL}/v1/chat/completions",
        data=payload,
        headers={
            "Content-Type": "application/json",
            "Authorization": f"Bearer {API_KEY}",
            "X-Hermes-Session-Id": session_id
        },
        method="POST"
    )
    try:
        with urllib.request.urlopen(req, timeout=300) as resp:
            data = json.loads(resp.read().decode())
            return True, data["choices"][0]["message"]["content"]
    except urllib.error.HTTPError as e:
        body = e.read().decode() if e.fp else ""
        return False, f"API Error {e.code}: {body}"
    except Exception as e:
        return False, str(e)

# ... (HTML pages omitted for brevity - same as current implementation)

class Handler(http.server.BaseHTTPRequestHandler):
    def log_message(self, fmt, *args):
        pass
    # ... (handler implementation same as current)

def main():
    server = http.server.HTTPServer((HOST, PORT), Handler)
    proto = "HTTPS" if USE_SSL else "HTTP"
    print(f"Hermes Web Chat (Full Agent) on {proto}://{HOST}:{PORT}")
    try:
        server.serve_forever()
    except KeyboardInterrupt:
        print("\nShutting down...")
        server.shutdown()

if __name__ == '__main__':
    main()
