Block non-retryable tool re-calls and add congestion ops recipes.

After insufficient_scope/retry_forbidden, refuse the same tool for the rest of the turn (even with new args), emit pre-call WA progress from ToolExecutor, TTL-cache findTopologyPaths, and add bandwidth congestion short-intent + schedule template.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
oliver 2026-08-10 23:19:03 +08:00
parent 9bbac6c0b8
commit 54cb8af8b0
6 changed files with 201 additions and 3 deletions

View file

@ -31,6 +31,11 @@ def test_license_short_intent() -> None:
assert detect_ops_short_intent("@bot licence check") == "license"
def test_congestion_short_intent() -> None:
assert detect_ops_short_intent("bandwidth congestion top") == "congestion"
assert detect_ops_short_intent("端口忙 拥塞") == "congestion"
def test_identical_failed_retry_blocked_across_rounds(tmp_path: Path) -> None:
store = SqliteStore(str(tmp_path / "retry.sqlite"))
sess = store.create_session("t")
@ -70,3 +75,56 @@ def test_identical_failed_retry_blocked_across_rounds(tmp_path: Path) -> None:
assert calls["n"] == 1
assert blocked.get("error_code") == "identical_retry_blocked"
assert blocked.get("failure_class") == "retry_guard"
def test_retry_forbidden_blocks_same_tool_different_args(tmp_path: Path) -> None:
store = SqliteStore(str(tmp_path / "scope.sqlite"))
sess = store.create_session("t")
calls = {"n": 0}
def _handler(_args):
calls["n"] += 1
return {
"ok": False,
"error_code": "insufficient_scope",
"error": "insufficient_scope:sql:query",
"retry_forbidden": True,
"failure_class": "auth",
}
reg = ToolRegistry(
[
ToolSpec(
name="mcp__netx__sqlQueryUme",
description="sql",
parameters={"type": "object", "properties": {"sql": {"type": "string"}}},
handler=_handler,
read_only=True,
)
]
)
ctx = ToolExecutionContext(
store=store,
tools=reg,
session_id=sess.id,
turn_uuid="turn-scope-1",
lang="en",
)
ToolExecutor().execute_tool_uses(
ctx=ctx,
assistant_msg_id=1,
tool_uses=[LLMToolCall(id="c1", name="mcp__netx__sqlQueryUme", arguments={"sql": "select 1"})],
signature_budget=2,
)
assert calls["n"] == 1
_, results = ToolExecutor().execute_tool_uses(
ctx=ctx,
assistant_msg_id=2,
tool_uses=[LLMToolCall(id="c2", name="mcp__netx__sqlQueryUme", arguments={"sql": "select 2"})],
signature_budget=2,
)
blocked, _ = results["c2"]
assert calls["n"] == 1
assert blocked.get("error_code") == "retry_forbidden_blocked"
assert blocked.get("retry_forbidden") is True

View file

@ -75,10 +75,14 @@ class RecipeHelpersTests(unittest.TestCase):
self.assertIn("ume_alarm_tally_daily", ids)
self.assertIn("ume_critical_xlsx_daily", ids)
self.assertIn("ne_license_check_weekly", ids)
self.assertIn("bandwidth_congestion_daily", ids)
tmpl = resolve_ops_recipe_template("alarm_tally")
assert tmpl is not None
self.assertTrue(recipe_has_playbook(tmpl))
self.assertEqual((tmpl.get("source") or {}).get("template_id"), "ume_alarm_tally_daily")
cong = resolve_ops_recipe_template("congestion")
assert cong is not None
self.assertEqual((cong.get("source") or {}).get("template_id"), "bandwidth_congestion_daily")
self.assertIsNone(resolve_ops_recipe_template("nope"))
def test_turn_instruction_modes(self) -> None: