优化页面布局
This commit is contained in:
parent
f484688a4b
commit
8887da8ba9
@ -10,84 +10,17 @@
|
|||||||
|
|
||||||
<!-- 用户输入的部分 -->
|
<!-- 用户输入的部分 -->
|
||||||
<div class="message-content" v-if="message.role === 'user'">
|
<div class="message-content" v-if="message.role === 'user'">
|
||||||
<div class="message-role"></div>
|
<Message.User :message="message" />
|
||||||
<div class="message-text">
|
|
||||||
<span>{{ message.content }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 助手返回的内容部分 -->
|
<!-- 助手返回的内容部分 -->
|
||||||
<div class="message-content" v-else-if="message.role === 'assistant/content'">
|
<div class="message-content" v-else-if="message.role === 'assistant/content'">
|
||||||
<div class="message-role">Agent</div>
|
<Message.Assistant :message="message" />
|
||||||
<div class="message-text">
|
|
||||||
<div v-if="message.content" v-html="markdownToHtml(message.content)"></div>
|
|
||||||
</div>
|
|
||||||
<MessageMeta :message="message" />
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 助手调用的工具部分 -->
|
<!-- 助手调用的工具部分 -->
|
||||||
<div class="message-content" v-else-if="message.role === 'assistant/tool_calls'">
|
<div class="message-content" v-else-if="message.role === 'assistant/tool_calls'">
|
||||||
<div class="message-role">
|
<Message.Toolcall :message="message" />
|
||||||
Agent
|
|
||||||
<span class="message-reminder" v-if="!message.toolResult">
|
|
||||||
正在使用工具
|
|
||||||
<span class="tool-loading iconfont icon-double-loading">
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div class="message-text tool_calls">
|
|
||||||
<div v-if="message.content" v-html="markdownToHtml(message.content)"></div>
|
|
||||||
|
|
||||||
<div class="tool-calls">
|
|
||||||
<div v-for="(call, index) in message.tool_calls" :key="index" class="tool-call-item">
|
|
||||||
<div class="tool-call-header">
|
|
||||||
<span class="tool-name">{{ call.function.name }}</span>
|
|
||||||
<span class="tool-type">{{ 'tool' }}</span>
|
|
||||||
<el-button @click="createTest(call)">
|
|
||||||
<span class="iconfont icon-send"></span>
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
<div class="tool-arguments">
|
|
||||||
<div class="inner">
|
|
||||||
<div v-html="jsonResultToHtml(call.function.arguments)"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 工具调用结果 -->
|
|
||||||
<div v-if="message.toolResult">
|
|
||||||
<div class="tool-call-header">
|
|
||||||
<span class="tool-name">{{ "响应" }}</span>
|
|
||||||
<span style="width: 200px;" class="tools-dialog-container">
|
|
||||||
<el-switch
|
|
||||||
v-model="message.showJson!.value"
|
|
||||||
inline-prompt
|
|
||||||
active-text="JSON"
|
|
||||||
inactive-text="Text"
|
|
||||||
style="margin-left: 10px; width: 200px;"
|
|
||||||
:inactive-action-style="'backgroundColor: var(--sidebar)'"
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div class="tool-result" v-if="isValidJSON(message.toolResult)">
|
|
||||||
<div v-if="message.showJson!.value" class="tool-result-content">
|
|
||||||
<div class="inner">
|
|
||||||
<div v-html="jsonResultToHtml(message.toolResult)"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<span v-else>
|
|
||||||
<div v-for="(item, index) in JSON.parse(message.toolResult)" :key="index">
|
|
||||||
<el-scrollbar width="100%">
|
|
||||||
<div v-if="item.type === 'text'" class="tool-text">{{ item.text }}</div>
|
|
||||||
<div v-else class="tool-other">{{ JSON.stringify(item) }}</div>
|
|
||||||
</el-scrollbar>
|
|
||||||
</div>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<MessageMeta :message="message" />
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -125,7 +58,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-footer class="chat-footer" ref="footerRef">
|
<footer class="chat-footer" ref="footerRef">
|
||||||
<div class="input-area">
|
<div class="input-area">
|
||||||
<div class="input-wrapper">
|
<div class="input-wrapper">
|
||||||
<Setting :tabId="tabId" />
|
<Setting :tabId="tabId" />
|
||||||
@ -139,7 +72,7 @@
|
|||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-footer>
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -148,16 +81,16 @@ import { ref, onMounted, defineComponent, defineProps, onUnmounted, computed, ne
|
|||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { ElMessage, ScrollbarInstance } from 'element-plus';
|
import { ElMessage, ScrollbarInstance } from 'element-plus';
|
||||||
import { tabs } from '../panel';
|
import { tabs } from '../panel';
|
||||||
import { ChatMessage, ChatStorage, getToolSchema, IExtraInfo, ToolCall } from './chat';
|
import { ChatMessage, ChatStorage, IExtraInfo, ToolCall } from './chat';
|
||||||
|
|
||||||
|
|
||||||
import Setting from './setting.vue';
|
import Setting from './setting.vue';
|
||||||
import MessageMeta from './message-meta.vue';
|
|
||||||
|
|
||||||
// 引入 markdown.ts 中的函数
|
// 引入 markdown.ts 中的函数
|
||||||
import { markdownToHtml, copyToClipboard } from './markdown';
|
import { markdownToHtml } from './markdown';
|
||||||
import { ChatCompletionChunk, TaskLoop } from './task-loop';
|
import { TaskLoop } from './task-loop';
|
||||||
import { createTest, llmManager, llms } from '@/views/setting/llm';
|
import { llmManager, llms } from '@/views/setting/llm';
|
||||||
|
|
||||||
|
import * as Message from './message';
|
||||||
|
|
||||||
defineComponent({ name: 'chat' });
|
defineComponent({ name: 'chat' });
|
||||||
|
|
||||||
@ -377,26 +310,9 @@ onUnmounted(() => {
|
|||||||
window.removeEventListener('resize', updateScrollHeight);
|
window.removeEventListener('resize', updateScrollHeight);
|
||||||
});
|
});
|
||||||
|
|
||||||
// 新增辅助函数检查是否为有效JSON
|
|
||||||
const isValidJSON = (str: string) => {
|
|
||||||
try {
|
|
||||||
JSON.parse(str);
|
|
||||||
return true;
|
|
||||||
} catch {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const jsonResultToHtml = (jsonString: string) => {
|
|
||||||
const formattedJson = JSON.stringify(JSON.parse(jsonString), null, 2);
|
|
||||||
const html = markdownToHtml('```json\n' + formattedJson + '\n```');
|
|
||||||
return html;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style>
|
||||||
.chat-container {
|
.chat-container {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -499,7 +415,7 @@ const jsonResultToHtml = (jsonString: string) => {
|
|||||||
border-top: 1px solid var(--el-border-color);
|
border-top: 1px solid var(--el-border-color);
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
height: fit-content;
|
height: fit-content !important;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
@ -554,72 +470,7 @@ const jsonResultToHtml = (jsonString: string) => {
|
|||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
|
|
||||||
.tool-calls {
|
|
||||||
margin-top: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tool-call-item {
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tool-call-header {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
margin-bottom: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tool-name {
|
|
||||||
font-weight: bold;
|
|
||||||
color: var(--el-color-primary);
|
|
||||||
margin-right: 8px;
|
|
||||||
margin-bottom: 0;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
height: 26px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tool-type {
|
|
||||||
font-size: 0.8em;
|
|
||||||
color: var(--el-text-color-secondary);
|
|
||||||
background-color: var(--el-fill-color-light);
|
|
||||||
padding: 2px 6px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tool-arguments {
|
|
||||||
margin: 0;
|
|
||||||
padding: 8px;
|
|
||||||
background-color: var(--el-fill-color-light);
|
|
||||||
border-radius: 4px;
|
|
||||||
font-family: monospace;
|
|
||||||
font-size: 0.9em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tool-result {
|
|
||||||
padding: 8px;
|
|
||||||
background-color: var(--el-fill-color-light);
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tool-text {
|
|
||||||
white-space: pre-wrap;
|
|
||||||
line-height: 1.6;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tool-other {
|
|
||||||
font-family: monospace;
|
|
||||||
font-size: 0.9em;
|
|
||||||
color: var(--el-text-color-secondary);
|
|
||||||
margin-top: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 新增样式来减小行距 */
|
|
||||||
.message-text p,
|
.message-text p,
|
||||||
.message-text h3,
|
.message-text h3,
|
||||||
.message-text ol,
|
.message-text ol,
|
||||||
@ -627,7 +478,6 @@ const jsonResultToHtml = (jsonString: string) => {
|
|||||||
margin-top: 0.5em;
|
margin-top: 0.5em;
|
||||||
margin-bottom: 0.5em;
|
margin-bottom: 0.5em;
|
||||||
line-height: 1.4;
|
line-height: 1.4;
|
||||||
/* 可以根据需要调整行高 */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.message-text ol li,
|
.message-text ol li,
|
||||||
|
@ -1,85 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="message-meta" @mouseenter="showTime = true" @mouseleave="showTime = false">
|
|
||||||
<span v-if="usageStatistic" class="message-usage">
|
|
||||||
<span>
|
|
||||||
{{ t('input-token') }} {{ usageStatistic.input }}
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<span>
|
|
||||||
{{ t('output-token') }} {{ usageStatistic.output }}
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<span>
|
|
||||||
{{ t('total') }} {{ usageStatistic.total }}
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<span>
|
|
||||||
{{ t('cache-hit-ratio') }} {{ usageStatistic.cacheHitRatio }}%
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<span v-else class="message-usage">
|
|
||||||
<span>{{ t('server-not-support-statistic') }}</span>
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<span v-show="showTime" class="message-time">
|
|
||||||
{{ props.message.extraInfo.serverName }} {{ t('answer-at') }}
|
|
||||||
{{ new Date(message.extraInfo.created).toLocaleString() }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { defineComponent, defineProps, ref, computed } from 'vue';
|
|
||||||
import { useI18n } from 'vue-i18n';
|
|
||||||
import { makeUsageStatistic } from './usage';
|
|
||||||
|
|
||||||
defineComponent({ name: 'message-meta' });
|
|
||||||
|
|
||||||
const { t } = useI18n();
|
|
||||||
|
|
||||||
const props = defineProps({
|
|
||||||
message: {
|
|
||||||
type: Object,
|
|
||||||
required: true
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const usageStatistic = computed(() => {
|
|
||||||
return makeUsageStatistic(props.message.extraInfo);
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log(props.message);
|
|
||||||
console.log(usageStatistic);
|
|
||||||
|
|
||||||
const showTime = ref(false);
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
|
|
||||||
.message-meta {
|
|
||||||
margin-top: 8px;
|
|
||||||
font-size: 0.8em;
|
|
||||||
color: var(--el-text-color-secondary);
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
.message-time {
|
|
||||||
opacity: 0.7;
|
|
||||||
padding: 2px 6px 2px 0;
|
|
||||||
transition: opacity 0.3s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.message-usage {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.message-usage > span {
|
|
||||||
background-color: var(--el-fill-color-light);
|
|
||||||
padding: 2px 6px;
|
|
||||||
border-radius: 4px;
|
|
||||||
margin-right: 3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
|
@ -2,11 +2,10 @@
|
|||||||
<div class="connection-option">
|
<div class="connection-option">
|
||||||
<span>{{ t('log') }}</span>
|
<span>{{ t('log') }}</span>
|
||||||
<el-scrollbar height="100%">
|
<el-scrollbar height="100%">
|
||||||
<div
|
<div class="output-content">
|
||||||
class="output-content"
|
<div v-for="(log, index) in connectionResult.logString" :key="index" :class="log.type">
|
||||||
contenteditable="false"
|
<span class="log-message">{{ log.message }}</span>
|
||||||
>
|
</div>
|
||||||
{{ connectionResult.logString }}
|
|
||||||
</div>
|
</div>
|
||||||
</el-scrollbar>
|
</el-scrollbar>
|
||||||
</div>
|
</div>
|
||||||
@ -34,7 +33,7 @@ const { t } = useI18n();
|
|||||||
|
|
||||||
.connection-option .output-content {
|
.connection-option .output-content {
|
||||||
border-radius: .5em;
|
border-radius: .5em;
|
||||||
padding: 15px;
|
padding: 12px 16px;
|
||||||
min-height: 300px;
|
min-height: 300px;
|
||||||
height: fit-content;
|
height: fit-content;
|
||||||
font-family: var(--code-font-family);
|
font-family: var(--code-font-family);
|
||||||
@ -42,9 +41,59 @@ const { t } = useI18n();
|
|||||||
word-break: break-all;
|
word-break: break-all;
|
||||||
user-select: text;
|
user-select: text;
|
||||||
cursor: text;
|
cursor: text;
|
||||||
font-size: 15px;
|
font-size: 14px;
|
||||||
line-height: 1.5;
|
line-height: 1.6;
|
||||||
background-color: var(--sidebar);
|
background-color: rgba(var(--sidebar), 0.3);
|
||||||
height: 95%;
|
height: 95%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.output-content .info {
|
||||||
|
background-color: rgba(103, 194, 58, 0.5);
|
||||||
|
margin: 8px 0;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
padding: 5px 9px;
|
||||||
|
border-radius: .5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.output-content .error {
|
||||||
|
background-color: rgba(245, 108, 108, 0.5);
|
||||||
|
margin: 8px 0;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
padding: 5px 9px;
|
||||||
|
border-radius: .5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.output-content .warning {
|
||||||
|
background-color: rgba(230, 162, 60, 0.5);
|
||||||
|
margin: 8px 0;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
padding: 5px 9px;
|
||||||
|
border-radius: .5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.log-icon {
|
||||||
|
display: inline-block;
|
||||||
|
width: 8px;
|
||||||
|
height: 8px;
|
||||||
|
border-radius: 50%;
|
||||||
|
margin-right: 8px;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.log-icon.info {
|
||||||
|
background-color: rgba(103, 194, 58, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.log-icon.error {
|
||||||
|
background-color: rgba(245, 108, 108, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.log-icon.warning {
|
||||||
|
background-color: rgba(230, 162, 60, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.log-message {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
@ -3,7 +3,6 @@ import { reactive } from 'vue';
|
|||||||
import { pinkLog } from '../setting/util';
|
import { pinkLog } from '../setting/util';
|
||||||
import { ElMessage } from 'element-plus';
|
import { ElMessage } from 'element-plus';
|
||||||
import { ILaunchSigature } from '@/hook/type';
|
import { ILaunchSigature } from '@/hook/type';
|
||||||
import { url } from 'inspector';
|
|
||||||
|
|
||||||
export const connectionMethods = reactive({
|
export const connectionMethods = reactive({
|
||||||
current: 'STDIO',
|
current: 'STDIO',
|
||||||
@ -80,17 +79,25 @@ export function doConnect() {
|
|||||||
bridge.addCommandListener('connect', async data => {
|
bridge.addCommandListener('connect', async data => {
|
||||||
const { code, msg } = data;
|
const { code, msg } = data;
|
||||||
connectionResult.success = (code === 200);
|
connectionResult.success = (code === 200);
|
||||||
connectionResult.logString = msg;
|
|
||||||
|
|
||||||
if (code === 200) {
|
if (code === 200) {
|
||||||
const res = await getServerVersion() as { name: string, version: string };
|
const res = await getServerVersion() as { name: string, version: string };
|
||||||
connectionResult.serverInfo.name = res.name || '';
|
connectionResult.serverInfo.name = res.name || '';
|
||||||
connectionResult.serverInfo.version = res.version || '';
|
connectionResult.serverInfo.version = res.version || '';
|
||||||
|
connectionResult.logString.push({
|
||||||
|
type: 'info',
|
||||||
|
message: msg
|
||||||
|
});
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
ElMessage({
|
ElMessage({
|
||||||
type: 'error',
|
type: 'error',
|
||||||
message: msg
|
message: msg
|
||||||
});
|
});
|
||||||
|
connectionResult.logString.push({
|
||||||
|
type: 'error',
|
||||||
|
message: msg
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
resolve(void 0);
|
resolve(void 0);
|
||||||
@ -189,9 +196,13 @@ async function launchStdio() {
|
|||||||
bridge.addCommandListener('connect', async data => {
|
bridge.addCommandListener('connect', async data => {
|
||||||
const { code, msg } = data;
|
const { code, msg } = data;
|
||||||
connectionResult.success = (code === 200);
|
connectionResult.success = (code === 200);
|
||||||
connectionResult.logString = msg;
|
|
||||||
|
|
||||||
if (code === 200) {
|
if (code === 200) {
|
||||||
|
connectionResult.logString.push({
|
||||||
|
type: 'info',
|
||||||
|
message: msg
|
||||||
|
});
|
||||||
|
|
||||||
const res = await getServerVersion() as { name: string, version: string };
|
const res = await getServerVersion() as { name: string, version: string };
|
||||||
connectionResult.serverInfo.name = res.name || '';
|
connectionResult.serverInfo.name = res.name || '';
|
||||||
connectionResult.serverInfo.version = res.version || '';
|
connectionResult.serverInfo.version = res.version || '';
|
||||||
@ -217,6 +228,11 @@ async function launchStdio() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
connectionResult.logString.push({
|
||||||
|
type: 'error',
|
||||||
|
message: msg
|
||||||
|
});
|
||||||
|
|
||||||
ElMessage({
|
ElMessage({
|
||||||
type: 'error',
|
type: 'error',
|
||||||
message: msg
|
message: msg
|
||||||
@ -257,9 +273,13 @@ async function launchSSE() {
|
|||||||
bridge.addCommandListener('connect', async data => {
|
bridge.addCommandListener('connect', async data => {
|
||||||
const { code, msg } = data;
|
const { code, msg } = data;
|
||||||
connectionResult.success = (code === 200);
|
connectionResult.success = (code === 200);
|
||||||
connectionResult.logString = msg;
|
|
||||||
|
|
||||||
if (code === 200) {
|
if (code === 200) {
|
||||||
|
connectionResult.logString.push({
|
||||||
|
type: 'info',
|
||||||
|
message: msg
|
||||||
|
});
|
||||||
|
|
||||||
const res = await getServerVersion() as { name: string, version: string };
|
const res = await getServerVersion() as { name: string, version: string };
|
||||||
connectionResult.serverInfo.name = res.name || '';
|
connectionResult.serverInfo.name = res.name || '';
|
||||||
connectionResult.serverInfo.version = res.version || '';
|
connectionResult.serverInfo.version = res.version || '';
|
||||||
@ -279,6 +299,11 @@ async function launchSSE() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
connectionResult.logString.push({
|
||||||
|
type: 'error',
|
||||||
|
message: msg
|
||||||
|
});
|
||||||
|
|
||||||
ElMessage({
|
ElMessage({
|
||||||
type: 'error',
|
type: 'error',
|
||||||
message: msg
|
message: msg
|
||||||
@ -328,9 +353,16 @@ export function doReconnect() {
|
|||||||
console.log();
|
console.log();
|
||||||
}
|
}
|
||||||
|
|
||||||
export const connectionResult = reactive({
|
export const connectionResult = reactive<{
|
||||||
|
success: boolean,
|
||||||
|
logString: { type: 'info' | 'error' | 'warning', message: string }[],
|
||||||
|
serverInfo: {
|
||||||
|
name: string,
|
||||||
|
version: string
|
||||||
|
}
|
||||||
|
}>({
|
||||||
success: false,
|
success: false,
|
||||||
logString: '',
|
logString: [],
|
||||||
serverInfo: {
|
serverInfo: {
|
||||||
name: '',
|
name: '',
|
||||||
version: ''
|
version: ''
|
||||||
@ -353,3 +385,7 @@ export function getServerVersion() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const envVarStatus = {
|
||||||
|
launched: false
|
||||||
|
};
|
@ -44,7 +44,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { defineComponent, onMounted, ref } from 'vue';
|
import { defineComponent, onMounted, ref } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { connectionEnv, connectionResult, EnvItem } from './connection';
|
import { connectionEnv, connectionResult, EnvItem, envVarStatus } from './connection';
|
||||||
import { useMessageBridge } from '@/api/message-bridge';
|
import { useMessageBridge } from '@/api/message-bridge';
|
||||||
|
|
||||||
defineComponent({ name: 'env-var' });
|
defineComponent({ name: 'env-var' });
|
||||||
@ -60,9 +60,18 @@ function lookupEnvVar(varNames: string[]) {
|
|||||||
const { code, msg } = data;
|
const { code, msg } = data;
|
||||||
|
|
||||||
if (code === 200) {
|
if (code === 200) {
|
||||||
|
connectionResult.logString.push({
|
||||||
|
type: 'info',
|
||||||
|
message: '预设环境变量同步完成'
|
||||||
|
});
|
||||||
|
|
||||||
resolve(msg);
|
resolve(msg);
|
||||||
} else {
|
} else {
|
||||||
connectionResult.logString += '\n' + msg;
|
connectionResult.logString.push({
|
||||||
|
type: 'error',
|
||||||
|
message: '预设环境变量同步失败: ' + msg
|
||||||
|
});
|
||||||
|
|
||||||
resolve(undefined);
|
resolve(undefined);
|
||||||
}
|
}
|
||||||
}, { once: true });
|
}, { once: true });
|
||||||
@ -149,7 +158,11 @@ async function handleEnvSwitch(enabled: boolean) {
|
|||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
if (envVarStatus.launched) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
handleEnvSwitch(envEnabled.value);
|
handleEnvSwitch(envEnabled.value);
|
||||||
|
envVarStatus.launched = true;
|
||||||
}, 200);
|
}, 200);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ import { useI18n } from 'vue-i18n';
|
|||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
import { connectionResult, doConnect, doReconnect, launchConnect } from './connection';
|
import { connectionResult, doConnect, launchConnect } from './connection';
|
||||||
|
|
||||||
import ConnectionMethod from './connection-method.vue';
|
import ConnectionMethod from './connection-method.vue';
|
||||||
import ConnectionArgs from './connection-args.vue';
|
import ConnectionArgs from './connection-args.vue';
|
||||||
@ -35,23 +35,14 @@ import EnvVar from './env-var.vue';
|
|||||||
|
|
||||||
import ConnectionLog from './connection-log.vue';
|
import ConnectionLog from './connection-log.vue';
|
||||||
|
|
||||||
import { acquireVsCodeApi, useMessageBridge } from '@/api/message-bridge';
|
import { acquireVsCodeApi } from '@/api/message-bridge';
|
||||||
|
|
||||||
defineComponent({ name: 'connect' });
|
defineComponent({ name: 'connect' });
|
||||||
|
|
||||||
const bridge = useMessageBridge();
|
|
||||||
|
|
||||||
bridge.addCommandListener('connect', data => {
|
|
||||||
const { code, msg } = data;
|
|
||||||
connectionResult.success = (code === 200);
|
|
||||||
connectionResult.logString = msg;
|
|
||||||
}, { once: false });
|
|
||||||
|
|
||||||
const isLoading = ref(false);
|
const isLoading = ref(false);
|
||||||
|
|
||||||
async function suitableConnect() {
|
async function suitableConnect() {
|
||||||
isLoading.value = true;
|
isLoading.value = true;
|
||||||
connectionResult.logString = '';
|
|
||||||
|
|
||||||
if (acquireVsCodeApi === undefined) {
|
if (acquireVsCodeApi === undefined) {
|
||||||
await doConnect();
|
await doConnect();
|
||||||
|
@ -44,7 +44,7 @@ async function connectHandler(option: MCPOptions, webview: PostMessageble) {
|
|||||||
client = await connect(option);
|
client = await connect(option);
|
||||||
const connectResult = {
|
const connectResult = {
|
||||||
code: 200,
|
code: 200,
|
||||||
msg: 'connect success\nHello from OpenMCP | virtual client version: 0.0.1'
|
msg: 'Connect to OpenMCP successfully\nWelcome back, Kirigaya'
|
||||||
};
|
};
|
||||||
webview.postMessage({ command: 'connect', data: connectResult });
|
webview.postMessage({ command: 'connect', data: connectResult });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user