From 47ae16de4dd81d52101a22cd0075ef474264590f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20St=C3=B6ckli?= Date: Tue, 20 Jan 2026 16:38:08 +0100 Subject: [PATCH 1/4] Retry on 499 errors Added APIStatusError handling to manage transient errors during API calls. --- src/seclab_taskflow_agent/__main__.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/seclab_taskflow_agent/__main__.py b/src/seclab_taskflow_agent/__main__.py index 1072907..d32c6d1 100644 --- a/src/seclab_taskflow_agent/__main__.py +++ b/src/seclab_taskflow_agent/__main__.py @@ -22,7 +22,7 @@ from agents.mcp import MCPServer, MCPServerStdio, MCPServerSse, MCPServerStreamableHttp, create_static_tool_filter from agents.extensions.handoff_prompt import prompt_with_handoff_instructions from agents import Tool, RunContextWrapper, TContext, Agent -from openai import BadRequestError, APITimeoutError, RateLimitError +from openai import BadRequestError, APITimeoutError, RateLimitError, APIStatusError from openai.types.responses import ResponseTextDeltaEvent from typing import Callable @@ -334,7 +334,15 @@ async def _run_streamed(): return except APITimeoutError: if not max_retry: - logging.error(f"Max retries for APITimeoutError reached") + logging.error(f"Max API retries reached") + raise + max_retry -= 1 + except APIStatusError as e: + # Retry transient “client closed request / upstream cancelled” style errors + if getattr(e, "status_code", None) != 499: + raise # propagate non-499 errors + # 499: retry + if not max_retry: raise max_retry -= 1 except RateLimitError: From 70c8be703311a285b4fc54767086c4e7d6e0131a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20St=C3=B6ckli?= Date: Tue, 20 Jan 2026 16:40:28 +0100 Subject: [PATCH 2/4] add logging statement --- src/seclab_taskflow_agent/__main__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/seclab_taskflow_agent/__main__.py b/src/seclab_taskflow_agent/__main__.py index d32c6d1..e6c6775 100644 --- a/src/seclab_taskflow_agent/__main__.py +++ b/src/seclab_taskflow_agent/__main__.py @@ -343,6 +343,7 @@ async def _run_streamed(): raise # propagate non-499 errors # 499: retry if not max_retry: + logging.error(f"Max API retries reached") raise max_retry -= 1 except RateLimitError: From c38b939e7ecb6d588fae9f5f5e223a346feca4cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20St=C3=B6ckli?= Date: Tue, 20 Jan 2026 17:17:55 +0100 Subject: [PATCH 3/4] Add APIStatusError handler --- src/seclab_taskflow_agent/__main__.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/seclab_taskflow_agent/__main__.py b/src/seclab_taskflow_agent/__main__.py index e6c6775..3308104 100644 --- a/src/seclab_taskflow_agent/__main__.py +++ b/src/seclab_taskflow_agent/__main__.py @@ -379,6 +379,11 @@ async def _run_streamed(): async_task=async_task, task_id=task_id) logging.error(f"Bad Request: {e}") + except APIStatusError as e: + await render_model_output(f"** 🤖❗ API Status Error: {e}\n", + async_task=async_task, + task_id=task_id) + logging.error(f"Bad Request: {e}") if async_task: await flush_async_output(task_id) From a0fe49ee2ab39a95658798249959b30294e378a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20St=C3=B6ckli?= Date: Tue, 20 Jan 2026 17:51:44 +0100 Subject: [PATCH 4/4] Improve error logging for API status errors --- src/seclab_taskflow_agent/__main__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/seclab_taskflow_agent/__main__.py b/src/seclab_taskflow_agent/__main__.py index 3308104..4c82887 100644 --- a/src/seclab_taskflow_agent/__main__.py +++ b/src/seclab_taskflow_agent/__main__.py @@ -383,7 +383,7 @@ async def _run_streamed(): await render_model_output(f"** 🤖❗ API Status Error: {e}\n", async_task=async_task, task_id=task_id) - logging.error(f"Bad Request: {e}") + logging.error(f"API Status Error: Status={e.status_code}, Response={e.response}") if async_task: await flush_async_output(task_id)