const { ToolExecution, Plan, Document, sequelize } = require('../models'); const logger = require('../utils/logger'); const queryModelService = require('../services/queryModelService'); const executeTool = async (req, res) => { try { const { planId, toolName, toolType, inputParameters } = req.body; if (!planId || !toolName || !toolType || !inputParameters) { return res.status(400).json({ success: false, error: 'Plan ID, tool name, type, and input parameters are required' }); } // Verify plan exists const plan = await Plan.findByPk(planId); if (!plan) { return res.status(404).json({ success: false, error: 'Plan not found' }); } // Execute tool using QUERYMODEL service const toolExecution = await queryModelService.executeTool( toolName, toolType, inputParameters, planId ); logger.info(`Tool executed: ${toolName} for plan ${planId}`); res.json({ success: true, data: { toolExecution } }); } catch (error) { logger.error('Execute tool error:', error); res.status(500).json({ success: false, error: 'Internal server error' }); } }; const getToolExecutions = async (req, res) => { try { const { planId, toolType, status, page = 1, limit = 10 } = req.query; const whereClause = {}; if (planId) whereClause.plan_id = planId; if (toolType) whereClause.tool_type = toolType; if (status) whereClause.status = status; const toolExecutions = await ToolExecution.findAndCountAll({ where: whereClause, include: [ { model: Plan, attributes: ['id', 'title', 'status'] }, { model: Document, attributes: ['id', 'filename', 'original_filename'] } ], order: [['created_at', 'DESC']], limit: parseInt(limit), offset: (parseInt(page) - 1) * parseInt(limit) }); res.json({ success: true, data: { toolExecutions: toolExecutions.rows, pagination: { page: parseInt(page), limit: parseInt(limit), total: toolExecutions.count, pages: Math.ceil(toolExecutions.count / parseInt(limit)) } } }); } catch (error) { logger.error('Get tool executions error:', error); res.status(500).json({ success: false, error: 'Internal server error' }); } }; const getToolExecution = async (req, res) => { try { const { executionId } = req.params; const toolExecution = await ToolExecution.findByPk(executionId, { include: [ { model: Plan, attributes: ['id', 'title', 'status'] }, { model: Document, attributes: ['id', 'filename', 'original_filename'] } ] }); if (!toolExecution) { return res.status(404).json({ success: false, error: 'Tool execution not found' }); } res.json({ success: true, data: { toolExecution } }); } catch (error) { logger.error('Get tool execution error:', error); res.status(500).json({ success: false, error: 'Internal server error' }); } }; const getToolStats = async (req, res) => { try { const stats = await ToolExecution.findAll({ attributes: [ 'tool_name', 'tool_type', [sequelize.fn('COUNT', sequelize.col('id')), 'count'], [sequelize.fn('AVG', sequelize.col('execution_time')), 'avg_execution_time'], [sequelize.fn('SUM', sequelize.col('tokens_used')), 'total_tokens'] ], group: ['tool_name', 'tool_type'], raw: true }); const totalExecutions = await ToolExecution.count(); const successfulExecutions = await ToolExecution.count({ where: { status: 'completed' } }); const failedExecutions = await ToolExecution.count({ where: { status: 'failed' } }); res.json({ success: true, data: { stats, summary: { total: totalExecutions, successful: successfulExecutions, failed: failedExecutions, successRate: totalExecutions > 0 ? (successfulExecutions / totalExecutions) * 100 : 0 } } }); } catch (error) { logger.error('Get tool stats error:', error); res.status(500).json({ success: false, error: 'Internal server error' }); } }; const retryToolExecution = async (req, res) => { try { const { executionId } = req.params; const toolExecution = await ToolExecution.findByPk(executionId); if (!toolExecution) { return res.status(404).json({ success: false, error: 'Tool execution not found' }); } if (toolExecution.status === 'running') { return res.status(400).json({ success: false, error: 'Tool execution is already running' }); } // Reset execution status await toolExecution.update({ status: 'pending', output_result: null, execution_time: null, error_message: null }); // Retry tool execution using QUERYMODEL service try { const retryExecution = await queryModelService.executeTool( toolExecution.tool_name, toolExecution.tool_type, toolExecution.input_parameters, toolExecution.plan_id ); // Update the original execution record with retry results await toolExecution.update({ output_result: retryExecution.output_result, status: retryExecution.status, execution_time: retryExecution.execution_time, tokens_used: retryExecution.tokens_used, error_message: null }); logger.info(`Tool execution retried successfully: ${executionId}`); } catch (retryError) { logger.error(`Tool execution retry failed: ${executionId}`, retryError); await toolExecution.update({ status: 'failed', error_message: retryError.message }); throw retryError; } logger.info(`Tool execution retried: ${executionId}`); res.json({ success: true, data: { toolExecution } }); } catch (error) { logger.error('Retry tool execution error:', error); res.status(500).json({ success: false, error: 'Internal server error' }); } }; module.exports = { executeTool, getToolExecutions, getToolExecution, getToolStats, retryToolExecution };