mirror of
https://github.com/openswarm-ai/openswarm.git
synced 2026-09-03 08:18:43 +02:00
[eric] workflows: an agent will not start a workflow the user switched off
This commit is contained in:
@@ -440,6 +440,19 @@ def handle_run_now(args: dict) -> dict:
|
||||
wid = args.get("workflow_id") or ""
|
||||
if not wid:
|
||||
return _err("workflow_id is required.")
|
||||
# A human clicking Run Now on a paused workflow can see it is paused and chose anyway, so the
|
||||
# route ignores `enabled` on purpose. An agent reaching the same route is NOT the same act: the
|
||||
# user never asked, and a workflow they deliberately switched off starting itself is the field
|
||||
# report ("a workflow that had been toggled off just started running again").
|
||||
info = _call("GET", f"/{wid}")
|
||||
if "_error" not in info:
|
||||
sched = info.get("schedule") or {}
|
||||
if isinstance(sched, dict) and sched.get("enabled") is False:
|
||||
title = info.get("title") or wid
|
||||
return _err(
|
||||
f"'{title}' is paused, so I did not run it. Tell the user it is switched off and ask "
|
||||
"them to turn it back on (or to confirm they want a one-off run) before trying again."
|
||||
)
|
||||
r = _call("POST", f"/{wid}/run")
|
||||
if "_error" in r:
|
||||
return _err(r["_error"])
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
"""An agent must not start a workflow the user switched off.
|
||||
|
||||
Field report (Haik, 1.7.4): "a workflow that had been toggled off just started running again".
|
||||
The route ignores `schedule.enabled` for manual runs on purpose, because a human clicking Run Now
|
||||
can see the paused state. An agent reaching that same route is a different act.
|
||||
"""
|
||||
|
||||
from unittest.mock import patch
|
||||
|
||||
import backend.apps.agents.schedule_mcp_server as mod
|
||||
|
||||
|
||||
def p_calls(get_result):
|
||||
seen = {"ran": False}
|
||||
def fake(method, path, body=None, timeout=None):
|
||||
if method == "GET":
|
||||
return get_result
|
||||
seen["ran"] = True
|
||||
return {"run_id": "r1"}
|
||||
return fake, seen
|
||||
|
||||
|
||||
def test_agent_refuses_to_run_a_paused_workflow():
|
||||
fake, seen = p_calls({"title": "Nightly report", "schedule": {"enabled": False}})
|
||||
with patch.object(mod, "_call", side_effect=fake):
|
||||
out = mod.handle_run_now({"workflow_id": "w1"})
|
||||
assert seen["ran"] is False, "the run must never be dispatched"
|
||||
assert out.get("isError") is True
|
||||
text = out["content"][0]["text"]
|
||||
assert "paused" in text and "Nightly report" in text
|
||||
|
||||
|
||||
def test_agent_runs_an_enabled_workflow_normally():
|
||||
fake, seen = p_calls({"title": "Nightly report", "schedule": {"enabled": True}})
|
||||
with patch.object(mod, "_call", side_effect=fake):
|
||||
out = mod.handle_run_now({"workflow_id": "w1"})
|
||||
assert seen["ran"] is True
|
||||
assert not out.get("isError")
|
||||
|
||||
|
||||
def test_an_unreadable_workflow_does_not_block_the_run():
|
||||
"""Fail open: if we cannot read the workflow, behave as before rather than refusing everything."""
|
||||
fake, seen = p_calls({"_error": "boom"})
|
||||
with patch.object(mod, "_call", side_effect=fake):
|
||||
out = mod.handle_run_now({"workflow_id": "w1"})
|
||||
assert seen["ran"] is True
|
||||
assert not out.get("isError")
|
||||
Reference in New Issue
Block a user