111 lines
4.4 KiB
Python
111 lines
4.4 KiB
Python
"""Native runtime tool strategy rendering."""
|
|
|
|
from __future__ import annotations
|
|
|
|
|
|
_FILE_READ_TOOLS = {"file_read", "list_dir", "glob", "grep", "file_search"}
|
|
_FILE_EDIT_TOOLS = {"file_write", "file_edit", "apply_patch"}
|
|
_SHELL_TOOLS = {"shell_exec"}
|
|
_PYTHON_TOOLS = {"python_exec"}
|
|
_WEB_TOOLS = {"web_search", "web_fetch"}
|
|
_BROWSER_TOOLS = {
|
|
"browser_navigate",
|
|
"browser_navigate_back",
|
|
"browser_click",
|
|
"browser_snapshot",
|
|
"browser_type",
|
|
"browser_wait_for",
|
|
"browser_scroll",
|
|
"browser_select_option",
|
|
"browser_take_screenshot",
|
|
"browser_close",
|
|
}
|
|
_TODO_TOOLS = {"todo_write", "todo_read"}
|
|
_SUBAGENT_TOOLS = {"agent_spawn", "agent_wait", "agent_send", "agent_list"}
|
|
_COMPANY_COLLABORATION_TOOLS = {
|
|
"inbox",
|
|
"send_dm",
|
|
"ask_peer_and_wait",
|
|
"reply_message",
|
|
"broadcast_issue",
|
|
"delegate_work",
|
|
"modify_work_item",
|
|
"delete_work_item",
|
|
"manager_board_read",
|
|
"manager_board_update",
|
|
"manager_board_release",
|
|
"manager_board_rollup",
|
|
"start_meeting",
|
|
"respond_meeting",
|
|
"propose_runtime_replan",
|
|
"propose_task_adjustment",
|
|
"route_work",
|
|
"find_and_ask_expert",
|
|
"read_inbox",
|
|
}
|
|
|
|
|
|
class NativeToolStrategyBuilder:
|
|
"""Render concise tool-selection guidance for the current native tool surface."""
|
|
|
|
def __init__(self, allowed_tools: list[str] | None, *, company_mode: bool = False) -> None:
|
|
self.allowed_tools = {
|
|
str(item or "").strip()
|
|
for item in list(allowed_tools or [])
|
|
if str(item or "").strip()
|
|
}
|
|
self.company_mode = bool(company_mode)
|
|
|
|
def render(self) -> str:
|
|
if not self.allowed_tools:
|
|
return "No explicit tool surface was supplied for this runtime."
|
|
|
|
lines = [
|
|
"Use the current tool schema as the source of truth for exact arguments.",
|
|
f"Available tool count: {len(self.allowed_tools)}",
|
|
f"Available tools: {self._preview_tools()}",
|
|
"",
|
|
"Selection strategy:",
|
|
]
|
|
rules = self._rules()
|
|
if rules:
|
|
lines.extend(f"- {rule}" for rule in rules)
|
|
else:
|
|
lines.append("- Use the provided tools directly when they advance the task.")
|
|
return "\n".join(lines).strip()
|
|
|
|
def _preview_tools(self) -> str:
|
|
ordered = sorted(self.allowed_tools)
|
|
preview = ", ".join(ordered[:24])
|
|
suffix = "" if len(ordered) <= 24 else f", +{len(ordered) - 24} more"
|
|
return f"{preview}{suffix}"
|
|
|
|
def _rules(self) -> list[str]:
|
|
rules: list[str] = []
|
|
tools = self.allowed_tools
|
|
has_file_read = bool(tools & _FILE_READ_TOOLS)
|
|
has_file_edit = bool(tools & _FILE_EDIT_TOOLS)
|
|
if has_file_read:
|
|
rules.append("Use dedicated read/search/list tools for workspace inspection instead of shell text commands.")
|
|
if has_file_edit:
|
|
rules.append("Use dedicated edit/write/patch tools for file changes; verify the resulting diff or file content when useful.")
|
|
if tools & _SHELL_TOOLS:
|
|
rules.append("Use shell execution for commands, builds, tests, package scripts, and process control.")
|
|
if tools & _PYTHON_TOOLS:
|
|
rules.append("Use Python execution for calculations, data processing, and focused local experiments.")
|
|
if tools & (_WEB_TOOLS | _BROWSER_TOOLS):
|
|
rules.append("Use web/browser tools only when current external information or direct page interaction is needed.")
|
|
if tools & _TODO_TOOLS:
|
|
rules.append("Use the task ledger for multi-step work; keep one item in progress and update it as work changes.")
|
|
if tools & _SUBAGENT_TOOLS:
|
|
rules.append("Use subagents only for bounded parallel work, isolation, verification, or clearly separate scopes.")
|
|
if self.company_mode and tools & _COMPANY_COLLABORATION_TOOLS:
|
|
rules.append("Use company collaboration tools only for the active work-item coordination surface and only when available this turn.")
|
|
if self._has_parallel_read_surface():
|
|
rules.append("Run independent read/search/context-gathering tool calls in parallel when there is no dependency between them.")
|
|
return rules
|
|
|
|
def _has_parallel_read_surface(self) -> bool:
|
|
read_like_count = len(self.allowed_tools & (_FILE_READ_TOOLS | _WEB_TOOLS | _BROWSER_TOOLS))
|
|
return read_like_count >= 2
|