mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-04-28 01:21:43 +00:00
feat: devex help, add Makefile, ruff, pre-commit, and modernize CI
This commit is contained in:
parent
172a38c344
commit
f4d7e6a29e
111 changed files with 11655 additions and 10200 deletions
|
|
@ -16,7 +16,7 @@ Import chain (circular-import safe):
|
|||
|
||||
import json
|
||||
import logging
|
||||
from typing import Any, Callable, Dict, List, Optional, Set
|
||||
from collections.abc import Callable
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
|
@ -25,12 +25,17 @@ class ToolEntry:
|
|||
"""Metadata for a single registered tool."""
|
||||
|
||||
__slots__ = (
|
||||
"name", "toolset", "schema", "handler", "check_fn",
|
||||
"requires_env", "is_async", "description",
|
||||
"name",
|
||||
"toolset",
|
||||
"schema",
|
||||
"handler",
|
||||
"check_fn",
|
||||
"requires_env",
|
||||
"is_async",
|
||||
"description",
|
||||
)
|
||||
|
||||
def __init__(self, name, toolset, schema, handler, check_fn,
|
||||
requires_env, is_async, description):
|
||||
def __init__(self, name, toolset, schema, handler, check_fn, requires_env, is_async, description):
|
||||
self.name = name
|
||||
self.toolset = toolset
|
||||
self.schema = schema
|
||||
|
|
@ -45,8 +50,8 @@ class ToolRegistry:
|
|||
"""Singleton registry that collects tool schemas + handlers from tool files."""
|
||||
|
||||
def __init__(self):
|
||||
self._tools: Dict[str, ToolEntry] = {}
|
||||
self._toolset_checks: Dict[str, Callable] = {}
|
||||
self._tools: dict[str, ToolEntry] = {}
|
||||
self._toolset_checks: dict[str, Callable] = {}
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Registration
|
||||
|
|
@ -81,7 +86,7 @@ class ToolRegistry:
|
|||
# Schema retrieval
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
def get_definitions(self, tool_names: Set[str], quiet: bool = False) -> List[dict]:
|
||||
def get_definitions(self, tool_names: set[str], quiet: bool = False) -> list[dict]:
|
||||
"""Return OpenAI-format tool schemas for the requested tool names.
|
||||
|
||||
Only tools whose ``check_fn()`` returns True (or have no check_fn)
|
||||
|
|
@ -122,6 +127,7 @@ class ToolRegistry:
|
|||
try:
|
||||
if entry.is_async:
|
||||
from model_tools import _run_async
|
||||
|
||||
return _run_async(entry.handler(args, **kwargs))
|
||||
return entry.handler(args, **kwargs)
|
||||
except Exception as e:
|
||||
|
|
@ -132,16 +138,16 @@ class ToolRegistry:
|
|||
# Query helpers (replace redundant dicts in model_tools.py)
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
def get_all_tool_names(self) -> List[str]:
|
||||
def get_all_tool_names(self) -> list[str]:
|
||||
"""Return sorted list of all registered tool names."""
|
||||
return sorted(self._tools.keys())
|
||||
|
||||
def get_toolset_for_tool(self, name: str) -> Optional[str]:
|
||||
def get_toolset_for_tool(self, name: str) -> str | None:
|
||||
"""Return the toolset a tool belongs to, or None."""
|
||||
entry = self._tools.get(name)
|
||||
return entry.toolset if entry else None
|
||||
|
||||
def get_tool_to_toolset_map(self) -> Dict[str, str]:
|
||||
def get_tool_to_toolset_map(self) -> dict[str, str]:
|
||||
"""Return ``{tool_name: toolset_name}`` for every registered tool."""
|
||||
return {name: e.toolset for name, e in self._tools.items()}
|
||||
|
||||
|
|
@ -160,14 +166,14 @@ class ToolRegistry:
|
|||
logger.debug("Toolset %s check raised; marking unavailable", toolset)
|
||||
return False
|
||||
|
||||
def check_toolset_requirements(self) -> Dict[str, bool]:
|
||||
def check_toolset_requirements(self) -> dict[str, bool]:
|
||||
"""Return ``{toolset: available_bool}`` for every toolset."""
|
||||
toolsets = set(e.toolset for e in self._tools.values())
|
||||
return {ts: self.is_toolset_available(ts) for ts in sorted(toolsets)}
|
||||
|
||||
def get_available_toolsets(self) -> Dict[str, dict]:
|
||||
def get_available_toolsets(self) -> dict[str, dict]:
|
||||
"""Return toolset metadata for UI display."""
|
||||
toolsets: Dict[str, dict] = {}
|
||||
toolsets: dict[str, dict] = {}
|
||||
for entry in self._tools.values():
|
||||
ts = entry.toolset
|
||||
if ts not in toolsets:
|
||||
|
|
@ -184,9 +190,9 @@ class ToolRegistry:
|
|||
toolsets[ts]["requirements"].append(env)
|
||||
return toolsets
|
||||
|
||||
def get_toolset_requirements(self) -> Dict[str, dict]:
|
||||
def get_toolset_requirements(self) -> dict[str, dict]:
|
||||
"""Build a TOOLSET_REQUIREMENTS-compatible dict for backward compat."""
|
||||
result: Dict[str, dict] = {}
|
||||
result: dict[str, dict] = {}
|
||||
for entry in self._tools.values():
|
||||
ts = entry.toolset
|
||||
if ts not in result:
|
||||
|
|
@ -217,11 +223,13 @@ class ToolRegistry:
|
|||
if self.is_toolset_available(ts):
|
||||
available.append(ts)
|
||||
else:
|
||||
unavailable.append({
|
||||
"name": ts,
|
||||
"env_vars": entry.requires_env,
|
||||
"tools": [e.name for e in self._tools.values() if e.toolset == ts],
|
||||
})
|
||||
unavailable.append(
|
||||
{
|
||||
"name": ts,
|
||||
"env_vars": entry.requires_env,
|
||||
"tools": [e.name for e in self._tools.values() if e.toolset == ts],
|
||||
}
|
||||
)
|
||||
return available, unavailable
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue