改进
This commit is contained in:
parent
2f9744d5a8
commit
de00770bff
@ -2,13 +2,18 @@
|
|||||||
<div>
|
<div>
|
||||||
<h3 class="mb-3">聊天记录</h3>
|
<h3 class="mb-3">聊天记录</h3>
|
||||||
|
|
||||||
<v-card v-for="message in messages.data" :key="message.id" class="mx-auto mt-3" width="100%">
|
<v-card
|
||||||
|
v-for="message in messages.data"
|
||||||
|
:key="message.id"
|
||||||
|
class="mx-auto mt-3"
|
||||||
|
width="100%"
|
||||||
|
>
|
||||||
<template #title>
|
<template #title>
|
||||||
<div class="font-weight-black">
|
<div class="font-weight-black">
|
||||||
<div v-if="message.role == 'assistant'"> AI </div>
|
<div v-if="message.role == 'assistant'">AI</div>
|
||||||
<div v-else-if="message.role == 'system'"> 系统 </div>
|
<div v-else-if="message.role == 'system'">系统</div>
|
||||||
|
|
||||||
<div v-else-if="message.role == 'user'" class="text-right"> 用户 </div>
|
<div v-else-if="message.role == 'user'" class="text-right">用户</div>
|
||||||
|
|
||||||
<div v-else>
|
<div v-else>
|
||||||
{{ message.role }}
|
{{ message.role }}
|
||||||
@ -24,40 +29,52 @@
|
|||||||
|
|
||||||
<div class="mt-3">
|
<div class="mt-3">
|
||||||
<div v-if="toolError" class="mb-3">
|
<div v-if="toolError" class="mb-3">
|
||||||
<v-alert density="compact" text="这个工具出现了异常,这应该不是我们的问题,如果你是此工具的开发者,请打开开发者控制台查看具体错误。"
|
<v-alert
|
||||||
:title="'工具 ' + toolName + ' 出现异常'" type="warning"></v-alert>
|
density="compact"
|
||||||
|
text="这个工具出现了异常,这应该不是我们的问题,如果你是此工具的开发者,请打开开发者控制台查看具体错误。"
|
||||||
|
:title="'工具 ' + toolName + ' 出现异常'"
|
||||||
|
type="warning"
|
||||||
|
></v-alert>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-show="toolCalling">
|
<div v-show="toolCalling">
|
||||||
<v-progress-circular color="primary" indeterminate :size="16"></v-progress-circular>
|
<v-progress-circular
|
||||||
|
color="primary"
|
||||||
|
indeterminate
|
||||||
|
:size="16"
|
||||||
|
></v-progress-circular>
|
||||||
正在执行 {{ toolName }}
|
正在执行 {{ toolName }}
|
||||||
</div>
|
</div>
|
||||||
<v-text-field v-model="input" label="输入消息" @keyup.enter="sendMessage"></v-text-field>
|
<v-text-field
|
||||||
|
v-model="input"
|
||||||
|
label="输入消息"
|
||||||
|
@keyup.enter="sendMessage"
|
||||||
|
></v-text-field>
|
||||||
<v-btn color="primary" @click="sendMessage">发送</v-btn>
|
<v-btn color="primary" @click="sendMessage">发送</v-btn>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ApiV1ChatsIdMessagesGet200Response } from "@/api"
|
import { ApiV1ChatsIdMessagesGet200Response } from "@/api";
|
||||||
import { ref } from "vue"
|
import { ref } from "vue";
|
||||||
import { api, conf } from "@/plugins/api"
|
import { api, conf } from "@/plugins/api";
|
||||||
import VueMarkdown from "vue-markdown-render"
|
import VueMarkdown from "vue-markdown-render";
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const chatId = parseInt(useRoute().params.id as string)
|
const chatId = parseInt(useRoute().params.id as string);
|
||||||
|
|
||||||
const messages: Ref<ApiV1ChatsIdMessagesGet200Response> = ref({
|
const messages: Ref<ApiV1ChatsIdMessagesGet200Response> = ref({
|
||||||
data: [],
|
data: [],
|
||||||
})
|
});
|
||||||
const input = ref("")
|
const input = ref("");
|
||||||
const toolName = ref("")
|
const toolName = ref("");
|
||||||
const toolError = ref(false)
|
const toolError = ref(false);
|
||||||
const toolCalling = ref(false)
|
const toolCalling = ref(false);
|
||||||
|
|
||||||
function sendMessage() {
|
function sendMessage() {
|
||||||
if (input.value !== "") {
|
if (input.value !== "") {
|
||||||
toolError.value = false
|
toolError.value = false;
|
||||||
api.ChatMessage.apiV1ChatsIdMessagesPost(chatId, {
|
api.ChatMessage.apiV1ChatsIdMessagesPost(chatId, {
|
||||||
message: input.value,
|
message: input.value,
|
||||||
})
|
})
|
||||||
@ -65,109 +82,113 @@ function sendMessage() {
|
|||||||
const newMessage = {
|
const newMessage = {
|
||||||
content: input.value,
|
content: input.value,
|
||||||
role: "user",
|
role: "user",
|
||||||
}
|
};
|
||||||
|
|
||||||
if (messages.value.data == null) {
|
if (messages.value.data == null) {
|
||||||
messages.value.data = [newMessage]
|
messages.value.data = [newMessage];
|
||||||
} else {
|
} else {
|
||||||
messages.value.data?.push(newMessage)
|
messages.value.data?.push(newMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
const streamId = res.data.data?.stream_id
|
const streamId = res.data.data?.stream_id;
|
||||||
|
|
||||||
if (streamId) {
|
if (streamId) {
|
||||||
streamChat(streamId)
|
streamChat(streamId);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
// if 409
|
// if 409
|
||||||
if (err.response.status === 409) {
|
if (err.response.status === 409) {
|
||||||
const streamId = err.response.data.data?.stream_id
|
const streamId = err.response.data.data?.stream_id;
|
||||||
|
|
||||||
if (streamId) {
|
if (streamId) {
|
||||||
streamChat(streamId)
|
streamChat(streamId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function streamChat(streamId: String) {
|
function streamChat(streamId: String) {
|
||||||
const url = conf.basePath + "/api/v1/stream/" + streamId
|
const url = conf.basePath + "/api/v1/stream/" + streamId;
|
||||||
|
|
||||||
const evtSource = new EventSource(url)
|
const evtSource = new EventSource(url);
|
||||||
|
|
||||||
let messageAdded = false
|
|
||||||
|
|
||||||
|
let messageAdded = false;
|
||||||
|
|
||||||
// 滚动页面到最底部
|
// 滚动页面到最底部
|
||||||
window.scrollTo(0, document.body.scrollHeight)
|
window.scrollTo(0, document.body.scrollHeight);
|
||||||
|
|
||||||
// set index
|
// set index
|
||||||
const i = (messages.value.data?.length ?? 1) - 1
|
const i = (messages.value.data?.length ?? 1) - 1;
|
||||||
|
|
||||||
evtSource.addEventListener("data", (e) => {
|
evtSource.addEventListener("data", (e) => {
|
||||||
const data = JSON.parse(e.data)
|
const data = JSON.parse(e.data);
|
||||||
console.log(data.state)
|
console.log(data.state);
|
||||||
|
|
||||||
let append = true
|
|
||||||
|
|
||||||
|
let append = true;
|
||||||
|
|
||||||
switch (data.state) {
|
switch (data.state) {
|
||||||
case "tool_calling":
|
case "tool_calling":
|
||||||
toolCalling.value = true
|
toolCalling.value = true;
|
||||||
toolName.value = data.tool_call_message.tool_name + " 中的 " + data.tool_call_message.function_name
|
toolName.value =
|
||||||
break
|
data.tool_call_message.tool_name +
|
||||||
|
" 中的 " +
|
||||||
|
data.tool_call_message.function_name;
|
||||||
|
break;
|
||||||
case "tool_response":
|
case "tool_response":
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
toolName.value = ""
|
toolName.value = "";
|
||||||
toolCalling.value = false
|
toolCalling.value = false;
|
||||||
}, 300)
|
}, 300);
|
||||||
break
|
break;
|
||||||
case "tool_failed":
|
case "tool_failed":
|
||||||
toolName.value = data.tool_response_message.tool_name + " 中的 " + data.tool_response_message.function_name
|
toolName.value =
|
||||||
toolError.value = true
|
data.tool_response_message.tool_name +
|
||||||
append = false
|
" 中的 " +
|
||||||
|
data.tool_response_message.function_name;
|
||||||
|
toolError.value = true;
|
||||||
|
append = false;
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
toolCalling.value = false
|
toolCalling.value = false;
|
||||||
}, 300)
|
}, 300);
|
||||||
break
|
break;
|
||||||
case "chunk":
|
case "chunk":
|
||||||
if (!messageAdded) {
|
if (!messageAdded) {
|
||||||
const newMessage = {
|
const newMessage = {
|
||||||
content: "",
|
content: "",
|
||||||
role: "assistant",
|
role: "assistant",
|
||||||
}
|
};
|
||||||
|
|
||||||
if (messages.value.data == null) {
|
if (messages.value.data == null) {
|
||||||
messages.value.data = [newMessage]
|
messages.value.data = [newMessage];
|
||||||
} else {
|
} else {
|
||||||
// add to messages
|
// add to messages
|
||||||
messages.value.data?.push(newMessage)
|
messages.value.data?.push(newMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
messageAdded = true
|
messageAdded = true;
|
||||||
append = true
|
append = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (append && messageAdded) {
|
if (append && messageAdded) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
messages.value.data[i].content += data.content
|
messages.value.data[i].content += data.content;
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
// close
|
// close
|
||||||
evtSource.addEventListener("close", () => {
|
evtSource.addEventListener("close", () => {
|
||||||
evtSource.close()
|
evtSource.close();
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const getMessages = () => {
|
const getMessages = () => {
|
||||||
api.ChatMessage.apiV1ChatsIdMessagesGet(chatId).then((res) => {
|
api.ChatMessage.apiV1ChatsIdMessagesGet(chatId).then((res) => {
|
||||||
messages.value = res.data
|
messages.value = res.data;
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
getMessages()
|
getMessages();
|
||||||
</script>
|
</script>
|
||||||
|
@ -1,83 +1,79 @@
|
|||||||
<template>
|
<template>
|
||||||
<h3>验证语法</h3>
|
<h3>验证语法</h3>
|
||||||
<p>目前处于测试阶段,不一定准确,但是能保证你添加成功。</p>
|
<p>目前处于测试阶段,不一定准确,但是能保证你添加成功。</p>
|
||||||
|
|
||||||
|
<!-- input -->
|
||||||
|
<v-textarea v-model="input" label="你的 JSON 数据"></v-textarea>
|
||||||
|
|
||||||
|
<v-btn class="mt-3 mb-3" color="primary" @click="validate()">验证</v-btn>
|
||||||
<!-- input -->
|
<div v-show="checked">
|
||||||
<v-textarea v-model="input" label="你的 JSON 数据"></v-textarea>
|
<p v-show="error" class="text-danger">错误:{{ errorReason }}</p>
|
||||||
|
<p v-show="!error" class="text-success">正确</p>
|
||||||
<v-btn color="primary" class="mt-3 mb-3" @click="validate()">验证</v-btn>
|
</div>
|
||||||
<div v-show="checked">
|
|
||||||
<p v-show="error" class="text-danger">错误:{{ errorReason }}</p>
|
|
||||||
<p v-show="!error" class="text-success">正确</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { RagNewInternalSchemaToolDiscoveryInput } from '@/api'
|
import { RagNewInternalSchemaToolDiscoveryInput } from "@/api";
|
||||||
import { api } from '@/plugins/api'
|
import { api } from "@/plugins/api";
|
||||||
|
|
||||||
const exampleJSON = {
|
const exampleJSON = {
|
||||||
"name": "My Functions",
|
name: "My Functions",
|
||||||
"description": "My Functions",
|
description: "My Functions",
|
||||||
"homepage_url": "https://ivampiresp.com/test",
|
homepage_url: "https://ivampiresp.com/test",
|
||||||
"callback_url": "https://ivampiresp.com/files/tool_test/index.php",
|
callback_url: "https://ivampiresp.com/files/tool_test/index.php",
|
||||||
"functions": [
|
functions: [
|
||||||
{
|
{
|
||||||
"name": "get_current_time",
|
name: "get_current_time",
|
||||||
"description": "当你想知道现在的时间时非常有用。",
|
description: "当你想知道现在的时间时非常有用。",
|
||||||
"parameters": {}
|
parameters: {},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "get_current_weather",
|
||||||
|
description: "当你想查询指定城市的天气时非常有用。",
|
||||||
|
parameters: {
|
||||||
|
type: "object",
|
||||||
|
properties: {
|
||||||
|
location: {
|
||||||
|
type: "string",
|
||||||
|
description: "城市或县区,比如北京市、杭州市、余杭区等。",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
},
|
||||||
"name": "get_current_weather",
|
required: ["location"],
|
||||||
"description": "当你想查询指定城市的天气时非常有用。",
|
},
|
||||||
"parameters": {
|
],
|
||||||
"type": "object",
|
};
|
||||||
"properties": {
|
|
||||||
"location": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "城市或县区,比如北京市、杭州市、余杭区等。"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"location"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
const input = ref("")
|
const input = ref("");
|
||||||
const checked = ref(false)
|
const checked = ref(false);
|
||||||
const error = ref(false)
|
const error = ref(false);
|
||||||
const errorReason = ref("")
|
const errorReason = ref("");
|
||||||
|
|
||||||
// unmashal
|
// unmashal
|
||||||
input.value = JSON.stringify(exampleJSON, null, 4)
|
input.value = JSON.stringify(exampleJSON, null, 4);
|
||||||
|
|
||||||
function validate() {
|
function validate() {
|
||||||
checked.value = true
|
checked.value = true;
|
||||||
// 如果能解析为 json
|
// 如果能解析为 json
|
||||||
try {
|
try {
|
||||||
JSON.parse(input.value)
|
JSON.parse(input.value);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
error.value = true
|
error.value = true;
|
||||||
errorReason.value = "JSON 格式错误"
|
errorReason.value = "JSON 格式错误";
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 强制类型转换
|
// 强制类型转换
|
||||||
const data: RagNewInternalSchemaToolDiscoveryInput = JSON.parse(input.value)
|
const data: RagNewInternalSchemaToolDiscoveryInput = JSON.parse(input.value);
|
||||||
|
|
||||||
|
api.Tool.apiV1ToolsSyntaxPost(data)
|
||||||
api.Tool.apiV1ToolsSyntaxPost(data).then((res) => {
|
.then(() => {
|
||||||
error.value = false
|
error.value = false;
|
||||||
errorReason.value = ""
|
errorReason.value = "";
|
||||||
}).catch((e) => {
|
|
||||||
error.value = true
|
|
||||||
errorReason.value = e.response.data.error
|
|
||||||
})
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
error.value = true;
|
||||||
|
errorReason.value = e.response.data.error;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
Loading…
Reference in New Issue
Block a user