Files
Timmy-time-dashboard/src/dashboard/routes/tools.py
Alexander Whitestone 45344ca5af
Some checks failed
Tests / test (pull_request) Has been skipped
Tests / lint (pull_request) Failing after 16s
fix: update TemplateResponse calls to new Starlette signature
Starlette changed TemplateResponse from TemplateResponse(name, context)
to TemplateResponse(request, name, context). The old calling convention
passed a dict as the 'name' parameter, which Jinja2 tried to use as a
cache key inside a tuple, causing TypeError: unhashable type: 'dict'.

Updated all old-style calls in routes/tools.py and routes/calm.py to
use the new positional-request-first signature and removed redundant
"request" key from context dicts (Starlette adds it automatically).

Fixes #1114

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 14:19:51 -04:00

62 lines
1.7 KiB
Python

"""Tools dashboard route — /tools endpoints.
Shows available tools and usage statistics.
"""
from collections import namedtuple
from fastapi import APIRouter, Request
from fastapi.responses import HTMLResponse, JSONResponse
from dashboard.templating import templates
from timmy.tools import get_all_available_tools
router = APIRouter(tags=["tools"])
_AgentView = namedtuple("AgentView", ["name", "status", "tools", "stats"])
_ToolView = namedtuple("ToolView", ["name", "description"])
_Stats = namedtuple("Stats", ["total_calls"])
def _build_agent_tools():
"""Build agent capability list from the available tools registry."""
available = get_all_available_tools()
if not available:
return []
tool_views = [
_ToolView(name=name, description=getattr(fn, "__doc__", "") or name)
for name, fn in available.items()
]
return [_AgentView(name="Timmy", status="idle", tools=tool_views, stats=_Stats(total_calls=0))]
@router.get("/tools", response_class=HTMLResponse)
async def tools_page(request: Request):
"""Render the tools dashboard page."""
available_tools = get_all_available_tools()
agent_tools = _build_agent_tools()
total_calls = 0
return templates.TemplateResponse(
request,
"tools.html",
{
"available_tools": available_tools,
"agent_tools": agent_tools,
"total_calls": total_calls,
},
)
@router.get("/tools/api/stats", response_class=JSONResponse)
async def tools_api_stats():
"""Return tool statistics as JSON."""
available_tools = get_all_available_tools()
return {
"all_stats": {},
"available_tools": list(available_tools.keys()),
}