mirror of
https://github.com/openswarm-ai/openswarm.git
synced 2026-09-08 18:57:43 +02:00
[eric] agents: the two guards that could fail silently now declare themselves (ENG-388, ENG-386)
This commit is contained in:
@@ -4,6 +4,7 @@ on boot). Split from SessionLifecycle (which handles ONE session at a time) so e
|
||||
one concern. self.sessions resolves across the MRO as before."""
|
||||
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
|
||||
from typeguard import typechecked
|
||||
@@ -22,7 +23,15 @@ logger = logging.getLogger(__name__)
|
||||
def running_under_test() -> bool:
|
||||
"""Auto-resume dispatches REAL turns: live credentials, live Bash, in whatever tree the process
|
||||
was started from. A test that boots the app lifespan must never do that to the developer's own
|
||||
chats, so this is the one gate that keeps a suite run from becoming an agent run."""
|
||||
chats, so this is the one gate that keeps a suite run from becoming an agent run.
|
||||
|
||||
The env var is the DECLARED signal and conftest sets it. `pytest in sys.modules` is kept only as
|
||||
a belt-and-braces fallback, and deliberately not as the primary: an incidental signal fails in
|
||||
the worst direction, because the day pytest becomes importable in a packaged build every
|
||||
crash-interrupted turn stops resuming and NOTHING says so. Work vanishing quietly is the worst
|
||||
bug this codebase can ship; a suite that loudly refuses to resume is merely annoying."""
|
||||
if os.environ.get("OSW_DISABLE_AUTO_RESUME") == "1":
|
||||
return True
|
||||
return "pytest" in sys.modules
|
||||
|
||||
|
||||
|
||||
@@ -33,6 +33,10 @@ def _isolate_browser_state(monkeypatch):
|
||||
monkeypatch.setenv("OPENSWARM_BROWSER_METRICS_DIR", metrics_dir)
|
||||
monkeypatch.setenv("OPENSWARM_BROWSER_PLAYBOOK_DIR", playbook_dir)
|
||||
# The speed levers are default-ON in prod; pin them off for the suite so mocked loop tests keep exact aux-call/turn expectations (same pattern as OPENSWARM_PERSISTENT_CLIENT). The levers are exercised by their own live gates + targeted tests that set the flag explicitly.
|
||||
# DECLARED, not inferred: auto-resume sends real turns with live credentials and live Bash into
|
||||
# whatever tree the suite runs from (ENG-388). The pytest-in-sys.modules fallback still exists,
|
||||
# but a gate that depends on an accident fails silently the day the accident changes.
|
||||
monkeypatch.setenv("OSW_DISABLE_AUTO_RESUME", "1")
|
||||
monkeypatch.setenv("OSW_PRESTAGE", "0")
|
||||
monkeypatch.setenv("OSW_FASTREAD_HOP", "0")
|
||||
monkeypatch.setenv("OSW_PRELUDE_TRIM", "0")
|
||||
|
||||
@@ -47,3 +47,11 @@ def test_the_gate_is_what_stops_it(monkeypatch):
|
||||
|
||||
def test_the_gate_sees_pytest():
|
||||
assert p_sp.running_under_test() is True
|
||||
|
||||
|
||||
def test_the_declared_signal_works_without_the_accidental_one(monkeypatch):
|
||||
"""The env var must stand on its own: the day `pytest in sys.modules` stops being true in some
|
||||
runner, the gate has to keep holding, or crash-resume silently reactivates against real chats."""
|
||||
monkeypatch.setenv("OSW_DISABLE_AUTO_RESUME", "1")
|
||||
monkeypatch.setitem(__import__("sys").modules, "pytest", None)
|
||||
assert p_sp.running_under_test() is True
|
||||
|
||||
@@ -408,7 +408,19 @@ const DefaultModelGuard: React.FC<{ children: React.ReactNode }> = ({ children }
|
||||
const fallback = pickFallbackModel(byProvider);
|
||||
if (!fallback) return;
|
||||
// A model absent from the catalog is genuinely gone; one merely absent from today's list is a provider we cannot reach this second, and moving the chat off it is never ours to do silently.
|
||||
if (!catalogComplete || knownValues.length === 0) return;
|
||||
// Going quiet here is itself a failure mode: a genuinely retired model then never heals and the
|
||||
// user just gets an error on every send. So when the catalog cannot be vouched for, say so once
|
||||
// for the sessions it would have touched instead of disabling the heal in silence.
|
||||
if (!catalogComplete || knownValues.length === 0) {
|
||||
const p_stranded = Object.values(store.getState().agents.sessions)
|
||||
.filter((s2) => s2.model && !valid.has(s2.model));
|
||||
if (p_stranded.length && !warnedSessionsRef.current.has('catalog-unverified')) {
|
||||
warnedSessionsRef.current.add('catalog-unverified');
|
||||
console.warn(`[models] catalog unverified (complete=${catalogComplete}, known=${knownValues.length}); ` +
|
||||
`${p_stranded.length} session(s) hold a model that is not currently available and will NOT be auto-switched`);
|
||||
}
|
||||
return;
|
||||
}
|
||||
const known = new Set(knownValues);
|
||||
const target = valid.has(settings.default_model) ? settings.default_model : fallback.value;
|
||||
let switched = false;
|
||||
|
||||
Reference in New Issue
Block a user