mirror of
https://github.com/hansjone/oclaw.git
synced 2026-10-09 04:40:45 +08:00
- Add runtime/plan_agent_v2 package and shims; gateway/direct_loop/WS wiring - Admin chat: interaction mode and specialist only in user menu; session API stores memory_mode and execution_mode only - POST /admin/api/chat/user-mode mirrors plan_agent_version to AIA_EXPERT_PLAN_AGENT_V2_ENABLED (v2 to 1, v1 to 0) - Composer cleanup (hidden mode select, no reasoning toggle in meta bar); tests and _local/system.env.example Co-authored-by: Cursor <cursoragent@cursor.com>
52 lines
1.3 KiB
Python
52 lines
1.3 KiB
Python
from __future__ import annotations
|
|
|
|
from typing import Iterable
|
|
|
|
from .models import PLAN_MODE_PLAN
|
|
from oclaw.runtime.tools.base import ToolRegistry, ToolSpec
|
|
|
|
|
|
_DEFAULT_PLAN_ALLOWLIST = frozenset(
|
|
{
|
|
"read_file",
|
|
"search_files",
|
|
"glob",
|
|
"list_directory",
|
|
"list_workspace_tree",
|
|
"search_files_context",
|
|
"system_time",
|
|
# Plan-mode control tools are non-read-only by design, but must stay callable.
|
|
"enter_plan_mode_v2",
|
|
"exit_plan_mode_v2",
|
|
}
|
|
)
|
|
|
|
|
|
def plan_mode_allowed_tool_names(extra_allowed: Iterable[str] | None = None) -> set[str]:
|
|
out = set(_DEFAULT_PLAN_ALLOWLIST)
|
|
for x in (extra_allowed or []):
|
|
n = str(x or "").strip()
|
|
if n:
|
|
out.add(n)
|
|
return out
|
|
|
|
|
|
def filter_tools_for_mode(
|
|
*,
|
|
registry: ToolRegistry,
|
|
mode: str,
|
|
extra_allowed: Iterable[str] | None = None,
|
|
) -> list[ToolSpec]:
|
|
tools = list(registry.list())
|
|
if str(mode or "").strip().lower() != PLAN_MODE_PLAN:
|
|
return tools
|
|
allow = plan_mode_allowed_tool_names(extra_allowed=extra_allowed)
|
|
out: list[ToolSpec] = []
|
|
for t in tools:
|
|
if t.name in allow or bool(t.is_read_only()):
|
|
out.append(t)
|
|
return out
|
|
|
|
|
|
__all__ = ["filter_tools_for_mode", "plan_mode_allowed_tool_names"]
|
|
|