69 lines
2.9 KiB
Python
69 lines
2.9 KiB
Python
"""Guards the OpenCode worker's presence in the shipped example agents.
|
|
|
|
Both polly and debby once declared an optional ``opencode`` sub-agent
|
|
(``harness: opencode-native``). Shipping a sub-agent whose harness older
|
|
clients don't recognize made every old runner/host fail to launch the agent at
|
|
all — the version-skew incident behind omnigent-ai/omnigent#1145. That incident
|
|
is now mitigated on the execution path: ``spec.load(...,
|
|
prune_invalid_sub_agents=True)`` (runner ``_entry`` + server ``agent_cache``)
|
|
gracefully DROPS a sub-agent whose harness a client doesn't recognize, so an old
|
|
client loads polly with its remaining workers instead of failing. Combined with
|
|
``opencode-native`` now being a recognized harness
|
|
(``omnigent.spec._omnigent_compat.OMNIGENT_HARNESSES``), polly re-declares its
|
|
``opencode`` worker; the positive test below guards that it stays wired.
|
|
|
|
debby, however, is still deliberately opencode-free (reverted in #1295), and the
|
|
negative test below guards that OpenCode does not creep back into that spec.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
|
|
from omnigent.spec import load
|
|
|
|
_REPO_ROOT = Path(__file__).resolve().parents[1]
|
|
|
|
|
|
def _sub_agents(bundle: str) -> dict[str, object]:
|
|
spec = load(_REPO_ROOT / "examples" / bundle)
|
|
return {sa.name: sa for sa in (getattr(spec, "sub_agents", None) or [])}
|
|
|
|
|
|
def _config(sub_agent: object) -> dict[str, object]:
|
|
executor = getattr(sub_agent, "executor", None)
|
|
config = getattr(executor, "config", None)
|
|
if isinstance(config, dict):
|
|
return config
|
|
return {}
|
|
|
|
|
|
def test_polly_declares_opencode_worker() -> None:
|
|
"""polly declares its ``opencode`` worker on the ``opencode-native`` harness.
|
|
|
|
Safe to re-add because #1145's graceful pruning drops the worker (rather than
|
|
failing the whole agent) on any client too old to recognize the harness, and
|
|
``opencode-native`` is a recognized harness on current clients. If this ever
|
|
regresses to failing old clients, prune-on-load is the contract to check.
|
|
"""
|
|
subs = _sub_agents("polly")
|
|
assert "opencode" in subs
|
|
assert _config(subs["opencode"]).get("harness") == "opencode-native"
|
|
|
|
|
|
def test_debby_does_not_declare_opencode_head() -> None:
|
|
"""debby stays opencode-free, so an older client can load it without skew.
|
|
|
|
debby is reverted to its two-head roster (claude + gpt). Re-adding an
|
|
``opencode`` head (or any ``opencode-native`` harness override) would
|
|
reintroduce the harness that broke old clients on spec validation.
|
|
"""
|
|
subs = _sub_agents("debby")
|
|
assert "opencode" not in subs
|
|
assert {"claude", "gpt"} <= set(subs)
|
|
config_text = (_REPO_ROOT / "examples" / "debby" / "config.yaml").read_text(encoding="utf-8")
|
|
assert "opencode" not in config_text.lower()
|
|
# No head re-introduces opencode-native via a harness override either.
|
|
for sub in subs.values():
|
|
assert "opencode-native" not in (_config(sub).get("allowed_harnesses") or [])
|