veda-programming / teacher.py
vedaco's picture
Update teacher.py
594bc39 verified
import requests
from typing import List, Dict, Optional
from config import (
OPENROUTER_API_KEY,
OPENROUTER_BASE_URL,
TEACHER_MODEL,
TEACHER_FALLBACK_MODELS,
TEACHER_TEMPERATURE,
TEACHER_MAX_TOKENS,
)
class TeacherModel:
"""
OpenRouter teacher client with:
- Primary model
- Fallback models
- Detailed error logging
"""
def __init__(self):
self.api_key = OPENROUTER_API_KEY
self.base_url = OPENROUTER_BASE_URL
self.session = requests.Session()
self.last_status_code: Optional[int] = None
self.last_error: str = ""
self.last_model_tried: str = ""
self.last_response_text: str = ""
def is_available(self) -> bool:
return bool(self.api_key)
def _call_model(
self,
model_id: str,
messages: List[Dict],
temperature: float,
max_tokens: int
) -> Optional[str]:
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {self.api_key}",
"Accept": "application/json",
# recommended by OpenRouter
"HTTP-Referer": "https://huggingface.co/spaces/vedaco/veda-programming",
"X-Title": "Veda Programming Assistant",
}
payload = {
"model": model_id,
"messages": messages,
"temperature": float(temperature),
"max_tokens": int(max_tokens),
"stream": False
}
r = self.session.post(self.base_url, headers=headers, json=payload, timeout=60)
self.last_status_code = r.status_code
self.last_response_text = r.text[:2000]
if r.status_code != 200:
try:
err = r.json()
except Exception:
err = {"raw": r.text}
self.last_error = f"HTTP {r.status_code}: {err}"
return None
data = r.json()
if "error" in data:
self.last_error = f"OpenRouter error field: {data['error']}"
return None
choices = data.get("choices") or []
if not choices:
self.last_error = f"No choices in response: {data}"
return None
msg = choices[0].get("message") or {}
content = msg.get("content", "")
if not content:
self.last_error = f"Empty content: {data}"
return None
self.last_error = ""
return content
def ask(
self,
user_message: str,
conversation_history: Optional[List[Dict[str, str]]] = None,
temperature: float = None,
max_tokens: int = None
) -> Optional[str]:
if not self.is_available():
self.last_error = "OPENROUTER_API_KEY missing"
print("[Teacher] Missing OPENROUTER_API_KEY")
return None
temperature = TEACHER_TEMPERATURE if temperature is None else float(temperature)
max_tokens = TEACHER_MAX_TOKENS if max_tokens is None else int(max_tokens)
messages = [
{
"role": "system",
"content": (
"You are a helpful programming assistant. "
"Answer clearly. When asked to write code, output correct Python code. "
"Use markdown code blocks like ```python ... ```."
)
}
]
if conversation_history:
for m in conversation_history[-10:]:
role = m.get("role", "user")
content = m.get("content", "")
if content:
messages.append({"role": role, "content": content})
messages.append({"role": "user", "content": user_message})
candidates = [TEACHER_MODEL] + list(TEACHER_FALLBACK_MODELS)
for model_id in candidates:
self.last_model_tried = model_id
out = self._call_model(model_id, messages, temperature, max_tokens)
if out:
return out
print(f"[Teacher] Failed model {model_id}: {self.last_error}")
return None
teacher = TeacherModel()