mirror of
https://github.com/hansjone/oclaw.git
synced 2026-10-09 03:30:48 +08:00
Ship Cursor-only MCP admin and modular Admin/Chat UI.
Plugins/Skills install and edit via mcpServers JSON, with clearer row actions, soft reloads, and instant loading placeholders; also drop MCP market and harden related scheduler/logging/exec guards. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
2aff012b48
commit
f6f129931f
61 changed files with 18057 additions and 16327 deletions
|
|
@ -130,15 +130,16 @@ def test_retry_forbidden_blocks_same_tool_different_args(tmp_path: Path) -> None
|
|||
assert blocked.get("retry_forbidden") is True
|
||||
|
||||
|
||||
def test_distinct_exec_managed_ne_calls_not_capped_by_count(tmp_path: Path) -> None:
|
||||
"""Field ops may legitimately CLI many NEs; only identical-arg loops are blocked."""
|
||||
def test_distinct_exec_managed_ne_calls_respect_single_budget(tmp_path: Path, monkeypatch) -> None:
|
||||
"""Single-NE loops are capped; batch ne_ids remains allowed after the budget."""
|
||||
monkeypatch.setenv("AIA_EXEC_MANAGED_NE_SINGLE_BUDGET", "3")
|
||||
store = SqliteStore(str(tmp_path / "cli.sqlite"))
|
||||
sess = store.create_session("t")
|
||||
calls = {"n": 0}
|
||||
|
||||
def _handler(args):
|
||||
calls["n"] += 1
|
||||
return {"ok": True, "data": {"ne_id": args.get("ne_id"), "n": calls["n"]}}
|
||||
return {"ok": True, "data": {"ne_id": args.get("ne_id") or args.get("ne_ids"), "n": calls["n"]}}
|
||||
|
||||
reg = ToolRegistry(
|
||||
[
|
||||
|
|
@ -158,7 +159,7 @@ def test_distinct_exec_managed_ne_calls_not_capped_by_count(tmp_path: Path) -> N
|
|||
turn_uuid="turn-cli-many",
|
||||
lang="en",
|
||||
)
|
||||
for i in range(8):
|
||||
for i in range(3):
|
||||
ToolExecutor().execute_tool_uses(
|
||||
ctx=ctx,
|
||||
assistant_msg_id=i + 1,
|
||||
|
|
@ -171,4 +172,96 @@ def test_distinct_exec_managed_ne_calls_not_capped_by_count(tmp_path: Path) -> N
|
|||
],
|
||||
signature_budget=2,
|
||||
)
|
||||
assert calls["n"] == 8
|
||||
assert calls["n"] == 3
|
||||
|
||||
_, blocked_results = ToolExecutor().execute_tool_uses(
|
||||
ctx=ctx,
|
||||
assistant_msg_id=99,
|
||||
tool_uses=[
|
||||
LLMToolCall(
|
||||
id="blocked",
|
||||
name="mcp__netx__execManagedNe",
|
||||
arguments={"ne_id": "ne-x", "commands": ["disp"]},
|
||||
)
|
||||
],
|
||||
signature_budget=2,
|
||||
)
|
||||
blocked, _ = blocked_results["blocked"]
|
||||
assert calls["n"] == 3
|
||||
assert blocked.get("error_code") == "cli_call_budget_exceeded"
|
||||
|
||||
_, batch_results = ToolExecutor().execute_tool_uses(
|
||||
ctx=ctx,
|
||||
assistant_msg_id=100,
|
||||
tool_uses=[
|
||||
LLMToolCall(
|
||||
id="batch",
|
||||
name="mcp__netx__execManagedNe",
|
||||
arguments={"ne_ids": ["a", "b", "c"], "commands": ["show version"]},
|
||||
)
|
||||
],
|
||||
signature_budget=2,
|
||||
)
|
||||
batch_out, _ = batch_results["batch"]
|
||||
assert calls["n"] == 4
|
||||
assert batch_out.get("ok") is True
|
||||
|
||||
|
||||
def test_exec_managed_ne_fail_budget_blocks_further_single(tmp_path: Path, monkeypatch) -> None:
|
||||
monkeypatch.setenv("AIA_EXEC_MANAGED_NE_FAIL_BUDGET", "2")
|
||||
monkeypatch.setenv("AIA_EXEC_MANAGED_NE_SINGLE_BUDGET", "10")
|
||||
store = SqliteStore(str(tmp_path / "cli-fail.sqlite"))
|
||||
sess = store.create_session("t")
|
||||
calls = {"n": 0}
|
||||
|
||||
def _handler(_args):
|
||||
calls["n"] += 1
|
||||
return {"ok": False, "error_code": "tool_timeout_or_failed", "error": "timeout"}
|
||||
|
||||
reg = ToolRegistry(
|
||||
[
|
||||
ToolSpec(
|
||||
name="mcp__netx__execManagedNe",
|
||||
description="exec",
|
||||
parameters={"type": "object", "properties": {"ne_id": {"type": "string"}}},
|
||||
handler=_handler,
|
||||
read_only=False,
|
||||
)
|
||||
]
|
||||
)
|
||||
ctx = ToolExecutionContext(
|
||||
store=store,
|
||||
tools=reg,
|
||||
session_id=sess.id,
|
||||
turn_uuid="turn-cli-fail",
|
||||
lang="en",
|
||||
)
|
||||
for i in range(2):
|
||||
ToolExecutor().execute_tool_uses(
|
||||
ctx=ctx,
|
||||
assistant_msg_id=i + 1,
|
||||
tool_uses=[
|
||||
LLMToolCall(
|
||||
id=f"f{i}",
|
||||
name="mcp__netx__execManagedNe",
|
||||
arguments={"ne_id": f"ne-{i}", "commands": ["disp"]},
|
||||
)
|
||||
],
|
||||
signature_budget=2,
|
||||
)
|
||||
assert calls["n"] == 2
|
||||
_, results = ToolExecutor().execute_tool_uses(
|
||||
ctx=ctx,
|
||||
assistant_msg_id=9,
|
||||
tool_uses=[
|
||||
LLMToolCall(
|
||||
id="f3",
|
||||
name="mcp__netx__execManagedNe",
|
||||
arguments={"ne_id": "ne-9", "commands": ["disp"]},
|
||||
)
|
||||
],
|
||||
signature_budget=2,
|
||||
)
|
||||
blocked, _ = results["f3"]
|
||||
assert calls["n"] == 2
|
||||
assert blocked.get("error_code") == "cli_fail_budget_exceeded"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue