agent功能开发增加MCP后端
This commit is contained in:
145
src/components/ChatBot/PlanCard.js
Normal file
145
src/components/ChatBot/PlanCard.js
Normal file
@@ -0,0 +1,145 @@
|
||||
// src/components/ChatBot/PlanCard.js
|
||||
// 执行计划展示卡片
|
||||
|
||||
import React from 'react';
|
||||
import {
|
||||
Box,
|
||||
VStack,
|
||||
HStack,
|
||||
Text,
|
||||
Badge,
|
||||
Accordion,
|
||||
AccordionItem,
|
||||
AccordionButton,
|
||||
AccordionPanel,
|
||||
AccordionIcon,
|
||||
Icon,
|
||||
useColorModeValue,
|
||||
Divider,
|
||||
} from '@chakra-ui/react';
|
||||
import { FiTarget, FiCheckCircle, FiXCircle, FiClock, FiTool } from 'react-icons/fi';
|
||||
|
||||
/**
|
||||
* 执行计划卡片组件
|
||||
*/
|
||||
export const PlanCard = ({ plan, stepResults }) => {
|
||||
const cardBg = useColorModeValue('blue.50', 'blue.900');
|
||||
const borderColor = useColorModeValue('blue.200', 'blue.700');
|
||||
const successColor = useColorModeValue('green.500', 'green.300');
|
||||
const errorColor = useColorModeValue('red.500', 'red.300');
|
||||
const pendingColor = useColorModeValue('gray.400', 'gray.500');
|
||||
|
||||
const getStepStatus = (stepIndex) => {
|
||||
if (!stepResults || stepResults.length === 0) return 'pending';
|
||||
const result = stepResults.find(r => r.step_index === stepIndex);
|
||||
return result ? result.status : 'pending';
|
||||
};
|
||||
|
||||
const getStepIcon = (status) => {
|
||||
switch (status) {
|
||||
case 'success':
|
||||
return FiCheckCircle;
|
||||
case 'failed':
|
||||
return FiXCircle;
|
||||
default:
|
||||
return FiClock;
|
||||
}
|
||||
};
|
||||
|
||||
const getStepColor = (status) => {
|
||||
switch (status) {
|
||||
case 'success':
|
||||
return successColor;
|
||||
case 'failed':
|
||||
return errorColor;
|
||||
default:
|
||||
return pendingColor;
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Box
|
||||
bg={cardBg}
|
||||
borderRadius="lg"
|
||||
borderWidth="2px"
|
||||
borderColor={borderColor}
|
||||
p={4}
|
||||
mb={4}
|
||||
boxShadow="md"
|
||||
>
|
||||
<VStack align="stretch" spacing={3}>
|
||||
{/* 目标 */}
|
||||
<HStack>
|
||||
<Icon as={FiTarget} color="blue.500" boxSize={5} />
|
||||
<Text fontWeight="bold" fontSize="md">执行目标</Text>
|
||||
</HStack>
|
||||
<Text fontSize="sm" color="gray.600" pl={7}>
|
||||
{plan.goal}
|
||||
</Text>
|
||||
|
||||
<Divider />
|
||||
|
||||
{/* 规划思路 */}
|
||||
{plan.reasoning && (
|
||||
<>
|
||||
<Text fontSize="sm" fontWeight="bold">规划思路:</Text>
|
||||
<Text fontSize="sm" color="gray.600">
|
||||
{plan.reasoning}
|
||||
</Text>
|
||||
<Divider />
|
||||
</>
|
||||
)}
|
||||
|
||||
{/* 执行步骤 */}
|
||||
<HStack justify="space-between">
|
||||
<Text fontSize="sm" fontWeight="bold">执行步骤</Text>
|
||||
<Badge colorScheme="blue">{plan.steps.length} 步</Badge>
|
||||
</HStack>
|
||||
|
||||
<VStack align="stretch" spacing={2}>
|
||||
{plan.steps.map((step, index) => {
|
||||
const status = getStepStatus(index);
|
||||
const StepIcon = getStepIcon(status);
|
||||
const stepColor = getStepColor(status);
|
||||
|
||||
return (
|
||||
<HStack
|
||||
key={index}
|
||||
p={2}
|
||||
bg={useColorModeValue('white', 'gray.700')}
|
||||
borderRadius="md"
|
||||
borderWidth="1px"
|
||||
borderColor={stepColor}
|
||||
align="flex-start"
|
||||
>
|
||||
<Icon as={StepIcon} color={stepColor} boxSize={4} mt={1} />
|
||||
<VStack align="stretch" flex={1} spacing={1}>
|
||||
<HStack justify="space-between">
|
||||
<Text fontSize="sm" fontWeight="bold">
|
||||
步骤 {index + 1}: {step.tool}
|
||||
</Text>
|
||||
<Badge
|
||||
colorScheme={
|
||||
status === 'success' ? 'green' :
|
||||
status === 'failed' ? 'red' : 'gray'
|
||||
}
|
||||
fontSize="xs"
|
||||
>
|
||||
{status === 'success' ? '✓ 完成' :
|
||||
status === 'failed' ? '✗ 失败' : '⏳ 等待'}
|
||||
</Badge>
|
||||
</HStack>
|
||||
<Text fontSize="xs" color="gray.600">
|
||||
{step.reason}
|
||||
</Text>
|
||||
</VStack>
|
||||
</HStack>
|
||||
);
|
||||
})}
|
||||
</VStack>
|
||||
</VStack>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default PlanCard;
|
||||
Reference in New Issue
Block a user