mirror of
https://github.com/openswarm-ai/openswarm.git
synced 2026-08-17 18:25:42 +02:00
86 lines
3.8 KiB
Python
86 lines
3.8 KiB
Python
"""Drive handle_run_error's out-of-credits branch. The is_out_of_tokens / extract_reset_hint
|
|
helpers were built but never wired in, so a provider credit/quota error fell through to the
|
|
raw-error blob; this pins the friendly card + agent:out_of_credits event (and the reset hint)."""
|
|
|
|
import asyncio
|
|
|
|
import backend.apps.agents.core.ws_manager as ws_mod
|
|
from backend.apps.agents.core.models import AgentSession
|
|
from backend.apps.agents.manager.run.handle_run_error import handle_run_error
|
|
from backend.apps.agents.manager.streaming.state import TurnState
|
|
|
|
|
|
def p_drive_error(monkeypatch, exc, stderr=None):
|
|
events = []
|
|
|
|
async def fake_send(session_id, event, data):
|
|
events.append((event, data))
|
|
|
|
monkeypatch.setattr(ws_mod.ws_manager, "send_to_session", fake_send, raising=True)
|
|
# Diagnostics are fire-and-forget network; keep the tests offline.
|
|
import backend.apps.service.client as service_client
|
|
monkeypatch.setattr(service_client, "submit_diagnostic", lambda payload: None, raising=True)
|
|
session = AgentSession(name="t", model="sonnet", dashboard_id="d")
|
|
asyncio.run(handle_run_error(exc, session, session.id, TurnState(), stderr or []))
|
|
return session, events
|
|
|
|
|
|
def test_out_of_credits_shows_friendly_card_not_raw_error(monkeypatch):
|
|
session, events = p_drive_error(
|
|
monkeypatch, Exception("Your credit balance is too low to run this request")
|
|
)
|
|
assert session.status == "error"
|
|
assert "agent:out_of_credits" in [e for e, _ in events]
|
|
sys_msgs = [m for m in session.messages if m.role == "system"]
|
|
assert sys_msgs, "expected a system card"
|
|
assert "out of credits or over your usage limit" in sys_msgs[-1].content
|
|
assert not sys_msgs[-1].content.startswith("Error:") # not the raw-error fallthrough
|
|
|
|
|
|
def test_out_of_credits_carries_the_provider_reset_hint(monkeypatch):
|
|
_, events = p_drive_error(
|
|
monkeypatch, Exception("insufficient_quota; resets at 7:42 AM")
|
|
)
|
|
payload = next(d for e, d in events if e == "agent:out_of_credits")
|
|
assert payload["reset_hint"] == "at 7:42 AM"
|
|
assert "resets at 7:42 AM" in payload["message"]
|
|
|
|
|
|
P_FIELD_CLI_MISSING = (
|
|
"Claude Code not found at: C:\\Users\\Rishi\\AppData\\Local\\openswarm\\app-1.5.6\\resources"
|
|
"\\python-env\\Lib\\site-packages\\claude_agent_sdk\\_bundled\\claude.exe"
|
|
)
|
|
|
|
|
|
def test_cli_missing_shows_repair_card_not_dead_path(monkeypatch):
|
|
session, events = p_drive_error(monkeypatch, Exception(P_FIELD_CLI_MISSING))
|
|
assert session.status == "error"
|
|
sys_msgs = [m for m in session.messages if m.role == "system"]
|
|
assert sys_msgs, "expected a system card"
|
|
card = sys_msgs[-1].content
|
|
assert "antivirus" in card
|
|
assert "reinstall" in card
|
|
# The raw path dump is exactly the unactionable card we're replacing.
|
|
assert "AppData" not in card
|
|
|
|
|
|
def test_unclassified_card_carries_scrubbed_stderr_tail(monkeypatch):
|
|
exc = Exception(
|
|
"Command failed with exit code 1 (exit code: 1)\nError output: Check stderr output for details"
|
|
)
|
|
# Neutral cause text: anything auth/capacity-shaped would (correctly) route to a friendlier branch instead.
|
|
secret = "sk-" + "ant-" + "A" * 28
|
|
stderr = ["boot noise", f"TypeError: cannot read properties of undefined (reading 'chunk') {secret}"]
|
|
session, _ = p_drive_error(monkeypatch, exc, stderr=stderr)
|
|
card = [m for m in session.messages if m.role == "system"][-1].content
|
|
assert "Runtime log tail" in card
|
|
assert "TypeError" in card
|
|
assert secret not in card
|
|
|
|
|
|
def test_informative_error_does_not_get_stderr_appended(monkeypatch):
|
|
exc = Exception("Something specific broke: widget frobnicator misconfigured")
|
|
session, _ = p_drive_error(monkeypatch, exc, stderr=["irrelevant tail"])
|
|
card = [m for m in session.messages if m.role == "system"][-1].content
|
|
assert "Runtime log tail" not in card
|