Update app.py
Browse files
app.py
CHANGED
@@ -2,10 +2,8 @@ import os
|
|
2 |
import json
|
3 |
import requests
|
4 |
from flask import Flask, request, jsonify
|
5 |
-
from datetime import datetime
|
6 |
import asyncio
|
7 |
-
import re
|
8 |
-
from urllib.parse import quote
|
9 |
|
10 |
app = Flask(__name__)
|
11 |
|
@@ -14,7 +12,6 @@ AI_API_ENDPOINT = os.environ.get('AI_API_ENDPOINT')
|
|
14 |
AI_API_KEY = os.environ.get('AI_API_KEY')
|
15 |
AI_MODEL = os.environ.get('AI_MODEL')
|
16 |
PHP_PROXY_URL = os.environ.get('PHP_PROXY_URL')
|
17 |
-
SEARXNG_URL = os.environ.get('SEARXNG_URL', 'https://sousuo.emoe.top') # 使用环境变量,默认值
|
18 |
|
19 |
if not all([TELEGRAM_BOT_TOKEN, AI_API_ENDPOINT, AI_API_KEY, AI_MODEL]):
|
20 |
raise ValueError("请设置所有必要的环境变量")
|
@@ -55,68 +52,6 @@ BOT_COMMANDS = [
|
|
55 |
]
|
56 |
DEFAULT_TEMP = 1.5
|
57 |
|
58 |
-
TOOLS = [
|
59 |
-
{
|
60 |
-
"type": "function",
|
61 |
-
"function": {
|
62 |
-
"name": "get_current_datetime",
|
63 |
-
"description": "获取当前的日期和时间",
|
64 |
-
"parameters": {
|
65 |
-
"type": "object",
|
66 |
-
"properties": {},
|
67 |
-
"required": []
|
68 |
-
}
|
69 |
-
}
|
70 |
-
},
|
71 |
-
{
|
72 |
-
"type": "function",
|
73 |
-
"function": {
|
74 |
-
"name": "search_with_searxng",
|
75 |
-
"description": "使用 Searxng 搜索信息,并返回搜索结果的摘要",
|
76 |
-
"parameters": {
|
77 |
-
"type": "object",
|
78 |
-
"properties": {
|
79 |
-
"query": {
|
80 |
-
"type": "string",
|
81 |
-
"description": "要搜索的关键词"
|
82 |
-
}
|
83 |
-
},
|
84 |
-
"required": ["query"]
|
85 |
-
}
|
86 |
-
}
|
87 |
-
}
|
88 |
-
]
|
89 |
-
|
90 |
-
def get_current_datetime():
|
91 |
-
utc_time = datetime.now(timezone.utc)
|
92 |
-
local_time = utc_time.astimezone(timezone(timedelta(hours=8)))
|
93 |
-
return local_time.strftime("%Y-%m-%d %H:%M:%S")
|
94 |
-
|
95 |
-
def search_with_searxng(query):
|
96 |
-
"""使用 Searxng 搜索信息,并返回搜索结果的摘要"""
|
97 |
-
try:
|
98 |
-
search_url = f"{SEARXNG_URL}/search?q={quote(query)}&format=json"
|
99 |
-
response = requests.get(search_url)
|
100 |
-
response.raise_for_status()
|
101 |
-
results = response.json().get('results', [])
|
102 |
-
if results:
|
103 |
-
# 提取标题和链接,返回格式化的结果
|
104 |
-
formatted_results = []
|
105 |
-
for result in results:
|
106 |
-
title = result.get('title', '无标题')
|
107 |
-
url = result.get('url', '无链接')
|
108 |
-
formatted_results.append(f"- [{title}]({url})")
|
109 |
-
return "\n".join(formatted_results)
|
110 |
-
else:
|
111 |
-
return "没有找到相关的搜索结果。"
|
112 |
-
except requests.exceptions.RequestException as e:
|
113 |
-
print(f"Searxng 请求失败: {e}")
|
114 |
-
return "搜索请求失败,请稍后再试。"
|
115 |
-
except Exception as e:
|
116 |
-
print(f"处理搜索结果时发生错误:{e}")
|
117 |
-
return "处理搜索结果时发生错误。"
|
118 |
-
|
119 |
-
|
120 |
def make_telegram_request(method, data=None):
|
121 |
url = f"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/{method}"
|
122 |
if PHP_PROXY_URL:
|
@@ -247,6 +182,7 @@ def parseCommand(userMessage):
|
|
247 |
command = command.split('@')[0]
|
248 |
return command[1:]
|
249 |
|
|
|
250 |
async def handlePrivateCommand(chatId, userMessage, fromUserId, isGroupChat):
|
251 |
command = parseCommand(userMessage)
|
252 |
if userMessage.startswith('/settemp '):
|
@@ -298,7 +234,7 @@ async def processAiMessage(chatId, userMessage, fromUserId, message_id):
|
|
298 |
{'role': 'system', 'content': currentPrompt},
|
299 |
*history
|
300 |
]
|
301 |
-
|
302 |
thinking_message = await sendTelegramMessage(chatId, "正在思考,请等待...", options={'reply_to_message_id': message_id})
|
303 |
thinking_message_id = thinking_message.get('result', {}).get('message_id')
|
304 |
|
@@ -308,11 +244,10 @@ async def processAiMessage(chatId, userMessage, fromUserId, message_id):
|
|
308 |
'messages': messages,
|
309 |
'max_tokens': MAX_TOKENS,
|
310 |
'temperature': userTemp,
|
311 |
-
'tools': TOOLS,
|
312 |
})
|
313 |
ai_response.raise_for_status()
|
314 |
ai_data = ai_response.json()
|
315 |
-
ai_reply = await handleAiResponse(ai_data, chatId, history
|
316 |
|
317 |
history.append({'role': 'assistant', 'content': ai_reply})
|
318 |
chatHistories[chatId] = history
|
@@ -325,78 +260,11 @@ async def processAiMessage(chatId, userMessage, fromUserId, message_id):
|
|
325 |
print(f'处理消息时发生错误: {error}')
|
326 |
await editTelegramMessage(chatId, thinking_message_id, '处理消息时发生错误,请稍后再试')
|
327 |
|
328 |
-
async def handleAiResponse(ai_data, chatId, history
|
329 |
if ai_data and ai_data.get('choices') and len(ai_data['choices']) > 0:
|
330 |
choice = ai_data['choices'][0]
|
331 |
-
if choice.get('message'):
|
332 |
-
|
333 |
-
if message.get('tool_calls'):
|
334 |
-
tool_call = message['tool_calls'][0]
|
335 |
-
function_name = tool_call['function']['name']
|
336 |
-
|
337 |
-
if function_name == 'get_current_datetime':
|
338 |
-
current_datetime = get_current_datetime()
|
339 |
-
history.append({
|
340 |
-
'tool_call_id': tool_call['id'],
|
341 |
-
'role': 'tool',
|
342 |
-
'name': function_name,
|
343 |
-
'content': current_datetime,
|
344 |
-
})
|
345 |
-
messages = [
|
346 |
-
{'role': 'system', 'content': PROMPT_TEMPLATES.get(USER_SETTINGS.get(chatId, {}).get('prompt_index', CURRENT_PROMPT_INDEX), "")},
|
347 |
-
*history
|
348 |
-
]
|
349 |
-
|
350 |
-
try:
|
351 |
-
ai_response = requests.post(AI_API_ENDPOINT, headers=AI_API_HEADERS, json={
|
352 |
-
'model': AI_MODEL,
|
353 |
-
'messages': messages,
|
354 |
-
'max_tokens': MAX_TOKENS,
|
355 |
-
'temperature': USER_SETTINGS.get(chatId, {}).get('temperature', DEFAULT_TEMP),
|
356 |
-
'tools': TOOLS,
|
357 |
-
})
|
358 |
-
ai_response.raise_for_status()
|
359 |
-
ai_data = ai_response.json()
|
360 |
-
return await handleAiResponse(ai_data, chatId, history, thinking_message_id)
|
361 |
-
except requests.exceptions.RequestException as e:
|
362 |
-
print(f'AI API 响应失败: {e}')
|
363 |
-
await editTelegramMessage(chatId, thinking_message_id, 'AI API 响应失败,请稍后再试')
|
364 |
-
return 'AI API 响应失败,请稍后再试'
|
365 |
-
elif function_name == 'search_with_searxng':
|
366 |
-
query = tool_call['function']['arguments']['query']
|
367 |
-
search_results = search_with_searxng(query)
|
368 |
-
history.append({
|
369 |
-
'tool_call_id': tool_call['id'],
|
370 |
-
'role': 'tool',
|
371 |
-
'name': function_name,
|
372 |
-
'content': search_results,
|
373 |
-
})
|
374 |
-
messages = [
|
375 |
-
{'role': 'system', 'content': PROMPT_TEMPLATES.get(USER_SETTINGS.get(chatId, {}).get('prompt_index', CURRENT_PROMPT_INDEX), "")},
|
376 |
-
*history
|
377 |
-
]
|
378 |
-
|
379 |
-
try:
|
380 |
-
ai_response = requests.post(AI_API_ENDPOINT, headers=AI_API_HEADERS, json={
|
381 |
-
'model': AI_MODEL,
|
382 |
-
'messages': messages,
|
383 |
-
'max_tokens': MAX_TOKENS,
|
384 |
-
'temperature': USER_SETTINGS.get(chatId, {}).get('temperature', DEFAULT_TEMP),
|
385 |
-
'tools': TOOLS,
|
386 |
-
})
|
387 |
-
ai_response.raise_for_status()
|
388 |
-
ai_data = ai_response.json()
|
389 |
-
return await handleAiResponse(ai_data, chatId, history, thinking_message_id)
|
390 |
-
except requests.exceptions.RequestException as e:
|
391 |
-
print(f'AI API 响应失败: {e}')
|
392 |
-
await editTelegramMessage(chatId, thinking_message_id, 'AI API 响应失败,请稍后再试')
|
393 |
-
return 'AI API 响应失败,请稍后再试'
|
394 |
-
|
395 |
-
else:
|
396 |
-
return '不支持的工具调用'
|
397 |
-
elif message.get('content'):
|
398 |
-
return message['content']
|
399 |
-
|
400 |
return 'AI 返回了无法识别的格式'
|
401 |
|
402 |
async def handleCallbackQuery(callbackQuery):
|
@@ -450,7 +318,6 @@ async def editTelegramMessage(chatId, message_id, text, options={}):
|
|
450 |
except requests.exceptions.RequestException as e:
|
451 |
print(f'编辑 Telegram 消息失败: {e}')
|
452 |
|
453 |
-
|
454 |
def getHelpMessage():
|
455 |
return f"""
|
456 |
可用指令:
|
|
|
2 |
import json
|
3 |
import requests
|
4 |
from flask import Flask, request, jsonify
|
5 |
+
from datetime import datetime
|
6 |
import asyncio
|
|
|
|
|
7 |
|
8 |
app = Flask(__name__)
|
9 |
|
|
|
12 |
AI_API_KEY = os.environ.get('AI_API_KEY')
|
13 |
AI_MODEL = os.environ.get('AI_MODEL')
|
14 |
PHP_PROXY_URL = os.environ.get('PHP_PROXY_URL')
|
|
|
15 |
|
16 |
if not all([TELEGRAM_BOT_TOKEN, AI_API_ENDPOINT, AI_API_KEY, AI_MODEL]):
|
17 |
raise ValueError("请设置所有必要的环境变量")
|
|
|
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:
|
|
|
182 |
command = command.split('@')[0]
|
183 |
return command[1:]
|
184 |
|
185 |
+
|
186 |
async def handlePrivateCommand(chatId, userMessage, fromUserId, isGroupChat):
|
187 |
command = parseCommand(userMessage)
|
188 |
if userMessage.startswith('/settemp '):
|
|
|
234 |
{'role': 'system', 'content': currentPrompt},
|
235 |
*history
|
236 |
]
|
237 |
+
|
238 |
thinking_message = await sendTelegramMessage(chatId, "正在思考,请等待...", options={'reply_to_message_id': message_id})
|
239 |
thinking_message_id = thinking_message.get('result', {}).get('message_id')
|
240 |
|
|
|
244 |
'messages': messages,
|
245 |
'max_tokens': MAX_TOKENS,
|
246 |
'temperature': userTemp,
|
|
|
247 |
})
|
248 |
ai_response.raise_for_status()
|
249 |
ai_data = ai_response.json()
|
250 |
+
ai_reply = await handleAiResponse(ai_data, chatId, history)
|
251 |
|
252 |
history.append({'role': 'assistant', 'content': ai_reply})
|
253 |
chatHistories[chatId] = history
|
|
|
260 |
print(f'处理消息时发生错误: {error}')
|
261 |
await editTelegramMessage(chatId, thinking_message_id, '处理消息时发生错误,请稍后再试')
|
262 |
|
263 |
+
async def handleAiResponse(ai_data, chatId, history):
|
264 |
if ai_data and ai_data.get('choices') and len(ai_data['choices']) > 0:
|
265 |
choice = ai_data['choices'][0]
|
266 |
+
if choice.get('message') and choice['message'].get('content'):
|
267 |
+
return choice['message']['content']
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
268 |
return 'AI 返回了无法识别的格式'
|
269 |
|
270 |
async def handleCallbackQuery(callbackQuery):
|
|
|
318 |
except requests.exceptions.RequestException as e:
|
319 |
print(f'编辑 Telegram 消息失败: {e}')
|
320 |
|
|
|
321 |
def getHelpMessage():
|
322 |
return f"""
|
323 |
可用指令:
|