mistpe commited on
Commit
1a7cbdc
·
verified ·
1 Parent(s): 51b2666

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +49 -20
app.py CHANGED
@@ -173,47 +173,63 @@ class SessionManager:
173
  class ImageService:
174
  @staticmethod
175
  def generate_image(prompt: str) -> str:
176
- """Generate image using grok-latest-image model and return markdown URL"""
177
  try:
178
- # Generate image using grok-latest-image
 
179
  response = requests.post(
180
  IMAGE_MODEL_URL,
181
- headers={'Authorization': f'Bearer {IMAGE_MODEL_KEY}'},
 
 
 
182
  json={
183
  "model": "grok-latest-image",
184
- "prompt": prompt
 
 
 
 
185
  }
186
  )
 
 
187
  response.raise_for_status()
 
188
  result = response.json()
 
189
 
190
- if not result.get('url'):
191
- raise ValueError("No image URL in response")
192
-
193
- return f"![image]({result['url']})"
 
 
 
194
  except Exception as e:
195
  logging.error(f"Image generation error: {str(e)}")
196
  raise
197
 
198
  @staticmethod
199
  def get_media_id(image_url: str) -> str:
200
- """Download image and upload to WeChat media storage"""
201
  try:
202
- # Download image
203
  image_response = requests.get(image_url)
204
  image_response.raise_for_status()
205
  image_data = image_response.content
206
-
207
- # Upload to WeChat
208
  upload_url = f'https://api.weixin.qq.com/cgi-bin/media/upload?access_token={TOKEN}&type=image'
209
  files = {'media': ('image.jpg', image_data, 'image/jpeg')}
210
  response = requests.post(upload_url, files=files)
211
  response.raise_for_status()
 
212
  result = response.json()
 
213
 
214
  if 'media_id' not in result:
215
  raise ValueError(f"Failed to get media_id: {result}")
216
 
 
217
  return result['media_id']
218
  except Exception as e:
219
  logging.error(f"WeChat media upload error: {str(e)}")
