This commit is contained in:
2025-02-24 15:30:15 +08:00
39 changed files with 1143 additions and 225 deletions

View File

@@ -1,6 +1,8 @@
# 打包路径
VITE_BASE_URL = /
VITE_IS_REQUEST_PROXY = true
VITE_API_URL = http://47.121.220.134
VITE_API_URL = http://159.75.70.95
VITE_API_URL_PREFIX = /matagent
VITE_WB_BASE_URL = ws://47.121.220.134:8000/matagent/chat
VITE_WB_BASE_URL = ws://8.210.37.238:8000/ws/chat
VITE_WB_CAMERA_ONE_URL = ws://159.75.70.95:8000/video_stream/camera1
VITE_WB_CAMERA_TWO_URL = ws://159.75.70.95:8000/video_stream/camera2

View File

@@ -3,4 +3,6 @@ VITE_BASE_URL = /
VITE_IS_REQUEST_PROXY = true
VITE_API_URL = http://159.75.91.126
VITE_API_URL_PREFIX = /matagent
VITE_WB_BASE_URL = ws://47.121.220.134:8000/matagent/chat
VITE_WB_BASE_URL = ws://8.210.37.238:8000/ws/chat
VITE_WB_CAMERA_ONE_URL = ws://159.75.70.95:8000/video_stream/camera1
VITE_WB_CAMERA_TWO_URL = ws://159.75.70.95:8000/video_stream/camera2

View File

@@ -3,4 +3,6 @@ VITE_BASE_URL = /
VITE_IS_REQUEST_PROXY = true
VITE_API_URL = http://159.75.91.126
VITE_API_URL_PREFIX = /matagent
VITE_WB_BASE_URL = ws://47.121.220.134:8000/matagent/chat
VITE_WB_BASE_URL = ws://47.121.220.134:8000/matagent/chat
VITE_WB_CAMERA_ONE_URL = ws://159.75.70.95:8000/video_stream/camera1
VITE_WB_CAMERA_TWO_URL = ws://159.75.70.95:8000/video_stream/camera2

View File

@@ -5,8 +5,6 @@
</div>
</template>
<script setup lang="ts">
import SwitchLanguage from "./components/SwitchLanguage.vue";
import SwitchLanguage from './components/SwitchLanguage.vue'
</script>
<style scoped>
</style>
<style scoped></style>

View File

@@ -20,3 +20,16 @@ export function getModelList() {
url: `/model`
})
}
// 获取历史消息列表
export function getSessionsList() {
return request.get<ProjectListResult>({
url: `/sessions`
})
}
// 获取单条历史消息的聊天历史
export function getSessionsInfoList(session_uuid: any) {
return request.get<ProjectListResult>({
url: `/history/${session_uuid}`
})
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 803 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 602 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 762 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 678 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@@ -0,0 +1,45 @@
.camera_box {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
z-index: 99;
background: rgba(0, 0, 0, 0.4);
.header_box {
width: 50%;
display: flex;
justify-content: flex-end;
padding: 10px 0;
box-sizing: border-box;
}
.img_box {
width: 50vh;
height: 50vh;
display: flex;
align-items: center;
justify-content: center;
padding: 0;
margin: 0;
.icon_box {
animation: spin 2s linear infinite;
}
}
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}

View File

@@ -0,0 +1,82 @@
<template>
<div class="camera_box">
<div class="header_box">
<el-icon color="#fff" size="20" @click="closeCamera"
><CircleClose
/></el-icon>
</div>
<div class="img_box">
<!-- <el-icon class="icon_box" color="#fff" size="36" v-show="!loading"
><Loading
/></el-icon> -->
<img
:src="imgOneVal"
style="width: 50vw; height: 50vh"
alt=""
v-show="cameraNumber === 1"
/>
<img
:src="imgTwoVal"
style="width: 50vw; height: 50vh"
alt=""
v-show="cameraNumber === 2"
/>
</div>
<!-- <canvas ref="cameraOne" style="width: 50vw; height: 50vh"></canvas> -->
<!-- <canvas ref="cameraTwo" style="width: 50vw; height: 50vh"></canvas> -->
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, onUnmounted, defineExpose, defineEmits } from 'vue'
import useWebSocket from '../../utils/websocket'
// const cameraOne = ref("")
// const cameraTwo = ref("");
const imgOneVal = ref('')
const imgTwoVal = ref('')
const loading = ref<boolean>(false)
const handleMessage = (e: any) => {
imgOneVal.value = 'data:image/jpeg;base64,' + e.data
if (!loading.value && imgOneVal.value) {
loading.value = true
}
}
const handleTwoMessage = (e: any) => {
imgTwoVal.value = 'data:image/jpeg;base64,' + e.data
if (!loading.value && imgTwoVal.value) {
loading.value = true
}
}
const cameraNumber = ref<Number>(0)
const ws: any = useWebSocket(handleMessage, import.meta.env.VITE_WB_CAMERA_ONE_URL)
const wsTwo: any = useWebSocket(
handleTwoMessage,
import.meta.env.VITE_WB_CAMERA_TWO_URL
)
const emit = defineEmits(['closeCamera'])
// const ws = new WebSocket(import.meta.env.VITE_WB_CAMERA_ONE_URL)
onMounted(() => {})
const closeCamera = () => {
cameraNumber.value = 0
emit('closeCamera')
}
const closeWs = () => {
if (ws) {
ws.handleClose()
}
}
const closeWsTwo = () => {
if (wsTwo) {
wsTwo.handleClose()
}
}
defineExpose({ cameraNumber })
onUnmounted(() => {
closeWs()
closeWsTwo()
})
</script>
<style scoped>
@import './index.less';
</style>

