yangtb24 commited on
Commit
ed7afc1
·
verified ·
1 Parent(s): 898e5e9

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +20 -210
app.py CHANGED
@@ -4,7 +4,6 @@ import requests
4
  from flask import Flask, request, jsonify
5
  from datetime import datetime
6
  import asyncio
7
- import aiohttp
8
 
9
  app = Flask(__name__)
10
 
@@ -53,69 +52,7 @@ BOT_COMMANDS = [
53
  ]
54
  DEFAULT_TEMP = 1.5
55
 
56
- TOOL_DEFINITIONS = [
57
- {
58
- "type": "function",
59
- "function": {
60
- "name": "get_current_time",
61
- "description": "获取当前时间",
62
- "parameters": {
63
- "type": "object",
64
- "properties": {},
65
- "required": []
66
- }
67
- }
68
- },
69
- {
70
- "type": "function",
71
- "function": {
72
- "name": "get_current_date",
73
- "description": "获取当前日期",
74
- "parameters": {
75
- "type": "object",
76
- "properties": {},
77
- "required": []
78
- }
79
- }
80
- },
81
- {
82
- "type": "function",
83
- "function": {
84
- "name": "web_scrape",
85
- "description": "从提供的 URL 中抓取内容并返回摘要。",
86
- "parameters": {
87
- "type": "object",
88
- "properties": {
89
- "urls": {
90
- "type": "array",
91
- "items": {"type": "string"},
92
- "description": "要抓取的 URL 列表,每个 URL 必须包含 http 或 https。",
93
- },
94
- },
95
- "required": ["urls"],
96
- },
97
- },
98
- },
99
- ]
100
-
101
- class EventEmitter:
102
- def __init__(self, event_emitter=None):
103
- self.event_emitter = event_emitter
104
-
105
- async def emit(self, event_type, data):
106
- if self.event_emitter:
107
- await self.event_emitter(type=event_type, data=data)
108
-
109
- async def update_status(self, description, done, action, urls):
110
- await self.emit('status', {'done': done, 'action': action, 'description': description, 'urls': urls})
111
-
112
- async def send_citation(self, title, url, content):
113
- await self.emit('citation', {
114
- 'document': [content],
115
- 'metadata': [{'name': title, 'source': url, 'html': False}],
116
- })
117
-
118
- async def make_telegram_request(method, data=None):
119
  url = f"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/{method}"
120
  if PHP_PROXY_URL:
121
  method_name = url.split('/')[-1]
@@ -124,11 +61,10 @@ async def make_telegram_request(method, data=None):
124
  if data:
125
  data = json.dumps(data)
126
  try:
127
- async with aiohttp.ClientSession() as session:
128
- async with session.post(url, headers=headers, data=data) as response:
129
- response.raise_for_status()
130
- return await response.json()
131
- except aiohttp.ClientError as e:
132
  print(f"Telegram request failed: {e}")
133
  return None
134
  except json.JSONDecodeError as e:
@@ -145,13 +81,13 @@ async def setBotCommands():
145
  set_url = f"{PHP_PROXY_URL}{set_method_name}"
146
 
147
  try:
148
- delete_response = await make_telegram_request('deleteMyCommands')
149
  if delete_response:
150
  print('Telegram 命令删除成功')
151
  else:
152
  print('Telegram 命令删除失败')
153
 
154
- set_response = await make_telegram_request('setMyCommands', {"commands": BOT_COMMANDS})
155
  if set_response:
156
  print('Telegram 命令设置成功')
157
  else:
@@ -270,13 +206,6 @@ def parseCommand(userMessage):
270
  command = command.split('@')[0]
271
  return command[1:]
272
 
273
- async def event_handler(event):
274
- print('Event:', event)
275
- if event.get('type') == 'status':
276
- await sendTelegramMessage(event['data']['chatId'], f"状态更新: {event['data']['description']}")
277
- elif event.get('type') == 'citation':
278
- await sendTelegramMessage(event['data']['chatId'], f"引用信息: {event['data']['metadata'][0]['name']}")
279
-
280
  async def processAiMessage(chatId, userMessage, fromUserId):
281
  history = chatHistories.get(chatId, [])
282
  userTemp = USER_SETTINGS.get(fromUserId, {}).get('temperature', DEFAULT_TEMP)
@@ -290,154 +219,36 @@ async def processAiMessage(chatId, userMessage, fromUserId):
290
  {'role': 'system', 'content': currentPrompt},
291
  *history
292
  ]
293
-
294
- eventEmitter = EventEmitter(event_handler)
295
 
296
  try:
297
- async with aiohttp.ClientSession() as session:
298
- async with session.post(AI_API_ENDPOINT, headers=AI_API_HEADERS, json={
299
  'model': AI_MODEL,
300
  'messages': messages,
301
  'max_tokens': MAX_TOKENS,
302
  'temperature': userTemp,
303
- 'tools': TOOL_DEFINITIONS
304
- }) as ai_response:
305
- ai_response.raise_for_status()
306
- ai_data = await ai_response.json()
307
- ai_reply = await handleAiResponse(ai_data, chatId, history, eventEmitter)
308
 