@@ -269,6 +285,7 @@ def generate_response_xml(to_user, from_user, content, response_type='text', med
269
  nonce = ''.join(random.choices(string.ascii_letters + string.digits, k=10))
270
 
271
  if response_type == 'image' and media_id:
 
272
  xml_content = f'''
273
  <xml>
274
  <ToUserName><![CDATA[{to_user}]]></ToUserName>
@@ -282,6 +299,7 @@ def generate_response_xml(to_user, from_user, content, response_type='text', med
282
  '''
283
  else:
284
  formatted_content = convert_markdown_to_wechat(content)
 
285
  xml_content = f'''
286
  <xml>
287
  <ToUserName><![CDATA[{to_user}]]></ToUserName>
@@ -333,24 +351,25 @@ def append_status_message(content, has_pending_parts=False, is_processing=False)
333
 
334
  def process_ai_response(messages):
335
  try:
 
336
  completion = client.chat.completions.create(
337
  model="o3-mini",
338
  messages=messages,
339
  tools=TOOLS,
340
  tool_choice="auto"
341
  )
 
342
 
343
  # Handle tool calls if present
344
  if completion.choices[0].message.tool_calls:
 
345
  for tool_call in completion.choices[0].message.tool_calls:
346
  if tool_call.function.name == "generate_image":
347
  try:
 
348
  args = json.loads(tool_call.function.arguments)
349
  # Generate image and get markdown URL
350
- image_markdown = ImageService.generate_image(args['prompt'])
351
-
352
- # Extract image URL from markdown
353
- image_url = re.search(r'\((.*?)\)', image_markdown).group(1)
354
 
355
  # Get WeChat media_id
356
  media_id = ImageService.get_media_id(image_url)
@@ -366,7 +385,7 @@ def process_ai_response(messages):
366
  "media_id": media_id
367
  }
368
  except Exception as e:
369
- logging.error(f"Image generation process failed: {str(e)}")
370
  return {
371
  "type": "text",
372
  "content": f"抱歉,图片生成失败:{str(e)}",
@@ -374,6 +393,7 @@ def process_ai_response(messages):
374
  }
375
 
376
  # Handle normal text response
 
377
  response_content = completion.choices[0].message.content
378
  messages.append({
379
  "role": "assistant",
@@ -390,10 +410,12 @@ def process_ai_response(messages):
390
 
391
  def handle_async_task(session, task_id, messages):
392
  try:
 
393
  if task_id not in session.response_queue:
394
  return
395
 
396
  result = process_ai_response(messages)
 
397
 
398
  if task_id in session.response_queue and not session.response_queue[task_id].is_expired():
399
  session.response_queue[task_id].status = "completed"
@@ -401,6 +423,7 @@ def handle_async_task(session, task_id, messages):
401
  session.response_queue[task_id].response_type = result.get("type")
402
  session.response_queue[task_id].media_id = result.get("media_id")
403
  except Exception as e:
 
404
  if task_id in session.response_queue:
405
  session.response_queue[task_id].status = "failed"
406
  session.response_queue[task_id].error = str(e)
@@ -541,21 +564,27 @@ def wechatai():
541
  encrypt_type=encrypt_type
542
  )
543
 
 
 
544
  session.messages.append({"role": "user", "content": user_content})
545
 
546
  task_id = str(uuid.uuid4())
547
  session.current_task = task_id
548
  session.response_queue[task_id] = AsyncResponse()
549
 
550
- # Replace asyncio.run with direct call
551
- handle_async_task(session, task_id, session.messages.copy())
 
552
 
553
- return generate_response_xml(
 
554
  from_user,
555
  to_user,
556
  append_status_message(generate_initial_response(), is_processing=True),
557
  encrypt_type=encrypt_type
558
  )
 
 
559
 
560
  except Exception as e:
561
  logging.error(f"处理请求时出错: {str(e)}")
 
173
  class ImageService:
174
  @staticmethod
175
  def generate_image(prompt: str) -> str:
 
176
  try:
177
+ logging.info(f"开始生成图片,提示词: {prompt}")
178
+
179
  response = requests.post(
180
  IMAGE_MODEL_URL,
181
+ headers={
182
+ 'Content-Type': 'application/json',
183
+ 'Authorization': f'Bearer {IMAGE_MODEL_KEY}'
184
+ },
185
  json={
186
  "model": "grok-latest-image",
187
+ "messages": [{
188
+ "role": "user",
189
+ "content": prompt
190
+ }],
191
+ "stream": False
192
  }
193
  )
194
+
195
+ logging.info(f"图片生成服务响应状态码: {response.status_code}")
196
  response.raise_for_status()
197
+
198
  result = response.json()
199
+ logging.info(f"图片生成服务响应内容: {json.dumps(result, ensure_ascii=False)}")
200
 
201
+ if not result.get('choices') or not result['choices'][0].get('message', {}).get('content'):
202
+ raise ValueError("Invalid response format")
203
+
204
+ image_url = result['choices'][0]['message']['content']
205
+ logging.info(f"成功获取图片URL: {image_url}")
206
+
207
+ return image_url
208
  except Exception as e:
209
  logging.error(f"Image generation error: {str(e)}")
210
  raise
211
 
212
  @staticmethod
213
  def get_media_id(image_url: str) -> str:
 
214
  try:
215
+ logging.info(f"开始下载图片: {image_url}")
216
  image_response = requests.get(image_url)
217
  image_response.raise_for_status()
218
  image_data = image_response.content
219
+
220
+ logging.info("开始上传图片到微信服务器")
221
  upload_url = f'https://api.weixin.qq.com/cgi-bin/media/upload?access_token={TOKEN}&type=image'
222
  files = {'media': ('image.jpg', image_data, 'image/jpeg')}
223
  response = requests.post(upload_url, files=files)
224
  response.raise_for_status()
225
+
226
  result = response.json()
227
+ logging.info(f"微信服务器响应: {json.dumps(result, ensure_ascii=False)}")
228
 
229
  if 'media_id' not in result:
230
  raise ValueError(f"Failed to get media_id: {result}")
231
 
232
+ logging.info(f"成功获取media_id: {result['media_id']}")
233
  return result['media_id']
234
  except Exception as e:
235
  logging.error(f"WeChat media upload error: {str(e)}")
 
285
  nonce = ''.join(random.choices(string.ascii_letters + string.digits, k=10))
286
 
287
  if response_type == 'image' and media_id:
288
+ logging.info(f"生成图片消息响应,media_id: {media_id}")
289
  xml_content = f'''
290
  <xml>
291
  <ToUserName><![CDATA[{to_user}]]></ToUserName>
 
299
  '''
300
  else:
301
  formatted_content = convert_markdown_to_wechat(content)
302
+ logging.info(f"生成文本消息响应: {formatted_content}")
303
  xml_content = f'''
304
  <xml>
305
  <ToUserName><![CDATA[{to_user}]]></ToUserName>
 
351
 
352
  def process_ai_response(messages):
353
  try:
354
+ logging.info("开始处理AI响应")
355
  completion = client.chat.completions.create(
356
  model="o3-mini",
357
  messages=messages,
358
  tools=TOOLS,
359
  tool_choice="auto"
360
  )
361
+ logging.info("收到AI响应")
362
 
363
  # Handle tool calls if present
364
  if completion.choices[0].message.tool_calls:
365
+ logging.info("检测到工具调用")
366
  for tool_call in completion.choices[0].message.tool_calls:
367
  if tool_call.function.name == "generate_image":
368
  try:
369
+ logging.info("开始执行图片生成")
370
  args = json.loads(tool_call.function.arguments)
371
  # Generate image and get markdown URL
372
+ image_url = ImageService.generate_image(args['prompt'])
 
 
 
373
 
374
  # Get WeChat media_id
375
  media_id = ImageService.get_media_id(image_url)
 
385
  "media_id": media_id
386
  }
