mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-20 15:33:54 +00:00
fix(image-gen): classify unsupported Codex image accounts
This commit is contained in:
parent
8a5f8379ed
commit
402969670d
2 changed files with 77 additions and 0 deletions
|
|
@ -40,6 +40,24 @@ from agent.image_gen_provider import (
|
|||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class CodexImageGenerationUnsupportedError(RuntimeError):
|
||||
"""The active Codex account cannot use the hosted image tool."""
|
||||
|
||||
|
||||
_IMAGE_GENERATION_UNAVAILABLE_MESSAGE = (
|
||||
"Image generation is not enabled for the current Codex account. "
|
||||
"Switch the image provider to OpenAI API key, FAL, or xAI."
|
||||
)
|
||||
|
||||
|
||||
def _is_image_generation_unsupported_error(status_code: int, body: str) -> bool:
|
||||
"""Match only Codex's account-capability rejection for the image tool."""
|
||||
if status_code != 400:
|
||||
return False
|
||||
normalized = " ".join((body or "").lower().split())
|
||||
return "tool choice 'image_generation' not found in 'tools' parameter" in normalized
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Model catalog — mirrors the ``openai`` plugin so the picker UX is identical.
|
||||
# ---------------------------------------------------------------------------
|
||||
|
|
@ -394,6 +412,11 @@ def _collect_image_b64(
|
|||
except httpx.HTTPStatusError as exc:
|
||||
exc.response.read()
|
||||
body = exc.response.text[:500]
|
||||
if _is_image_generation_unsupported_error(
|
||||
exc.response.status_code,
|
||||
body,
|
||||
):
|
||||
raise CodexImageGenerationUnsupportedError(body) from exc
|
||||
raise RuntimeError(
|
||||
f"Codex Responses API returned HTTP {exc.response.status_code}: {body}"
|
||||
) from exc
|
||||
|
|
@ -542,6 +565,19 @@ class OpenAICodexImageGenProvider(ImageGenProvider):
|
|||
quality=meta["quality"],
|
||||
input_images=input_images or None,
|
||||
)
|
||||
except CodexImageGenerationUnsupportedError:
|
||||
logger.debug(
|
||||
"Codex account does not expose image generation",
|
||||
exc_info=True,
|
||||
)
|
||||
return error_response(
|
||||
error=_IMAGE_GENERATION_UNAVAILABLE_MESSAGE,
|
||||
error_type="capability_unsupported",
|
||||
provider="openai-codex",
|
||||
model=tier_id,
|
||||
prompt=prompt,
|
||||
aspect_ratio=aspect,
|
||||
)
|
||||
except Exception as exc:
|
||||
logger.debug("Codex image generation failed", exc_info=True)
|
||||
return error_response(
|
||||
|
|
|
|||
|
|
@ -307,6 +307,47 @@ class TestGenerate:
|
|||
assert result["error_type"] == "api_error"
|
||||
assert "cloudflare 403" in result["error"]
|
||||
|
||||
def test_unsupported_image_tool_returns_capability_error(self, provider, monkeypatch):
|
||||
monkeypatch.setattr(codex_plugin, "_read_codex_access_token", lambda: "codex-token")
|
||||
|
||||
def _unsupported(*args, **kwargs):
|
||||
raise codex_plugin.CodexImageGenerationUnsupportedError(
|
||||
"Tool choice 'image_generation' not found in 'tools' parameter."
|
||||
)
|
||||
|
||||
monkeypatch.setattr(codex_plugin, "_collect_image_b64", _unsupported)
|
||||
|
||||
result = provider.generate("a cat")
|
||||
|
||||
assert result["success"] is False
|
||||
assert result["error_type"] == "capability_unsupported"
|
||||
assert "current Codex account" in result["error"]
|
||||
assert "OpenAI API key, FAL, or xAI" in result["error"]
|
||||
|
||||
|
||||
class TestCapabilityErrorDetection:
|
||||
@pytest.mark.parametrize(
|
||||
"body",
|
||||
[
|
||||
"Tool choice 'image_generation' not found in 'tools' parameter.",
|
||||
'{"error":{"message":"Tool choice \'image_generation\' not found in \'tools\' parameter."}}',
|
||||
],
|
||||
)
|
||||
def test_detects_exact_codex_image_tool_rejection(self, body):
|
||||
assert codex_plugin._is_image_generation_unsupported_error(400, body) is True
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("status_code", "body"),
|
||||
[
|
||||
(401, "Tool choice 'image_generation' not found in 'tools' parameter."),
|
||||
(400, "Tool choice 'web_search' not found in 'tools' parameter."),
|
||||
(400, "The image_generation request was rejected by moderation."),
|
||||
(500, "Tool choice 'image_generation' not found in 'tools' parameter."),
|
||||
],
|
||||
)
|
||||
def test_does_not_misclassify_other_failures(self, status_code, body):
|
||||
assert codex_plugin._is_image_generation_unsupported_error(status_code, body) is False
|
||||
|
||||
|
||||
# ── Plugin entry point ──────────────────────────────────────────────────────
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue