feat: pipeline guarantees task submission regardless of LLM tool calling

Added _force_submit() and _is_submitted() helpers. After the agent
finishes writing code, the pipeline checks if the task was actually
submitted. If not (LLM failed to call tools), the pipeline submits
directly via MCP — no LLM involved in the critical submit step.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-26 22:57:24 +03:00
parent 7744a97012
commit 1d73c5e439
+40
View File
@@ -103,6 +103,40 @@ def _is_coding(task: TaskInfo) -> bool:
return True return True
async def _force_submit(task_id: str) -> bool:
"""Гарантированно сабмитит задание через MCP напрямую, минуя LLM.
Вызывается пайплайном после того, как агент написал код в репо.
Возвращает True если сабмит прошёл успешно.
"""
repo_url = f"https://git.brojs.ru/{GITEA_OWNER}/task-{task_id}"
update_tool = _get_journal_tool("task_update_answer")
submit_tool = _get_journal_tool("task_submit")
if not update_tool or not submit_tool:
print(f"[pipeline] force_submit: инструменты не найдены")
return False
try:
await update_tool.ainvoke({
"taskId": task_id,
"answerType": "link",
"content": repo_url,
"commit": {"repoUrl": repo_url, "branch": "main"},
})
await submit_tool.ainvoke({"taskId": task_id, "confirmSubmit": True})
print(f"[pipeline] Задание {task_id[:8]} — сабмит выполнен пайплайном ✓")
return True
except Exception as e:
print(f"[pipeline] force_submit ошибка: {e}")
return False
async def _is_submitted(task_id: str) -> bool:
"""Проверяет, сменился ли статус задания на ready_for_review / done."""
data = await _task_json(task_id)
status = data.get("status", "")
return status in ("ready_for_review", "done")
async def _task_text(task_id: str) -> str: async def _task_text(task_id: str) -> str:
tool = _get_journal_tool("task_text") tool = _get_journal_tool("task_text")
if not tool: if not tool:
@@ -298,6 +332,12 @@ async def process_one_task(state: PipelineState) -> dict:
) )
verification = await _verify_repo(repo_name) verification = await _verify_repo(repo_name)
# Гарантированный сабмит пайплайном — не полагаемся на LLM
submitted = await _is_submitted(task_id)
if not submitted:
print(f"[pipeline] Задание {task_id[:8]} — агент не сабмитил, делаем сами...")
await _force_submit(task_id)
print(f"[pipeline] Задание {task_id[:8]} — OK (retries={retries})") print(f"[pipeline] Задание {task_id[:8]} — OK (retries={retries})")
results.append({ results.append({
"task_id": task_id, "task_id": task_id,