first commit
This commit is contained in:
@@ -0,0 +1,261 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import axios from 'axios';
|
||||
import './ToolsPage.css';
|
||||
|
||||
const ToolsPage = () => {
|
||||
const [toolExecutions, setToolExecutions] = useState([]);
|
||||
const [selectedTool, setSelectedTool] = useState('');
|
||||
const [toolInput, setToolInput] = useState('');
|
||||
const [executing, setExecuting] = useState(false);
|
||||
const [message, setMessage] = useState('');
|
||||
|
||||
const tools = [
|
||||
{
|
||||
id: 'query_expander',
|
||||
name: 'Query Expander',
|
||||
description: 'Expands and refines engineering queries for better understanding',
|
||||
icon: '🔍',
|
||||
color: 'blue'
|
||||
},
|
||||
{
|
||||
id: 'extraction',
|
||||
name: 'Document Extraction',
|
||||
description: 'Extracts relevant information from uploaded documents',
|
||||
icon: '📄',
|
||||
color: 'green'
|
||||
},
|
||||
{
|
||||
id: 'report1',
|
||||
name: 'Report Generator',
|
||||
description: 'Generates structured engineering reports',
|
||||
icon: '📊',
|
||||
color: 'purple'
|
||||
},
|
||||
{
|
||||
id: 'report2',
|
||||
name: 'File Generator',
|
||||
description: 'Creates downloadable engineering files',
|
||||
icon: '📁',
|
||||
color: 'orange'
|
||||
},
|
||||
{
|
||||
id: 'web_search',
|
||||
name: 'Web Search',
|
||||
description: 'Searches the web for current engineering information',
|
||||
icon: '🌐',
|
||||
color: 'cyan'
|
||||
},
|
||||
{
|
||||
id: 'encyclopedia_pdf',
|
||||
name: 'Encyclopedia Search',
|
||||
description: 'Searches internal PDF knowledge base',
|
||||
icon: '📚',
|
||||
color: 'red'
|
||||
}
|
||||
];
|
||||
|
||||
useEffect(() => {
|
||||
loadToolExecutions();
|
||||
}, []);
|
||||
|
||||
const loadToolExecutions = async () => {
|
||||
try {
|
||||
const response = await axios.get('/api/tools/executions');
|
||||
setToolExecutions(response.data.data.executions || []);
|
||||
} catch (error) {
|
||||
console.error('Error loading tool executions:', error);
|
||||
}
|
||||
};
|
||||
|
||||
const executeTool = async () => {
|
||||
setMessage('⚠️ **Manual tool execution is disabled.** Tools can only be executed as part of an approved engineering plan. Please use the Chat page to create and execute plans.');
|
||||
setSelectedTool('');
|
||||
setToolInput('');
|
||||
};
|
||||
|
||||
const retryExecution = async (executionId) => {
|
||||
try {
|
||||
await axios.post(`/api/tools/executions/${executionId}/retry`);
|
||||
setMessage('✅ Tool execution retried');
|
||||
loadToolExecutions();
|
||||
} catch (error) {
|
||||
console.error('Retry error:', error);
|
||||
setMessage(`❌ Retry failed: ${error.response?.data?.error || error.message}`);
|
||||
}
|
||||
};
|
||||
|
||||
const getStatusColor = (status) => {
|
||||
switch (status) {
|
||||
case 'completed': return 'success';
|
||||
case 'failed': return 'error';
|
||||
case 'running': return 'warning';
|
||||
default: return 'info';
|
||||
}
|
||||
};
|
||||
|
||||
const formatDate = (dateString) => {
|
||||
return new Date(dateString).toLocaleString();
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="tools-page">
|
||||
<div className="page-header">
|
||||
<h1>🔧 Engineering Tools</h1>
|
||||
<p>View tool execution history and results from approved engineering plans</p>
|
||||
</div>
|
||||
|
||||
{message && (
|
||||
<div className={`message ${message.includes('✅') ? 'success' : message.includes('⚠️') ? 'warning' : 'error'}`}>
|
||||
{message}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Tool Selection */}
|
||||
<div className="tool-selection">
|
||||
<div className="section-header">
|
||||
<h2>🛠️ Tool Information</h2>
|
||||
<p>Available engineering tools (execution requires approved plan)</p>
|
||||
</div>
|
||||
|
||||
<div className="tool-selector">
|
||||
<div className="tool-grid">
|
||||
{tools.map((tool) => (
|
||||
<button
|
||||
key={tool.id}
|
||||
className={`tool-card ${selectedTool === tool.id ? 'selected' : ''} ${tool.color}`}
|
||||
onClick={() => setSelectedTool(tool.id)}
|
||||
>
|
||||
<div className="tool-icon">{tool.icon}</div>
|
||||
<div className="tool-info">
|
||||
<h3>{tool.name}</h3>
|
||||
<p>{tool.description}</p>
|
||||
</div>
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{selectedTool && (
|
||||
<div className="execution-panel">
|
||||
<div className="panel-header">
|
||||
<h3>{tools.find(t => t.id === selectedTool)?.name} Information</h3>
|
||||
</div>
|
||||
<div className="panel-content">
|
||||
<div className="tool-info">
|
||||
<p><strong>Description:</strong> {tools.find(t => t.id === selectedTool)?.description}</p>
|
||||
<p><strong>Usage:</strong> This tool is automatically executed as part of approved engineering plans.</p>
|
||||
<p><strong>To use this tool:</strong></p>
|
||||
<ol>
|
||||
<li>Go to the Chat page</li>
|
||||
<li>Ask an engineering question</li>
|
||||
<li>Review the generated plan</li>
|
||||
<li>Approve the plan</li>
|
||||
<li>The system will automatically execute the appropriate tools</li>
|
||||
</ol>
|
||||
</div>
|
||||
<div className="execution-actions">
|
||||
<button
|
||||
className="execute-btn disabled"
|
||||
onClick={executeTool}
|
||||
disabled={true}
|
||||
>
|
||||
🔒 Manual Execution Disabled
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Execution History */}
|
||||
<div className="execution-history">
|
||||
<div className="section-header">
|
||||
<h2>📋 Execution History</h2>
|
||||
<p>View past tool executions and their results</p>
|
||||
</div>
|
||||
|
||||
<div className="history-container">
|
||||
{toolExecutions.length > 0 ? (
|
||||
<div className="executions-list">
|
||||
{toolExecutions.map((execution) => (
|
||||
<div key={execution.id} className="execution-card">
|
||||
<div className="execution-header">
|
||||
<div className="execution-info">
|
||||
<h4>
|
||||
{tools.find(t => t.id === execution.tool_name)?.icon}
|
||||
{tools.find(t => t.id === execution.tool_name)?.name || execution.tool_name}
|
||||
</h4>
|
||||
<div className="execution-meta">
|
||||
<span className="execution-id">ID: {execution.id}</span>
|
||||
<span className="execution-time">{formatDate(execution.created_at)}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="execution-status">
|
||||
<span className={`status-badge ${getStatusColor(execution.status)}`}>
|
||||
{execution.status}
|
||||
</span>
|
||||
{execution.status === 'failed' && (
|
||||
<button
|
||||
className="retry-btn"
|
||||
onClick={() => retryExecution(execution.id)}
|
||||
>
|
||||
🔄 Retry
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="execution-details">
|
||||
<div className="detail-section">
|
||||
<h5>Input Parameters</h5>
|
||||
<pre className="code-block">
|
||||
{JSON.stringify(execution.input_parameters, null, 2)}
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
{execution.output_result && (
|
||||
<div className="detail-section">
|
||||
<h5>Output Result</h5>
|
||||
<pre className="code-block">
|
||||
{JSON.stringify(execution.output_result, null, 2)}
|
||||
</pre>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{execution.error_message && (
|
||||
<div className="detail-section error">
|
||||
<h5>Error Message</h5>
|
||||
<pre className="error-block">
|
||||
{execution.error_message}
|
||||
</pre>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="execution-metrics">
|
||||
<div className="metric">
|
||||
<span className="metric-label">Duration:</span>
|
||||
<span className="metric-value">{execution.duration || 'N/A'}ms</span>
|
||||
</div>
|
||||
<div className="metric">
|
||||
<span className="metric-label">Tokens Used:</span>
|
||||
<span className="metric-value">{execution.tokens_used || 'N/A'}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<div className="empty-state">
|
||||
<div className="empty-icon">🔧</div>
|
||||
<h3>No tool executions yet</h3>
|
||||
<p>Execute your first tool to see the results here</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ToolsPage;
|
||||
Reference in New Issue
Block a user