feat: 新增停止大模型回答功能(关联 Issue #104)

This commit is contained in:
zhaoshibao 2025-03-30 12:08:32 +08:00
commit 964e5f9079
5 changed files with 104 additions and 23 deletions

View File

@ -1,7 +1,8 @@
source "https://rubygems.org"
gem "jekyll", "~> 4.3.2"
gem "just-the-docs", "~> 0.5.0"
# gem "just-the-docs", "~> 0.5.0"
gem "minima", "~> 2.5"
group :jekyll_plugins do
gem "jekyll-include-cache"
@ -22,4 +23,4 @@ gem "wdm", "~> 0.1.1", :platforms => [:mingw, :x64_mingw, :mswin]
# Lock `http_parser.rb` gem to `v0.6.x` on JRuby builds since newer versions of the gem
# do not have a Java counterpart.
gem "http_parser.rb", "~> 0.6.0", :platforms => [:jruby]
gem "http_parser.rb", "~> 0.6.0", :platforms => [:jruby]

View File

@ -1,4 +1,4 @@
remote_theme: just-the-docs/just-the-docs
# remote_theme: just-the-docs/just-the-docs
url: https://xerrors.github.io/Yuxi-Know
baseurl: /Yuxi-Know
title: 语析 - 基于大模型的知识库与知识图谱问答系统
@ -23,4 +23,4 @@ defaults:
type: pages
values:
layout: home
search_exclude: true
search_exclude: true

View File

@ -1,5 +1,5 @@
---
layout: home
layout: default
title: 语析 - 基于大模型的知识库与知识图谱问答系统
nav_order: 1
description: "语析是一个强大的问答平台,结合了大模型 RAG 知识库与知识图谱技术,基于 Llamaindex + VueJS + FastAPI + Neo4j 构建。"
@ -133,4 +133,4 @@ docker tag m.daocloud.io/docker.io/library/neo4j:latest neo4j:latest
## 许可证
本项目采用 MIT 许可证 - 详见 [LICENSE](LICENSE) 文件
本项目采用 MIT 许可证 - 详见 [LICENSE](LICENSE) 文件

View File

@ -9,11 +9,29 @@
>
<MenuOutlined />
</div>
<a-tooltip :title="configStore.config?.model_name" placement="rightTop">
<div class="newchat nav-btn" @click="$emit('newconv')">
<PlusCircleOutlined /> <span class="text">新对话</span>
</div>
</a-tooltip>
<div class="newchat nav-btn" @click="$emit('newconv')">
<PlusCircleOutlined /> <span class="text">新对话</span>
</div>
<a-dropdown>
<a class="model-select nav-btn" @click.prevent>
<BulbOutlined /> <span class="text">{{ configStore.config?.model_provider }}/{{ configStore.config?.model_name }}</span>
</a>
<template #overlay>
<a-menu class="scrollable-menu">
<a-menu-item-group v-for="(item, key) in modelKeys" :key="key" :title="modelNames[item]?.name">
<a-menu-item v-for="(model, idx) in modelNames[item]?.models" :key="`${item}-${idx}`" @click="selectModel(item, model)">
{{ item }}/{{ model }}
</a-menu-item>
</a-menu-item-group>
<a-menu-item-group v-if="customModels.length > 0" title="自定义模型">
<a-menu-item v-for="(model, idx) in customModels" :key="`custom-${idx}`" @click="selectModel('custom', model.custom_id)">
custom/{{ model.custom_id }}
</a-menu-item>
</a-menu-item-group>
</a-menu>
</template>
</a-dropdown>
</div>
<div class="header__right">
<div class="nav-btn text" @click="opts.showPanel = !opts.showPanel">
@ -179,7 +197,7 @@
</template>
<script setup>
import { reactive, ref, onMounted, toRefs, nextTick, onUnmounted, watch } from 'vue'
import { reactive, ref, onMounted, toRefs, nextTick, onUnmounted, watch, computed } from 'vue'
import {
SendOutlined,
MenuOutlined,
@ -199,7 +217,7 @@ import {
FolderOpenOutlined,
GlobalOutlined,
FileTextOutlined,
RobotOutlined,
BulbOutlined,
CaretRightOutlined,
DeploymentUnitOutlined,
StopOutlined
@ -638,6 +656,7 @@ watch(
{ deep: true }
);
<<<<<<< HEAD
//
const handleSendOrStop = () => {
if (isStreaming.value) {
@ -666,6 +685,22 @@ const retryStoppedMessage = (message) => {
conv.value.messages = conv.value.messages.slice(0, messageIndex);
}
}
=======
const modelNames = computed(() => configStore.config?.model_names)
const modelStatus = computed(() => configStore.config?.model_provider_status)
const customModels = computed(() => configStore.config?.custom_models || [])
// modelStatus key
const modelKeys = computed(() => {
return Object.keys(modelStatus.value || {}).filter(key => modelStatus.value?.[key])
})
//
const selectModel = (provider, name) => {
configStore.setConfigValue('model_provider', provider)
configStore.setConfigValue('model_name', name)
message.success(`已切换到模型: ${provider}/${name}`)
>>>>>>> 2cec299306b323c10368dd3af82c110753ae963b
}
</script>
@ -709,9 +744,9 @@ const retryStoppedMessage = (message) => {
border-radius: 8px;
color: var(--gray-900);
cursor: pointer;
font-size: 1rem;
// font-size: 1rem;
width: auto;
padding: 0.5rem 1rem;
padding: 0.5rem 0.75rem;
.text {
margin-left: 10px;
@ -722,6 +757,18 @@ const retryStoppedMessage = (message) => {
}
}
.model-select {
// color: var(--gray-900);
max-width: 300px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
.text {
overflow: hidden;
text-overflow: ellipsis;
}
}
}
.metas {
display: flex;
@ -1170,6 +1217,7 @@ const retryStoppedMessage = (message) => {
}
}
<<<<<<< HEAD
.retry-hint {
margin-top: 8px;
padding: 8px 16px;
@ -1195,6 +1243,28 @@ const retryStoppedMessage = (message) => {
&:hover {
background-color: #ff7875 !important;
}
=======
.scrollable-menu {
max-height: 300px;
overflow-y: auto;
&::-webkit-scrollbar {
width: 6px;
}
&::-webkit-scrollbar-track {
background: transparent;
border-radius: 3px;
}
&::-webkit-scrollbar-thumb {
background: var(--gray-400);
border-radius: 3px;
}
&::-webkit-scrollbar-thumb:hover {
background: var(--gray-500);
>>>>>>> 2cec299306b323c10368dd3af82c110753ae963b
}
}
</style>
@ -1249,4 +1319,14 @@ const retryStoppedMessage = (message) => {
}
</style>
<style lang="less">
// dropdown
.ant-dropdown-menu {
&.scrollable-menu {
max-height: 300px;
overflow-y: auto;
}
}
</style>

View File

@ -94,7 +94,7 @@
</div>
<div class="setting" v-if="state.windowWidth <= 520 || state.section === 'model'">
<h3>模型配置</h3>
<p>请在 <code>src/.env</code> 文件中配置对应的 APIKEY</p>
<p>请在 <code>src/.env</code> 文件中配置对应的 APIKEY并重新启动服务</p>
<div class="model-provider-card">
<div class="card-header">
<h3>自定义模型</h3>
@ -167,9 +167,9 @@
<InfoCircleOutlined />
</a>
</div>
<a-button
type="text"
class="expand-button"
<a-button
type="text"
class="expand-button"
@click.stop="toggleExpand(item)"
>
<span class="icon-wrapper" :class="{'rotated': expandedModels[item]}">
@ -550,7 +550,7 @@ const sendRestart = () => {
.model-icon {
width: 28px;
height: 28px;
//
filter: grayscale(100%);
img {
@ -627,7 +627,7 @@ const sendRestart = () => {
.icon-wrapper {
display: inline-flex;
transition: transform 0.2s ease;
&.rotated {
transform: rotate(180deg);
}
@ -639,7 +639,7 @@ const sendRestart = () => {
max-height: 0;
overflow: hidden;
transition: max-height 0.2s ease-out; //
&.expanded {
max-height: 700px; /* 设置一个足够大的值 */
}
@ -710,7 +710,7 @@ const sendRestart = () => {
flex: 1;
margin-right: 8px;
position: relative;
&:hover::after {
content: attr(title);
position: absolute;