bluewinliang commited on
Commit
cbcfe71
·
verified ·
1 Parent(s): 2ef0835

Upload proxy_handler.py

Browse files
Files changed (1) hide show
  1. proxy_handler.py +7 -19
proxy_handler.py CHANGED
@@ -27,7 +27,7 @@ class ProxyHandler:
27
  if not self.client.is_closed:
28
  await self.client.aclose()
29
 
30
- # --- Text utilities (REVISED _clean_answer_from_edit) ---
31
  def _clean_thinking(self, s: str) -> str:
32
  if not s: return ""
33
  s = re.sub(r'<details[^>]*>.*?</details>', '', s, flags=re.DOTALL)
@@ -44,15 +44,15 @@ class ProxyHandler:
44
  if not s: return ""
45
 
46
  if from_edit_content:
47
- # Find the position of the last </details> tag
48
  last_details_pos = s.rfind('</details>')
49
  if last_details_pos != -1:
50
- # Extract everything after the tag
51
  s = s[last_details_pos + len('</details>'):]
52
 
53
- # General cleanup for any remaining <details> blocks (just in case)
54
  s = re.sub(r"<details[^>]*>.*?</details>", "", s, flags=re.DOTALL)
55
- return s.lstrip() # Use lstrip to remove leading whitespace like '\n' but keep internal space
 
 
 
56
 
57
  # ... Other methods like _serialize_msgs, _prep_upstream remain the same ...
58
  def _serialize_msgs(self, msgs) -> list:
@@ -76,10 +76,7 @@ class ProxyHandler:
76
  ck = None
77
  try:
78
  body, headers, ck = await self._prep_upstream(req)
79
- comp_id = f"chatcmpl-{uuid.uuid4().hex[:29]}"
80
- think_open = False
81
- phase_cur = None
82
-
83
  async with self.client.stream("POST", settings.UPSTREAM_URL, json=body, headers=headers) as resp:
84
  if resp.status_code != 200:
85
  await cookie_manager.mark_cookie_failed(ck); err_body = await resp.aread()
@@ -100,7 +97,6 @@ class ProxyHandler:
100
  dat = json.loads(payload_str).get("data", {})
101
  except (json.JSONDecodeError, AttributeError): continue
102
 
103
- # FIX: Differentiate content source
104
  is_edit = "edit_content" in dat
105
  content = dat.get("delta_content", "") or dat.get("edit_content", "")
106
  new_phase = dat.get("phase")
@@ -124,7 +120,6 @@ class ProxyHandler:
124
  think_open = True
125
  text_to_yield = self._clean_thinking(content)
126
  elif current_content_phase == "answer":
127
- # FIX: Use the new cleaning logic
128
  text_to_yield = self._clean_answer(content, from_edit_content=is_edit)
129
 
130
  if text_to_yield:
@@ -140,13 +135,11 @@ class ProxyHandler:
140
  body, headers, ck = await self._prep_upstream(req)
141
  full_content = []
142
  phase_cur = None
143
-
144
  async with self.client.stream("POST", settings.UPSTREAM_URL, json=body, headers=headers) as resp:
145
  if resp.status_code != 200:
146
  await cookie_manager.mark_cookie_failed(ck); error_detail = await resp.text()
147
  raise HTTPException(resp.status_code, f"Upstream error: {error_detail}")
148
  await cookie_manager.mark_cookie_success(ck)
149
-
150
  async for raw in resp.aiter_text():
151
  for line in raw.strip().split('\n'):
152
  line = line.strip()
@@ -156,14 +149,11 @@ class ProxyHandler:
156
  try:
157
  dat = json.loads(payload_str).get("data", {})
158
  except (json.JSONDecodeError, AttributeError): continue
159
-
160
  is_edit = "edit_content" in dat
161
  content = dat.get("delta_content") or dat.get("edit_content")
162
  new_phase = dat.get("phase")
163
-
164
  if new_phase: phase_cur = new_phase
165
  if content and phase_cur:
166
- # Store the content along with its source (is_edit)
167
  full_content.append((phase_cur, content, is_edit))
168
  else: continue
169
  break
@@ -174,16 +164,14 @@ class ProxyHandler:
174
  if phase == "thinking":
175
  think_buf.append(self._clean_thinking(content))
176
  elif phase == "answer":
177
- # FIX: Use the new cleaning logic
178
  answer_buf.append(self._clean_answer(content, from_edit_content=is_edit))