387
  except Exception as e:
388
+ logging.error(f"图片生成过程失败: {str(e)}")
389
  return {
390
  "type": "text",
391
  "content": f"抱歉,图片生成失败:{str(e)}",
 
393
  }
394
 
395
  # Handle normal text response
396
+ logging.info("处理普通文本响应")
397
  response_content = completion.choices[0].message.content
398
  messages.append({
399
  "role": "assistant",
 
410
 
411
  def handle_async_task(session, task_id, messages):
412
  try:
413
+ logging.info(f"开始处理异步任务: {task_id}")
414
  if task_id not in session.response_queue:
415
  return
416
 
417
  result = process_ai_response(messages)
418
+ logging.info(f"异步任务处理完成: {task_id}")
419
 
420
  if task_id in session.response_queue and not session.response_queue[task_id].is_expired():
421
  session.response_queue[task_id].status = "completed"
 
423
  session.response_queue[task_id].response_type = result.get("type")
424
  session.response_queue[task_id].media_id = result.get("media_id")
425
  except Exception as e:
426
+ logging.error(f"异步任务处理失败: {str(e)}")
427
  if task_id in session.response_queue:
428
  session.response_queue[task_id].status = "failed"
429
  session.response_queue[task_id].error = str(e)
 
564
  encrypt_type=encrypt_type
565
  )
566
 
567
+ # Regular message processing
568
+ logging.info("准备开始处理用户消息")
569
  session.messages.append({"role": "user", "content": user_content})
570
 
571
  task_id = str(uuid.uuid4())
572
  session.current_task = task_id
573
  session.response_queue[task_id] = AsyncResponse()
574
 
575
+ # Submit task to executor
576
+ logging.info(f"提交任务到执行器: {task_id}")
577
+ executor.submit(handle_async_task, session, task_id, session.messages.copy())
578
 
579
+ # Return immediate response
580
+ initial_response = generate_response_xml(
581
  from_user,
582
  to_user,
583
  append_status_message(generate_initial_response(), is_processing=True),
584
  encrypt_type=encrypt_type
585
  )
586
+ logging.info("返回初始响应给用户")
587
+ return initial_response
588
 
589
  except Exception as e:
590
  logging.error(f"处理请求时出错: {str(e)}")