mirror of
https://github.com/jihe520/MathModelAgent.git
synced 2026-09-19 08:09:48 +08:00
backup
This commit is contained in:
@@ -106,5 +106,10 @@ class WriterMessage(AgentMessage):
|
||||
|
||||
# 所有可能的消息类型
|
||||
MessageType = Union[
|
||||
SystemMessage, UserMessage, ModelerMessage, CoderMessage, WriterMessage
|
||||
SystemMessage,
|
||||
UserMessage,
|
||||
ModelerMessage,
|
||||
CoderMessage,
|
||||
WriterMessage,
|
||||
CoordinatorMessage,
|
||||
]
|
||||
|
||||
@@ -1,9 +1,180 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import { useTaskStore } from '@/stores/task'
|
||||
import { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/card'
|
||||
import { Separator } from '@/components/ui/separator'
|
||||
|
||||
const taskStore = useTaskStore()
|
||||
|
||||
// 获取最新的CoordinatorMessage
|
||||
const latestCoordinatorMessage = computed(() => {
|
||||
const messages = taskStore.coordinatorMessages
|
||||
return messages.length > 0 ? messages[messages.length - 1] : null
|
||||
})
|
||||
|
||||
// 解析CoordinatorMessage的JSON内容
|
||||
const coordinatorData = computed(() => {
|
||||
if (!latestCoordinatorMessage.value?.content) return null
|
||||
|
||||
try {
|
||||
const content = latestCoordinatorMessage.value.content
|
||||
// 移除可能的```json标记
|
||||
const cleanContent = content.replace(/```json\n?/, '').replace(/```$/, '').trim()
|
||||
return JSON.parse(cleanContent)
|
||||
} catch (error) {
|
||||
console.error('解析CoordinatorMessage失败:', error)
|
||||
return null
|
||||
}
|
||||
})
|
||||
|
||||
// 获取最新的ModelerMessage
|
||||
const latestModelerMessage = computed(() => {
|
||||
const messages = taskStore.modelerMessages
|
||||
return messages.length > 0 ? messages[messages.length - 1] : null
|
||||
})
|
||||
|
||||
// 解析ModelerMessage的JSON内容
|
||||
const modelerData = computed(() => {
|
||||
if (!latestModelerMessage.value?.content) return null
|
||||
|
||||
try {
|
||||
const content = latestModelerMessage.value.content
|
||||
// 移除可能的```json标记
|
||||
const cleanContent = content.replace(/```json\n?/, '').replace(/```$/, '').trim()
|
||||
return JSON.parse(cleanContent)
|
||||
} catch (error) {
|
||||
console.error('解析ModelerMessage失败:', error)
|
||||
return null
|
||||
}
|
||||
})
|
||||
|
||||
// 生成问题列表
|
||||
const questionsList = computed(() => {
|
||||
if (!coordinatorData.value) return []
|
||||
|
||||
const questions = []
|
||||
for (let i = 1; i <= coordinatorData.value.ques_count; i++) {
|
||||
const quesKey = `ques${i}`
|
||||
if (coordinatorData.value[quesKey]) {
|
||||
questions.push({
|
||||
number: i,
|
||||
content: coordinatorData.value[quesKey]
|
||||
})
|
||||
}
|
||||
}
|
||||
return questions
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="h-full min-w-0 pb-4">
|
||||
modeler editor
|
||||
<div class="h-full min-w-0 flex flex-col">
|
||||
<!-- 上半部分:CoordinatorMessage 结构化信息 -->
|
||||
<div class="flex-1 p-4 overflow-auto">
|
||||
<Card class="h-full">
|
||||
<CardHeader>
|
||||
<CardTitle class="text-lg font-semibold">题目信息</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent class="space-y-4">
|
||||
<div v-if="coordinatorData">
|
||||
<!-- 题目标题 -->
|
||||
<div class="space-y-2">
|
||||
<h3 class="text-base font-medium text-gray-700">题目标题</h3>
|
||||
<div class="text-lg font-semibold text-gray-900">
|
||||
{{ coordinatorData.title }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Separator />
|
||||
|
||||
<!-- 题目背景 -->
|
||||
<div class="space-y-2">
|
||||
<h3 class="text-base font-medium text-gray-700">题目背景</h3>
|
||||
<div class="text-sm text-gray-800 leading-relaxed whitespace-pre-wrap">
|
||||
{{ coordinatorData.background }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Separator />
|
||||
|
||||
<!-- 问题数量和问题列表 -->
|
||||
<div class="space-y-2">
|
||||
<div class="flex items-center gap-2">
|
||||
<h3 class="text-base font-medium text-gray-700">问题列表</h3>
|
||||
<span class="px-2 py-1 text-xs bg-gray-100 rounded">{{ coordinatorData.ques_count }} 个问题</span>
|
||||
</div>
|
||||
|
||||
<div class="space-y-3">
|
||||
<div v-for="question in questionsList" :key="question.number"
|
||||
class="border-l-4 border-blue-500 pl-4 py-2 bg-blue-50 rounded-r">
|
||||
<div class="text-sm font-medium text-blue-700 mb-1">
|
||||
问题 {{ question.number }}
|
||||
</div>
|
||||
<div class="text-sm text-gray-800 leading-relaxed">
|
||||
{{ question.content }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-else class="text-center py-8 text-gray-500">
|
||||
暂无题目信息
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
<!-- 下半部分:ModelerMessage 建模手册 -->
|
||||
<div class="flex-1 p-4 pt-0 overflow-auto">
|
||||
<Card class="h-full">
|
||||
<CardHeader>
|
||||
<CardTitle class="text-lg font-semibold">建模手册</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div v-if="modelerData" class="space-y-4">
|
||||
<!-- EDA部分 -->
|
||||
<div v-if="modelerData.eda" class="space-y-2">
|
||||
<h3 class="text-base font-medium text-gray-700 flex items-center gap-2">
|
||||
<span class="px-2 py-1 text-xs bg-gray-200 border rounded">EDA</span>
|
||||
探索性数据分析
|
||||
</h3>
|
||||
<div class="text-sm text-gray-800 leading-relaxed whitespace-pre-wrap bg-gray-50 p-3 rounded">
|
||||
{{ modelerData.eda }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 问题解决方案 -->
|
||||
<div v-for="question in questionsList" :key="`solution-${question.number}`" class="space-y-2">
|
||||
<div v-if="modelerData[`ques${question.number}`]">
|
||||
<h3 class="text-base font-medium text-gray-700 flex items-center gap-2">
|
||||
<span class="px-2 py-1 text-xs bg-gray-200 border rounded">问题{{ question.number }}</span>
|
||||
解决方案
|
||||
</h3>
|
||||
<div
|
||||
class="text-sm text-gray-800 leading-relaxed whitespace-pre-wrap bg-green-50 p-3 rounded border-l-4 border-green-500">
|
||||
{{ modelerData[`ques${question.number}`] }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 敏感性分析 -->
|
||||
<div v-if="modelerData.sensitivity_analysis" class="space-y-2">
|
||||
<h3 class="text-base font-medium text-gray-700 flex items-center gap-2">
|
||||
<span class="px-2 py-1 text-xs bg-gray-200 border rounded">敏感性分析</span>
|
||||
</h3>
|
||||
<div
|
||||
class="text-sm text-gray-800 leading-relaxed whitespace-pre-wrap bg-orange-50 p-3 rounded border-l-4 border-orange-500">
|
||||
{{ modelerData.sensitivity_analysis }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-else class="text-center py-8 text-gray-500">
|
||||
暂无建模手册信息
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -16,6 +16,9 @@ import { submitModelingTask } from '@/apis/submitModelingApi'
|
||||
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert'
|
||||
import { Rocket } from 'lucide-vue-next'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { useTaskStore } from '@/stores/task'
|
||||
|
||||
const taskStore = useTaskStore()
|
||||
|
||||
const currentStep = ref(1)
|
||||
const fileUploaded = ref(true)
|
||||
@@ -102,6 +105,7 @@ const handleSubmit = async () => {
|
||||
)
|
||||
|
||||
taskId.value = response?.data?.task_id ?? null
|
||||
taskStore.addUserMessage(question.value)
|
||||
|
||||
showSubmitSuccess.value = true
|
||||
setTimeout(() => {
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { ref, computed } from 'vue'
|
||||
import { TaskWebSocket } from '@/utils/websocket'
|
||||
import type { Message, CoderMessage, WriterMessage } from '@/utils/response'
|
||||
import type { Message, CoderMessage, WriterMessage, UserMessage, ModelerMessage, CoordinatorMessage } from '@/utils/response'
|
||||
// import messageData from '@/test/20250524-115938-d4c84576.json'
|
||||
import messageData from '@/test/20250524-133152-0f9d6be8.json'
|
||||
import { AgentType } from '@/utils/enum'
|
||||
|
||||
export const useTaskStore = defineStore('task', () => {
|
||||
// 初始化时直接加载测试数据,确保页面首次渲染时有数据
|
||||
@@ -30,6 +31,14 @@ export const useTaskStore = defineStore('task', () => {
|
||||
ws?.close()
|
||||
}
|
||||
|
||||
function addUserMessage(content: string) {
|
||||
messages.value.push({
|
||||
id: Date.now().toString(),
|
||||
msg_type: 'user',
|
||||
content: content,
|
||||
} as UserMessage)
|
||||
}
|
||||
|
||||
// 下载消息
|
||||
function downloadMessages() {
|
||||
const dataStr = "data:text/json;charset=utf-8," + encodeURIComponent(JSON.stringify(messages.value, null, 2))
|
||||
@@ -45,10 +54,10 @@ export const useTaskStore = defineStore('task', () => {
|
||||
const chatMessages = computed(() =>
|
||||
messages.value.filter(
|
||||
(msg) => {
|
||||
if (msg.msg_type === 'agent' && msg.agent_type === 'CoderAgent' && msg.content == null) {
|
||||
if (msg.msg_type === 'agent' && msg.agent_type === AgentType.CODER && msg.content == null) {
|
||||
return false
|
||||
}
|
||||
if (msg.msg_type === 'agent' && msg.agent_type === 'WriterAgent') {
|
||||
if (msg.msg_type === 'agent' && msg.agent_type === AgentType.WRITER) {
|
||||
return false
|
||||
}
|
||||
return msg.msg_type === 'agent' && msg.content || msg.msg_type === 'system'
|
||||
@@ -56,12 +65,30 @@ export const useTaskStore = defineStore('task', () => {
|
||||
)
|
||||
)
|
||||
|
||||
const coordinatorMessages = computed(() =>
|
||||
messages.value.filter(
|
||||
(msg): msg is CoordinatorMessage =>
|
||||
msg.msg_type === 'agent' &&
|
||||
msg.agent_type === AgentType.COORDINATOR &&
|
||||
msg.content != null
|
||||
)
|
||||
)
|
||||
|
||||
const modelerMessages = computed(() =>
|
||||
messages.value.filter(
|
||||
(msg): msg is ModelerMessage =>
|
||||
msg.msg_type === 'agent' &&
|
||||
msg.agent_type === AgentType.MODELER &&
|
||||
msg.content != null
|
||||
)
|
||||
)
|
||||
|
||||
const coderMessages = computed(() =>
|
||||
messages.value.filter(
|
||||
(msg): msg is CoderMessage =>
|
||||
msg.msg_type === 'agent' &&
|
||||
msg.agent_type === 'CoderAgent' &&
|
||||
(msg.code != null || msg.code_results != null)
|
||||
msg.agent_type === AgentType.CODER &&
|
||||
msg.content != null
|
||||
)
|
||||
)
|
||||
|
||||
@@ -69,7 +96,7 @@ export const useTaskStore = defineStore('task', () => {
|
||||
messages.value.filter(
|
||||
(msg): msg is WriterMessage =>
|
||||
msg.msg_type === 'agent' &&
|
||||
msg.agent_type === 'WriterAgent' &&
|
||||
msg.agent_type === AgentType.WRITER &&
|
||||
msg.content != null
|
||||
)
|
||||
)
|
||||
@@ -79,7 +106,7 @@ export const useTaskStore = defineStore('task', () => {
|
||||
// 反向遍历消息找到最新的文件列表
|
||||
for (let i = coderMessages.value.length - 1; i >= 0; i--) {
|
||||
const msg = coderMessages.value[i]
|
||||
if ('files' in msg && msg.files?.length) {
|
||||
if ('files' in msg && msg.files && Array.isArray(msg.files) && msg.files.length > 0) {
|
||||
console.log('找到文件列表:', msg.files)
|
||||
return msg.files
|
||||
}
|
||||
@@ -96,11 +123,14 @@ export const useTaskStore = defineStore('task', () => {
|
||||
return {
|
||||
messages,
|
||||
chatMessages,
|
||||
coordinatorMessages,
|
||||
modelerMessages,
|
||||
coderMessages,
|
||||
writerMessages,
|
||||
files,
|
||||
connectWebSocket,
|
||||
closeWebSocket,
|
||||
downloadMessages
|
||||
downloadMessages,
|
||||
addUserMessage
|
||||
}
|
||||
})
|
||||
@@ -15,7 +15,7 @@ export interface ToolMessage extends BaseMessage {
|
||||
msg_type: 'tool';
|
||||
tool_name: 'execute_code' | 'search_scholar';
|
||||
input: {};
|
||||
output: [];
|
||||
output: string[] | OutputItem[];
|
||||
}
|
||||
|
||||
export interface SystemMessage extends BaseMessage {
|
||||
@@ -79,7 +79,20 @@ export interface ErrorExecution extends BaseCodeExecution {
|
||||
traceback: string;
|
||||
}
|
||||
|
||||
export type CodeExecutionResult = StdOutExecution | StdErrExecution | ResultExecution | ErrorExecution;
|
||||
export type OutputItem = StdOutExecution | StdErrExecution | ResultExecution | ErrorExecution;
|
||||
|
||||
export interface ScholarMessage extends ToolMessage {
|
||||
tool_name: 'search_scholar';
|
||||
input: {};
|
||||
output: string[];
|
||||
}
|
||||
|
||||
export interface InterpreterMessage extends ToolMessage {
|
||||
tool_name: 'execute_code';
|
||||
input: {};
|
||||
output: OutputItem[];
|
||||
}
|
||||
|
||||
|
||||
export interface CoderMessage extends AgentMessage {
|
||||
agent_type: AgentType.CODER;
|
||||
@@ -90,4 +103,4 @@ export interface WriterMessage extends AgentMessage {
|
||||
sub_title?: string;
|
||||
}
|
||||
|
||||
export type Message = SystemMessage | UserMessage | CoderMessage | WriterMessage;
|
||||
export type Message = SystemMessage | UserMessage | CoderMessage | WriterMessage | ModelerMessage | CoordinatorMessage;
|
||||
Reference in New Issue
Block a user