forked from zovos/bot_tg
feat: multi-user awareness in chat, per-user /talk prompt, thinking tokens for /talk
This commit is contained in:
parent
acb7421cc0
commit
89a14f2ebf
1 changed files with 29 additions and 4 deletions
|
|
@ -41,6 +41,8 @@ SUMMARY_LINE_CHAR_LIMIT = 220
|
|||
HISTORY_LINE_CHAR_LIMIT = 450
|
||||
RETRY_MIN_MAX_TOKENS = 512
|
||||
RETRY_MAX_MAX_TOKENS = 1_024
|
||||
TALK_MAX_TOKENS = 1536
|
||||
TALK_THINKING_BUDGET = 1024
|
||||
|
||||
REPLY_RULES = {
|
||||
"mention": {"cooldown": 25, "min_user_messages": 1},
|
||||
|
|
@ -128,10 +130,21 @@ BOT_STYLE_PROMPT = (
|
|||
|
||||
SYSTEM_PROMPT = (
|
||||
f"{BOT_STYLE_PROMPT}\n\n"
|
||||
"Ты отвечаешь как живой участник одного Telegram-чата. "
|
||||
"Ты отвечаешь как живой участник Telegram-чата с несколькими разными людьми. "
|
||||
"Сообщения в истории записаны в формате «Имя: текст» — каждое имя это отдельный человек, не путай их. "
|
||||
"Отвечай тому, кто написал последним, учитывай контекст именно его сообщений. "
|
||||
"Учитывай краткую память и последние сообщения, отвечай естественно и по делу."
|
||||
)
|
||||
|
||||
TALK_SYSTEM_PROMPT = (
|
||||
f"{BOT_STYLE_PROMPT}\n\n"
|
||||
"Ты ведёшь личный разговор тет-а-тет с одним конкретным человеком через /talk. "
|
||||
"Помни всё, что он говорил раньше — ты видишь историю этого разговора и должен её учитывать. "
|
||||
"Замечай если человек продолжает старую тему или переходит к новой. "
|
||||
"Отвечай КОРОТКО: 1–3 предложения максимум. "
|
||||
"Только если тебя прямо попросили объяснить, развернуть или написать подробно — тогда можно больше."
|
||||
)
|
||||
|
||||
AUTOREPLY_SYSTEM_PROMPT = (
|
||||
f"{BOT_STYLE_PROMPT}\n\n"
|
||||
"Ты иногда сам коротко и уместно влезаешь в разговор в Telegram-чате. "
|
||||
|
|
@ -533,6 +546,7 @@ async def _call_single_model(
|
|||
temperature: float,
|
||||
top_p: float,
|
||||
disable_thinking: bool,
|
||||
reasoning_budget: int = 0,
|
||||
) -> str:
|
||||
url = f"{api_url.rstrip('/')}/v1/chat/completions"
|
||||
headers = {"Content-Type": "application/json"}
|
||||
|
|
@ -551,6 +565,8 @@ async def _call_single_model(
|
|||
"reasoning_format": "none",
|
||||
"chat_template_kwargs": {"enable_thinking": False, "thinking": False},
|
||||
})
|
||||
elif reasoning_budget > 0:
|
||||
payload["reasoning_budget"] = reasoning_budget
|
||||
timeout = aiohttp.ClientTimeout(total=120)
|
||||
async with aiohttp.ClientSession(timeout=timeout) as session:
|
||||
async with session.post(url, json=payload, headers=headers) as resp:
|
||||
|
|
@ -582,7 +598,7 @@ async def _call_single_model(
|
|||
messages,
|
||||
api_url=api_url, api_key=api_key, model=model,
|
||||
max_tokens=retry_max_tokens, temperature=temperature, top_p=top_p,
|
||||
disable_thinking=True,
|
||||
disable_thinking=True, reasoning_budget=0,
|
||||
)
|
||||
return cleaned_content
|
||||
|
||||
|
|
@ -594,6 +610,7 @@ async def _call_llm(
|
|||
temperature: float,
|
||||
top_p: float,
|
||||
disable_thinking: bool | None = None,
|
||||
reasoning_budget: int = 0,
|
||||
) -> str:
|
||||
disable_thinking = FORCE_DISABLE_THINKING if disable_thinking is None else disable_thinking
|
||||
|
||||
|
|
@ -606,6 +623,7 @@ async def _call_llm(
|
|||
temperature=temperature,
|
||||
top_p=top_p,
|
||||
disable_thinking=disable_thinking,
|
||||
reasoning_budget=reasoning_budget,
|
||||
)
|
||||
|
||||
# Если основная модель не смогла ответить — пробуем fallback
|
||||
|
|
@ -622,6 +640,7 @@ async def _call_llm(
|
|||
temperature=temperature,
|
||||
top_p=top_p,
|
||||
disable_thinking=disable_thinking,
|
||||
reasoning_budget=reasoning_budget,
|
||||
)
|
||||
if fallback_result:
|
||||
return f"{fallback_result}\n\n<i>🤖 {fallback_model}</i>"
|
||||
|
|
@ -696,6 +715,8 @@ async def _generate_response(
|
|||
max_tokens: int,
|
||||
temperature: float,
|
||||
top_p: float,
|
||||
disable_thinking: bool | None = None,
|
||||
reasoning_budget: int = 0,
|
||||
) -> str:
|
||||
await _maybe_refresh_summary(chat_id, user_id=user_id)
|
||||
if current_content is None:
|
||||
|
|
@ -721,6 +742,8 @@ async def _generate_response(
|
|||
max_tokens=max_tokens,
|
||||
temperature=temperature,
|
||||
top_p=top_p,
|
||||
disable_thinking=disable_thinking,
|
||||
reasoning_budget=reasoning_budget,
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -1040,11 +1063,13 @@ async def handle_talk(message: Message) -> None:
|
|||
await message.bot.send_chat_action(chat_id=chat_id, action="typing")
|
||||
response = await _generate_response(
|
||||
chat_id,
|
||||
system_prompt=SYSTEM_PROMPT,
|
||||
system_prompt=TALK_SYSTEM_PROMPT,
|
||||
user_id=user_id,
|
||||
max_tokens=768,
|
||||
max_tokens=TALK_MAX_TOKENS,
|
||||
temperature=0.7,
|
||||
top_p=0.95,
|
||||
disable_thinking=False,
|
||||
reasoning_budget=TALK_THINKING_BUDGET,
|
||||
)
|
||||
except Exception:
|
||||
logger.exception("Talk command generation failed")
|
||||
|
|
|
|||
Loading…
Reference in a new issue