Increase default tool rounds to 100 with 300 cap.

Raise Admin/UI defaults and backend clamps for AIA_TURN_MAX_TOOL_ROUNDS across gateway, worker, and direct loop paths.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
oliver 2026-05-28 11:34:20 +08:00
parent 89b295293d
commit 8233db93db
9 changed files with 18 additions and 18 deletions

View file

@ -422,7 +422,7 @@ TAVILY_API_KEY=
# 二十一、下列 keys 常在「管理后台 → 网关/运维」中配置(SQLite),与 env 二选一或叠加
# 若代码未 getenv,请使用后台保存;不要仅写在本文件。
# -----------------------------------------------------------------------------
# AIA_TURN_MAX_CONTEXT_MESSAGES / AIA_TURN_MAX_TOOL_ROUNDS (默认 30,上限 100) / AIA_TURN_MAX_TOOL_WORKERS
# AIA_TURN_MAX_CONTEXT_MESSAGES / AIA_TURN_MAX_TOOL_ROUNDS (默认 100,上限 300) / AIA_TURN_MAX_TOOL_WORKERS
# AIA_OCLAW_MAX_ATTEMPTS
# AIA_ENABLE_PLUGIN_TOOLS(注意与 AIA_PLUGIN_TOOLS_ENABLED 命名区分,以后台为准)
# AIA_TOOL_CONTEXT_TRUNCATE_ENABLED

View file

@ -32,8 +32,8 @@
- 生效:`oclaw/oclaw_runtime/gateway.py`, `oclaw/oclaw_runtime/direct_loop.py`
- `AIA_TURN_MAX_TOOL_ROUNDS`
- 默认:`30`
- 上限:`100`(Admin / gateway / worker 会钳制)
- 默认:`100`
- 上限:`300`(Admin / gateway / worker 会钳制)
- 作用:单轮工具循环轮次上限(一轮 = 模型思考一次并执行一批工具)
- 生效:`runtime/gateway.py`, `runtime/direct_loop.py`, `runtime/worker.py`

View file

@ -1961,7 +1961,7 @@ def build_admin_router() -> APIRouter:
tmr_raw = str(store.get_setting("AIA_TURN_MAX_TOOL_ROUNDS") or "").strip()
tmc_raw = str(store.get_setting("AIA_TURN_MAX_CONTEXT_MESSAGES") or "").strip()
turn_max_tool_workers = max(1, min(int(tmw_raw), 32)) if tmw_raw.isdigit() else 8
turn_max_tool_rounds = max(1, min(int(tmr_raw), 100)) if tmr_raw.isdigit() else 30
turn_max_tool_rounds = max(1, min(int(tmr_raw), 300)) if tmr_raw.isdigit() else 100
turn_max_context_messages = max(10, min(int(tmc_raw), 400)) if tmc_raw.isdigit() else 80
# Oclaw takeover: legacy runner switches are disconnected (kept in DB for later).
turn_runner_impl = "oclaw"
@ -2057,7 +2057,7 @@ def build_admin_router() -> APIRouter:
sm = True
sig_budget_n = 2
tmw = payload.get("turn_max_tool_workers", 8)
tmr = payload.get("turn_max_tool_rounds", 30)
tmr = payload.get("turn_max_tool_rounds", 100)
tmc = payload.get("turn_max_context_messages", 80)
tri = "oclaw"
try:
@ -2065,9 +2065,9 @@ def build_admin_router() -> APIRouter:
except Exception:
tmw_n = 8
try:
tmr_n = max(1, min(int(tmr), 100))
tmr_n = max(1, min(int(tmr), 300))
except Exception:
tmr_n = 30
tmr_n = 100
try:
tmc_n = max(10, min(int(tmc), 400))
except Exception:

View file

