feat(assistant): implement tool registry and expand assistant capabilities
Introduce a centralized tool registry system for the assistant to manage executable operations, permissions, and tool catalogs. This refactors the assistant dispatch logic from a monolithic approach to a modular, decorator-based registry. Key changes: - Implement `AssistantToolRegistry` to handle tool registration, permission checks, and safe operation identification. - Add a suite of new assistant tools: backup, commit, branch creation, deployment, health summary, environment listing, LLM operations, maintenance, migration, and dashboard searching. - Refactor `_dispatch.py` and `_llm_planner.py` to utilize the new registry for intent resolution and tool catalog building. - Enhance the LLM planner to support more descriptive clarification responses in Russian when intents are ambiguous. - Update the frontend to support the new tool-based workflow, including improved i18n labels for assistant operations and a new step-by-step wizard for the migration page. - Add ADR-0008 to document the architectural decision for the tool registry.
This commit is contained in:
79
backend/src/api/routes/assistant/_tool_task_status.py
Normal file
79
backend/src/api/routes/assistant/_tool_task_status.py
Normal file
@@ -0,0 +1,79 @@
|
||||
# #region AssistantToolTaskStatus [C:3] [TYPE Module] [SEMANTICS assistant, tool, status, task]
|
||||
# @BRIEF Handler for the "get_task_status" tool — retrieve task status by id or latest user task.
|
||||
# @LAYER API
|
||||
# @RELATION DEPENDS_ON -> [AssistantToolRegistry]
|
||||
# @RELATION DEPENDS_ON -> [TaskManager]
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
from fastapi import HTTPException
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from src.core.config_manager import ConfigManager
|
||||
from src.core.logger import belief_scope, logger
|
||||
from src.core.task_manager import TaskManager
|
||||
from src.schemas.auth import User
|
||||
|
||||
from ._resolvers import _build_task_observability_summary, _extract_result_deep_links
|
||||
from ._schemas import AssistantAction
|
||||
from ._tool_registry import _check_any_permission, assistant_tool
|
||||
|
||||
|
||||
# #region handle_get_task_status [C:3] [TYPE Function]
|
||||
@assistant_tool(
|
||||
operation="get_task_status",
|
||||
domain="status",
|
||||
description="Get task status by task_id or latest user task",
|
||||
optional_entities=["task_id"],
|
||||
risk_level="safe",
|
||||
requires_confirmation=False,
|
||||
permission_checks=[("tasks", "READ")],
|
||||
)
|
||||
@belief_scope("get_task_status")
|
||||
async def handle_get_task_status(
|
||||
intent: dict[str, Any],
|
||||
current_user: User,
|
||||
task_manager: TaskManager,
|
||||
config_manager: ConfigManager,
|
||||
db: Session,
|
||||
) -> tuple[str, str | None, list[AssistantAction]]:
|
||||
"""Get task status by task_id or latest user task."""
|
||||
_check_any_permission(current_user, [("tasks", "READ")])
|
||||
entities = intent.get("entities", {})
|
||||
task_id = entities.get("task_id")
|
||||
if not task_id:
|
||||
recent = [
|
||||
t
|
||||
for t in task_manager.get_tasks(limit=20, offset=0)
|
||||
if t.user_id == current_user.id
|
||||
]
|
||||
if not recent:
|
||||
return ("У вас пока нет задач в истории.", None, [])
|
||||
task = recent[0]
|
||||
actions = [AssistantAction(type="open_task", label="Open Task", target=task.id)]
|
||||
if str(task.status).upper() in {"SUCCESS", "FAILED"}:
|
||||
actions.extend(_extract_result_deep_links(task, config_manager))
|
||||
summary_line = _build_task_observability_summary(task, config_manager)
|
||||
text = (
|
||||
f"Последняя задача: {task.id}, статус: {task.status}."
|
||||
+ (f"\n{summary_line}" if summary_line else "")
|
||||
)
|
||||
return (text, task.id, actions)
|
||||
task = task_manager.get_task(task_id)
|
||||
if not task:
|
||||
raise HTTPException(status_code=404, detail=f"Task {task_id} not found")
|
||||
actions = [AssistantAction(type="open_task", label="Open Task", target=task.id)]
|
||||
if str(task.status).upper() in {"SUCCESS", "FAILED"}:
|
||||
actions.extend(_extract_result_deep_links(task, config_manager))
|
||||
summary_line = _build_task_observability_summary(task, config_manager)
|
||||
text = (
|
||||
f"Статус задачи {task.id}: {task.status}."
|
||||
+ (f"\n{summary_line}" if summary_line else "")
|
||||
)
|
||||
return (text, task.id, actions)
|
||||
|
||||
|
||||
# #endregion handle_get_task_status
|
||||
# #endregion AssistantToolTaskStatus
|
||||
Reference in New Issue
Block a user