sofhiaazzhr's picture
[KM-678] feat(tools): trim FE slash menu to /help + /report
fed17cc
Raw
History Blame
5.24 kB
"""Tool / command catalog API endpoints.
Exposes the agent's user-invocable slash-command catalog so the Golang backend
can cache it and the frontend can render its "/" command menu WITHOUT calling the
AI agent for every list (Golang GETs + caches `list_tools`).
Scope (2026-06-24, KM-674): the FE slash-command catalog is now just the two
FE-callable skills — `/help` and `/report`. Naming: verb-first, kebab-case, `/`
prefix; each command maps 1:1 to a real internal tool/intent `name` (the dispatch
key).
The analytics + data-access tools (analyze_*, check_*, retrieve_*) and the retired
`/problem-statement` skill are kept COMMENTED in the catalog below, NOT deleted —
they still exist and run via the router/Planner, and check_data/check_knowledge are
served by Golang; they are simply not surfaced in the FE slash menu for now. Slash
invocation bypasses the router to the tool directly, so re-exposing one is a matter
of un-commenting its entry.
Stateless and deterministic — safe for the Golang backend to cache.
"""
from typing import Literal
from fastapi import APIRouter
from pydantic import BaseModel
from src.middlewares.logging import get_logger, log_execution
logger = get_logger("tools_api")
router = APIRouter(prefix="/api/v1", tags=["Tools"])
CommandType = Literal["skill", "analytics", "data_access"]
class CommandResponse(BaseModel):
command: str # FE-facing slash command, e.g. "/analyze-descriptive"
name: str # internal handler/tool name, e.g. "analyze_descriptive"
type: CommandType
description: str
class ListToolsResponse(BaseModel):
count: int
tools: list[CommandResponse]
# Single source of truth for the FE slash-command catalog. Order = display order.
# Keep `command` in Harry's convention (verb-first, kebab-case, `/`); `name` is the
# internal route/tool name used by the orchestrator.
#
# 2026-06-24 (KM-674 batch): the FE-callable skills are ONLY /help + /report. The rest
# below are COMMENTED OUT — NOT deleted — on purpose:
# - /problem-statement is retired (objective + business_questions now live in the
# New-Analysis form, not a slash skill).
# - check_data / check_knowledge stay available but are served by Golang, not exposed
# in the FE slash menu.
# - the analytics + data-access tools still exist and run via the router/Planner; they
# are simply not surfaced as FE slash commands here.
# Re-enable any line if the FE slash menu is later widened back out.
_COMMAND_CATALOG: list[CommandResponse] = [
CommandResponse(
command="/help",
name="help",
type="skill",
description="Show what the assistant can do and guide your next step.",
),
CommandResponse(
command="/report",
name="report",
type="skill",
description="Generate a versioned analysis report (background, EDA, "
"key findings, insights).",
),
# CommandResponse(
# command="/problem-statement",
# name="problem_statement",
# type="skill",
# description="Define and validate your analysis goal (objective + metric) "
# "before exploring data.",
# ),
# CommandResponse(
# command="/analyze-descriptive",
# name="analyze_descriptive",
# type="analytics",
# description="Summary statistics for selected columns (count, mean, min, max, …).",
# ),
# CommandResponse(
# command="/analyze-aggregate",
# name="analyze_aggregate",
# type="analytics",
# description="Group and aggregate values (sum, count, average) by dimension.",
# ),
# CommandResponse(
# command="/analyze-correlation",
# name="analyze_correlation",
# type="analytics",
# description="Correlation strength between numeric columns.",
# ),
# CommandResponse(
# command="/analyze-trend",
# name="analyze_trend",
# type="analytics",
# description="Trend of a value over time at a chosen frequency.",
# ),
# CommandResponse(
# command="/check-data",
# name="check_data",
# type="data_access",
# description="Inventory of the available structured data sources.",
# ),
# CommandResponse(
# command="/check-knowledge",
# name="check_knowledge",
# type="data_access",
# description="Inventory of the available knowledge / uploaded documents.",
# ),
# CommandResponse(
# command="/retrieve-data",
# name="retrieve_data",
# type="data_access",
# description="Pull rows from a structured source for analysis.",
# ),
# CommandResponse(
# command="/retrieve-knowledge",
# name="retrieve_knowledge",
# type="data_access",
# description="Retrieve relevant passages from your uploaded documents.",
# ),
]
@router.get("/tools", response_model=ListToolsResponse)
@log_execution(logger)
async def list_tools() -> ListToolsResponse:
"""List the user-invocable slash-command catalog (skills + tools).
Static per deployment — safe for the Golang backend to cache.
"""
return ListToolsResponse(count=len(_COMMAND_CATALOG), tools=_COMMAND_CATALOG)