2026-03-14 11:29:27 -07:00
#!/usr/bin/env python3
""" Workspace tool — inspect and search the Hermes workspace. """
from __future__ import annotations
import json
from typing import Any
2026-03-14 11:53:38 -07:00
from agent . workspace import (
index_workspace_knowledgebase ,
workspace_list ,
workspace_retrieve ,
workspace_search ,
workspace_status ,
)
2026-03-14 11:29:27 -07:00
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 " ,
2026-03-14 11:53:38 -07:00
" 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. " ,
2026-03-14 11:29:27 -07:00
} ,
" 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 " :
2026-03-14 11:53:38 -07:00
result = index_workspace_knowledgebase ( config )
2026-03-14 11:29:27 -07:00
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 ,
)
2026-03-14 11:53:38 -07:00
elif action == " retrieve " :
result = workspace_retrieve (
query = query ,
config = config ,
limit = limit ,
)
2026-03-14 11:29:27 -07:00
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 ,
)