mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-03 09:17:09 +08:00
124 lines
4.0 KiB
Python
124 lines
4.0 KiB
Python
#!/usr/bin/env python3
|
|
"""Workspace tool — inspect and search the Hermes workspace."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
from typing import Any
|
|
|
|
from agent.workspace import (
|
|
index_workspace_knowledgebase,
|
|
workspace_list,
|
|
workspace_retrieve,
|
|
workspace_search,
|
|
workspace_status,
|
|
)
|
|
from hermes_cli.config import load_config
|
|
from tools.registry import registry
|
|
|
|
|
|
WORKSPACE_SCHEMA = {
|
|
"name": "workspace",
|
|
"description": "Manage the Hermes workspace under HERMES_HOME. Use this to inspect workspace status, rebuild the workspace manifest, list files, or search within workspace documents without relying on the terminal environment.",
|
|
"parameters": {
|
|
"type": "object",
|
|
"properties": {
|
|
"action": {
|
|
"type": "string",
|
|
"enum": ["status", "index", "list", "search", "retrieve"],
|
|
"description": "What to do: status shows roots and counts, index rebuilds the manifest and chunk index, list enumerates files, search searches text lines, retrieve returns ranked chunk-level retrieval results.",
|
|
},
|
|
"query": {
|
|
"type": "string",
|
|
"description": "Regex query to search for when action='search'.",
|
|
},
|
|
"path": {
|
|
"type": "string",
|
|
"description": "Optional subpath within the workspace to scope list/search operations.",
|
|
},
|
|
"file_glob": {
|
|
"type": "string",
|
|
"description": "Optional filename glob filter for search, e.g. '*.md'.",
|
|
},
|
|
"limit": {
|
|
"type": "integer",
|
|
"description": "Maximum number of entries or matches to return.",
|
|
"default": 20,
|
|
},
|
|
"offset": {
|
|
"type": "integer",
|
|
"description": "Skip the first N entries or matches.",
|
|
"default": 0,
|
|
},
|
|
"recursive": {
|
|
"type": "boolean",
|
|
"description": "When action='list', recurse through subdirectories (default true).",
|
|
"default": True,
|
|
},
|
|
},
|
|
"required": ["action"],
|
|
},
|
|
}
|
|
|
|
|
|
def workspace_tool(
|
|
action: str,
|
|
query: str = "",
|
|
path: str = "",
|
|
file_glob: str | None = None,
|
|
limit: int = 20,
|
|
offset: int = 0,
|
|
recursive: bool = True,
|
|
) -> str:
|
|
try:
|
|
config = load_config()
|
|
if action == "status":
|
|
result: dict[str, Any] = workspace_status(config)
|
|
elif action == "index":
|
|
result = index_workspace_knowledgebase(config)
|
|
elif action == "list":
|
|
result = workspace_list(
|
|
config=config,
|
|
relative_path=path,
|
|
recursive=recursive,
|
|
limit=limit,
|
|
offset=offset,
|
|
)
|
|
elif action == "search":
|
|
result = workspace_search(
|
|
query=query,
|
|
config=config,
|
|
relative_path=path,
|
|
file_glob=file_glob,
|
|
limit=limit,
|
|
offset=offset,
|
|
)
|
|
elif action == "retrieve":
|
|
result = workspace_retrieve(
|
|
query=query,
|
|
config=config,
|
|
limit=limit,
|
|
)
|
|
else:
|
|
result = {"success": False, "error": f"Unknown action: {action}"}
|
|
return json.dumps(result, ensure_ascii=False)
|
|
except Exception as e: # pragma: no cover - defensive wrapper
|
|
return json.dumps({"success": False, "error": str(e)}, ensure_ascii=False)
|
|
|
|
|
|
registry.register(
|
|
name="workspace",
|
|
toolset="workspace",
|
|
schema=WORKSPACE_SCHEMA,
|
|
handler=lambda args, **kw: workspace_tool(
|
|
action=args.get("action", ""),
|
|
query=args.get("query", ""),
|
|
path=args.get("path", ""),
|
|
file_glob=args.get("file_glob"),
|
|
limit=args.get("limit", 20),
|
|
offset=args.get("offset", 0),
|
|
recursive=args.get("recursive", True),
|
|
),
|
|
check_fn=lambda: True,
|
|
)
|