@ -4381,7 +4381,7 @@ async function renderPlugins() {
tool_loop_state_machine: true,
tool_signature_budget: 2,
turn_max_tool_workers: 8,
turn_max_tool_rounds: 30,
turn_max_tool_rounds: 100,
turn_max_context_messages: 80,
turn_runner_impl: "oclaw",
manager_decision_mode: "",
@ -4635,8 +4635,8 @@ async function renderPlugins() {
class: "input",
type: "number",
min: "1",
max: "100",
value: String(Number(toolPolicy.turn_max_tool_rounds || 30)),
max: "300",
value: String(Number(toolPolicy.turn_max_tool_rounds || 100)),
style: "max-width:120px",
});
const turnMaxCtxInput = el("input", {
@ -4728,7 +4728,7 @@ async function renderPlugins() {
onclick: async () => {
const r = await apiPost("/admin/api/tool-policy", {
turn_max_tool_workers: Number(turnMaxWorkersInput.value || 8),
turn_max_tool_rounds: Number(turnMaxRoundsInput.value || 30),
turn_max_tool_rounds: Number(turnMaxRoundsInput.value || 100),
turn_max_context_messages: Number(turnMaxCtxInput.value || 80),
// manager_decision_mode is legacy-only; no longer submitted.
sse_queue_maxsize: Number(sseQueueMaxsizeInput.value || 2000),
@ -6069,7 +6069,7 @@ async function renderPlugins() {
turnMaxWorkersInput,
]),
el("div", { class: "row" }, [
el("label", { text: "Turn max tool rounds (1-100)" }),
el("label", { text: "Turn max tool rounds (1-300)" }),
turnMaxRoundsInput,
]),
el("div", { class: "row" }, [

View file

@ -32,7 +32,7 @@ class AgentCoreRunInput:
parent_span_id: str | None
run_id: str | None = None
max_messages: int = 80
max_tool_rounds: int = 30
max_tool_rounds: int = 100
max_tool_workers: int = 8
max_attempts: int = 2
memory_context: OclawMemoryContext | None = None

View file

@ -42,7 +42,7 @@ class GenerationInterrupted(Exception):
@dataclass(frozen=True)
class AgentConfig:
max_messages: int = AGENT_CONTEXT_MESSAGES
max_tool_rounds: int = 30
max_tool_rounds: int = 100
max_tool_workers: int = 8

View file

@ -1364,7 +1364,7 @@ def run_oclaw_direct_loop(
run_id: str | None = None,
attempt_no: int | None = None,
max_messages: int = 80,
max_tool_rounds: int = 30,
max_tool_rounds: int = 100,
max_tool_workers: int = 8,
on_token: Optional[Callable[[str], None]] = None,
on_progress: Optional[Callable[[str], None]] = None,

View file

@ -1198,7 +1198,7 @@ class OclawGateway:
parent_span_id=None,
run_id=rid,
max_messages=_get_int_setting("AIA_TURN_MAX_CONTEXT_MESSAGES", 80, 10, 400),
max_tool_rounds=_get_int_setting("AIA_TURN_MAX_TOOL_ROUNDS", 30, 1, 100),
max_tool_rounds=_get_int_setting("AIA_TURN_MAX_TOOL_ROUNDS", 100, 1, 300),
max_tool_workers=_get_int_setting("AIA_TURN_MAX_TOOL_WORKERS", 8, 1, 32),
max_attempts=_get_int_setting("AIA_OCLAW_MAX_ATTEMPTS", 2, 1, 5),
memory_context=memory_context,

View file

@ -269,7 +269,7 @@ def _worker_loop(*, store: Any, worker_id: str, poll_interval_s: float) -> None:
system_prompt = str(getattr(executor, "system_prompt", "") or "")
max_messages = int(store.get_setting("AIA_TURN_MAX_CONTEXT_MESSAGES") or 80)
max_tool_rounds = int(store.get_setting("AIA_TURN_MAX_TOOL_ROUNDS") or 30)
max_tool_rounds = int(store.get_setting("AIA_TURN_MAX_TOOL_ROUNDS") or 100)
max_tool_workers = int(store.get_setting("AIA_TURN_MAX_TOOL_WORKERS") or 8)
msg = StandardMessage(
@ -301,7 +301,7 @@ def _worker_loop(*, store: Any, worker_id: str, poll_interval_s: float) -> None:
parent_span_id=None,
run_id=run_id,
max_messages=max(10, min(max_messages, 400)),
max_tool_rounds=max(1, min(max_tool_rounds, 100)),
max_tool_rounds=max(1, min(max_tool_rounds, 300)),
max_tool_workers=max(1, min(max_tool_workers, 32)),
max_attempts=2,
memory_context=memory_ctx,