diff --git a/_local/system.env.example b/_local/system.env.example index 04aa81a5..b7ab8068 100644 --- a/_local/system.env.example +++ b/_local/system.env.example @@ -422,7 +422,7 @@ TAVILY_API_KEY= # 二十一、下列 keys 常在「管理后台 → 网关/运维」中配置(SQLite),与 env 二选一或叠加 # 若代码未 getenv,请使用后台保存;不要仅写在本文件。 # ----------------------------------------------------------------------------- -# AIA_TURN_MAX_CONTEXT_MESSAGES / AIA_TURN_MAX_TOOL_ROUNDS / AIA_TURN_MAX_TOOL_WORKERS +# AIA_TURN_MAX_CONTEXT_MESSAGES / AIA_TURN_MAX_TOOL_ROUNDS (默认 30,上限 100) / AIA_TURN_MAX_TOOL_WORKERS # AIA_OCLAW_MAX_ATTEMPTS # AIA_ENABLE_PLUGIN_TOOLS(注意与 AIA_PLUGIN_TOOLS_ENABLED 命名区分,以后台为准) # AIA_TOOL_CONTEXT_TRUNCATE_ENABLED diff --git a/docs/ENVIRONMENT_VARIABLES.md b/docs/ENVIRONMENT_VARIABLES.md index 4838bbb6..7115d777 100644 --- a/docs/ENVIRONMENT_VARIABLES.md +++ b/docs/ENVIRONMENT_VARIABLES.md @@ -32,9 +32,10 @@ - 生效:`oclaw/oclaw_runtime/gateway.py`, `oclaw/oclaw_runtime/direct_loop.py` - `AIA_TURN_MAX_TOOL_ROUNDS` - - 默认:`8` - - 作用:工具循环轮次上限 - - 生效:`oclaw/oclaw_runtime/gateway.py`, `oclaw/oclaw_runtime/direct_loop.py` + - 默认:`30` + - 上限:`100`(Admin / gateway / worker 会钳制) + - 作用:单轮工具循环轮次上限(一轮 = 模型思考一次并执行一批工具) + - 生效:`runtime/gateway.py`, `runtime/direct_loop.py`, `runtime/worker.py` - `AIA_TURN_MAX_CONTEXT_MESSAGES` - 默认:`80` diff --git a/interfaces/admin/routes.py b/interfaces/admin/routes.py index 20fc9859..3c2c45f1 100644 --- a/interfaces/admin/routes.py +++ b/interfaces/admin/routes.py @@ -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), 30)) if tmr_raw.isdigit() else 8 + turn_max_tool_rounds = max(1, min(int(tmr_raw), 100)) if tmr_raw.isdigit() else 30 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", 8) + tmr = payload.get("turn_max_tool_rounds", 30) 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), 30)) + tmr_n = max(1, min(int(tmr), 100)) except Exception: - tmr_n = 8 + tmr_n = 30 try: tmc_n = max(10, min(int(tmc), 400)) except Exception: diff --git a/interfaces/admin/static/app.js b/interfaces/admin/static/app.js index 064749d1..43368293 100644 --- a/interfaces/admin/static/app.js +++ b/interfaces/admin/static/app.js @@ -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: 8, + turn_max_tool_rounds: 30, 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: "30", - value: String(Number(toolPolicy.turn_max_tool_rounds || 8)), + max: "100", + value: String(Number(toolPolicy.turn_max_tool_rounds || 30)), 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 || 8), + turn_max_tool_rounds: Number(turnMaxRoundsInput.value || 30), 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-30)" }), + el("label", { text: "Turn max tool rounds (1-100)" }), turnMaxRoundsInput, ]), el("div", { class: "row" }, [ diff --git a/runtime/agent_core_run.py b/runtime/agent_core_run.py index c36e9722..5e6f7e3b 100644 --- a/runtime/agent_core_run.py +++ b/runtime/agent_core_run.py @@ -32,7 +32,7 @@ class AgentCoreRunInput: parent_span_id: str | None run_id: str | None = None max_messages: int = 80 - max_tool_rounds: int = 8 + max_tool_rounds: int = 30 max_tool_workers: int = 8 max_attempts: int = 2 memory_context: OclawMemoryContext | None = None diff --git a/runtime/chat/agent.py b/runtime/chat/agent.py index 2a48f71c..cc6af8f1 100644 --- a/runtime/chat/agent.py +++ b/runtime/chat/agent.py @@ -42,7 +42,7 @@ class GenerationInterrupted(Exception): @dataclass(frozen=True) class AgentConfig: max_messages: int = AGENT_CONTEXT_MESSAGES - max_tool_rounds: int = 8 + max_tool_rounds: int = 30 max_tool_workers: int = 8 diff --git a/runtime/direct_loop.py b/runtime/direct_loop.py index c71badbb..a562bc49 100644 --- a/runtime/direct_loop.py +++ b/runtime/direct_loop.py @@ -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 = 8, + max_tool_rounds: int = 30, max_tool_workers: int = 8, on_token: Optional[Callable[[str], None]] = None, on_progress: Optional[Callable[[str], None]] = None, diff --git a/runtime/gateway.py b/runtime/gateway.py index 6ce3453a..3bd7ed99 100644 --- a/runtime/gateway.py +++ b/runtime/gateway.py @@ -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", 8, 1, 30), + max_tool_rounds=_get_int_setting("AIA_TURN_MAX_TOOL_ROUNDS", 30, 1, 100), 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, diff --git a/runtime/worker.py b/runtime/worker.py index be6fd94f..8a8316c4 100644 --- a/runtime/worker.py +++ b/runtime/worker.py @@ -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 8) + max_tool_rounds = int(store.get_setting("AIA_TURN_MAX_TOOL_ROUNDS") or 30) 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, 30)), + max_tool_rounds=max(1, min(max_tool_rounds, 100)), max_tool_workers=max(1, min(max_tool_workers, 32)), max_attempts=2, memory_context=memory_ctx,