134 lines
5.5 KiB
Python
134 lines
5.5 KiB
Python
import asyncio, sys, time
|
||
sys.path.insert(0, '.')
|
||
print("[1/3] Импортируем агента (MCP init ~20-60с)...")
|
||
from langchain_core.messages import HumanMessage
|
||
from src.agent.agent import homework_direct_agent
|
||
from src.agent.graph.pipeline import _invoke_with_retry, _get_journal_tool, _parse_text
|
||
print("[2/3] Агент готов, запускаем задание...")
|
||
|
||
# ── Настройки ────────────────────────────────────────────────────────────────
|
||
TASK_ID = "6a1867fa8a94f887e50d52bd" # ← taskId из platform.brojs.ru
|
||
OWNER = "KirillKutlakhmetov"
|
||
REPO = f"task-{TASK_ID}"
|
||
URL = f"https://git.brojs.ru/{OWNER}/{REPO}"
|
||
|
||
# ── Вспомогательные функции ──────────────────────────────────────────────────
|
||
|
||
def _was_submitted(msgs: list) -> bool:
|
||
for m in msgs:
|
||
for tc in getattr(m, "tool_calls", []):
|
||
if "task_submit" in tc.get("name", ""):
|
||
return True
|
||
return False
|
||
|
||
|
||
def _is_rate_limit(e) -> bool:
|
||
full = repr(e)
|
||
if hasattr(e, 'exceptions'):
|
||
full += " ".join(repr(sub) for sub in e.exceptions)
|
||
return "429" in full or "rate" in full.lower()
|
||
|
||
|
||
def _is_not_found(e) -> bool:
|
||
full = repr(e)
|
||
if hasattr(e, 'exceptions'):
|
||
full += " ".join(repr(sub) for sub in e.exceptions)
|
||
return "not found" in full.lower() or "submission" in full.lower()
|
||
|
||
|
||
async def _force_submit(task_id: str):
|
||
"""Страховка: сдаёт задание если агент не сделал этого сам."""
|
||
task_get = _get_journal_tool("task_get")
|
||
update = _get_journal_tool("task_update_answer")
|
||
submit = _get_journal_tool("task_submit")
|
||
|
||
if not update or not submit:
|
||
print("[!] journal-инструменты недоступны — сдать не удалось")
|
||
return
|
||
|
||
# Сначала вызываем task_get — это инициализирует submission если его нет
|
||
if task_get:
|
||
try:
|
||
print("[AUTO] task_get (инициализация submission)...")
|
||
await task_get.ainvoke({"taskId": task_id})
|
||
await asyncio.sleep(2)
|
||
except BaseException:
|
||
pass # не критично
|
||
|
||
for attempt in range(1, 6):
|
||
try:
|
||
print(f"[AUTO] task_update_answer (попытка {attempt})...")
|
||
r1 = await update.ainvoke({
|
||
"taskId": task_id,
|
||
"answerType": "link",
|
||
"content": URL,
|
||
})
|
||
print(f"[AUTO] update OK: {_parse_text(r1)[:120]}")
|
||
await asyncio.sleep(3)
|
||
|
||
print(f"[AUTO] task_submit...")
|
||
r2 = await submit.ainvoke({"taskId": task_id, "confirmSubmit": True})
|
||
print(f"[AUTO] submit OK: {_parse_text(r2)[:120]}")
|
||
return
|
||
|
||
except BaseException as e:
|
||
full = repr(e)
|
||
if hasattr(e, 'exceptions'):
|
||
full += " ".join(repr(sub) for sub in e.exceptions)
|
||
if "429" in full and attempt < 5:
|
||
print(f"[AUTO] Rate limit 429 — жду 10с...")
|
||
await asyncio.sleep(10)
|
||
elif attempt < 5:
|
||
print(f"[AUTO] Ошибка (попытка {attempt}): {full[:150]} — жду 10с...")
|
||
await asyncio.sleep(10)
|
||
else:
|
||
print(f"[!] Все попытки исчерпаны: {full[:200]}")
|
||
return
|
||
|
||
|
||
# ── Основной запуск ──────────────────────────────────────────────────────────
|
||
|
||
async def main():
|
||
prompt = f"""Выполни задание из курса BroJS.
|
||
|
||
taskId: {TASK_ID}
|
||
owner: {OWNER}
|
||
repo: {REPO}
|
||
|
||
ШАГ 1. mcp__journal-bh-professor__task_text(taskId='{TASK_ID}')
|
||
ШАГ 2. gitea_create_repo(name='{REPO}')
|
||
ШАГ 3. gitea_write_file — загрузи все файлы (main.py, requirements.txt, README.md + модули). Полный код, без заглушек.
|
||
ШАГ 4. mcp__journal-bh-professor__task_update_answer(taskId='{TASK_ID}', answerType='link', content='{URL}')
|
||
ШАГ 5. mcp__journal-bh-professor__task_submit(taskId='{TASK_ID}', confirmSubmit=True)"""
|
||
|
||
config = {"configurable": {"thread_id": f"hw-{TASK_ID}-{int(time.time())}"}}
|
||
print(f"[3/3] Агент работает...")
|
||
|
||
result = await _invoke_with_retry(
|
||
homework_direct_agent,
|
||
{"messages": [HumanMessage(content=prompt)]},
|
||
config,
|
||
)
|
||
|
||
print("[ГОТОВО] Агент завершил работу.")
|
||
msgs = result.get("messages", [])
|
||
print(f"[{len(msgs)} сообщений]")
|
||
for i, m in enumerate(msgs):
|
||
role = type(m).__name__
|
||
tcs = getattr(m, "tool_calls", [])
|
||
text = str(getattr(m, "content", ""))
|
||
if tcs:
|
||
for tc in tcs:
|
||
print(f" [{i}] {role} -> {tc['name']}({str(tc.get('args',''))[:120]})")
|
||
elif text.strip():
|
||
print(f" [{i}] {role}: {text[:200]}")
|
||
|
||
if not _was_submitted(msgs):
|
||
print("\n[!] Агент не вызвал task_submit — сдаю автоматически...")
|
||
await _force_submit(TASK_ID)
|
||
else:
|
||
print("\n[OK] Задание сдано агентом самостоятельно.")
|
||
|
||
|
||
asyncio.run(main())
|