refactor: split tool declarations into domain files + role config UI

tools/__init__.py shrinks from 1,137 → 250 lines. Each domain file now
owns both its callables and its FunctionDeclarations (DECLARATIONS list),
so adding a new tool only touches one file.

New TOOL_CATEGORIES dict exported from __init__ — used by the UI for
grouped tool checkboxes.

Role config UI (Settings → Model Registry → Role Assignments):
- ⚙ button per role expands an inline configure panel
- Textarea for system_append (injected into system prompt for this role)
- Grouped checkboxes for tool allow-list (all checked = no restriction)
- POST /api/models/role-config saves both fields; updates ROLE_CONFIG_DATA
  in-page so re-open reflects current state without a page reload

Backend:
- model_registry.set_role_config() writes system_append + tools to registry
- TOOL_CATEGORIES exported from tools/__init__ for UI rendering
- TOOLS.md header updated: 30 → 39 tools (ae_journal_* and cortex_* additions)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Scott Idem
2026-05-01 20:40:50 -04:00
parent 49123cdd5c
commit eab92d876d
15 changed files with 993 additions and 974 deletions

View File

@@ -415,6 +415,24 @@ def get_best_local_model(username: str, role: str = "chat") -> dict | None:
return None
def set_role_config(username: str, role: str, system_append: str, tools: list[str] | None) -> None:
"""Save system_append and tools allow-list for a role.
tools=None clears the allow-list (role uses all accessible tools).
tools=[] would mean no tools at all — validate in the caller if that's undesired.
"""
data = _load(username)
roles = data.setdefault("roles", {})
if role not in roles:
roles[role] = {}
roles[role]["system_append"] = system_append.strip()
if tools is None:
roles[role].pop("tools", None)
else:
roles[role]["tools"] = [t for t in tools if t]
_save(username, data)
def get_role_config(username: str, role: str) -> dict:
"""
Return supplemental config for a role: system_append and tools.