|
4 | 4 | from contextlib import asynccontextmanager |
5 | 5 | from typing import Any, Literal |
6 | 6 |
|
| 7 | +from loguru import logger |
| 8 | +from pydantic_ai.exceptions import UsageLimitExceeded |
7 | 9 | from pydantic_ai.run import AgentRunResult |
8 | 10 | from pydantic_evals import Case |
9 | 11 |
|
@@ -49,14 +51,31 @@ def make_task_lifecycle( |
49 | 51 | ) -> Callable[..., Any]: |
50 | 52 | """Return a context manager factory: callable(case) for use as case_context_manager. |
51 | 53 |
|
52 | | - Marks task as finished on clean exit using task.name. |
| 54 | + Marks task as finished in run state. For certain errors (e.g., ModelUsageExceeded), |
| 55 | + marks as finished even though the task failed, suppressing the exception so it |
| 56 | + doesn't propagate to pydantic_evals (which will still mark case as failed in reporting). |
| 57 | +
|
| 58 | + This distinction is important: some errors indicate the task *execution* completed |
| 59 | + but was interrupted by external constraints (e.g., quota exceeded), so retrying |
| 60 | + makes no sense. The task should be marked done in run state for resume purposes. |
53 | 61 | """ |
54 | 62 |
|
55 | 63 | @asynccontextmanager |
56 | 64 | async def _lifecycle(case: Case[Task[Any, Any], AgentRunResult, None]) -> AsyncIterator[None]: |
57 | 65 | task = case.inputs |
58 | | - async with task: |
59 | | - yield |
60 | | - await state.mark_task_finished(split_idx, phase, task.name) |
| 66 | + try: |
| 67 | + async with task: |
| 68 | + yield |
| 69 | + except Exception as e: |
| 70 | + if isinstance(e, UsageLimitExceeded): |
| 71 | + logger.exception( |
| 72 | + f"[{task.name}] Usage exceeded" |
| 73 | + "Task will be marked as finished (not retried), but case marked as failed in reporting." |
| 74 | + ) |
| 75 | + await state.mark_task_finished(split_idx, phase, task.name) |
| 76 | + raise |
| 77 | + else: |
| 78 | + # Success path: no exception occurred |
| 79 | + await state.mark_task_finished(split_idx, phase, task.name) |
61 | 80 |
|
62 | 81 | return _lifecycle |
0 commit comments