309
- history.append({'role': 'assistant', 'content': ai_reply})
310
- chatHistories[chatId] = history
311
 
312
- await sendTelegramMessage(chatId, ai_reply)
313
- except aiohttp.ClientError as e:
314
  print(f'AI API 响应失败: {e}')
315
  await sendTelegramMessage(chatId, 'AI API 响应失败,请稍后再试')
316
  except Exception as error:
317
  print(f'处理消息时发生错误: {error}')
318
  await sendTelegramMessage(chatId, '处理消息时发生错误,请稍后再试')
319
 
320
- async def handleAiResponse(ai_data, chatId, history, eventEmitter):
321
  if ai_data and ai_data.get('choices') and len(ai_data['choices']) > 0:
322
  choice = ai_data['choices'][0]
323
  if choice.get('message') and choice['message'].get('content'):
324
  return choice['message']['content']
325
- elif choice.get('message') and choice['message'].get('tool_calls'):
326
- toolCalls = choice['message']['tool_calls']
327
- toolResults = []
328
- for toolCall in toolCalls:
329
- toolResult = await executeToolCall(toolCall, eventEmitter,chatId)
330
- toolResults.append(toolResult)
331
-
332
- newMessages = [
333
- *history,
334
- {'role': "assistant", 'content': None, 'tool_calls': toolCalls},
335
- *toolResults,
336
- ]
337
- async with aiohttp.ClientSession() as session:
338
- async with session.post(AI_API_ENDPOINT, headers=AI_API_HEADERS, json={
339
- 'model': AI_MODEL,
340
- 'messages': newMessages,
341
- 'max_tokens': MAX_TOKENS,
342
- 'temperature': USER_SETTINGS.get(chatId, {}).get('temperature', DEFAULT_TEMP)
343
- }) as ai_response:
344
- ai_response.raise_for_status()
345
- ai_data = await ai_response.json()
346
- if ai_data and ai_data.get('choices') and len(ai_data['choices']) > 0 and ai_data['choices'][0].get('message') and ai_data['choices'][0]['message'].get('content'):
347
- return ai_data['choices'][0]['message']['content']
348
- return 'AI 返回了无法识别的格式'
349
  return 'AI 返回了无法识别的格式'
350
 
351
- async def executeToolCall(toolCall, eventEmitter,chatId):
352
- name = toolCall['function']['name']
353
- args = toolCall['function'].get('arguments', {})
354
-
355
- if name == 'web_scrape':
356
- urls = args.get('urls', [])
357
- if not urls or not isinstance(urls, list) or len(urls) == 0:
358
- return {
359
- 'tool_call_id': toolCall['id'],
360
- 'role': "tool",
361
- 'name': name,
362
- 'content': '请提供有效的 URL 列表。',
363
- }
364
- api_url = "https://gpts.webpilot.ai/api/read"
365
- headers = { "Content-Type": "application/json", "WebPilot-Friend-UID": "0" }
366
-
367
- await eventEmitter.update_status(
368
- f"开始读取 {len(urls)} 个网页",
369
- False,
370
- "web_search",
371
- urls
372
- )
373
-
374
- async def processUrl(url):
375
- try:
376
- async with aiohttp.ClientSession() as session:
377
- async with session.post(api_url, headers=headers, json={
378
- "link": url,
379
- "ur": "summary of the page",
380
- "lp": True,
381
- "rt": False,
382
- "l": "en",
383
- }) as response:
384
- response.raise_for_status()
385
- result = await response.json()
386
- if result.get('rules'):
387
- del result['rules']
388
- content = json.dumps(result)
389
- title = result.get('title', url)
390
- await eventEmitter.send_citation(title, url, content)
391
- return f"{content}\n"
392
- except aiohttp.ClientError as e:
393
- error_message = f"读取网页 {url} 时出错: {e}"
394
- await eventEmitter.update_status(error_message, False, "web_scrape", [url])
395
- await eventEmitter.send_citation(f"Error from {url}", url, str(e))
396
- return f"URL: {url}\n错误: {error_message}\n"
397
-
398
- results = await asyncio.gather(*[processUrl(url) for url in urls])
399
-
400
- await eventEmitter.update_status(
401
- f"已完成 {len(urls)} 个网页的读取",
402
- True,
403
- "web_search",
404
- urls
405
- )
406
-
407
- return {
408
- 'tool_call_id': toolCall['id'],
409
- 'role': "tool",
410
- 'name': name,
411
- 'content': '\n'.join(results)
412
- }
413
- elif name == 'get_current_time':
414
- now = datetime.utcnow()
415
- utc8_time = now + datetime.timedelta(hours=8)
416
- formatted_time = utc8_time.strftime("%H:%M:%S")
417
- return {
418
- 'tool_call_id': toolCall['id'],
419
- 'role': "tool",
420
- 'name': name,
421
- 'content': f"Current Time: {formatted_time}"
422
- }
423
- elif name == 'get_current_date':
424
- now = datetime.utcnow()
425
- utc8_time = now + datetime.timedelta(hours=8)
426
- formatted_date = utc8_time.strftime("%A, %B %d, %Y")
427
- return {
428
- 'tool_call_id': toolCall['id'],
429
- 'role': "tool",
430
- 'name': name,
431
- 'content': f"Today's date is {formatted_date}"
432
- }
433
- else:
434
- return {
435
- 'tool_call_id': toolCall['id'],
436
- 'role': "tool",
437
- 'name': name,
438
- 'content': '未知的工具调用'
439
- }
440
-
441
  async def handleCallbackQuery(callbackQuery):
