add typing simulation
This commit is contained in:
@@ -6,7 +6,6 @@ from typing import Any
|
||||
from zoneinfo import ZoneInfo
|
||||
|
||||
from telegram import Update
|
||||
from telegram.constants import ChatAction
|
||||
from telegram.ext import ContextTypes
|
||||
|
||||
from .ai import AIClientError
|
||||
@@ -16,16 +15,14 @@ from .prompts import ASSISTANT_SYSTEM_PROMPT
|
||||
from .reminders import parse_reminder
|
||||
from .storage import AssistantStorage
|
||||
from .telegram_utils import (
|
||||
edit_markdown,
|
||||
edit_or_reply,
|
||||
escape_markdown_text,
|
||||
get_ai_client,
|
||||
get_storage,
|
||||
get_tz,
|
||||
markdown_code,
|
||||
parse_positive_int,
|
||||
reply_markdown,
|
||||
require_user_id,
|
||||
typing_action,
|
||||
)
|
||||
from .time_utils import format_local_dt, to_utc_iso, utc_now
|
||||
|
||||
@@ -435,92 +432,81 @@ async def run_agent_prompt(
|
||||
{"role": "user", "content": prompt},
|
||||
]
|
||||
|
||||
await context.bot.send_chat_action(
|
||||
chat_id=chat_id,
|
||||
action=ChatAction.TYPING,
|
||||
)
|
||||
placeholder = await reply_markdown(
|
||||
update.effective_message,
|
||||
f"💭 *Думаю через {escape_markdown_text(ai_client.display_name)} / "
|
||||
f"{markdown_code(model)}…*",
|
||||
)
|
||||
|
||||
try:
|
||||
last_tool_results: list[dict[str, Any]] = []
|
||||
reset_context = False
|
||||
for _step in range(MAX_AGENT_STEPS):
|
||||
raw_answer = await ai_client.chat(model, messages, json_mode=True)
|
||||
decision = parse_agent_decision(raw_answer)
|
||||
reset_context = reset_context or decision.reset_context
|
||||
final_answer: str | None = None
|
||||
|
||||
if decision.tool_calls:
|
||||
tool_results = []
|
||||
for call in decision.tool_calls:
|
||||
result = execute_agent_tool(
|
||||
name=str(call.get("name", "")),
|
||||
arguments=call.get("arguments", {}),
|
||||
storage=storage,
|
||||
user_id=user_id,
|
||||
chat_id=chat_id,
|
||||
tz=tz,
|
||||
)
|
||||
tool_results.append(
|
||||
async with typing_action(context.bot, chat_id):
|
||||
for _step in range(MAX_AGENT_STEPS):
|
||||
raw_answer = await ai_client.chat(model, messages, json_mode=True)
|
||||
decision = parse_agent_decision(raw_answer)
|
||||
reset_context = reset_context or decision.reset_context
|
||||
|
||||
if decision.tool_calls:
|
||||
tool_results = []
|
||||
for call in decision.tool_calls:
|
||||
result = execute_agent_tool(
|
||||
name=str(call.get("name", "")),
|
||||
arguments=call.get("arguments", {}),
|
||||
storage=storage,
|
||||
user_id=user_id,
|
||||
chat_id=chat_id,
|
||||
tz=tz,
|
||||
)
|
||||
tool_results.append(
|
||||
{
|
||||
"name": call.get("name"),
|
||||
"arguments": call.get("arguments", {}),
|
||||
"result": result,
|
||||
}
|
||||
)
|
||||
|
||||
last_tool_results = tool_results
|
||||
messages.append(
|
||||
{
|
||||
"name": call.get("name"),
|
||||
"arguments": call.get("arguments", {}),
|
||||
"result": result,
|
||||
"role": "assistant",
|
||||
"content": json_dumps(
|
||||
{"tool_calls": decision.tool_calls}
|
||||
),
|
||||
}
|
||||
)
|
||||
messages.append(
|
||||
{
|
||||
"role": "user",
|
||||
"content": (
|
||||
"Результаты tools:\n"
|
||||
f"{json_dumps({'tool_results': tool_results})}\n"
|
||||
"Продолжи. Верни либо следующий tool_calls, либо final. "
|
||||
"Ответ снова строго JSON."
|
||||
),
|
||||
}
|
||||
)
|
||||
continue
|
||||
|
||||
last_tool_results = tool_results
|
||||
messages.append(
|
||||
{
|
||||
"role": "assistant",
|
||||
"content": json_dumps({"tool_calls": decision.tool_calls}),
|
||||
}
|
||||
if decision.final:
|
||||
final_answer = decision.final
|
||||
break
|
||||
|
||||
messages.append({"role": "assistant", "content": raw_answer})
|
||||
|
||||
if final_answer is None:
|
||||
final_answer = await ai_client.chat(
|
||||
model,
|
||||
[
|
||||
*messages,
|
||||
{
|
||||
"role": "user",
|
||||
"content": (
|
||||
"Лимит tool-шагов исчерпан. Больше не вызывай tools. "
|
||||
f"Последние результаты tools: {json_dumps(last_tool_results)}. "
|
||||
"Сформулируй короткий финальный ответ пользователю обычным Markdown."
|
||||
),
|
||||
},
|
||||
],
|
||||
)
|
||||
messages.append(
|
||||
{
|
||||
"role": "user",
|
||||
"content": (
|
||||
"Результаты tools:\n"
|
||||
f"{json_dumps({'tool_results': tool_results})}\n"
|
||||
"Продолжи. Верни либо следующий tool_calls, либо final. "
|
||||
"Ответ снова строго JSON."
|
||||
),
|
||||
}
|
||||
)
|
||||
continue
|
||||
|
||||
if decision.final:
|
||||
await edit_or_reply(placeholder, decision.final)
|
||||
save_conversation_exchange(
|
||||
storage,
|
||||
user_id,
|
||||
chat_id,
|
||||
prompt,
|
||||
decision.final,
|
||||
reset_context,
|
||||
)
|
||||
return
|
||||
|
||||
messages.append({"role": "assistant", "content": raw_answer})
|
||||
|
||||
final_answer = await ai_client.chat(
|
||||
model,
|
||||
[
|
||||
*messages,
|
||||
{
|
||||
"role": "user",
|
||||
"content": (
|
||||
"Лимит tool-шагов исчерпан. Больше не вызывай tools. "
|
||||
f"Последние результаты tools: {json_dumps(last_tool_results)}. "
|
||||
"Сформулируй короткий финальный ответ пользователю обычным Markdown."
|
||||
),
|
||||
},
|
||||
],
|
||||
)
|
||||
await edit_or_reply(placeholder, final_answer)
|
||||
await reply_markdown(update.effective_message, final_answer)
|
||||
save_conversation_exchange(
|
||||
storage,
|
||||
user_id,
|
||||
@@ -536,8 +522,8 @@ async def run_agent_prompt(
|
||||
hint = (
|
||||
"Проверь YANDEX_CLOUD_FOLDER, YC_API_KEY и доступ к выбранной модели."
|
||||
)
|
||||
await edit_markdown(
|
||||
placeholder,
|
||||
await reply_markdown(
|
||||
update.effective_message,
|
||||
f"⚠️ **Не получилось вызвать "
|
||||
f"{escape_markdown_text(ai_client.display_name)}.**\n\n"
|
||||
f"{escape_markdown_text(exc)}\n\n"
|
||||
@@ -546,8 +532,8 @@ async def run_agent_prompt(
|
||||
return
|
||||
except Exception:
|
||||
logger.exception("Failed to run AI prompt")
|
||||
await edit_markdown(
|
||||
placeholder,
|
||||
await reply_markdown(
|
||||
update.effective_message,
|
||||
"⚠️ **Произошла внутренняя ошибка** при запросе к модели.",
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user