From 49ab1e6ff885d4fb734e689c723b60b71acbd9f9 Mon Sep 17 00:00:00 2001 From: Gujiassh Date: Thu, 12 Mar 2026 15:45:20 +0900 Subject: [PATCH] Fix running background status in s_full Keep the reference agent's background status output readable by reporting '(running)' instead of leaking a None placeholder for unfinished tasks. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus --- agents/s_full.py | 2 +- tests/test_s_full_background.py | 67 +++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 tests/test_s_full_background.py diff --git a/agents/s_full.py b/agents/s_full.py index d4dcfd3c6..5a240cc36 100644 --- a/agents/s_full.py +++ b/agents/s_full.py @@ -350,7 +350,7 @@ def _exec(self, tid: str, command: str, timeout: int): def check(self, tid: str = None) -> str: if tid: t = self.tasks.get(tid) - return f"[{t['status']}] {t.get('result', '(running)')}" if t else f"Unknown: {tid}" + return f"[{t['status']}] {t.get('result') or '(running)'}" if t else f"Unknown: {tid}" return "\n".join(f"{k}: [{v['status']}] {v['command'][:60]}" for k, v in self.tasks.items()) or "No bg tasks." def drain(self) -> list: diff --git a/tests/test_s_full_background.py b/tests/test_s_full_background.py new file mode 100644 index 000000000..4bdb10b5a --- /dev/null +++ b/tests/test_s_full_background.py @@ -0,0 +1,67 @@ +import importlib.util +import os +import sys +import tempfile +import types +import unittest +from pathlib import Path + + +REPO_ROOT = Path(__file__).resolve().parents[1] +MODULE_PATH = REPO_ROOT / "agents" / "s_full.py" + + +def load_s_full_module(temp_cwd: Path): + fake_anthropic = types.ModuleType("anthropic") + + class FakeAnthropic: + def __init__(self, *args, **kwargs): + self.messages = types.SimpleNamespace(create=None) + + fake_dotenv = types.ModuleType("dotenv") + setattr(fake_anthropic, "Anthropic", FakeAnthropic) + setattr(fake_dotenv, "load_dotenv", lambda override=True: None) + + previous_anthropic = sys.modules.get("anthropic") + previous_dotenv = sys.modules.get("dotenv") + previous_cwd = Path.cwd() + spec = importlib.util.spec_from_file_location("s_full_under_test", MODULE_PATH) + if spec is None or spec.loader is None: + raise RuntimeError(f"Unable to load {MODULE_PATH}") + module = importlib.util.module_from_spec(spec) + + sys.modules["anthropic"] = fake_anthropic + sys.modules["dotenv"] = fake_dotenv + try: + os.chdir(temp_cwd) + os.environ.setdefault("MODEL_ID", "test-model") + spec.loader.exec_module(module) + return module + finally: + os.chdir(previous_cwd) + if previous_anthropic is None: + sys.modules.pop("anthropic", None) + else: + sys.modules["anthropic"] = previous_anthropic + if previous_dotenv is None: + sys.modules.pop("dotenv", None) + else: + sys.modules["dotenv"] = previous_dotenv + + +class BackgroundManagerTests(unittest.TestCase): + def test_check_returns_running_placeholder_when_result_is_none(self): + with tempfile.TemporaryDirectory() as tmp: + module = load_s_full_module(Path(tmp)) + manager = module.BackgroundManager() + manager.tasks["abc123"] = { + "status": "running", + "command": "sleep 1", + "result": None, + } + + self.assertEqual(manager.check("abc123"), "[running] (running)") + + +if __name__ == "__main__": + unittest.main()