This commit is contained in:
wuyifan18 2025-10-18 14:31:34 +08:00
parent e40cdd1dee
commit da2318a40c
27 changed files with 14793 additions and 3642 deletions

View File

@ -237,8 +237,10 @@ async def _achat_completion_stream(messages: list[dict]) -> str:
def _chat_completion(messages: list[dict]) -> str: def _chat_completion(messages: list[dict]) -> str:
print(messages, flush=True)
rsp = openai.ChatCompletion.create(**_cons_kwargs(messages)) rsp = openai.ChatCompletion.create(**_cons_kwargs(messages))
content = rsp["choices"][0]["message"]["content"] content = rsp["choices"][0]["message"]["content"]
print(content, flush=True)
return content return content

View File

@ -51,6 +51,7 @@ TaskContent: Describe the task of the current step.
InputObject_List: The list of the input obejects that will be used in current step. InputObject_List: The list of the input obejects that will be used in current step.
OutputObject: The name of the final output object of current step. OutputObject: The name of the final output object of current step.
请用中文回答
""" """

View File

@ -90,6 +90,7 @@ InputObject_List: List existing objects that should be utilized in current step.
AgentName: Specify the agent who will perform the action, You CAN ONLY USE THE NAME APPEARS IN "AgentInvolved". AgentName: Specify the agent who will perform the action, You CAN ONLY USE THE NAME APPEARS IN "AgentInvolved".
ActionType: Specify the type of action, note that only the last action can be of type "Finalize", and the last action must be "Finalize". ActionType: Specify the type of action, note that only the last action can be of type "Finalize", and the last action must be "Finalize".
请用中文回答
""" """

File diff suppressed because one or more lines are too long

View File

@ -9,4 +9,4 @@ GROQ_API_KEY: ""
MISTRAL_API_KEY: "" MISTRAL_API_KEY: ""
## options under experimentation, leave them as Fasle unless you know what it is for ## options under experimentation, leave them as Fasle unless you know what it is for
USE_CACHE: False USE_CACHE: True

View File