View File

@@ -0,0 +1,459 @@
.process_box {
position: fixed;
bottom: 20px;
right: 6px;
width: 230px;
height: 230px;
// background: url('../../assets/chart/chart.png') no-repeat;
// background-size: cover;
.body-box {
position: relative;
width: 100%;
height: 100%;
.out_list {
width: 100%;
position: relative;
.out_item {
position: absolute;
.item_text {
position: relative;
width: 55px;
height: 52px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding-top: 5px;
.item_round {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
}
.p {
font-size: 12px;
width: 22px;
height: 16px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
transform: scale(0.8);
font-weight: 600;
}
.span {
transform: scale(0.6);
font-size: 12px;
margin-top: -4px;
}
.dashed_line {
position: absolute;
width: 14px;
img {
width: 100%;
}
}
}
&:nth-child(1) {
top: 82px;
left: 84px;
.item_text {
width: 68px;
height: 63px;
}
.p {
width: 18px;
height: 18px;
background: #bfd8ee;
color: #fff;
}
.span {
color: #649ed2;
margin-top: -6px;
}
}
&:nth-child(2) {
top: 2px;
left: 2px;
.p {
background: #FBEEB7;
color: #DAA600;
}
.span {
color: #DAA600;
}
.dashed_line {
transform: rotate(-90deg);
top: -38px;
left: 113px;
}
}
&:nth-child(3) {
top: 1px;
right: -2px;
.p {
background: #c5e0b4;
color: #e58881;
}
.span {
color: #5e913b;
}
.dashed_line {
top: 61px;
left: 28px;
width: 13.4px;
}
}
&:nth-child(4) {
top: 173px;
right: -2px;
.p {
background: #cccfde;
color: #5e913b;
}
.span {
color: #5e913b;
}
.dashed_line {
transform: rotate(90deg);
top: -23px;
left: -70.6px;
}
}
&:nth-child(5) {
top: 173px;
left: 1px;
.p {
background: #edd1cf;
color: #e58881;
}
.span {
color: #e58881;
}
.dashed_line {
transform: rotate(180deg);
top: -117px;
left: 14px;
width: 13.4px;
}
}
.centent_box {
position: relative;
.sector_box {
position: absolute;
z-index: 1;
&:nth-child(2) {
top: -50px;
left: 15px;
}
.one_box {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
img:nth-child(1) {
width: 19px;
height: 20px;
}
p {
width: 39px;
height: 16px;
border-radius: 50%;
background: #bfd7ec;
color: #447cb8;
margin-top: -3px;
margin-bottom: -1px;
text-align: center;
line-height: 13px;
span {
display: inline-block;
font-size: 12px;
transform: scale(0.6);
margin-left: -2px;
}
}
img:nth-child(3) {
width: 2px;
height: 37px;
}
}
.two_box {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
position: relative;
.top_box {
display: flex;
justify-content: center;
column-gap: 4px;
height: 19px;
.arrow_box_left {
img {
width: 4px;
height: 15px;
}
}
.person {
width: 7px;
height: 15px;
transform: rotate(45deg);
margin-top: 2px;
}
.arrow_box_right {
img {
width: 4px;
height: 15px;
}
}
}
.admin_box {
position: absolute;
top: 19px;
left: 3px;
width: 34px;
height: 16px;
border-radius: 50%;
background: #fcf7d9;
line-height: 12px;
span {
display: inline-block;
font-size: 12px;
transform: scale(0.6);
margin-left: -2px;
}
}
.bottom_box {
position: absolute;
top: 37px;
left: -12px;
display: flex;
justify-content: center;
p {
width: 2px;
height: 8px;
display: flex;
writing-mode: vertical-rl;
span {
font-size: 12px;
transform: scale(0.5);
display: inline-block;
width: 100%;
height: 100%;
line-height: 4px;
}
}
.sit {
width: 15px;
height: 19px;
transform: rotate(46deg)
}
.down_arrow {
width: 14px;
height: 29px;
margin-left: -3px;
}
.up_arrow {
width: 14px;
height: 29px;
margin-left: -2px;
}
.stand {
width: 15px;
height: 18px;
transform: rotate(46deg);
margin-top: 4px;
margin-left: -2px;
}
}
}
&:nth-child(3) {
top: -32px;
left: -46px;
transform: rotate(315deg);
}
&:nth-child(4) {
top: -33px;
right: -43px;
transform: rotate(45deg);
.two_box {
.top_box {
.person {
transform: rotate(-43deg);
}
}
.admin_box {
top: 18px;
left: -12px;
background: #daefdb;
}
.bottom_box {
top: 36px;
left: -23px;
.stand {
transform: rotate(-43deg);
margin-top: 7px;
margin-left: 0;
}
.sit {
transform: rotate(-46deg);
margin-top: 4px;
margin-left: 1px;
}
}
}
}
&:nth-child(5) {
bottom: -28px;
right: -46px;
transform: rotate(133deg);
.two_box {
.top_box {
.person {
transform: rotate(-135deg);
margin-top: 4px;
}
}
.admin_box {
top: 17px;
left: -3px;
transform: rotate(10deg);
background: #d8dae8;
}
.bottom_box {
top: 35px;
left: -11px;
.stand {
transform: rotate(-43deg);
margin-top: 7px;
margin-left: 0;
}
.sit {
transform: rotate(-123deg);
margin-top: 1px;
margin-left: 2px;
}
.up_arrow {
margin-left: -3px;
}
}
}
}
&:nth-child(6) {
bottom: -28px;
left: -48px;
transform: rotate(230deg);
.two_box {
.top_box {
.person {
transform: rotate(-231deg);
margin-top: 5px;
margin-left: 1px
}
}
.admin_box {
top: 20px;
left: -15px;
transform: rotate(-9deg);
background: #fceeed;
}
.bottom_box {
top: 36px;
left: -25px;
transform: rotate(-5deg);
.stand {
transform: rotate(109deg);
margin-top: 6px;
margin-left: 0px;
}
.sit {
transform: rotate(137deg);
margin-top: 6px;
margin-left: 2px;
}
.up_arrow {
margin-left: -3px;
}
}
}
}
}
}
}
}
}
}

