vedaco commited on
Commit
594bc39
·
verified ·
1 Parent(s): 9f753c3

Update teacher.py

Browse files
Files changed (1) hide show
  1. teacher.py +106 -91
teacher.py CHANGED
@@ -1,125 +1,140 @@
1
- """Teacher Model - Calls OpenRouter API for knowledge distillation"""
2
-
3
  import requests
4
- import json
5
- from typing import Optional, Dict, Any, List
6
  from config import (
7
  OPENROUTER_API_KEY,
8
  OPENROUTER_BASE_URL,
9
  TEACHER_MODEL,
 
10
  TEACHER_TEMPERATURE,
11
  TEACHER_MAX_TOKENS,
12
  )
13
 
14
-
15
  class TeacherModel:
16
- """Wrapper for the OpenRouter teacher model (Dolphin Mistral)"""
 
 
 
 
 
17
 
18
  def __init__(self):
19
  self.api_key = OPENROUTER_API_KEY
20
  self.base_url = OPENROUTER_BASE_URL
21
- self.model = TEACHER_MODEL
22
- self.headers = {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
  "Content-Type": "application/json",
24
  "Authorization": f"Bearer {self.api_key}",
 
 
25
  "HTTP-Referer": "https://huggingface.co/spaces/vedaco/veda-programming",
26
  "X-Title": "Veda Programming Assistant",
27
  }
28
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  def ask(
30
  self,
31
  user_message: str,
32
- conversation_history: List[Dict[str, str]] = None,
33
  temperature: float = None,
34
- max_tokens: int = None,
35
  ) -> Optional[str]:
36
- """
37
- Ask the teacher model a question.
38
-
39
- Args:
40
- user_message: The user's question
41
- conversation_history: Previous messages [{"role": "user/assistant", "content": "..."}]
42
- temperature: Sampling temperature
43
- max_tokens: Maximum tokens to generate
44
-
45
- Returns:
46
- Teacher's response as string, or None if error
47
- """
48
- if not self.api_key or self.api_key == "":
49
- print("Warning: No OpenRouter API key configured")
50
  return None
51
 
52
- temperature = temperature or TEACHER_TEMPERATURE
53
- max_tokens = max_tokens or TEACHER_MAX_TOKENS
54
-
55
- # Build messages
56
- messages = []
57
-
58
- # System prompt to make teacher respond like a programming assistant
59
- messages.append({
60
- "role": "system",
61
- "content": """You are a helpful programming assistant. You help users with:
62
- - Writing Python code
63
- - Explaining programming concepts
64
- - Debugging code
65
- - Answering questions about algorithms and data structures
66
-
67
- Be clear, concise, and provide code examples when helpful.
68
- Format code blocks with ```python and ```.
69
- """
70
- })
71
-
72
- # Add conversation history
73
  if conversation_history:
74
- for msg in conversation_history[-6:]: # Last 6 messages for context
75
- messages.append({
76
- "role": msg.get("role", "user"),
77
- "content": msg.get("content", "")
78
- })
79
-
80
- # Add current user message
81
- messages.append({
82
- "role": "user",
83
- "content": user_message
84
- })
85
 
86
- payload = {
87
- "model": self.model,
88
- "messages": messages,
89
- "temperature": temperature,
90
- "max_tokens": max_tokens,
91
- }
92
 
93
- try:
94
- response = requests.post(
95
- self.base_url,
96
- headers=self.headers,
97
- json=payload,
98
- timeout=60
99
- )
100
-
101
- if response.status_code == 200:
102
- data = response.json()
103
- if "choices" in data and len(data["choices"]) > 0:
104
- return data["choices"][0]["message"]["content"]
105
- else:
106
- print(f"Teacher API unexpected response: {data}")
107
- return None
108
- else:
109
- print(f"Teacher API error: {response.status_code} - {response.text}")
110
- return None
111
-
112
- except requests.exceptions.Timeout:
113
- print("Teacher API timeout")
114
- return None
115
- except Exception as e:
116
- print(f"Teacher API exception: {e}")
117
- return None
118
 
119
- def is_available(self) -> bool:
120
- """Check if teacher API is available"""
121
- return bool(self.api_key and self.api_key != "")
 
 
 
122
 
 
123
 
124
- # Global teacher instance
125
  teacher = TeacherModel()
 
 
 
1
  import requests
2
+ from typing import List, Dict, Optional
3
+
4
  from config import (
5
  OPENROUTER_API_KEY,
6
  OPENROUTER_BASE_URL,
7
  TEACHER_MODEL,
8
+ TEACHER_FALLBACK_MODELS,
9
  TEACHER_TEMPERATURE,
10
  TEACHER_MAX_TOKENS,
11
  )
