refactor(tools): fold tool_search_names into tool_search_catalog (single importer pair), dict-dispatch modal backend selection, compact registry.register calls and shebangs
This commit is contained in:
+2
-7
@@ -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="💡")
|
||||
|
||||
+2
-7
@@ -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="📋")
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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.
|
||||
|
||||
+5
-10
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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})
|
||||
+5
-11
@@ -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="🧭")
|
||||
|
||||
Reference in New Issue
Block a user