View File

@@ -0,0 +1,176 @@
<template>
<div class="process_box" v-show="isCollapse">
<div class="body-box">
<div class="out_list">
<div class="out_item" v-for="(item, index) in outList" :key="index">
<div class="item_text" v-if="index">
<img class="item_round" :src="item.url" alt="" />
<p class="p">{{ item.goup }}</p>
<span class="span">{{ item.content }}</span>
<div class="dashed_line">
<img src="../../assets/chart/dashed_line_arrow.png" alt="" />
</div>
</div>
<div class="centent_box" v-else>
<div class="item_text">
<img class="item_round" :src="item.url" alt="" />
<p class="p">{{ item.goup }}</p>
<span class="span">{{ item.content }}</span>
</div>
<div class="sector_box" v-for="(key, num) in centerList" :key="num">
<div class="one_box" v-if="!num">
<img src="../../assets/chart/user.png" alt="" />
<p>
<span>{{ key.getter }}</span>
</p>
<img src="../../assets/chart/one_arrow.png" alt="" />
</div>
<div class="two_box" v-else>
<div class="top_box">
<p class="arrow_box_left">
<img
src="../../assets/chart/three_arrow.png"
v-show="num === 2"
alt=""
/>
<img
src="../../assets/chart/five_arrow.png"
v-show="num === 4"
alt=""
/>
</p>
<img
class="person"
src="../../assets/chart/person.png"
alt=""
/>
<p class="arrow_box_right">
<img
src="../../assets/chart/two_arrow.png"
v-show="num === 1"
alt=""
/>
<img
src="../../assets/chart/four_arrow.png"
v-show="num === 3"
alt=""
/>
</p>
</div>
<div class="admin_box">
<span>{{ key.getter }}</span>
</div>
<div class="bottom_box" v-if="num != 2">
<img class="sit" src="../../assets/chart/sit.png" alt="" />
<img
class="down_arrow"
src="../../assets/chart/down_arrow.png"
alt=""
/>
<p>
<span>{{ key.typeText }}</span>
</p>
<img
class="up_arrow"
src="../../assets/chart/up_arrow.png"
alt=""
/>
<img
class="stand"
src="../../assets/chart/stand.png"
alt=""
v-if="num != 3"
/>
</div>
<div class="bottom_box" v-else>
<img
class="stand"
src="../../assets/chart/stand.png"
alt=""
/>
<img
class="up_arrow"
src="../../assets/chart/up_arrow.png"
alt=""
/>
<p>
<span>{{ key.typeText }}</span>
</p>
<img
class="down_arrow"
src="../../assets/chart/down_arrow.png"
alt=""
/>
<img class="sit" src="../../assets/chart/sit.png" alt="" />
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import oneRound from '../../assets/chart/one_round.png'
import twoRound from '../../assets/chart/two_round.png'
import threeRound from '../../assets/chart/three_round.png'
import fourRound from '../../assets/chart/four_round.png'
import fiveRound from '../../assets/chart/five_round.png'
const isCollapse = ref<boolean>(true)
const outList = ref<Array<any>>([
{
url: oneRound,
goup: 'G1',
content: 'ORCHESTRATOR'
},
{
url: twoRound,
goup: 'G2',
content: 'SCIENTIST'
},
{
url: threeRound,
goup: 'G3',
content: 'ENGINEER'
},
{
url: fourRound,
goup: 'G4',
content: 'EXECUTOR'
},
{
url: fiveRound,
goup: 'G5',
content: 'ANALYST'
}
])
const centerList = ref<Array<any>>([
{
getter: 'Human',
typeText: ''
},
{
getter: 'Admin',
typeText: 'Handoff'
},
{
getter: 'Admin',
typeText: 'Handoff'
},
{
getter: 'Admin',
typeText: 'Handoff'
},
{
getter: 'Admin',
typeText: 'Handoff'
}
])
</script>
<style scoped>
@import './index.less';
</style>