12
 
 
13
  class TeacherModel:
14
+ """
15
+ OpenRouter teacher client with:
16
+ - Primary model
17
+ - Fallback models
18
+ - Detailed error logging
19
+ """
20
 
21
  def __init__(self):
22
  self.api_key = OPENROUTER_API_KEY
23
  self.base_url = OPENROUTER_BASE_URL
24
+ self.session = requests.Session()
25
+
26
+ self.last_status_code: Optional[int] = None
27
+ self.last_error: str = ""
28
+ self.last_model_tried: str = ""
29
+ self.last_response_text: str = ""
30
+
31
+ def is_available(self) -> bool:
32
+ return bool(self.api_key)
33
+
34
+ def _call_model(
35
+ self,
36
+ model_id: str,
37
+ messages: List[Dict],
38
+ temperature: float,
39
+ max_tokens: int
40
+ ) -> Optional[str]:
41
+
42
+ headers = {
43
  "Content-Type": "application/json",
44
  "Authorization": f"Bearer {self.api_key}",
45
+ "Accept": "application/json",
46
+ # recommended by OpenRouter
47
  "HTTP-Referer": "https://huggingface.co/spaces/vedaco/veda-programming",
48
  "X-Title": "Veda Programming Assistant",
49
  }
50
 
51
+ payload = {
52
+ "model": model_id,
53
+ "messages": messages,
54
+ "temperature": float(temperature),
55
+ "max_tokens": int(max_tokens),
56
+ "stream": False
57
+ }
58
+
59
+ r = self.session.post(self.base_url, headers=headers, json=payload, timeout=60)
60
+
61
+ self.last_status_code = r.status_code
62
+ self.last_response_text = r.text[:2000]
63
+
64
+ if r.status_code != 200:
65
+ try:
66
+ err = r.json()
67
+ except Exception:
68
+ err = {"raw": r.text}
69
+
70
+ self.last_error = f"HTTP {r.status_code}: {err}"
71
+ return None
72
+
73
+ data = r.json()
74
+ if "error" in data:
75
+ self.last_error = f"OpenRouter error field: {data['error']}"
76
+ return None
77
+
78
+ choices = data.get("choices") or []
79
+ if not choices:
80
+ self.last_error = f"No choices in response: {data}"
81
+ return None
82
+
83
+ msg = choices[0].get("message") or {}
84
+ content = msg.get("content", "")
85
+
86
+ if not content:
87
+ self.last_error = f"Empty content: {data}"
88
+ return None
89
+
90
+ self.last_error = ""
91
+ return content
92
+
93
  def ask(
94
  self,
95
  user_message: str,
96
+ conversation_history: Optional[List[Dict[str, str]]] = None,
97
  temperature: float = None,
98
+ max_tokens: int = None
99
  ) -> Optional[str]:
100
+
101
+ if not self.is_available():
102
+ self.last_error = "OPENROUTER_API_KEY missing"
103
+ print("[Teacher] Missing OPENROUTER_API_KEY")
 
 
 
 
 
 
 
 
 
 
104
  return None
105
 
106
+ temperature = TEACHER_TEMPERATURE if temperature is None else float(temperature)
107
+ max_tokens = TEACHER_MAX_TOKENS if max_tokens is None else int(max_tokens)
108
+
109
+ messages = [
110
+ {
111
+ "role": "system",
112
+ "content": (
113
+ "You are a helpful programming assistant. "
114
+ "Answer clearly. When asked to write code, output correct Python code. "
115
+ "Use markdown code blocks like ```python ... ```."
116
+ )
117
+ }
118
+ ]
119
+
 
 
 
 
 
 
 
120
  if conversation_history:
121
+ for m in conversation_history[-10:]:
122
+ role = m.get("role", "user")
123
+ content = m.get("content", "")
124
+ if content:
125
+ messages.append({"role": role, "content": content})
 
 
 
 
 
 
126
 
127
+ messages.append({"role": "user", "content": user_message})
 
 
 
 
 
128
 
129
+ candidates = [TEACHER_MODEL] + list(TEACHER_FALLBACK_MODELS)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
130
 
131
+ for model_id in candidates:
132
+ self.last_model_tried = model_id
133
+ out = self._call_model(model_id, messages, temperature, max_tokens)
134
+ if out:
135
+ return out
136
+ print(f"[Teacher] Failed model {model_id}: {self.last_error}")
137
 
138
+ return None
139
 
 
140
  teacher = TeacherModel()