typedef ToolHandler = Future> Function(Map args); class ToolDefinition { final String name; final String description; final Map parameters; final ToolHandler handler; ToolDefinition({ required this.name, required this.description, required this.parameters, required this.handler, }); } class ToolRegistry { static final Map _tools = {}; static bool _initialized = false; static void initialize() { if (_initialized) return; _tools['create_calendar_event'] = ToolDefinition( name: 'create_calendar_event', description: '创建一个日历事件或待办事项', parameters: { 'type': 'object', 'properties': { 'title': { 'type': 'string', 'description': '事件标题', 'minLength': 1, 'maxLength': 100, }, 'description': {'type': 'string', 'description': '事件描述'}, 'startAt': { 'type': 'string', 'format': 'date-time', 'description': '开始时间 (ISO8601)', }, 'endAt': { 'type': 'string', 'format': 'date-time', 'description': '结束时间 (ISO8601)', }, 'timezone': {'type': 'string', 'default': 'Asia/Shanghai'}, 'location': {'type': 'string'}, 'notes': {'type': 'string'}, }, 'required': ['title', 'startAt'], }, handler: _handleCreateCalendarEvent, ); _initialized = true; } static Future> _handleCreateCalendarEvent( Map args, ) async { final eventId = 'evt_${DateTime.now().millisecondsSinceEpoch}'; return { 'eventId': eventId, 'ok': true, 'message': '日程已创建', 'title': args['title'], 'description': args['description'], 'startAt': args['startAt'], 'endAt': args['endAt'], 'timezone': args['timezone'] ?? 'Asia/Shanghai', 'location': args['location'], 'color': '#4F46E5', 'sourceType': 'agentGenerated', }; } static ToolDefinition? getTool(String name) => _tools[name]; static List getAllTools() => _tools.values.toList(); static Future> execute( String toolName, Map args, ) async { final tool = _tools[toolName]; if (tool == null) throw ToolNotFoundException('Tool not found: $toolName'); return tool.handler(args); } static ToolValidationResult validateArgs( String toolName, Map args, ) { final tool = _tools[toolName]; if (tool == null) return ToolValidationResult( ok: false, error: 'Tool not found: $toolName', ); final required = tool.parameters['required'] as List? ?? []; final missing = []; for (final field in required) { if (!args.containsKey(field) || args[field] == null) missing.add(field as String); } if (missing.isNotEmpty) { return ToolValidationResult( ok: false, error: 'Missing required fields: ${missing.join(', ')}', ); } return ToolValidationResult(ok: true); } } class ToolNotFoundException implements Exception { final String message; ToolNotFoundException(this.message); @override String toString() => 'ToolNotFoundException: $message'; } class ToolValidationResult { final bool ok; final String? error; ToolValidationResult({required this.ok, this.error}); }