first commit
This commit is contained in:
@@ -0,0 +1,250 @@
|
||||
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
|
||||
};
|
||||
Reference in New Issue
Block a user