View File

@@ -7,7 +7,7 @@
:id="`${num}title`"
>
<div class="title-box">
<p>{{generateTitle('问题设定')}}:</p>
<p>{{ generateTitle('问题设定') }}:</p>
<span>{{ key.title }}</span>
</div>
<div
@@ -18,28 +18,44 @@
>
<div class="title">
<img src="../../assets/logo.png" alt="" />
<span v-if="item.group_name === 'Planner'">{{generateTitle('角色')}}{{ item.group_name }}</span>
<span v-else>{{generateTitle('模型名称')}}{{ `${item.group_name}: ${item.agent_name}` }}</span>
<span v-if="item.source === 'Planner'"
>{{ generateTitle('角色') }}{{ item.source }}</span
>
<span v-else
>{{ generateTitle('模型名称') }}{{ `${item.source}` }}</span
>
<!-- <span v-else>{{generateTitle('模型名称')}}{{ `${item.source}: ${item.agent_name}` }}</span> -->
<p
class="active_item"
v-if="reasonStatus.index === index && reasonStatus.show"
v-if="key.children.length - 1 === index && reasonStatus.show"
>
<img src="../../assets/layout/vector.png" alt="" />
{{generateTitle('推理中')}}...
{{ generateTitle('推理中') }}...
</p>
</div>
<div class="reasoning-content">
<div
class="reasoning-text"
:class="{
active: reasonStatus.index === index && reasonStatus.show
active: key.children.length - 1 === index && reasonStatus.show
}"
>
<div
style="font-size: 14px"
:class="{ 'show-box': current[index] }"
>
<MdPreview style="background: linear-gradient(to bottom,#d5e6f4 0%,#afceea 50%,#c2d9ef 100%);" :editorId="id" :modelValue="item.content" />
<MdPreview
style="
background: linear-gradient(
to bottom,
#d5e6f4 0%,
#afceea 50%,
#c2d9ef 100%
);
"
:editorId="id"
:modelValue="item.content"
/>
</div>
</div>
<div class="icon-box">
@@ -53,7 +69,11 @@
class="complete-box"
v-if="completeList[num].show && num === completeList[num].index"
>
{{ generateTitle('推理完成,如果希望了解更多可继续在下面框中提问或新建对话。')}}
{{
generateTitle(
'推理完成,如果希望了解更多可继续在下面框中提问或新建对话。'
)
}}
</div>
</div>
</div>
@@ -62,7 +82,7 @@
import { ref, defineExpose, defineEmits, defineProps } from 'vue'
import { Plus, Minus } from '@element-plus/icons-vue'
import { MdPreview } from 'md-editor-v3'
import {generateTitle} from '../../utils/i18n'
import { generateTitle } from '../../utils/i18n'
import 'md-editor-v3/lib/style.css'
const props: any = defineProps({
reasoningList: {

View File

@@ -13,8 +13,9 @@
@click="toContent(index, num)"
v-for="(key, num) in item.children"
:key="num"
style="width: 100%;"
>
<div v-if="key.group_name !== 'Planner'" class="li">
<div v-if="key.source !== 'Planner'" class="li">
<div
class="p-box"
:class="{
@@ -31,7 +32,8 @@
src="../assets/layout/vector.png"
alt=""
/>
<span>{{ `${key.group_name?key.group_name+':':''} ${key.agent_name}` }}</span>
<span>{{ `${key.source || ''}` }}</span>
<!-- <span>{{ `${key.source?key.source+':':''} ${key.agent_name}` }}</span> -->
</div>
<img
class="next"

View File

@@ -1,9 +1,11 @@
<template>
<div class="textarea-content">
<el-input
v-model="chatData.message"
v-model="chatData.content"
@keydown="handleKeydown"
:placeholder="generateTitle('在此输入您的问题或需求有问必答Shift+Enter换行')"
:placeholder="
generateTitle('在此输入您的问题或需求有问必答Shift+Enter换行')
"
type="textarea"
:autosize="{ minRows: props.minRows }"
:disabled="disableStatus"
@@ -11,7 +13,8 @@
</el-input>
<div class="btn-box">
<el-button type="primary" @click="submitFun" :disabled="disableStatus"
><el-icon color="#fff" size="16"><Promotion /></el-icon>{{generateTitle('发送')}}</el-button
><el-icon color="#fff" size="16"><Promotion /></el-icon
>{{ generateTitle('发送') }}</el-button
>
</div>
</div>
@@ -20,7 +23,7 @@
import { ref, defineProps, defineEmits, defineExpose } from 'vue'
import { Promotion } from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'
import {generateTitle} from '../utils/i18n'
import { generateTitle } from '../utils/i18n'
// import { chat } from "../api/user";
const handleKeydown = (event: any) => {
@@ -38,14 +41,15 @@ const props = defineProps({
})
const chatData = ref<any>({
chat_id: '',
message: ''
// chat_id: '',
source: 'user',
content: ''
})
//如何在室温条件下合成CsPbBr3
const disableStatus = ref(false)
const emits = defineEmits(['submitFun'])
const submitFun = async () => {
if (!chatData.value.message) {
if (!chatData.value.content) {
ElMessage.error('请输入问题')
return
}
@@ -53,11 +57,12 @@ const submitFun = async () => {
ElMessage.error('回答输出中,暂不能再次提问')
return
}
chatData.value.chat_id = new Date().getTime()
// chatData.value.chat_id = new Date().getTime()
emits('submitFun', JSON.stringify(chatData.value))
chatData.value = {
chat_id: '',
message: ''
// chat_id: '',
source: 'user',
content: ''
}
}
defineExpose({

View File

@@ -3,12 +3,13 @@
}
.aside-box {
// height: calc(100vh - 175px);
height: calc(100vh - 175px);
overflow: inherit;
position: relative;
.collapse-demo {
width: 36px;
// height: 100%;
height: calc(100% - 260px);
background: #093e7a;
border: 1px solid rgba(2, 83, 137, 1);
@@ -67,6 +68,9 @@
padding-left: 30px;
font-size: 16px;
font-weight: 600;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
}
@@ -287,6 +291,7 @@
margin-top: -3px;
}
}
.chart-active {
.type-box {
@@ -295,9 +300,11 @@
text-align: center;
z-index: 9;
}
.model-title {
color: #333;
}
.chart-bg {
position: absolute;
top: 3px;
@@ -583,6 +590,7 @@
.model-box {
position: relative;
}
.chart-active {
.type-box {
@@ -591,9 +599,11 @@
text-align: center;
z-index: 9;
}
.model-title {
color: #333;
}
.chart-bg {
position: absolute;
top: 3px;

View File

@@ -5,23 +5,30 @@
width="230px"
>
<div>
<div class="collapse-demo" :class="{ active: isCollapse }" width="230px">
<div
class="collapse-demo"
:class="['collapse-demo', { active: isCollapse }]"
width="230px"
>
<div class="collapse-title">
<div class="icon-box" @click="changeStatusFun">
<el-icon size="14" color="rgba(157, 215, 248, 1)"
><component :is="getIcon()"></component
></el-icon>
</div>
<div class="title">{{ generateTitle("模型调用流程") }}</div>
<div class="title">{{ generateTitle('模型调用流程') }}</div>
</div>
<div style="height: 100%" v-show="isCollapse">
<steps-view :reasoningList="reasoningList" />
</div>
<div v-show="isCollapse">
<ProcessView />
</div>
<!-- <div class="user-box">
<img src="../../assets/logo.png" alt="" />
<span v-show="isCollapse">Jayson</span>
</div> -->
<div class="chart-box" v-show="isCollapse">
<!-- <div class="chart-box" v-show="isCollapse">
<div class="body-box">
<div class="out-round-list">
<div
@@ -87,76 +94,77 @@
</div>
</div>
</div>
</div>
</div> -->
</div>
</div>
</div>
</template>
<script setup lang="ts">
import StepsView from "../StepsView.vue";
import { ref, defineProps, defineExpose, defineEmits } from "vue";
import { ArrowLeft, ArrowRight } from "@element-plus/icons-vue";
import { generateTitle } from "../../utils/i18n";
import StepsView from '../StepsView.vue'
import ProcessView from '../ProcessView/index.vue'
import { ref, defineProps, defineExpose, defineEmits } from 'vue'
import { ArrowLeft, ArrowRight } from '@element-plus/icons-vue'
import { generateTitle } from '../../utils/i18n'
const getIcon = () => {
return isCollapse.value ? ArrowLeft : ArrowRight;
};
const props = defineProps({
return isCollapse.value ? ArrowLeft : ArrowRight
}
defineProps({
reasoningList: {
type: Array,
default: [],
},
});
const chartList = ref<Array<any>>([
{
type: "G1",
group_name: "Planner",
},
{
type: "G2",
group_name: "Retrieval",
},
{
type: "G3",
group_name: "Generate",
},
{
type: "G4",
group_name: "Converter",
},
{
type: "G5",
group_name: "Executor",
},
{
type: "G6",
group_name: "Optimize",
},
]);
const emits = defineEmits(["changeStatusFun"]);
const getStatus = (val: any) => {
let arr: any = props.reasoningList;
if (arr.length) {
let children: any = arr[arr.length - 1].children;
if (!children.length) {
return false;
}
let group_name = children[children.length - 1].group_name.toLowerCase();
return group_name === val.toLowerCase();
} else {
return false;
default: []
}
};
})
// const chartList = ref<Array<any>>([
// {
// type: 'G1',
// group_name: 'Planner'
// },
// {
// type: 'G2',
// group_name: 'Retrieval'
// },
// {
// type: 'G3',
// group_name: 'Generate'
// },
// {
// type: 'G4',
// group_name: 'Converter'
// },
// {
// type: 'G5',
// group_name: 'Executor'
// },
// {
// type: 'G6',
// group_name: 'Optimize'
// }
// ])
const emits = defineEmits(['changeStatusFun'])
// const getStatus = (val: any) => {
// let arr: any = props.reasoningList
// if (arr.length) {
// let children: any = arr[arr.length - 1].children
// if (!children.length) {
// return false
// }
// let group_name = children[children.length - 1].group_name.toLowerCase()
// return group_name === val.toLowerCase()
// } else {
// return false
// }
// }
const changeStatusFun = () => {
isCollapse.value = !isCollapse.value;
emits("changeStatusFun", isCollapse.value);
};
const isCollapse = ref<boolean>(true);
isCollapse.value = !isCollapse.value
emits('changeStatusFun', isCollapse.value)
}
const isCollapse = ref<boolean>(true)
defineExpose({
isCollapse,
});
isCollapse
})
</script>
<style scoped>
@import "./index.less";
@import './index.less';
</style>

View File

@@ -1,31 +1,33 @@
export default {
routers:{
logOut:'Log Out',
restore:'Restore data',
'智能协作无界,材料创新无限':'Collaborative Intelligence, Revolutionary Materials',
'问题设定':'Problem Setting',
'模型名称':'Model Name',
'新建对话':'Create New Conversation',
'推理完成,如果希望了解更多可继续在下面框中提问或新建对话。':'The reasoning is complete. If you wish to learn more, you can continue to ask questions or create a new conversation in the box below.',
'推理中':'In Reasoning',
'角色':'Role',
'模型调用流程':'Model Calling Process',
'发送':'send',
'您好多智能体MARS为您服务':'Hello,multi-agent MARS is at your service',
'推荐问题':'Recommended Questions',
'在此输入您的问题或需求有问必答Shift+Enter换行':'Enter your question or requirement here, answer all questions, Shift+Enter line break',
'MARS多智能体材料创制系统':'MARS Model Creation System',
'账号':'account',
'密码':'password',
'验证码':'code',
'登录':'login',
'请输入账号':'Please enter your account',
'请输入密码':'Please enter your password',
'请输入验证码':'Please enter your code',
'验证码错误':'code error',
'请输入问题':'Please enter the question',
'回答输出中,暂不能再次提问':'Answer output, cannot be asked again temporarily',
routers: {
logOut: 'Log Out',
restore: 'Restore data',
'智能协作无界,材料创新无限': 'Collaborative Intelligence, Revolutionary Materials',
'问题设定': 'Problem Setting',
'模型名称': 'Model Name',
'新建对话': 'Create New Conversation',
'推理完成,如果希望了解更多可继续在下面框中提问或新建对话。': 'The reasoning is complete. If you wish to learn more, you can continue to ask questions or create a new conversation in the box below.',
'推理中': 'In Reasoning',
'角色': 'Role',
'模型调用流程': 'Agent Calling',
'发送': 'send',
'您好多智能体MARS为您服务': 'Hello,multi-agent MARS is at your service',
'推荐问题': 'Recommended Questions',
'在此输入您的问题或需求有问必答Shift+Enter换行': 'Enter your question or requirement here, answer all questions, Shift+Enter line break',
'MARS多智能体材料创制系统': 'MARS Model Creation System',
'账号': 'account',
'密码': 'password',
'验证码': 'code',
'登录': 'login',
'请输入账号': 'Please enter your account',
'请输入密码': 'Please enter your password',
'请输入验证码': 'Please enter your code',
'验证码错误': 'code error',
'请输入问题': 'Please enter the question',
'回答输出中,暂不能再次提问': 'Answer output, cannot be asked again temporarily',
'监控1': 'monitor one',
'监控2': 'monitor two',
}
}

View File

@@ -1,30 +1,32 @@
export default {
routers:{
logOut:'退出登录',
restore:'还原数据',
'智能协作无界,材料创新无限':'智能协作无界,材料创新无限',
'问题设定':'问题设定',
'模型名称':'模型名称',
'新建对话':'新建对话',
'推理完成,如果希望了解更多可继续在下面框中提问或新建对话。':'推理完成,如果希望了解更多可继续在下面框中提问或新建对话。',
'推理中':'推理中',
'角色':'角色',
'模型调用流程':'模型调用流程',
'发送':'发送',
'您好多智能体MARS为您服务':'您好多智能体MARS为您服务',
'推荐问题':'推荐问题',
'在此输入您的问题或需求有问必答Shift+Enter换行':'在此输入您的问题或需求有问必答Shift+Enter换行',
'MARS多智能体材料创制系统':'MARS多智能体材料创制系统',
'账号':'账号',
'密码':'密码',
'验证码':'验证码',
'登录':'登录',
'请输入账号':'请输入账号',
'请输入密码':'请输入密码',
'请输入验证码':'请输入验证码',
'验证码错误':'验证码错误',
'请输入问题':'请输入问题',
'回答输出中,暂不能再次提问':'回答输出中,暂不能再次提问',
routers: {
logOut: '退出登录',
restore: '还原数据',
'智能协作无界,材料创新无限': '智能协作无界,材料创新无限',
'问题设定': '问题设定',
'模型名称': '模型名称',
'新建对话': '新建对话',
'推理完成,如果希望了解更多可继续在下面框中提问或新建对话。': '推理完成,如果希望了解更多可继续在下面框中提问或新建对话。',
'推理中': '推理中',
'角色': '角色',
'模型调用流程': '模型调用流程',
'发送': '发送',
'您好多智能体MARS为您服务': '您好多智能体MARS为您服务',
'推荐问题': '推荐问题',
'在此输入您的问题或需求有问必答Shift+Enter换行': '在此输入您的问题或需求有问必答Shift+Enter换行',
'MARS多智能体材料创制系统': 'MARS多智能体材料创制系统',
'账号': '账号',
'密码': '密码',
'验证码': '验证码',
'登录': '登录',
'请输入账号': '请输入账号',
'请输入密码': '请输入密码',
'请输入验证码': '请输入验证码',
'验证码错误': '验证码错误',
'请输入问题': '请输入问题',
'回答输出中,暂不能再次提问': '回答输出中,暂不能再次提问',
'监控1': '监控1',
'监控2': '监控2',
}
}

View File

@@ -1,5 +1,5 @@
function useWebsocket(handleMessage: any) {
const ws = new WebSocket(import.meta.env.VITE_WB_BASE_URL)
function useWebsocket(handleMessage: any,url: any) {
const ws = new WebSocket(url||import.meta.env.VITE_WB_BASE_URL)
const init = () => {
bindEvent();
}

View File

@@ -74,7 +74,7 @@
display: flex;
align-items: center;
justify-content: center;
text-align: justify;
text-align: left;
}
}
}

View File

@@ -40,13 +40,15 @@ const recommendList = ref<Array<any>>([
const router = useRouter()
const submitFun = (e: any) => {
let data = {
chat_id: new Date().getTime(),
message: e
// chat_id: new Date().getTime(),
// message: e
content: e,
source: 'user'
}
router.push('/reasoning?message=' + JSON.stringify(data))
router.push('/reasoning?content=' + JSON.stringify(data))
}
const reasoningFun = (e: any) => {
router.push('/reasoning?message=' + e)
router.push('/reasoning?content=' + e)
}
onMounted(() => {})
</script>

View File

@@ -27,7 +27,7 @@
}
}
.message-box {
.content-box {
width: calc(100% - 48px);
padding-top: 30px;
@@ -71,4 +71,33 @@
}
}
.camera_dialog {
position: fixed;
top: 0;
left: 66px;
z-index: 99;
display: flex;
align-items: center;
column-gap: 12px;
.camera_item {
display: flex;
align-items: center;
flex-direction: column;
cursor: pointer;
width: 72px;
span {
font-size: 12px;
color: #fff;
}
}
}
.message_btn {
position: fixed;
top: 0;
left: 150px;
cursor: pointer;
}
}

View File

@@ -3,7 +3,7 @@
<div
class="content-left"
:style="{
width: isCollapse ? 'calc(100% - 200px)' : 'calc(100% - 7px)',
width: isCollapse ? 'calc(100% - 200px)' : 'calc(100% - 7px)'
}"
>
<div class="body-box" ref="container">
@@ -13,14 +13,14 @@
:reasoningList="reasoningList"
/>
</div>
<div class="message-box">
<div class="content-box">
<div class="tip-box">
<p class="active_item">
<el-icon size="6" color="#fff"><Plus /></el-icon>
{{ generateTitle("新建对话") }}
{{ generateTitle('新建对话') }}
</p>
<div class="tip-text" v-show="disableStatus">
{{ generateTitle("回答输出中暂不能再次提问") }}
{{ generateTitle('回答输出中暂不能再次提问') }}
</div>
</div>
<TextareaView ref="textareaRef" :minRows="1" @submitFun="submitFun" />
@@ -31,28 +31,70 @@
:reasoningList="reasoningList"
@changeStatusFun="changeStatusFun"
/>
<div class="camera_dialog">
<div class="camera_item" @click="cameraFun(1)">
<el-icon color="#fff" size="16"><VideoCameraFilled /></el-icon>
<span>{{ generateTitle('监控1') }}</span>
</div>
<div class="camera_item" @click="cameraFun(2)">
<el-icon color="#fff" size="16"><VideoCameraFilled /></el-icon>
<span>{{ generateTitle('监控2') }}</span>
</div>
</div>
<!-- <div class="message_btn">
<el-icon color="#fff" size="16" v-show="messageShow"><Expand /></el-icon>
<el-icon color="#fff" size="16" v-show="!messageShow"><Fold /></el-icon>
</div> -->
<el-drawer
v-model="messageShow"
title="I am the title"
direction="ltr"
:before-close="handleClose"
>
<span>Hi, there!</span>
</el-drawer>
<CameraView
ref="cameraViewRef"
v-show="cameraShow"
@closeCamera="closeCamera"
/>
</div>
</template>
<script setup lang="ts">
import ReasoningView from "../../components/ReasoningView/index.vue";
import TextareaView from "../../components/TextareaView.vue";
import collapseView from "../../components/collapseView/index.vue";
import { Plus } from "@element-plus/icons-vue";
import { ref, onMounted, nextTick } from "vue";
import ReasoningView from '../../components/ReasoningView/index.vue'
import TextareaView from '../../components/TextareaView.vue'
import collapseView from '../../components/collapseView/index.vue'
import CameraView from '../../components/CameraView/index.vue'
// Expand, Fold
import { Plus, VideoCameraFilled } from '@element-plus/icons-vue'
import { ref, onMounted, nextTick } from 'vue'
// import { getModelList } from '../../api/user'
import { useRoute } from "vue-router";
import useWebSocket from "../../utils/websocket";
import { useRoute } from 'vue-router'
import useWebSocket from '../../utils/websocket'
// import { getAgent } from '../../utils/agent'
import { generateTitle } from "../../utils/i18n";
const route: any = useRoute();
const reasoningRef = ref<any>(null);
const textareaRef = ref<any>(null);
const collapseRef = ref<any>(null);
const isCollapse = ref<boolean>(true);
import { generateTitle } from '../../utils/i18n'
const route: any = useRoute()
const reasoningRef = ref<any>(null)
const textareaRef = ref<any>(null)
const collapseRef = ref<any>(null)
const isCollapse = ref<boolean>(true)
const cameraShow = ref<boolean>(false)
const messageShow = ref<boolean>(false)
const cameraViewRef = ref<any>(null)
const changeStatusFun = (val: boolean) => {
isCollapse.value = val;
};
const reasoningList = ref<Array<any>>([]);
isCollapse.value = val
}
const handleClose = () => {
messageShow.value = false
}
const cameraFun = (val: number) => {
cameraShow.value = true
cameraViewRef.value.cameraNumber = val
}
const closeCamera = () => {
cameraShow.value = false
}
const reasoningList = ref<Array<any>>([])
// const getModelListFun = async () => {
// try {
// const { data, code } = await getModelList()
@@ -64,75 +106,86 @@ const reasoningList = ref<Array<any>>([]);
// }
// }
const submitFun = (val: any) => {
completeFun();
addMode(JSON.parse(val).message);
ws.send(val);
};
completeFun()
addMode(JSON.parse(val).content)
// let data = val
// data.content = JSON.stringify(data.content)
ws.send(val)
}
const addMode = (val: any) => {
endStatus.value = false;
endStatus.value = false
reasoningList.value.push({
title: val,
children: [],
});
children: []
})
reasoningRef.value.completeList.push({
show: false,
index: reasoningRef.value.completeList.length,
});
};
const disableStatus = ref(false);
index: reasoningRef.value.completeList.length
})
}
const disableStatus = ref(false)
const completeFun = () => {
disableStatus.value = true;
textareaRef.value.disableStatus = true;
};
disableStatus.value = true
textareaRef.value.disableStatus = true
}
const handleMessage = (e: any) => {
getMessage(e.data);
getHeight();
};
const endStatus = ref(false);
getMessage(e.data)
getHeight()
}
const endStatus = ref(false)
const getMessage = async (e: any) => {
reasoningRef.value.reasonStatus.show = true;
console.log(JSON.parse(e), "e::");
let data = JSON.parse(e);
let list = reasoningList.value[reasoningList.value.length - 1].children;
let status = list.filter((key: any) => key.group_name === data.group_name &&
key.agent_name === data.agent_name)[0]
if (list.length && status && status.agent_name) {
for (let i = 0; i < list.length; i++) {
const item = list[i];
if (
item.group_name === data.group_name &&
item.agent_name === data.agent_name
) {
item.content += data.content;
}
}
} else {
list.push(
JSON.parse(e)
);
reasoningRef.value.reasonStatus.show = true
let data = JSON.parse(e)
if (data.type === 'UserInputRequestedEvent') {
disableStatus.value = false
textareaRef.value.disableStatus = false
reasoningRef.value.reasonStatus.show = false
}
};
const ws = useWebSocket(handleMessage);
if (data.content) {
let list = reasoningList.value[reasoningList.value.length - 1].children
list.push(data)
// let status = list.filter(
// (key: any) =>
// key.group_name === data.group_name && key.agent_name === data.agent_name
// )[0]
// if (list.length && status && status.agent_name) {
// for (let i = 0; i < list.length; i++) {
// const item = list[i]
// if (
// item.group_name === data.group_name &&
// item.agent_name === data.agent_name
// ) {
// item.content += data.content
// }
// }
// } else {
// list.push(JSON.parse(e))
// }
}
}
const ws = useWebSocket(handleMessage, '')
const sendFun = () => {
setTimeout(() => {
addMode(JSON.parse(route.query.message).message);
completeFun();
ws.send(JSON.stringify(route.query.message));
}, 300);
};
const container = ref<any>(null);
addMode(JSON.parse(route.query.content).content)
completeFun()
// let data = route.query.content
// data.content = JSON.stringify(data.content)
ws.send(route.query.content)
}, 300)
}
const container = ref<any>(null)
const getHeight = () => {
container.value.scrollTop = container.value.scrollHeight + 150;
collapseRef.value.scrollTop = collapseRef.value.scrollHeight + 50;
};
container.value.scrollTop = container.value.scrollHeight + 150
collapseRef.value.scrollTop = collapseRef.value.scrollHeight + 50
}
onMounted(() => {
// getModelListFun();
nextTick(() => {
getHeight();
sendFun();
});
});
getHeight()
sendFun()
})
})
</script>
<style scoped>
@import "./index.less";
@import './index.less';
</style>

View File

@@ -8,7 +8,7 @@ export default defineConfig({
host: '0.0.0.0',
proxy: {
'/matagent': {
target: 'http://47.121.220.134:8000',
target: 'http://159.75.91.126:8000',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/matagent/, '/matagent')
}

6
package-lock.json generated Normal file
View File

@@ -0,0 +1,6 @@
{
"name": "matagent",
"lockfileVersion": 3,
"requires": true,
"packages": {}
}