Compare commits

...

6 Commits
main ... pku

Author SHA1 Message Date
Nex Zhu
9a74d2813e Merge branch 'main' into pku 2025-11-20 09:42:26 +08:00
wuyifan18
f50dcd2fe7 update 2025-10-21 10:13:14 +08:00
wuyifan18
744945f68d update 2025-10-21 10:09:18 +08:00
wuyifan18
25853d8174 update 2025-10-19 18:54:11 +08:00
wuyifan18
ceb57acd23 update 2025-10-19 18:14:21 +08:00
wuyifan18
da2318a40c update 2025-10-18 14:31:34 +08:00
37 changed files with 16103 additions and 3687 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

@ -33,7 +33,7 @@ class JSON_ABILITY_REQUIREMENT_GENERATION(BaseModel):
PROMPT_AGENT_SELECTION_GENERATION = """ PROMPT_AGENT_SELECTION_GENERATION = """
## Instruction ## Instruction
Based on "General Goal", "Current Task" and "Agent Board", output a formatted "Agent Selection Plan". Your selection should consider the ability needed for "Current Task" and the profile of each agent in "Agent Board". Based on "General Goal", "Current Task" and "Agent Board", output a formatted "Agent Selection Plan". Your selection should consider the ability needed for "Current Task" and the profile of each agent in "Agent Board". Agent Selection Plan ranks from high to low according to ability.
## General Goal (Specify the general goal for the collaboration plan) ## General Goal (Specify the general goal for the collaboration plan)
{General_Goal} {General_Goal}

View File

@ -7,14 +7,14 @@ import AgentCoord.util as util
def generate_basePlan( def generate_basePlan(
General_Goal, Agent_Board, AgentProfile_Dict, InitialObject_List General_Goal, Agent_Board, AgentProfile_Dict, InitialObject_List, context
): ):
basePlan = { basePlan = {
"Initial Input Object": InitialObject_List, "Initial Input Object": InitialObject_List,
"Collaboration Process": [], "Collaboration Process": [],
} }
PlanOutline = generate_PlanOutline( PlanOutline = generate_PlanOutline(
InitialObject_List=[], General_Goal=General_Goal InitialObject_List=[], General_Goal=General_Goal + context
) )
for stepItem in PlanOutline: for stepItem in PlanOutline:
Current_Task = { Current_Task = {
@ -44,7 +44,7 @@ def generate_basePlan(
), ),
} }
TaskProcess = generate_TaskProcess( TaskProcess = generate_TaskProcess(
General_Goal=General_Goal, General_Goal=General_Goal + context,
Current_Task_Description=Current_Task_Description, Current_Task_Description=Current_Task_Description,
) )
# add the generated AgentSelection and TaskProcess to the stepItem # add the generated AgentSelection and TaskProcess to the stepItem

View File

@ -5,7 +5,7 @@ import json
PROMPT_PLAN_OUTLINE_GENERATION = """ PROMPT_PLAN_OUTLINE_GENERATION = """
## Instruction ## Instruction
Based on "Output Format Example", "General Goal", and "Initial Key Object List", output a formatted "Plan_Outline". Based on "Output Format Example", "General Goal", and "Initial Key Object List", output a formatted "Plan_Outline". The number of steps in the Plan Outline cannot exceed 5.
## Initial Key Object List (Specify the list of initial key objects available, each initial key object should be the input object of at least one Step) ## Initial Key Object List (Specify the list of initial key objects available, each initial key object should be the input object of at least one Step)
{InitialObject_List} {InitialObject_List}
@ -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".
请用中文回答
""" """

View File

@ -5,7 +5,7 @@ Note: You can say something before you provide the improved version of the conte
The improved version you provide must be a completed version (e.g. if you provide a improved story, you should give completed story content, rather than just reporting where you have improved). The improved version you provide must be a completed version (e.g. if you provide a improved story, you should give completed story content, rather than just reporting where you have improved).
When you decide to give the improved version of the content, it should be start like this: When you decide to give the improved version of the content, it should be start like this:
## Improved version of xxx ## xxx的改进版本
(the improved version of the content) (the improved version of the content)
``` ```

View File

