Files
tianxuan/analysis/tools/_dispatch.py
T

100 lines
4.1 KiB
Python

"""Tool call dispatcher — maps tool names to handler functions."""
import asyncio
from ._helpers import _truncate_response
from .load_data import _handle_load_data
from .profile import _handle_profile_data
from .filter import _handle_filter_data
from .preprocess import _handle_preprocess_data
from .clustering import _handle_run_clustering, _handle_filter_and_cluster
from .evaluate import _handle_evaluate_clustering
from .features import _handle_extract_features
from .export import _handle_export_results
from .entities import _handle_build_entity_profiles, _handle_compute_scores
from .anomalies import _handle_detect_anomalies, _handle_visualize_anomalies
from .diagnostics import (
_handle_validate_data, _handle_explore_distributions, _handle_find_outliers,
_handle_diagnose_clustering, _handle_compare_datasets,
_handle_export_debug_sample, _handle_repair_schema,
)
from .analysis import (
_handle_analyze_patterns, _handle_analyze_temporal, _handle_analyze_fft,
_handle_analyze_tls_health, _handle_analyze_geo_distribution,
_handle_analyze_entity_detail,
)
from .data_mgmt import _handle_list_datasets, _handle_drop_dataset, _handle_clone_dataset
from .distance_matrix import _handle_compute_distance_matrix
async def handle_call(name: str, arguments: dict) -> dict:
"""Dispatch a tool call to the appropriate handler.
Extracts the mandatory ``_timeout`` parameter (set by the LLM) from
*arguments* and enforces it as an ``asyncio.wait_for`` deadline.
Args:
name: Tool name (must match one of the 30 tools).
arguments: Tool-specific parameters, must include ``_timeout``.
Returns:
A JSON-serialisable dict.
Raises:
ValueError: If *name* is not a recognised tool.
"""
_handlers = {
'load_data': _handle_load_data,
'profile_data': _handle_profile_data,
'filter_data': _handle_filter_data,
'preprocess_data': _handle_preprocess_data,
'run_clustering': _handle_run_clustering,
'evaluate_clustering': _handle_evaluate_clustering,
'extract_features': _handle_extract_features,
'export_results': _handle_export_results,
'list_datasets': _handle_list_datasets,
'drop_dataset': _handle_drop_dataset,
'clone_dataset': _handle_clone_dataset,
'build_entity_profiles': _handle_build_entity_profiles,
'compute_scores': _handle_compute_scores,
'filter_and_cluster': _handle_filter_and_cluster,
'detect_anomalies': _handle_detect_anomalies,
'visualize_anomalies': _handle_visualize_anomalies,
'validate_data': _handle_validate_data,
'explore_distributions': _handle_explore_distributions,
'find_outliers': _handle_find_outliers,
'diagnose_clustering': _handle_diagnose_clustering,
'compare_datasets': _handle_compare_datasets,
'export_debug_sample': _handle_export_debug_sample,
'repair_schema': _handle_repair_schema,
'analyze_patterns': _handle_analyze_patterns,
'analyze_temporal': _handle_analyze_temporal,
'analyze_fft': _handle_analyze_fft,
'analyze_tls_health': _handle_analyze_tls_health,
'analyze_geo_distribution': _handle_analyze_geo_distribution,
'analyze_entity_detail': _handle_analyze_entity_detail,
'compute_distance_matrix': _handle_compute_distance_matrix,
}
handler = _handlers.get(name)
if handler is None:
raise ValueError(f"Unknown tool: '{name}'")
# Extract mandatory _timeout from the LLM-provided arguments
timeout = arguments.pop('_timeout', 0)
cleaned_args = arguments # _timeout already removed by pop
# Execute the handler with optional timeout
if timeout and timeout > 0:
try:
result = await asyncio.wait_for(
handler(**cleaned_args),
timeout=timeout,
)
except asyncio.TimeoutError:
result = {'error': f'工具 {name} 执行超时 ({timeout}秒)'}
else:
result = await handler(**cleaned_args)
# Always ensure truncated key exists
if 'truncated' not in result:
result['truncated'] = False
return _truncate_response(result)