@ -1,5 +1,6 @@
from flask import Flask, request, jsonify from flask import Flask, request, jsonify
import json import json
import time
from DataProcess import Add_Collaboration_Brief_FrontEnd from DataProcess import Add_Collaboration_Brief_FrontEnd
from AgentCoord.RehearsalEngine_V2.ExecutePlan import executePlan from AgentCoord.RehearsalEngine_V2.ExecutePlan import executePlan
from AgentCoord.PlanEngine.basePlan_Generator import generate_basePlan from AgentCoord.PlanEngine.basePlan_Generator import generate_basePlan
@ -48,6 +49,7 @@ def Handle_fill_stepTask_TaskProcess():
if USE_CACHE: if USE_CACHE:
if requestIdentifier in Request_Cache: if requestIdentifier in Request_Cache:
time.sleep(1)
return jsonify(Request_Cache[requestIdentifier]) return jsonify(Request_Cache[requestIdentifier])
filled_stepTask = fill_stepTask_TaskProcess( filled_stepTask = fill_stepTask_TaskProcess(
@ -118,6 +120,7 @@ def Handle_fill_stepTask():
if USE_CACHE: if USE_CACHE:
if requestIdentifier in Request_Cache: if requestIdentifier in Request_Cache:
time.sleep(1)
return jsonify(Request_Cache[requestIdentifier]) return jsonify(Request_Cache[requestIdentifier])
filled_stepTask = fill_stepTask( filled_stepTask = fill_stepTask(
@ -211,6 +214,7 @@ def Handle_generate_basePlan():
if USE_CACHE: if USE_CACHE:
if requestIdentifier in Request_Cache: if requestIdentifier in Request_Cache:
time.sleep(2)
return jsonify(Request_Cache[requestIdentifier]) return jsonify(Request_Cache[requestIdentifier])
basePlan = generate_basePlan( basePlan = generate_basePlan(
@ -239,6 +243,7 @@ def Handle_executePlan():
if USE_CACHE: if USE_CACHE:
if requestIdentifier in Request_Cache: if requestIdentifier in Request_Cache:
time.sleep(3)
return jsonify(Request_Cache[requestIdentifier]) return jsonify(Request_Cache[requestIdentifier])
RehearsalLog = executePlan( RehearsalLog = executePlan(
@ -252,14 +257,14 @@ def Handle_executePlan():
return response return response
@app.route("/_saveRequestCashe", methods=["post"]) @app.route("/_saveRequestCashe", methods=["GET"])
def Handle_saveRequestCashe(): def Handle_saveRequestCashe():
with open( with open(
os.path.join(os.getcwd(), "RequestCache", "Request_Cache.json"), "w" os.path.join(os.getcwd(), "RequestCache", "Request_Cache.json"), "w"
) as json_file: ) as json_file:
json.dump(Request_Cache, json_file, indent=4) json.dump(Request_Cache, json_file, indent=4)
response = jsonify( response = jsonify(
{"code": 200, "content": "request cashe sucessfully saved"} {"code": 200, "content": "request cashe sucessfully saved: " + os.path.join(os.getcwd(), "RequestCache", "Request_Cache.json")}
) )
return response return response

View File

@ -21,11 +21,12 @@ services:
ports: ports:
- "8000:8000" - "8000:8000"
environment: environment:
- OPENAI_API_BASE=htts://api.openai.com - OPENAI_API_BASE=https://api.moleapi.com/v1
- OPENAI_API_KEY= - OPENAI_API_KEY=sk-sps7FBCbEvu85DfPoS8SdnPwYLEoW7u5Dd8vCDTXqPLpHuyb
- OPENAI_API_MODEL=gpt-4-turbo-preview - OPENAI_API_MODEL=gpt-4.1-mini
- FAST_DESIGN_MODE=True - FAST_DESIGN_MODE=False
- GROQ_API_KEY= - GROQ_API_KEY=
- USE_CACHE=True
networks: networks:
- agentcoord-network - agentcoord-network

View File

@ -15,8 +15,9 @@ FROM base AS runner
WORKDIR /app WORKDIR /app
EXPOSE 8080/tcp EXPOSE 8080/tcp
COPY .npmrc ./ COPY .npmrc ./
RUN npm install @modern-js/app-tools @modern-js/runtime --no-optional --no-shrinkwrap && mkdir src COPY src ./src
COPY modern.config.ts package.json ./ COPY modern.config.ts package.json ./
COPY --from=builder /app/dist ./dist COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
ENV API_BASE= ENV API_BASE=
CMD ["npm", "run", "serve"] CMD ["npm", "run", "serve"]

View File

@ -65,7 +65,6 @@ export default observer(({ agent, style = {} }: IAgentCardProps) => (
userSelect: 'none', userSelect: 'none',
}} }}
> >
{agent.profile}
</Box> </Box>
</Box> </Box>
<Box <Box
@ -105,7 +104,7 @@ export default observer(({ agent, style = {} }: IAgentCardProps) => (
marginLeft: '2px', marginLeft: '2px',
}} }}
> >
Current Duty: :
</Box> </Box>
<Box> <Box>
{agent.actions.map((action, index) => ( {agent.actions.map((action, index) => (

View File

@ -4,6 +4,7 @@ import Box from '@mui/material/Box';
import MoreHorizIcon from '@mui/icons-material/MoreHoriz'; import MoreHorizIcon from '@mui/icons-material/MoreHoriz';
import UnfoldLessIcon from '@mui/icons-material/UnfoldLess'; import UnfoldLessIcon from '@mui/icons-material/UnfoldLess';
import { IAgentAction, globalStorage } from '@/storage'; import { IAgentAction, globalStorage } from '@/storage';
import { getActionTypeDisplayText } from '@/storage/plan/action'; // 导入映射函数
export interface IDutyItem { export interface IDutyItem {
action: IAgentAction; action: IAgentAction;
@ -38,7 +39,7 @@ export default React.memo<IDutyItem>(({ action, style = {} }) => {
..._style, ..._style,
}} }}
> >
{action.type} {getActionTypeDisplayText(action.type)}
<Box <Box
onClick={() => setExpand(true)} onClick={() => setExpand(true)}
sx={{ sx={{
@ -83,7 +84,7 @@ export default React.memo<IDutyItem>(({ action, style = {} }) => {
marginLeft: '2px', marginLeft: '2px',
}} }}
> >
{action.type} {getActionTypeDisplayText(action.type)}
</Box> </Box>
<Divider <Divider
sx={{ sx={{

View File

@ -88,7 +88,7 @@ export default observer(({ style = {} }: IAgentBoardProps) => {
'& > input': { display: 'none' }, '& > input': { display: 'none' },
}} }}
> >
<Title title="Agent Board" /> <Title title="智能体库" />
<Box <Box
sx={{ sx={{
flexGrow: 1, flexGrow: 1,

View File

@ -1,3 +1,4 @@
import AbigailChenMilitary from '@/static/AgentIcons/Abigail_Chen_military.png';
import AbigailChen from '@/static/AgentIcons/Abigail_Chen.png'; import AbigailChen from '@/static/AgentIcons/Abigail_Chen.png';
import AdamSmith from '@/static/AgentIcons/Adam_Smith.png'; import AdamSmith from '@/static/AgentIcons/Adam_Smith.png';
import ArthurBurton from '@/static/AgentIcons/Arthur_Burton.png'; import ArthurBurton from '@/static/AgentIcons/Arthur_Burton.png';
@ -26,6 +27,7 @@ import YurikoYamamoto from '@/static/AgentIcons/Yuriko_Yamamoto.png';
import Unknown from '@/static/AgentIcons/Unknow.png'; import Unknown from '@/static/AgentIcons/Unknow.png';
export enum IconName { export enum IconName {
AbigailChenMilitary = 'Abigail_Chen_military',
AbigailChen = 'Abigail_Chen', AbigailChen = 'Abigail_Chen',
AdamSmith = 'Adam_Smith', AdamSmith = 'Adam_Smith',
ArthurBurton = 'Arthur_Burton', ArthurBurton = 'Arthur_Burton',
@ -82,6 +84,7 @@ export const IconMap = new Proxy<{ [key: string]: IconName }>(
export const IconUrl: { [key in IconName]: string } = { export const IconUrl: { [key in IconName]: string } = {
[IconName.Unknown]: Unknown, [IconName.Unknown]: Unknown,
[IconName.AbigailChenMilitary]: AbigailChenMilitary,
[IconName.AbigailChen]: AbigailChen, [IconName.AbigailChen]: AbigailChen,
[IconName.AdamSmith]: AdamSmith, [IconName.AdamSmith]: AdamSmith,
[IconName.ArthurBurton]: ArthurBurton, [IconName.ArthurBurton]: ArthurBurton,

View File

@ -151,7 +151,7 @@ export default observer(({ style = {} }: { style?: SxProps }) => {
> >
<LogoIcon /> <LogoIcon />
<Box sx={{ marginLeft: '6px', fontWeight: 800, fontSize: '20px' }}> <Box sx={{ marginLeft: '6px', fontWeight: 800, fontSize: '20px' }}>
AGENTCOORD
</Box> </Box>
</Box> </Box>
) : ( ) : (

View File

@ -8,6 +8,7 @@ import RemoveIcon from '@mui/icons-material/Remove';
import AdjustIcon from '@mui/icons-material/Adjust'; import AdjustIcon from '@mui/icons-material/Adjust';
import { ObjectProps, ProcessProps } from './interface'; import { ObjectProps, ProcessProps } from './interface';
import AgentIcon from '@/components/AgentIcon'; import AgentIcon from '@/components/AgentIcon';
import DescriptionCard from '@/components/ProcessDiscription/DescriptionCard';
import { globalStorage } from '@/storage'; import { globalStorage } from '@/storage';
export interface IEditObjectProps { export interface IEditObjectProps {
@ -329,6 +330,13 @@ export const ProcessCard: React.FC<IProcessCardProps> = React.memo(
// handleEditStep(step.name, { ...step, task: text }); // handleEditStep(step.name, { ...step, task: text });
}} }}
/> />
{/* 这里直接渲染对应的 DescriptionCard */}
{/* {(() => {
const step = globalStorage.planManager.currentPlan.find(
s => s.id === process.id
);
return step ? <DescriptionCard step={step} /> : null;
})()} */}
</Box> </Box>
)} )}
</Box> </Box>

View File

@ -118,10 +118,10 @@ const D3Graph: React.FC<D3GraphProps> = ({
stepName: stepCardName, stepName: stepCardName,
objectName: objectCardName, objectName: objectCardName,
type, type,
x1: objectRect.left + objectRect.width, x1: stepRect.left + stepRect.width,
y1: objectRect.top + 0.5 * objectRect.height, y1: stepRect.top + 0.5 * stepRect.height,
x2: stepRect.left, x2: objectRect.left,
y2: stepRect.top + 0.5 * stepRect.height, y2: objectRect.top + 0.5 * objectRect.height,
}; };
}); });
const objectMetrics = calculateLineMetrics(cardRect, 'object'); const objectMetrics = calculateLineMetrics(cardRect, 'object');
@ -152,17 +152,17 @@ const D3Graph: React.FC<D3GraphProps> = ({
userSelect: 'none', userSelect: 'none',
}} }}
> >
<marker <marker
id="arrowhead" id="arrowhead"
markerWidth="4" markerWidth="2"
markerHeight="4" markerHeight="2"
refX="2" refX="1"
refY="2" refY="1"
orient="auto" orient="auto"
markerUnits="strokeWidth" markerUnits="strokeWidth"
> >
<path d="M0,0 L4,2 L0,4 z" fill="#E5E5E5" /> <path d="M0,0 L2,1 L0,2 z" fill="#E5E5E5" />
</marker> </marker>
<marker <marker
id="starter" id="starter"
markerWidth="4" markerWidth="4"
@ -184,7 +184,7 @@ const D3Graph: React.FC<D3GraphProps> = ({
fill="#898989" fill="#898989"
fontWeight="800" fontWeight="800"
> >
Key Object
</text> </text>
<line <line
x1={objectLine.x} x1={objectLine.x}
@ -204,7 +204,7 @@ const D3Graph: React.FC<D3GraphProps> = ({
fill="#898989" fill="#898989"
fontWeight="800" fontWeight="800"
> >
Process
</text> </text>
<line <line
x1={processLine.x} x1={processLine.x}

View File

@ -53,7 +53,7 @@ export default observer(() => {
const handleEditContent = (stepTaskId: string, newContent: string) => { const handleEditContent = (stepTaskId: string, newContent: string) => {
globalStorage.setStepTaskContent(stepTaskId, newContent); globalStorage.setStepTaskContent(stepTaskId, newContent);
}; };
const WidthRatio = ['30%', '15%', '52.5%']; const WidthRatio = ['35%', '10%', '50%'];
const [cardRefMapReady, setCardRefMapReady] = React.useState(false); const [cardRefMapReady, setCardRefMapReady] = React.useState(false);
@ -175,6 +175,34 @@ export default observer(() => {
sx={{ display: 'flex' }} sx={{ display: 'flex' }}
ref={ref} ref={ref}
> >
<Box
sx={{
// display: 'flex',
alignItems: 'center',
// width: WidthRatio[2],
justifyContent: 'center',
flex: `0 0 ${WidthRatio[2]}`,
}}
>
{name && (
<ProcessCard
process={{
id,
name,
icons: agentIcons,
agents,
content,
cardRef: getCardRef(`process.${name}`),
}}
handleProcessClick={handleProcessClick}
isFocusing={focusingStepTaskId === id}
isAddActive={id === activeProcessIdAdd}
handleAddActive={handleProcessAdd}
handleEditContent={handleEditContent}
/>
)}
</Box>
<Box sx={{ flex: `0 0 ${WidthRatio[1]}` }} />
<Box <Box
sx={{ sx={{
display: 'flex', display: 'flex',
@ -209,34 +237,6 @@ export default observer(() => {
/> />
)} )}
</Box> </Box>
<Box sx={{ flex: `0 0 ${WidthRatio[1]}` }} />
<Box
sx={{
// display: 'flex',
alignItems: 'center',
// width: WidthRatio[2],
justifyContent: 'center',
flex: `0 0 ${WidthRatio[2]}`,
}}
>
{name && (
<ProcessCard
process={{
id,
name,
icons: agentIcons,
agents,
content,
cardRef: getCardRef(`process.${name}`),
}}
handleProcessClick={handleProcessClick}
isFocusing={focusingStepTaskId === id}
isAddActive={id === activeProcessIdAdd}
handleAddActive={handleProcessAdd}
handleEditContent={handleEditContent}
/>
)}
</Box>
</Box> </Box>
), ),
)} )}

View File

@ -25,7 +25,7 @@ export default observer(({ style = {} }: { style?: SxProps }) => {
...style, ...style,
}} }}
> >
<Title title="Plan Outline" /> <Title title="任务大纲" />
<Box <Box
sx={{ sx={{
position: 'relative', position: 'relative',

View File

@ -19,7 +19,7 @@ export default observer(({ style = {} }: { style?: SxProps }) => {
...style, ...style,
}} }}
> >
<Title title="Task Process" /> <Title title="任务流程" />
<Stack <Stack
spacing={1} spacing={1}
sx={{ sx={{

View File

@ -1,6 +1,6 @@
import React from 'react'; import React, { useState } from 'react';
import { observer } from 'mobx-react-lite'; import { observer } from 'mobx-react-lite';
import { Divider, SxProps } from '@mui/material'; import { Divider, SxProps, Tooltip, Typography} from '@mui/material';
import Box from '@mui/material/Box'; import Box from '@mui/material/Box';
import UnfoldLessIcon from '@mui/icons-material/UnfoldLess'; import UnfoldLessIcon from '@mui/icons-material/UnfoldLess';
import MoreHorizIcon from '@mui/icons-material/MoreHoriz'; import MoreHorizIcon from '@mui/icons-material/MoreHoriz';
@ -9,6 +9,7 @@ import { globalStorage } from '@/storage';
import type { IExecuteStepHistoryItem } from '@/apis/execute-plan'; import type { IExecuteStepHistoryItem } from '@/apis/execute-plan';
import AgentIcon from '@/components/AgentIcon'; import AgentIcon from '@/components/AgentIcon';
import { getAgentActionStyle } from '@/storage/plan'; import { getAgentActionStyle } from '@/storage/plan';
import { getActionTypeDisplayText } from '@/storage/plan/action';
export interface IStepHistoryItemProps { export interface IStepHistoryItemProps {
item: IExecuteStepHistoryItem; item: IExecuteStepHistoryItem;
@ -46,6 +47,170 @@ export default observer(
}, 10); }, 10);
} }
}, [expand]); }, [expand]);
interface DataSpaceCard {
name: string;
data_space: string;
doId: string;
fromRepo: string;
}
interface DataSpaceIndicatorProps {
cards?: DataSpaceCard[];
}
const DataSpaceIndicator = ({ cards = [] }: DataSpaceIndicatorProps) => {
const [currentCard, setCurrentCard] = useState(0);
if (!cards || cards.length === 0) {
return null;
}
const tooltipContent = (
<>
{/* 添加标题 */}
<Box
sx={{
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
padding: '8px 12px',
backgroundColor: '#1565c0',
color: 'white',
borderRadius: '4px 4px 0 0',
fontWeight: 'bold',
fontSize: '14px',
}}
>
<span></span>
<Box sx={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
<span style={{ fontSize: '12px', color: 'rgba(255,255,255,0.8)' }}>
{currentCard + 1}/{cards.length}
</span>
<button
onClick={(e) => {
e.stopPropagation();
setCurrentCard((prev) => (prev + 1) % cards.length);
}}
style={{
fontSize: '12px',
padding: '2px 8px',
backgroundColor: 'white',
color: '#1565c0',
border: 'none',
borderRadius: '3px',
cursor: 'pointer',
fontWeight: 'bold'
}}
>
</button>
</Box>
</Box>
<Box
sx={{
padding: '12px',
borderRadius: '4px',
backgroundColor: '#e3f2fd',
border: '1px solid #1565c0',
minWidth: '450px', // 设置卡片最小宽度
}}
>
<Box sx={{ display: 'flex', alignItems: 'flex-start', marginBottom: '4px' }}>
<Typography variant="caption" sx={{ fontWeight: 'bold', color: '#666', minWidth: '60px' }}>
:
</Typography>
<Typography variant="body2" sx={{ color: 'black' }}>
{cards[currentCard]?.name}
</Typography>
</Box>
<Box sx={{ display: 'flex', alignItems: 'flex-start', marginBottom: '4px' }}>
<Typography variant="caption" sx={{ fontWeight: 'bold', color: '#666', minWidth: '60px' }}>
:
</Typography>
<Typography variant="body2" sx={{ color: 'black' }}>
{cards[currentCard]?.data_space}
</Typography>
</Box>
<Box sx={{ display: 'flex', alignItems: 'flex-start', marginBottom: '4px' }}>
<Typography variant="caption" sx={{ fontWeight: 'bold', color: '#666', minWidth: '60px' }}>
DOID:
</Typography>
<Typography variant="body2" sx={{ color: 'black' }}>
{cards[currentCard]?.doId}
</Typography>
</Box>
<Box sx={{ display: 'flex', alignItems: 'flex-start', marginBottom: '4px' }}>
<Typography variant="caption" sx={{ fontWeight: 'bold', color: '#666', minWidth: '60px' }}>
:
</Typography>
<Typography variant="body2" sx={{ color: 'black' }}>
{cards[currentCard]?.fromRepo}
</Typography>
</Box>
</Box>
</>
);
return (
<Tooltip
title={tooltipContent}
arrow
slotProps={{
tooltip: {
sx: {
maxWidth: 500, // 只需要这一行来增加宽度
},
},
}}
>
<Box
sx={{
display: 'inline-flex',
alignItems: 'center',
justifyContent: 'center',
width: '20px',
height: '20px',
borderRadius: '50%',
backgroundColor: '#9e9e9e',
color: 'white',
fontSize: '12px',
fontWeight: '600',
cursor: 'pointer',
'&:hover': {
backgroundColor: '#1565c0',
}
}}
>
{cards.length}
</Box>
</Tooltip>
);
};
const cardData = [
{
name: "3D Semantic-Geometric Corrosion Mapping Implementations",
data_space: "江苏省产研院",
doId: "bdware.scenario/d8f3ff8c-3fb3-4573-88a6-5dd823627c37",
fromRepo: "https://arxiv.org/abs/2404.13691"
},
{
name: "RustSEG -- Automated segmentation of corrosion using deep learning",
data_space: "江苏省产研院",
doId: "bdware.scenario/67445299-110a-4a4e-9fda-42e4b5a493c2",
fromRepo: "https://arxiv.org/abs/2205.05426"
},
{
name: "Pixel-level Corrosion Detection on Metal Constructions by Fusion of Deep Learning Semantic and Contour Segmentation",
data_space: "江苏省产研院",
doId: "bdware.scenario/115d5135-85d3-4123-8b81-9eb9f07b6153",
fromRepo: "https://arxiv.org/abs/2008.05204"
},
];
const s = { ...getAgentActionStyle(item.type), ...style } as SxProps; const s = { ...getAgentActionStyle(item.type), ...style } as SxProps;
React.useEffect(() => { React.useEffect(() => {
console.log(item); console.log(item);
@ -77,7 +242,7 @@ export default observer(
{item.agent} {item.agent}
</Box> </Box>
<Box component="span" sx={{ fontWeight: 400 }}> <Box component="span" sx={{ fontWeight: 400 }}>
: {item.type} : {getActionTypeDisplayText(item.type)}
</Box> </Box>
</Box> </Box>
{item.result ? ( {item.result ? (
@ -103,10 +268,14 @@ export default observer(
marginBottom: '4px', marginBottom: '4px',
color: '#0009', color: '#0009',
fontWeight: 400, fontWeight: 400,
display: 'inline-flex',
alignItems: 'center',
gap: '8px',
}} }}
> >
{item.description} {item.description}
</Box> </Box>
<DataSpaceIndicator cards={cardData} />
<MarkdownBlock <MarkdownBlock
text={item.result} text={item.result}
style={{ style={{

View File

@ -79,7 +79,7 @@ export default observer(({ style = {} }: { style?: SxProps }) => {
alignItems: 'center', alignItems: 'center',
}} }}
> >
<Title title="Execution Result" /> <Title title="执行结果" />
<Box <Box
sx={{ sx={{
flexGrow: 1, flexGrow: 1,

View File

@ -4,6 +4,8 @@ import { SxProps } from '@mui/material';
import Box from '@mui/material/Box'; import Box from '@mui/material/Box';
import IconButton from '@mui/material/IconButton'; import IconButton from '@mui/material/IconButton';
import FormControl from '@mui/material/FormControl'; import FormControl from '@mui/material/FormControl';
import Autocomplete from '@mui/material/Autocomplete';
import TextField from '@mui/material/TextField';
import FilledInput from '@mui/material/FilledInput'; import FilledInput from '@mui/material/FilledInput';
import TelegramIcon from '@mui/icons-material/Telegram'; import TelegramIcon from '@mui/icons-material/Telegram';
import CircularProgress from '@mui/material/CircularProgress'; import CircularProgress from '@mui/material/CircularProgress';
@ -16,6 +18,18 @@ export interface UserGoalInputProps {
export default observer(({ style = {} }: UserGoalInputProps) => { export default observer(({ style = {} }: UserGoalInputProps) => {
const inputRef = React.useRef<string>(''); const inputRef = React.useRef<string>('');
const inputElementRef = React.useRef<HTMLInputElement>(null); const inputElementRef = React.useRef<HTMLInputElement>(null);
const goalOptions = [
'如何快速筛选慢性肾脏病药物潜在受试者?',
'如何补充“丹芍活血胶囊”不良反应数据?',
'如何快速研发用于战场失血性休克的药物?',
'二维材料的光电性质受哪些关键因素影响?',
'如何通过AI模拟的方法分析材料的微观结构?',
'如何分析获取液态金属热力学参数?',
'如何解决固态电池的成本和寿命难题?',
'如何解决船舶制造中的材料腐蚀难题?',
'如何解决船舶制造中流体模拟和建模优化难题?',
];
React.useEffect(() => { React.useEffect(() => {
if (inputElementRef.current) { if (inputElementRef.current) {
if (globalStorage.planManager) { if (globalStorage.planManager) {
@ -32,42 +46,70 @@ export default observer(({ style = {} }: UserGoalInputProps) => {
...style, ...style,
}} }}
> >
<FilledInput <Autocomplete
freeSolo
disableClearable
disabled={ disabled={
globalStorage.api.busy || globalStorage.api.busy ||
!globalStorage.api.agentsReady || !globalStorage.api.agentsReady ||
globalStorage.api.planReady globalStorage.api.planReady
} }
placeholder="Yout Goal" options={goalOptions}
fullWidth value={inputRef.current || (globalStorage.planManager ? globalStorage.planManager.goal : globalStorage.briefGoal)}
inputRef={inputElementRef} onChange={(event, newValue) => {
onChange={event => (inputRef.current = event.target.value)} if (newValue) {
size="small" inputRef.current = newValue;
sx={{ }
borderRadius: '10px',
background: '#E1E1E1',
borderBottom: 'none !important',
'&::before': {
borderBottom: 'none !important',
},
'& > input': {
padding: '10px',
},
}} }}
startAdornment={ onInputChange={(event, newInputValue) => {
<Box inputRef.current = newInputValue;
}}
renderInput={(params) => (
<TextField
{...params}
variant="filled"
placeholder="请输入你的任务"
fullWidth
size="small"
inputRef={inputElementRef}
sx={{ sx={{
color: '#4A9C9E', borderRadius: '10px',
fontWeight: 800, background: '#E1E1E1',
fontSize: '18px', borderBottom: 'none !important',
textWrap: 'nowrap', '& .MuiFilledInput-root': {
userSelect: 'none', height: '45px',
borderRadius: '10px',
background: '#E1E1E1',
paddingTop: '5px',
borderBottom: 'none !important',
'&::before': {
borderBottom: 'none !important',
},
'&::after': {
borderBottom: 'none !important',
},
},
}} }}
> InputProps={{
\General Goal: ...params.InputProps,
</Box> startAdornment: (
} <Box
/> sx={{
color: '#4A9C9E',
fontWeight: 800,
fontSize: '18px',
textWrap: 'nowrap',
userSelect: 'none',
}}
>
</Box>
),
}}
/>
)}
/>
{globalStorage.api.planGenerating ? ( {globalStorage.api.planGenerating ? (
<CircularProgress <CircularProgress
sx={{ sx={{

View File

@ -88,24 +88,24 @@ export default observer(() => {
setConnectors(<></>); setConnectors(<></>);
} }
const outlinePosition = const outlinePosition =
ElementToLink[0]?.current?.getBoundingClientRect?.(); ElementToLink[1]?.current?.getBoundingClientRect?.();
if (!outlinePosition) { if (!outlinePosition) {
return; return;
} }
const agentRects = ElementToLink[1] const agentRects = ElementToLink[0]
.map(ele => ele.current?.getBoundingClientRect?.() as DOMRect) .map(ele => ele.current?.getBoundingClientRect?.() as DOMRect)
.filter(rect => rect); .filter(rect => rect);
if (agentRects.length === 0) { if (agentRects.length === 0) {
return; return;
} }
const agentsPosition = mergeRects(...agentRects); const agentsPosition = mergeRects(...agentRects);
const descriptionPosition = // const descriptionPosition =
ElementToLink[2]?.current?.getBoundingClientRect?.(); // ElementToLink[2]?.current?.getBoundingClientRect?.();
if (!descriptionPosition) { // if (!descriptionPosition) {
return; // return;
} // }
const LogRects = ElementToLink[3] const LogRects = ElementToLink[2]
.map(ele => ele?.current?.getBoundingClientRect?.() as DOMRect) .map(ele => ele?.current?.getBoundingClientRect?.() as DOMRect)
.filter(rect => rect); .filter(rect => rect);
if (LogRects.length > 0) { if (LogRects.length > 0) {
@ -115,15 +115,14 @@ export default observer(() => {
setConnectors( setConnectors(
drawConnectors( drawConnectors(
outlinePosition,
agentsPosition, agentsPosition,
descriptionPosition, outlinePosition,
logPosition, logPosition,
), ),
); );
} else { } else {
setConnectors( setConnectors(
drawConnectors(outlinePosition, agentsPosition, descriptionPosition), drawConnectors(agentsPosition,outlinePosition),
); );
} }
} catch (e) { } catch (e) {

View File

@ -99,16 +99,7 @@ export default React.memo(() => {
}} }}
/> />
<Box sx={{ height: 0, flexGrow: 1, display: 'flex' }}> <Box sx={{ height: 0, flexGrow: 1, display: 'flex' }}>
<ResizeableColumn columnWidth="25%"> <ResizeableColumn columnWidth="19%">
<Outline
style={{
height: '100%',
width: '100%',
marginRight: '6px',
}}
/>
</ResizeableColumn>
<ResizeableColumn columnWidth="25%">
<AgentBoard <AgentBoard
style={{ style={{
height: '100%', height: '100%',
@ -118,8 +109,8 @@ export default React.memo(() => {
onAddAgent={() => setShowAgentHiring(true)} onAddAgent={() => setShowAgentHiring(true)}
/> />
</ResizeableColumn> </ResizeableColumn>
<ResizeableColumn columnWidth="25%"> <ResizeableColumn columnWidth="26%">
<ProcessDiscrption <Outline
style={{ style={{
height: '100%', height: '100%',
width: '100%', width: '100%',
@ -127,6 +118,15 @@ export default React.memo(() => {
}} }}
/> />
</ResizeableColumn> </ResizeableColumn>
{/* <ResizeableColumn columnWidth="25%">
<ProcessDiscrption
style={{
height: '100%',
width: '100%',
marginRight: '6px',
}}
/>
</ResizeableColumn> */}
<ProcessRehearsal <ProcessRehearsal
style={{ style={{
height: '100%', height: '100%',

Binary file not shown.

After

Width:  |  Height:  |  Size: 412 KiB

View File

@ -285,17 +285,15 @@ export class GlobalStorage {
} }
public get ElementToLink(): [ public get ElementToLink(): [
React.RefObject<HTMLElement> | undefined,
React.RefObject<HTMLElement>[], React.RefObject<HTMLElement>[],
React.RefObject<HTMLElement> | undefined, React.RefObject<HTMLElement> | undefined,
(React.RefObject<HTMLElement> | undefined)[], (React.RefObject<HTMLElement> | undefined)[],
] { ] {
return [ return [
this.refMap.OutlineCard.get(this.focusingStepTaskId ?? ''),
this.focusingStepTask?.agentSelection?.agents?.map( this.focusingStepTask?.agentSelection?.agents?.map(
agent => this.refMap.AgentCard.get(agent) ?? [], agent => this.refMap.AgentCard.get(agent) ?? [],
) ?? ([] as any), ) ?? ([] as any),
this.refMap.DiscriptionCard.get(this.focusingStepTaskId ?? ''), this.refMap.OutlineCard.get(this.focusingStepTaskId ?? ''),
this.logManager.outdate this.logManager.outdate
? [] ? []
: [ : [

View File

@ -11,6 +11,17 @@ export enum ActionType {
Finalize = 'Finalize', Finalize = 'Finalize',
} }
export const getActionTypeDisplayText = (actionType: ActionType | string): string => {
const displayMap: Record<string, string> = {
[ActionType.Propose]: '提议',
[ActionType.Critique]: '评审',
[ActionType.Improve]: '改进',
[ActionType.Finalize]: '总结',
};
return displayMap[actionType] || actionType;
};
const AgentActionStyles = new Map<ActionType | '', SxProps>([ const AgentActionStyles = new Map<ActionType | '', SxProps>([
[ActionType.Propose, { backgroundColor: '#B9EBF9', borderColor: '#94c2dc' }], [ActionType.Propose, { backgroundColor: '#B9EBF9', borderColor: '#94c2dc' }],
[ActionType.Critique, { backgroundColor: '#EFF9B9', borderColor: '#c0dc94' }], [ActionType.Critique, { backgroundColor: '#EFF9B9', borderColor: '#c0dc94' }],

View File

@ -20,7 +20,7 @@ const nameJoin = (names: string[]) => {
const last = tmp.pop()!; const last = tmp.pop()!;
let t = tmp.join(', '); let t = tmp.join(', ');
if (t.length > 0) { if (t.length > 0) {
t = `${t} and ${last}`; t = `${t} ${last}`;
} else { } else {
t = last; t = last;
} }
@ -102,14 +102,14 @@ export class StepTaskNode implements INodeBase {
text: this.output, text: this.output,
style: { background: '#FFCA8C' }, style: { background: '#FFCA8C' },
}; };
outputSentence = `to obtain !<${indexOffset}>!`; outputSentence = `得到 !<${indexOffset}>!`;
} }
// Join them togeter // Join them togeter
let content = inputSentence; let content = inputSentence;
if (content) { if (content) {
content = `Based on ${content}, ${nameSentence} perform the task of !<${actionIndex}>!`; content = `基于${content}, ${nameSentence} 执行任务 !<${actionIndex}>!`;
} else { } else {
content = `${nameSentence} perform the task of !<${actionIndex}>!`; content = `${nameSentence} 执行任务 !<${actionIndex}>!`;
} }
if (outputSentence) { if (outputSentence) {
content = `${content}, ${outputSentence}.`; content = `${content}, ${outputSentence}.`;