179
 
180
  ans_text = ''.join(answer_buf)
181
  final_content = ans_text
182
-
183
  if settings.SHOW_THINK_TAGS and think_buf:
184
  think_text = ''.join(think_buf).strip()
185
  if think_text:
186
- # No longer need to manually add newline, as .lstrip() in _clean_answer handles it
187
  final_content = f"<think>{think_text}</think>{ans_text}"
188
 
189
  return ChatCompletionResponse(
 
27
  if not self.client.is_closed:
28
  await self.client.aclose()
29
 
30
+ # --- Text utilities (REVISED _clean_answer) ---
31
  def _clean_thinking(self, s: str) -> str:
32
  if not s: return ""
33
  s = re.sub(r'<details[^>]*>.*?</details>', '', s, flags=re.DOTALL)
 
44
  if not s: return ""
45
 
46
  if from_edit_content:
 
47
  last_details_pos = s.rfind('</details>')
48
  if last_details_pos != -1:
 
49
  s = s[last_details_pos + len('</details>'):]
50
 
 
51
  s = re.sub(r"<details[^>]*>.*?</details>", "", s, flags=re.DOTALL)
52
+
53
+ # FIX: Use a more specific lstrip to only remove leading newlines,
54
+ # but preserve leading spaces which are important for markdown.
55
+ return s.lstrip('\n\r')
56
 
57
  # ... Other methods like _serialize_msgs, _prep_upstream remain the same ...
58
  def _serialize_msgs(self, msgs) -> list:
 
76
  ck = None
77
  try:
78
  body, headers, ck = await self._prep_upstream(req)
79
+ comp_id = f"chatcmpl-{uuid.uuid4().hex[:29]}"; think_open = False; phase_cur = None
 
 
 
80
  async with self.client.stream("POST", settings.UPSTREAM_URL, json=body, headers=headers) as resp:
81
  if resp.status_code != 200:
82
  await cookie_manager.mark_cookie_failed(ck); err_body = await resp.aread()
 
97
  dat = json.loads(payload_str).get("data", {})
98
  except (json.JSONDecodeError, AttributeError): continue
99
 
 
100
  is_edit = "edit_content" in dat
101
  content = dat.get("delta_content", "") or dat.get("edit_content", "")
102
  new_phase = dat.get("phase")
 
120
  think_open = True
121
  text_to_yield = self._clean_thinking(content)
122
  elif current_content_phase == "answer":
 
123
  text_to_yield = self._clean_answer(content, from_edit_content=is_edit)
124
 
125
  if text_to_yield:
 
135
  body, headers, ck = await self._prep_upstream(req)
136
  full_content = []
137
  phase_cur = None
 
138
  async with self.client.stream("POST", settings.UPSTREAM_URL, json=body, headers=headers) as resp:
139
  if resp.status_code != 200:
140
  await cookie_manager.mark_cookie_failed(ck); error_detail = await resp.text()
141
  raise HTTPException(resp.status_code, f"Upstream error: {error_detail}")
142
  await cookie_manager.mark_cookie_success(ck)
 
143
  async for raw in resp.aiter_text():
144
  for line in raw.strip().split('\n'):
145
  line = line.strip()
 
149
  try:
150
  dat = json.loads(payload_str).get("data", {})
151
  except (json.JSONDecodeError, AttributeError): continue
 
152
  is_edit = "edit_content" in dat
153
  content = dat.get("delta_content") or dat.get("edit_content")
154
  new_phase = dat.get("phase")
 
155
  if new_phase: phase_cur = new_phase
156
  if content and phase_cur:
 
157
  full_content.append((phase_cur, content, is_edit))
158
  else: continue
159
  break
 
164
  if phase == "thinking":
165
  think_buf.append(self._clean_thinking(content))
166
  elif phase == "answer":
 
167
  answer_buf.append(self._clean_answer(content, from_edit_content=is_edit))
168
 
169
  ans_text = ''.join(answer_buf)
170
  final_content = ans_text
 
171
  if settings.SHOW_THINK_TAGS and think_buf:
172
  think_text = ''.join(think_buf).strip()
173
  if think_text:
174
+ # The newline is handled by the answer itself now, so we can just concatenate.
175
  final_content = f"<think>{think_text}</think>{ans_text}"
176
 
177
  return ChatCompletionResponse(