diff --git a/tools/tip_tool.py b/tools/tip_tool.py index 40e4057df0..37c3d44133 100644 --- a/tools/tip_tool.py +++ b/tools/tip_tool.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 """Point at something in the Hermes desktop GUI and say one line about it — the quiet sibling of ``tour`` (same ``data-tour`` handles) with no scrim/spotlight/paging. Fire-and-forget: a tip is not a question, so blocking on a round-trip would stall the @@ -76,11 +75,7 @@ def check_tips_enabled() -> bool: registry.register( - name="show_tip", - toolset="desktop_ui", - schema=TIP_SCHEMA, + name="show_tip", toolset="desktop_ui", schema=TIP_SCHEMA, check_fn=check_tips_enabled, handler=lambda args, **kw: tip_tool( **{k: args.get(k, "") for k in ("text", "selector", "title", "side")}), - check_fn=check_tips_enabled, - emoji="💡", -) + emoji="💡") diff --git a/tools/todo_tool.py b/tools/todo_tool.py index 88d520d908..f6c972d29c 100644 --- a/tools/todo_tool.py +++ b/tools/todo_tool.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 """Todo tool: in-memory, revisioned task list for multi-step work. State lives on the AIAgent (one per session), is re-injected after context compression, and every write bumps a monotonic revision so UI clients can reject stale updates. One ``todo_list`` tool: pass @@ -293,11 +292,7 @@ TODO_SCHEMA = { from tools.registry import registry, tool_error registry.register( - name="todo_list", - toolset="todo", - schema=TODO_SCHEMA, + name="todo_list", toolset="todo", schema=TODO_SCHEMA, check_fn=check_todo_requirements, handler=lambda args, **kw: todo_tool( todos=args.get("todos"), merge=args.get("merge", False), store=kw.get("store")), - check_fn=check_todo_requirements, - emoji="📋", -) + emoji="📋") diff --git a/tools/tool_backend_helpers.py b/tools/tool_backend_helpers.py index 4bcb3ff543..14cd2c3c8e 100644 --- a/tools/tool_backend_helpers.py +++ b/tools/tool_backend_helpers.py @@ -10,8 +10,6 @@ from typing import Any, Dict, Optional from utils import is_truthy_value logger = logging.getLogger(__name__) - - _DEFAULT_BROWSER_PROVIDER = "local" _DEFAULT_MODAL_MODE = "auto" _VALID_MODAL_MODES = {"auto", "direct", "managed"} @@ -83,19 +81,14 @@ def resolve_modal_backend_state( if managed_enabled is None: managed_enabled = managed_nous_tools_enabled() managed_ok = managed_enabled and managed_ready - if requested_mode == "managed": - selected_backend = "managed" if managed_ok else None - elif requested_mode == "direct": - selected_backend = "direct" if has_direct else None - else: - selected_backend = "managed" if managed_ok else "direct" if has_direct else None - return { - "requested_mode": requested_mode, - "mode": requested_mode, - "has_direct": has_direct, - "managed_ready": managed_ready, - "managed_mode_blocked": requested_mode == "managed" and not managed_enabled, - "selected_backend": selected_backend} + exclusive = {"managed": "managed" if managed_ok else None, + "direct": "direct" if has_direct else None} + selected_backend = exclusive.get( + requested_mode, "managed" if managed_ok else "direct" if has_direct else None) + return {"requested_mode": requested_mode, "mode": requested_mode, "has_direct": has_direct, + "managed_ready": managed_ready, + "managed_mode_blocked": requested_mode == "managed" and not managed_enabled, + "selected_backend": selected_backend} def _scoped_credential(name: str) -> str: diff --git a/tools/tool_result_storage.py b/tools/tool_result_storage.py index d2bb5ba7c2..4cd2c069ca 100644 --- a/tools/tool_result_storage.py +++ b/tools/tool_result_storage.py @@ -214,9 +214,8 @@ def maybe_persist_tool_result( preview, has_more = generate_preview(content, max_chars=config.preview_size) def _persisted(path: str, host_suffix: str = "") -> str: - logger.info( - "Persisted large tool result: %s (%s, %d chars -> %s%s)", - tool_name, tool_use_id, len(content), path, host_suffix) + logger.info("Persisted large tool result: %s (%s, %d chars -> %s%s)", + tool_name, tool_use_id, len(content), path, host_suffix) return _build_persisted_message(preview, has_more, len(content), path) # Always persist host-side first: cache/spillover is the single canonical home. diff --git a/tools/tool_search.py b/tools/tool_search.py index c753b5344b..ade6fcbb10 100644 --- a/tools/tool_search.py +++ b/tools/tool_search.py @@ -17,25 +17,21 @@ from dataclasses import dataclass from typing import Any, Dict, Iterable, List, Optional, Tuple from tools.registry import tool_error -from tools.tool_search_names import ( # noqa: F401 — re-exported public names - BRIDGE_TOOL_NAMES, TOOL_CALL_NAME, TOOL_DESCRIBE_NAME, TOOL_SEARCH_NAME) from tools.tool_search_catalog import ( # noqa: F401 — re-exported public/test names - CHARS_PER_TOKEN, CatalogEntry, _corpus_stats, _entry_search_text, _fn, - _listing_group_label, _registry_entry, _short_desc, _stem, _tokenize, - build_catalog, build_catalog_listing_with_form, search_catalog) + BRIDGE_TOOL_NAMES, CHARS_PER_TOKEN, TOOL_CALL_NAME, TOOL_DESCRIBE_NAME, TOOL_SEARCH_NAME, + CatalogEntry, _corpus_stats, _entry_search_text, _fn, _listing_group_label, + _registry_entry, _short_desc, _stem, _tokenize, build_catalog, + build_catalog_listing_with_form, search_catalog) from tools.tool_search_validation import validate_deferred_call_args # noqa: F401 logger = logging.getLogger("tools.tool_search") - -# Bound the work one bridge call can request. -_MAX_QUERIES_PER_CALL = 10 +_MAX_QUERIES_PER_CALL = 10 # bound the work one bridge call can request _MAX_DESCRIBE_NAMES_PER_CALL = 10 @dataclass(frozen=True) class ToolSearchConfig: """Resolved, validated tool-search configuration for a single assembly.""" - enabled: str # "auto" | "on" | "off" — "auto" is an alias of "on" today # Listing budget as % of context; does NOT gate activation, only bounds how much # the embedded manifest may consume before it degrades (full -> names -> bare). @@ -313,7 +309,6 @@ def bridge_tool_schemas( @dataclass class AssemblyResult: """Outcome of one assembly (tests and observability).""" - tool_defs: List[Dict[str, Any]] activated: bool deferred_count: int = 0 diff --git a/tools/tool_search_catalog.py b/tools/tool_search_catalog.py index ee2e0110b7..e08603a2b5 100644 --- a/tools/tool_search_catalog.py +++ b/tools/tool_search_catalog.py @@ -13,8 +13,12 @@ from typing import Any, Dict, List, Optional, Tuple import snowballstemmer -from tools.tool_search_names import TOOL_CALL_NAME, TOOL_DESCRIBE_NAME, TOOL_SEARCH_NAME - +# Reserved bridge names: a user/plugin/MCP tool may not take them (registry override +# protection rejects such registrations). +TOOL_SEARCH_NAME = "tool_search" +TOOL_DESCRIBE_NAME = "tool_describe" +TOOL_CALL_NAME = "tool_call" +BRIDGE_TOOL_NAMES = frozenset({TOOL_SEARCH_NAME, TOOL_DESCRIBE_NAME, TOOL_CALL_NAME}) # Chars-per-token rule of thumb; 4.0 slightly underestimates (fewer false activations). CHARS_PER_TOKEN = 4.0 diff --git a/tools/tool_search_names.py b/tools/tool_search_names.py deleted file mode 100644 index bd775460da..0000000000 --- a/tools/tool_search_names.py +++ /dev/null @@ -1,9 +0,0 @@ -"""Reserved bridge tool names shared by tool_search and its catalog module.""" - -# Reserved: a user/plugin/MCP tool may not take these names — the registry's -# override protection rejects such registrations. -TOOL_SEARCH_NAME = "tool_search" -TOOL_DESCRIBE_NAME = "tool_describe" -TOOL_CALL_NAME = "tool_call" - -BRIDGE_TOOL_NAMES = frozenset({TOOL_SEARCH_NAME, TOOL_DESCRIBE_NAME, TOOL_CALL_NAME}) diff --git a/tools/tour_tool.py b/tools/tour_tool.py index f4f208d386..cab47f6da1 100644 --- a/tools/tour_tool.py +++ b/tools/tour_tool.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 """Guided tour (highlight + narrate UI elements) in the Hermes desktop GUI. Generic: the agent discovers targets (``action="targets"``), then highlights one step at a time (``show``) or hands over a step list the user pages (``start``). Round-trips @@ -139,14 +138,9 @@ def check_tours_enabled() -> bool: registry.register( - name="gui_tour", - toolset="desktop_ui", - schema=TOUR_SCHEMA, + name="gui_tour", toolset="desktop_ui", schema=TOUR_SCHEMA, check_fn=check_tours_enabled, handler=lambda args, **kw: tour_tool( - action=args.get("action", ""), - **{k: args.get(k) for k in ("surface", "selector", "title", "text", "side", "steps", "step_index")}, - callback=kw.get("callback"), - ), - check_fn=check_tours_enabled, - emoji="🧭", -) + action=args.get("action", ""), callback=kw.get("callback"), + **{k: args.get(k) for k in ("surface", "selector", "title", "text", "side", "steps", + "step_index")}), + emoji="🧭")