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())