@ -4,7 +4,7 @@ from termcolor import colored
# Accept inputs: num_StepToRun (the number of step to run, if None, run to the end), plan, RehearsalLog, AgentProfile_Dict # Accept inputs: num_StepToRun (the number of step to run, if None, run to the end), plan, RehearsalLog, AgentProfile_Dict
def executePlan(plan, num_StepToRun, RehearsalLog, AgentProfile_Dict): def executePlan(plan, num_StepToRun, RehearsalLog, AgentProfile_Dict, context):
# Prepare for execution # Prepare for execution
KeyObjects = {} KeyObjects = {}
finishedStep_index = -1 finishedStep_index = -1
@ -101,7 +101,7 @@ def executePlan(plan, num_StepToRun, RehearsalLog, AgentProfile_Dict):
KeyObjects=KeyObjects, KeyObjects=KeyObjects,
) )
ActionInfo_with_Result = currentAction.run( ActionInfo_with_Result = currentAction.run(
General_Goal=plan["General Goal"], General_Goal=plan["General Goal"] + "\n\n### Useful Information (some information can help accomplish the task)\n如果使用该信息,请在回答中显示指出是来自数联网的数据。例如,基于数联网数据搜索结果。" + context,
TaskDescription=TaskDescription, TaskDescription=TaskDescription,
agentName=agentName, agentName=agentName,
AgentProfile_Dict=AgentProfile_Dict, AgentProfile_Dict=AgentProfile_Dict,
@ -113,6 +113,8 @@ def executePlan(plan, num_StepToRun, RehearsalLog, AgentProfile_Dict):
ActionHistory.append(ActionInfo_with_Result) ActionHistory.append(ActionInfo_with_Result)
# post processing for the group chat (finish) # post processing for the group chat (finish)
objectLogNode["content"] = KeyObjects[OutputName] objectLogNode["content"] = KeyObjects[OutputName]
if StepRun_count == len(plan["Collaboration Process"][(finishedStep_index + 1): run_to]):
objectLogNode["content"] += context
RehearsalLog.append(stepLogNode) RehearsalLog.append(stepLogNode)
RehearsalLog.append(objectLogNode) RehearsalLog.append(objectLogNode)
stepLogNode["ActionHistory"] = ActionHistory stepLogNode["ActionHistory"] = ActionHistory

View File

@ -0,0 +1,97 @@
[
{
"Icon": "Hailey_Johnson.png",
"Name": "船舶设计师",
"Profile": "提供船舶制造中的实际需求和约束。"
},
{
"Icon": "Jennifer_Moore.png",
"Name": "防护工程专家",
"Profile": "专注于船舶腐蚀防护技术的设计与应用。在你的总结回答中,必须引用来自数联网的搜索数据,是搜索数据,不是数联网的研究成果。"
},
{
"Icon": "Jane_Moreno.png",
"Name": "病理生理学家",
"Profile": "专注于失血性休克的疾病机制,为药物研发提供理论靶点。"
},
{
"Icon": "Giorgio_Rossi.png",
"Name": "药物化学家",
"Profile": "负责将靶点概念转化为实际可合成的分子。"
},
{
"Icon": "Tamara_Taylor.png",
"Name": "制剂工程师",
"Profile": "负责将活性药物成分API变成稳定、可用、符合战场要求的剂型。"
},
{
"Icon": "Maria_Lopez.png",
"Name": "监管事务专家",
"Profile": "深谙药品审评法规,目标是找到最快的合法上市路径。"
},
{
"Icon": "Sam_Moore.png",
"Name": "物理学家",
"Profile": "从热力学与统计力学的基本原理出发,研究液态金属的自由能、焓、熵、比热等参数的理论建模。"
},
{
"Icon": "Yuriko_Yamamoto.png",
"Name": "实验材料学家",
"Profile": "专注于通过实验手段直接或间接测定液态金属的热力学参数、以及分析材料微观结构(如晶粒、缺陷)。"
},
{
"Icon": "Carlos_Gomez.png",
"Name": "计算模拟专家",
"Profile": "侧重于利用数值计算和模拟技术获取液态金属的热力学参数。"
},
{
"Icon": "John_Lin.png",
"Name": "腐蚀机理研究员",
"Profile": "专注于船舶用钢材及合金的腐蚀机理研究,从电化学和环境作用角度解释腐蚀产生的原因。在你的总结回答中,必须引用来自数联网的搜索数据,是搜索数据,不是数联网的研究成果。"
},
{
"Icon": "Arthur_Burton.png",
"Name": "先进材料研发员",
"Profile": "专注于开发和评估新型耐腐蚀材料、复合材料及固态电池材料。"
},
{
"Icon": "Eddy_Lin.png",
"Name": "肾脏病学家",
"Profile": "专注于慢性肾脏病的诊断、治疗和患者管理,能提供临床洞察。"
},
{
"Icon": "Isabella_Rodriguez.png",
"Name": "临床研究协调员",
"Profile": "负责受试者招募和临床试验流程优化。"
},
{
"Icon": "Latoya_Williams.png",
"Name": "中医药专家",
"Profile": "理解药物的中药成分和作用机制。"
},
{
"Icon": "Carmen_Ortiz.png",
"Name": "药物安全专家",
"Profile": "专注于药物不良反应数据收集、分析和报告。"
},
{
"Icon": "Rajiv_Patel.png",
"Name": "二维材料科学家",
"Profile": "专注于二维材料(如石墨烯)的合成、性质和应用。"
},
{
"Icon": "Tom_Moreno.png",
"Name": "光电物理学家",
"Profile": "研究材料的光电转换机制和关键影响因素。"
},
{
"Icon": "Ayesha_Khan.png",
"Name": "机器学习专家",
"Profile": "专注于开发和应用AI模型用于材料模拟。"
},
{
"Icon": "Mei_Lin.png",
"Name": "流体动力学专家",
"Profile": "专注于流体行为理论和模拟。"
}
]

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
@ -31,6 +32,56 @@ else:
USE_CACHE = USE_CACHE.lower() in ["true", "1", "yes"] USE_CACHE = USE_CACHE.lower() in ["true", "1", "yes"]
AgentBoard = None AgentBoard = None
AgentProfile_Dict = {} AgentProfile_Dict = {}
c1 = '''
=====数联网搜索结果=====
1. 论文
- Surface Defect Detection and Evaluation for Marine Vessels using Multi-Stage Deep Learning提出一个面向船舶制造与检修的多阶段深度学习流水线用于船体表面缺陷检测与评估重点识别和量化与船舶制造材料腐蚀相关的现象包括腐蚀rust附着物fouling涂层剥离delamination研究特别关注船舶材料腐蚀在不同涂层颜色光照条件和相机角度下的鲁棒性有助于提高船舶制造过程中对材料腐蚀的检测与管理能力论文强调其方法在船舶材料表面腐蚀监测和维修决策中的应用价值链接https://arxiv.org/abs/2203.09580
论文复现链接http://8.130.138.52:21001/#/view/reproduction?doid=newID/5a4fef68-a138-4adb-ba88-43aa4474c08c
- Efficient Metal Corrosion Area Detection Model Combining Convolution and Transformer (MCD-Net)提出了一种高效的金属腐蚀区域检测模型该模型创新性地结合了卷积编码器与视觉Transformer序列编码器利用注意力融合模块增强边界识别并采用基于得分的多尺度增强机制来突出腐蚀区域该方法在阴影遮挡和复杂纹理条件下依然能保持高精度在公开数据集上取得了优异的F1性能特别适用于船舶制造与检修中对船体钢板和涂层腐蚀的自动化识别与量化分析链接https://www.mdpi.com/2076-3417/14/21/9900
论文复现链接http://8.130.138.52:21001/#/view/reproduction?doid=newID/b200a489-e2c8-4dbd-8767-682d15dd4c04
- Mechanical Failure and Metal Degradation of Ships and Marine Structures系统探讨了船舶与海洋结构中金属材料包括高强钢不锈钢铜合金钛合金等在海洋环境下的机械损伤与电化学腐蚀协同作用问题重点分析了"机械载荷+腐蚀"耦合导致的疲劳裂纹及腐蚀裂纹等失效机制并对相应的检测预警与保护措施进行了深入讨论链接https://doi.org/10.3390/met13020272
- Research Progress of Marine Anti-Fouling Coatings2024全面综述了海洋防污涂层的研究进展涵盖自我抛光涂料生物可降解涂料低表面能涂层仿生涂层和纳米涂层等新型涂层技术虽然重点在于防污但文中指出许多防污机制与防腐蚀机制相互关联通过阻碍生物附着可有效减少微生物引起的腐蚀和表面破坏链接https://doi.org/10.3390/coatings14091227
- Corrosion-Wear Behavior of Shipbuilding Steels (EH40, FH40, 921A) in Seawater研究了三种常用船用钢EH40FH40921A在海水环境中磨损与腐蚀共同作用下的复合失效行为通过机械-电化学方法系统测定了腐蚀磨损损失表面形貌变化和耐腐蚀性能差异发现在此类工况中921A钢表现最佳Journal of Chinese Society for Corrosion and Protection, Vol 45(4): 894-904, 2025
- Sulfur-Selenium Alloy Coatings for Universal Corrosion Resistance设计了一种硫-硒合金涂层能够在包括模拟海水和硫酸盐还原菌生物环境在内的各种条件下为钢材提供高效的防腐蚀保护约99.9%效率腐蚀速率比裸钢低6-7个数量级该涂层具有良好的机械性能非多孔结构能有效阻碍多种扩散性腐蚀因子的渗透arXiv:2009.02451
2. 代码
- CoaST - Anti-corrosive coatings research (DTU, Denmark)丹麦技术大学的CoaST项目专注于抗腐蚀涂层的性能表征与失效机制分析该项目采用电化学测试与表面/界面无损检测技术相结合的方法系统评估涂层的保护效果与失效途径为船舶腐蚀防护提供了重要的研究平台链接https://www.kt.dtu.dk/research/coast/research-areas/anti-corrosive-coatings
- Surface Defect Detection 仓库该仓库集成了多种表面缺陷检测算法为实现船舶腐蚀检测提供了可靠的代码基础和参考架构链接https://github.com/Charmve/Surface-Defect-Detection
- Hugging Face 预训练模型平台提供了轻量级的腐蚀检测模型可直接下载并微调用于快速验证和部署链接https://huggingface.co/mahdavian/corrosion-model
3. 数据集
用于训练和验证MCD-Net模型的相关数据集包括
- iamcloud/Corrosion_Dataset一个包含约2000多张标注图像的数据集ImageFolder格式Apache-2.0协议专门收录材料腐蚀图像适用于船舶腐蚀监测模型的训练链接https://huggingface.co/datasets/iamcloud/Corrosion_Dataset
- Francesco/corrosion-bi3q3此数据集提供了多种腐蚀实例可用于支持船舶涂层损坏与基体腐蚀的自动化检测任务链接https://huggingface.co/datasets/Francesco/corrosion-bi3q3
4. 研究团队
- 海洋腐蚀与防护全国重点实验室是我国在该领域最具权威性的国家级研究机构依托于中国船舶集团旗下725所实验室提供从材料设计到运维的全生命周期腐蚀控制解决方案其核心优势在于能够进行多技术阴极保护+涂层的综合集成研发与验证其研究成果广泛应用于船舶海洋平台等国家重大工程为保障我国海洋装备的安全与耐久性提供了关键支撑
- 水性船舶防腐涂层新材料项目团队是一支源自东北石油大学的创新创业团队专注于推动船舶涂料行业的环保化转型团队致力于攻克水性涂料在船舶高湿环境下干燥慢早期耐水性差的技术瓶颈旨在开发出兼具优异防腐性能和施工便利性的水性体系以替代传统溶剂型涂料其目标是实现进口产品替代并大幅减少船舶制造与维修过程中的VOCs排放
- 微纳一体化防腐耐磨技术研发团队是以广州航海学院青年技术骨干为核心的新锐力量团队针对铝合金在极端海洋环境中的腐蚀-磨损难题创新性地提出了微米级氧化陶瓷层+纳米自润滑固化层+改性硅烷钝化层的三层复合防护体系该技术使防护层的结合强度耐磨性提升2000倍和耐腐蚀性能自腐蚀电流密度降低6个数量级实现了质的飞跃
- 北京大学南京创新研究院BXCFD团队专注于自主可控的高性能计算流体力学软件研发团队在船舶与海洋工程水动力学领域取得关键突破其自主研发的软件在船舶兴波阻力预报精度上达到国际先进水平并成功实现了对复杂的船--舵6自由度运动的耦合高精度模拟为船舶水动力性能研究与优化提供了强大的国产化工具
- 清华大学多相流与生物流动力学实验室由罗先武教授带领长期专注于流体机械及工程领域团队重点研究高速船舶喷水推进装置的基础理论与空化流动机理其研究成果为攻克喷水推进系统中的空化振动与噪声问题提供了坚实的理论依据和技术支持对我国高性能船舶推进技术的发展具有重要意义
'''
context = {"材料腐蚀":c1}
Request_Cache: dict[str, str] = {} Request_Cache: dict[str, str] = {}
app = Flask(__name__) app = Flask(__name__)
@ -48,6 +99,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 +170,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 +264,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(
@ -218,6 +272,7 @@ def Handle_generate_basePlan():
Agent_Board=AgentBoard, Agent_Board=AgentBoard,
AgentProfile_Dict=AgentProfile_Dict, AgentProfile_Dict=AgentProfile_Dict,
InitialObject_List=incoming_data["Initial Input Object"], InitialObject_List=incoming_data["Initial Input Object"],
context="\n请注意,目标是给出解决方案,而不是工程实现,不需要实验验证,也不需要推广计划。"
) )
basePlan_withRenderSpec = Add_Collaboration_Brief_FrontEnd(basePlan) basePlan_withRenderSpec = Add_Collaboration_Brief_FrontEnd(basePlan)
Request_Cache[requestIdentifier] = basePlan_withRenderSpec Request_Cache[requestIdentifier] = basePlan_withRenderSpec
@ -228,6 +283,10 @@ def Handle_generate_basePlan():
@app.route("/executePlan", methods=["post"]) @app.route("/executePlan", methods=["post"])
def Handle_executePlan(): def Handle_executePlan():
incoming_data = request.get_json() incoming_data = request.get_json()
cur_context = ""
if "材料腐蚀" in incoming_data["plan"]["General Goal"]:
cur_context = context["材料腐蚀"]
requestIdentifier = str( requestIdentifier = str(
( (
"/executePlan", "/executePlan",
@ -239,6 +298,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(
@ -246,20 +306,21 @@ def Handle_executePlan():
incoming_data["num_StepToRun"], incoming_data["num_StepToRun"],
incoming_data["RehearsalLog"], incoming_data["RehearsalLog"],
AgentProfile_Dict, AgentProfile_Dict,
context=cur_context
) )
Request_Cache[requestIdentifier] = RehearsalLog Request_Cache[requestIdentifier] = RehearsalLog
response = jsonify(RehearsalLog) response = jsonify(RehearsalLog)
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

@ -17,7 +17,7 @@ import _ from 'lodash';
// fakeAgentSelections, // fakeAgentSelections,
// fakeCurrentAgentSelection, // fakeCurrentAgentSelection,
// } from './data/fakeAgentAssignment'; // } from './data/fakeAgentAssignment';
import CheckIcon from '@/icons/CheckIcon'; import CheckIcon from '@/icons/checkIcon';
import AgentIcon from '@/components/AgentIcon'; import AgentIcon from '@/components/AgentIcon';
import { globalStorage } from '@/storage'; import { globalStorage } from '@/storage';
import SendIcon from '@/icons/SendIcon'; import SendIcon from '@/icons/SendIcon';
@ -351,7 +351,7 @@ export default observer(({ style = {} }: IPlanModification) => {
overflowY: 'auto', overflowY: 'auto',
}} }}
> >
<Box sx={{ marginBottom: '6px', fontWeight: '600' }}>Assignment</Box> <Box sx={{ marginBottom: '6px', fontWeight: '600' }}></Box>
<Box> <Box>
{Object.keys(agentSelections).map(selectionId => ( {Object.keys(agentSelections).map(selectionId => (
<Box <Box
@ -405,7 +405,7 @@ export default observer(({ style = {} }: IPlanModification) => {
overflowY: 'auto', overflowY: 'auto',
}} }}
> >
<Box sx={{ marginBottom: '4px', fontWeight: '600' }}>Comparison</Box> <Box sx={{ marginBottom: '4px', fontWeight: '600' }}></Box>
<Box <Box
sx={{ sx={{

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,4 +1,5 @@
import AbigailChen from '@/static/AgentIcons/Abigail_Chen.png'; import AbigailChen from '@/static/AgentIcons/Abigail_Chen.png';
import AbigailChenMilitary from '@/static/AgentIcons/Abigail_Chen_military.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';
import AyeshaKhan from '@/static/AgentIcons/Ayesha_Khan.png'; import AyeshaKhan from '@/static/AgentIcons/Ayesha_Khan.png';
@ -8,9 +9,11 @@ import EddyLin from '@/static/AgentIcons/Eddy_Lin.png';
import FranciscoLopez from '@/static/AgentIcons/Francisco_Lopez.png'; import FranciscoLopez from '@/static/AgentIcons/Francisco_Lopez.png';
import GiorgioRossi from '@/static/AgentIcons/Giorgio_Rossi.png'; import GiorgioRossi from '@/static/AgentIcons/Giorgio_Rossi.png';
import HaileyJohnson from '@/static/AgentIcons/Hailey_Johnson.png'; import HaileyJohnson from '@/static/AgentIcons/Hailey_Johnson.png';
import HaileyJohnsonMilitary from '@/static/AgentIcons/Hailey_Johnson_military.png';
import IsabellaRodriguez from '@/static/AgentIcons/Isabella_Rodriguez.png'; import IsabellaRodriguez from '@/static/AgentIcons/Isabella_Rodriguez.png';
import JaneMoreno from '@/static/AgentIcons/Jane_Moreno.png'; import JaneMoreno from '@/static/AgentIcons/Jane_Moreno.png';
import JenniferMoore from '@/static/AgentIcons/Jennifer_Moore.png'; import JenniferMoore from '@/static/AgentIcons/Jennifer_Moore.png';
import JenniferMooreMilitary from '@/static/AgentIcons/Jennifer_Moore_military.png';
import JohnLin from '@/static/AgentIcons/John_Lin.png'; import JohnLin from '@/static/AgentIcons/John_Lin.png';
import KlausMueller from '@/static/AgentIcons/Klaus_Mueller.png'; import KlausMueller from '@/static/AgentIcons/Klaus_Mueller.png';
import LatoyaWilliams from '@/static/AgentIcons/Latoya_Williams.png'; import LatoyaWilliams from '@/static/AgentIcons/Latoya_Williams.png';
@ -27,6 +30,7 @@ import Unknown from '@/static/AgentIcons/Unknow.png';
export enum IconName { export enum IconName {
AbigailChen = 'Abigail_Chen', AbigailChen = 'Abigail_Chen',
AbigailChenMilitary = 'Abigail_Chen_military',
AdamSmith = 'Adam_Smith', AdamSmith = 'Adam_Smith',
ArthurBurton = 'Arthur_Burton', ArthurBurton = 'Arthur_Burton',
AyeshaKhan = 'Ayesha_Khan', AyeshaKhan = 'Ayesha_Khan',
@ -45,9 +49,11 @@ export enum IconName {
GabeSmith = 'Gabe_Smith', GabeSmith = 'Gabe_Smith',
GiorgioRossi = 'Giorgio_Rossi', GiorgioRossi = 'Giorgio_Rossi',
HaileyJohnson = 'Hailey_Johnson', HaileyJohnson = 'Hailey_Johnson',
HaileyJohnsonMilitary = 'Hailey_Johnson_military',
IsabellaRodriguez = 'Isabella_Rodriguez', IsabellaRodriguez = 'Isabella_Rodriguez',
JaneMoreno = 'Jane_Moreno', JaneMoreno = 'Jane_Moreno',
JenniferMoore = 'Jennifer_Moore', JenniferMoore = 'Jennifer_Moore',
JenniferMooreMilitary = 'Jennifer_Moore_military',
JohnLin = 'John_Lin', JohnLin = 'John_Lin',
KlausMueller = 'Klaus_Mueller', KlausMueller = 'Klaus_Mueller',
LatoyaWilliams = 'Latoya_Williams', LatoyaWilliams = 'Latoya_Williams',
@ -83,6 +89,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.AbigailChen]: AbigailChen, [IconName.AbigailChen]: AbigailChen,
[IconName.AbigailChenMilitary]: AbigailChenMilitary,
[IconName.AdamSmith]: AdamSmith, [IconName.AdamSmith]: AdamSmith,
[IconName.ArthurBurton]: ArthurBurton, [IconName.ArthurBurton]: ArthurBurton,
[IconName.AyeshaKhan]: AyeshaKhan, [IconName.AyeshaKhan]: AyeshaKhan,
@ -101,9 +108,11 @@ export const IconUrl: { [key in IconName]: string } = {
[IconName.GabeSmith]: AbigailChen, [IconName.GabeSmith]: AbigailChen,
[IconName.GiorgioRossi]: GiorgioRossi, [IconName.GiorgioRossi]: GiorgioRossi,
[IconName.HaileyJohnson]: HaileyJohnson, [IconName.HaileyJohnson]: HaileyJohnson,
[IconName.HaileyJohnsonMilitary]: HaileyJohnsonMilitary,
[IconName.IsabellaRodriguez]: IsabellaRodriguez, [IconName.IsabellaRodriguez]: IsabellaRodriguez,
[IconName.JaneMoreno]: JaneMoreno, [IconName.JaneMoreno]: JaneMoreno,
[IconName.JenniferMoore]: JenniferMoore, [IconName.JenniferMoore]: JenniferMoore,
[IconName.JenniferMooreMilitary]: JenniferMooreMilitary,
[IconName.JohnLin]: JohnLin, [IconName.JohnLin]: JohnLin,
[IconName.KlausMueller]: KlausMueller, [IconName.KlausMueller]: KlausMueller,
[IconName.LatoyaWilliams]: LatoyaWilliams, [IconName.LatoyaWilliams]: LatoyaWilliams,

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

@ -1,33 +1,33 @@
import { Box } from '@mui/material'; import { Box } from '@mui/material';
import React from 'react'; import React from 'react';
// 定义你的图标属性类型,这里可以扩展成任何你需要的属性 // 定义你的图标属性类型,这里可以扩展成任何你需要的属性
interface CustomIconProps { interface CustomIconProps {
size?: number | string; size?: number | string;
color?: string; color?: string;
// ...其他你需要的props // ...其他你需要的props
} }
// 创建你的自定义SVG图标组件 // 创建你的自定义SVG图标组件
const CheckIcon: React.FC<CustomIconProps> = ({ const CheckIcon: React.FC<CustomIconProps> = ({
size = '100%', size = '100%',
color = 'currentColor', color = 'currentColor',
}) => { }) => {
return ( return (
<Box <Box
component="svg" component="svg"
width={size} width={size}
height="auto" height="auto"
viewBox="0 0 11 9" viewBox="0 0 11 9"
fill="none" fill="none"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
> >
<path <path
d="M10.7204 0C7.37522 1.94391 4.95071 4.40066 3.85635 5.63171L1.18331 3.64484L0 4.54699L4.61463 9C5.4068 7.07085 7.92593 3.30116 11 0.620227L10.7204 0Z" d="M10.7204 0C7.37522 1.94391 4.95071 4.40066 3.85635 5.63171L1.18331 3.64484L0 4.54699L4.61463 9C5.4068 7.07085 7.92593 3.30116 11 0.620227L10.7204 0Z"
fill={color} fill={color}
/> />
</Box> </Box>
); );
}; };
export default CheckIcon; export default CheckIcon;

View File

@ -44,7 +44,7 @@ export default observer(() => {
)} )}
{globalStorage.agentAssigmentWindow ? ( {globalStorage.agentAssigmentWindow ? (
<FloatWindow <FloatWindow
title="Assignment Exploration" title="智能体选择"
onClose={() => (globalStorage.agentAssigmentWindow = false)} onClose={() => (globalStorage.agentAssigmentWindow = false)}
> >
<AgentAssignment <AgentAssignment

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: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 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}.`;