Investment Plans workspace
Open raw ↗
"""GLM AI adapter for HAD Digital MVP.

Connects to ZhipuAI GLM API for real AI chat.
Reads GLM_API_KEY from environment.
Placeholder implementation - requires network access.
"""

import os
import json
import urllib.request
import urllib.error
from adapters.base import BaseAdapter


class GLMAdapter(BaseAdapter):
    """Adapter for ZhipuAI GLM-4 API."""

    def __init__(self):
        self.api_key = os.environ.get("GLM_API_KEY", "")
        self.model = os.environ.get("GLM_MODEL", "glm-4-flash")
        self.endpoint = os.environ.get(
            "GLM_ENDPOINT",
            "https://open.bigmodel.cn/api/paas/v4/chat/completions",
        )

    def chat(self, message: str, context: dict = None) -> dict:
        """Send message to GLM API and return response."""
        if not self.api_key:
            return {
                "response": "GLM API key not configured. Set GLM_API_KEY environment variable.",
                "sources": [],
                "confidence": 0.0,
                "actions": [],
                "adapter": "glm",
                "error": "api_key_missing",
            }

        context = context or {}
        system_prompt = self._build_system_prompt(context)

        messages = [{"role": "system", "content": system_prompt}]

        # Add conversation history
        for msg in context.get("history", [])[-10:]:
            messages.append({"role": msg.get("role", "user"), "content": msg.get("content", "")})

        messages.append({"role": "user", "content": message})

        payload = {
            "model": self.model,
            "messages": messages,
            "temperature": 0.7,
            "max_tokens": 1024,
        }

        headers = {
            "Content-Type": "application/json",
            "Authorization": f"Bearer {self.api_key}",
        }

        try:
            req = urllib.request.Request(
                self.endpoint,
                data=json.dumps(payload).encode("utf-8"),
                headers=headers,
                method="POST",
            )
            with urllib.request.urlopen(req, timeout=30) as resp:
                data = json.loads(resp.read().decode("utf-8"))

            content = data["choices"][0]["message"]["content"]
            return {
                "response": content,
                "sources": ["GLM-4 AI Assistant"],
                "confidence": 0.9,
                "actions": [],
                "adapter": "glm",
                "model": self.model,
                "usage": data.get("usage", {}),
            }
        except urllib.error.URLError as e:
            return {
                "response": f"Erreur de connexion au service AI: {str(e)}",
                "sources": [],
                "confidence": 0.0,
                "actions": [],
                "adapter": "glm",
                "error": "connection_error",
            }
        except Exception as e:
            return {
                "response": f"Erreur du service AI: {str(e)}",
                "sources": [],
                "confidence": 0.0,
                "actions": [],
                "adapter": "glm",
                "error": "unknown_error",
            }

    def _build_system_prompt(self, context: dict) -> str:
        """Build a system prompt with medical context."""
        prompt = (
            "Vous etes l'assistant medical virtuel du systeme HAD Digital (Hospitalisation "
            "a Domicile). Vous aidez les patients en chimiotherapie a gerer leurs effets "
            "secondaires.\n\n"
            "Regles importantes:\n"
            "1. Donnez des conseils medicaux prudents et generaux\n"
            "2. En cas de doute, recommandez de contacter l'equipe soignante\n"
            "3. Pour les urgences (fievre >=38.3C avec neutropenie, saignements severes, "
            "   difficultes respiratoires), recommandez immediatement le 15 (SAMU)\n"
            "4. Repondez en francais\n"
            "5. Soyez empathique et rassurant\n"
        )

        patient_id = context.get("patient_id")
        if patient_id:
            prompt += f"\nPatient ID: {patient_id}"

        user_role = context.get("user_role")
        if user_role:
            prompt += f"\nRole de l'utilisateur: {user_role}"

        symptoms = context.get("symptoms", [])
        if symptoms:
            prompt += f"\nSymptomes actuels: {json.dumps(symptoms, ensure_ascii=False)}"

        return prompt

    def get_name(self) -> str:
        return "glm"

    def is_available(self) -> bool:
        return bool(self.api_key)