442
  chatId = callbackQuery['message']['chat']['id']
443
  data = callbackQuery['data']
@@ -463,10 +274,9 @@ async def sendTelegramMessage(chatId, text, options={}):
463
  **options
464
  }
465
  try:
466
- async with aiohttp.ClientSession() as session:
467
- async with session.post(url, headers={'Content-Type': 'application/json'}, json=data) as response:
468
- response.raise_for_status()
469
- except aiohttp.ClientError as e:
470
  print(f'发送 Telegram 消息失败: {e}')
471
 
472
  def getHelpMessage():
 
4
  from flask import Flask, request, jsonify
5
  from datetime import datetime
6
  import asyncio
 
7
 
8
  app = Flask(__name__)
9
 
 
52
  ]
53
  DEFAULT_TEMP = 1.5
54
 
55
+ def make_telegram_request(method, data=None):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56
  url = f"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/{method}"
57
  if PHP_PROXY_URL:
58
  method_name = url.split('/')[-1]
 
61
  if data:
62
  data = json.dumps(data)
63
  try:
64
+ response = requests.post(url, headers=headers, data=data)
65
+ response.raise_for_status()
66
+ return response.json()
67
+ except requests.exceptions.RequestException as e:
 
68
  print(f"Telegram request failed: {e}")
69
  return None
70
  except json.JSONDecodeError as e:
 
81
  set_url = f"{PHP_PROXY_URL}{set_method_name}"
82
 
83
  try:
84
+ delete_response = make_telegram_request('deleteMyCommands')
85
  if delete_response:
86
  print('Telegram 命令删除成功')
87
  else:
88
  print('Telegram 命令删除失败')
89
 
90
+ set_response = make_telegram_request('setMyCommands', {"commands": BOT_COMMANDS})
91
  if set_response:
92
  print('Telegram 命令设置成功')
93
  else:
 
206
  command = command.split('@')[0]
207
  return command[1:]
208
 
 
 
 
 
 
 
 
209
  async def processAiMessage(chatId, userMessage, fromUserId):
210
  history = chatHistories.get(chatId, [])
211
  userTemp = USER_SETTINGS.get(fromUserId, {}).get('temperature', DEFAULT_TEMP)
 
219
  {'role': 'system', 'content': currentPrompt},
220
  *history
221
  ]
 
 
222
 
223
  try:
224
+ ai_response = requests.post(AI_API_ENDPOINT, headers=AI_API_HEADERS, json={
 
225
  'model': AI_MODEL,
226
  'messages': messages,
227
  'max_tokens': MAX_TOKENS,
228
  'temperature': userTemp,
229
+ })
230
+ ai_response.raise_for_status()
231
+ ai_data = ai_response.json()
232
+ ai_reply = await handleAiResponse(ai_data, chatId, history)
 
233
 
234
+ history.append({'role': 'assistant', 'content': ai_reply})
235
+ chatHistories[chatId] = history
236
 
237
+ await sendTelegramMessage(chatId, ai_reply)
238
+ except requests.exceptions.RequestException as e:
239
  print(f'AI API 响应失败: {e}')
240
  await sendTelegramMessage(chatId, 'AI API 响应失败,请稍后再试')
241
  except Exception as error:
242
  print(f'处理消息时发生错误: {error}')
243
  await sendTelegramMessage(chatId, '处理消息时发生错误,请稍后再试')
244
 
245
+ async def handleAiResponse(ai_data, chatId, history):
246
  if ai_data and ai_data.get('choices') and len(ai_data['choices']) > 0:
247
  choice = ai_data['choices'][0]
248
  if choice.get('message') and choice['message'].get('content'):
249
  return choice['message']['content']
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
250
  return 'AI 返回了无法识别的格式'
251
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
252
  async def handleCallbackQuery(callbackQuery):
253
  chatId = callbackQuery['message']['chat']['id']
254
  data = callbackQuery['data']
 
274
  **options
275
  }
276
  try:
277
+ response = requests.post(url, headers={'Content-Type': 'application/json'}, json=data)
278
+ response.raise_for_status()
279
+ except requests.exceptions.RequestException as e:
 
280
  print(f'发送 Telegram 消息失败: {e}')
281
 
282
  def getHelpMessage():