优化部分视觉表现

This commit is contained in:
Wenjie Zhang 2024-10-24 20:08:23 +08:00
parent 7b021e1efc
commit aeabe769d6
6 changed files with 65 additions and 39 deletions

View File

@ -58,8 +58,9 @@ class ZhipuEmbedding:
def predict(self, message): def predict(self, message):
data = [] data = []
batch_size = 40
if len(message) > 10: if len(message) > batch_size:
global GLOBAL_EMBED_STATE global GLOBAL_EMBED_STATE
task_id = hashstr(message) task_id = hashstr(message)
logger.info(f"Creating new state for process {task_id}") logger.info(f"Creating new state for process {task_id}")
@ -69,12 +70,12 @@ class ZhipuEmbedding:
'progress': 0 'progress': 0
} }
for i in range(0, len(message), 10): for i in range(0, len(message), batch_size):
if len(message) > 10: if len(message) > batch_size:
logger.info(f"Encoding {i} to {i+10} with {len(message)} messages") logger.info(f"Encoding {i} to {i+batch_size} with {len(message)} messages")
GLOBAL_EMBED_STATE[task_id]['progress'] = i GLOBAL_EMBED_STATE[task_id]['progress'] = i
group_msg = message[i:i+10] group_msg = message[i:i+batch_size]
response = self.client.embeddings.create( response = self.client.embeddings.create(
model=self.model_info.default_path, model=self.model_info.default_path,
input=group_msg, input=group_msg,
@ -82,7 +83,7 @@ class ZhipuEmbedding:
data.extend([a.embedding for a in response.data]) data.extend([a.embedding for a in response.data])
if len(message) > 10: if len(message) > batch_size:
GLOBAL_EMBED_STATE[task_id]['progress'] = len(message) GLOBAL_EMBED_STATE[task_id]['progress'] = len(message)
GLOBAL_EMBED_STATE[task_id]['status'] = 'completed' GLOBAL_EMBED_STATE[task_id]['status'] = 'completed'

View File

@ -1,10 +1,8 @@
import time
import uuid
from fastapi import APIRouter, HTTPException, Request, Body
from fastapi.responses import StreamingResponse, Response
from concurrent.futures import ThreadPoolExecutor
import json import json
import asyncio import asyncio
from fastapi import APIRouter, Body
from fastapi.responses import StreamingResponse, Response
from concurrent.futures import ThreadPoolExecutor
from src.core import HistoryManager from src.core import HistoryManager
from src.core.startup import startup from src.core.startup import startup
from src.utils.logging_config import setup_logger from src.utils.logging_config import setup_logger
@ -63,7 +61,6 @@ def chat_post(
else: else:
content += delta.content content += delta.content
logger.debug(f"Response: {content}")
chunk = make_chunk(content, "loading", history=history_manager.update_ai(content)) chunk = make_chunk(content, "loading", history=history_manager.update_ai(content))
yield chunk yield chunk

View File

@ -667,6 +667,7 @@ watch(
top: 20%; top: 20%;
width: 100%; width: 100%;
z-index: 9; z-index: 9;
animation: slideInUp 0.5s ease-out;
h1 { h1 {
margin-bottom: 20px; margin-bottom: 20px;
@ -913,7 +914,7 @@ watch(
@keyframes pulse { @keyframes pulse {
0%, 80%, 100% { 0%, 80%, 100% {
transform: scale(0.6); transform: scale(0.8);
opacity: 0.3; opacity: 0.3;
} }
40% { 40% {
@ -929,6 +930,9 @@ watch(
@-webkit-keyframes swing-in-top-fwd{0%{-webkit-transform:rotateX(-100deg);transform:rotateX(-100deg);-webkit-transform-origin:top;transform-origin:top;opacity:0}100%{-webkit-transform:rotateX(0deg);transform:rotateX(0deg);-webkit-transform-origin:top;transform-origin:top;opacity:1}}@keyframes swing-in-top-fwd{0%{-webkit-transform:rotateX(-100deg);transform:rotateX(-100deg);-webkit-transform-origin:top;transform-origin:top;opacity:0}100%{-webkit-transform:rotateX(0deg);transform:rotateX(0deg);-webkit-transform-origin:top;transform-origin:top;opacity:1}} @-webkit-keyframes swing-in-top-fwd{0%{-webkit-transform:rotateX(-100deg);transform:rotateX(-100deg);-webkit-transform-origin:top;transform-origin:top;opacity:0}100%{-webkit-transform:rotateX(0deg);transform:rotateX(0deg);-webkit-transform-origin:top;transform-origin:top;opacity:1}}@keyframes swing-in-top-fwd{0%{-webkit-transform:rotateX(-100deg);transform:rotateX(-100deg);-webkit-transform-origin:top;transform-origin:top;opacity:0}100%{-webkit-transform:rotateX(0deg);transform:rotateX(0deg);-webkit-transform-origin:top;transform-origin:top;opacity:1}}
@-webkit-keyframes slide-out-left{0%{-webkit-transform:translateX(0);transform:translateX(0);opacity:1}100%{-webkit-transform:translateX(-1000px);transform:translateX(-1000px);opacity:0}}@keyframes slide-out-left{0%{-webkit-transform:translateX(0);transform:translateX(0);opacity:1}100%{-webkit-transform:translateX(-1000px);transform:translateX(-1000px);opacity:0}} @-webkit-keyframes slide-out-left{0%{-webkit-transform:translateX(0);transform:translateX(0);opacity:1}100%{-webkit-transform:translateX(-1000px);transform:translateX(-1000px);opacity:0}}@keyframes slide-out-left{0%{-webkit-transform:translateX(0);transform:translateX(0);opacity:1}100%{-webkit-transform:translateX(-1000px);transform:translateX(-1000px);opacity:0}}
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes slideInUp { from { transform: translateY(20px); opacity: 0; } to { transform: translateY(0); opacity: 1; } }
@media (max-width: 520px) { @media (max-width: 520px) {
.chat { .chat {
height: calc(100vh - 60px); height: calc(100vh - 60px);
@ -971,6 +975,8 @@ watch(
} }
} }
} }
</style> </style>
<style lang="less"> <style lang="less">
@ -989,6 +995,17 @@ watch(
h1, h2, h3, h4, h5, h6 { h1, h2, h3, h4, h5, h6 {
font-size: 1rem; font-size: 1rem;
} }
li, ol, ul {
& > p {
margin: 0.25rem 0;
}
}
ol, ul {
padding-left: 1rem;
}
} }
</style> </style>

View File

@ -104,20 +104,20 @@
<div class="sider"> <div class="sider">
<div class="sider-top"> <div class="sider-top">
<div class="query-params" v-if="state.curPage == 'query-test'"> <div class="query-params" v-if="state.curPage == 'query-test'">
<h3 class="params-title">参数配置</h3> <!-- <h3 class="params-title">参数配置</h3> -->
<div class="params-group"> <div class="params-group">
<div class="params-item"> <div class="params-item">
<p>检索数量</p> <p>检索数量</p>
<a-input-number size="small" v-model:value="meta.maxQueryCount" :min="1" :max="20" /> <a-input-number size="small" v-model:value="meta.maxQueryCount" :min="1" :max="20" />
</div> </div>
<div class="params-item">
<p>TopK</p>
<a-input-number size="small" v-model:value="meta.topK" :min="1" :max="meta.maxQueryCount" />
</div>
<div class="params-item"> <div class="params-item">
<p>过滤低质量</p> <p>过滤低质量</p>
<a-switch v-model:checked="meta.filter" /> <a-switch v-model:checked="meta.filter" />
</div> </div>
<div class="params-item">
<p>筛选 TopK</p>
<a-input-number size="small" v-model:value="meta.topK" :min="1" :max="meta.maxQueryCount" />
</div>
</div> </div>
<div class="params-group"> <div class="params-group">
<div class="params-item w100" v-if="configStore.config.enable_reranker"> <div class="params-item w100" v-if="configStore.config.enable_reranker">
@ -160,6 +160,7 @@
</div> </div>
<!-- 新增示例按钮 --> <!-- 新增示例按钮 -->
<span>示例查询</span>
<div class="query-examples"> <div class="query-examples">
<a-button v-for="example in queryExamples" :key="example" @click="useQueryExample(example)"> <a-button v-for="example in queryExamples" :key="example" @click="useQueryExample(example)">
{{ example }} {{ example }}
@ -602,14 +603,17 @@ onMounted(() => {
.query-params { .query-params {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
border-radius: 8px;
box-sizing: border-box; box-sizing: border-box;
font-size: 15px; font-size: 15px;
gap: 12px; gap: 12px;
background-color: var(--main-light-6); // background-color: var(--main-light-6);
padding: 16px; // padding: 16px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05); // box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
border: 1px solid var(--main-light-3); // border: 1px solid var(--main-light-3);
// border-radius: 8px;
padding-top: 12px;
padding-right: 16px;
border-right: 1px solid var(--main-light-3);
.params-title { .params-title {
margin-top: 0; margin-top: 0;
@ -644,7 +648,7 @@ onMounted(() => {
p { p {
margin: 0; margin: 0;
font-size: 15px; font-size: 16px;
color: var(--gray-900); color: var(--gray-900);
} }
@ -706,18 +710,18 @@ onMounted(() => {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
gap: 8px; gap: 8px;
margin-bottom: 20px; margin: 10px 0;
.ant-btn { .ant-btn {
font-size: 14px; font-size: 14px;
padding: 4px 12px; padding: 4px 12px;
height: auto; height: auto;
background-color: var(--main-light-4); background-color: var(--gray-200);
border: none; border: none;
color: var(--main-600); color: var(--gray-800);
&:hover { &:hover {
background-color: var(--main-light-3); background-color: var(--gray-300);
} }
} }
} }
@ -903,6 +907,7 @@ onMounted(() => {
.params-item.col .ant-segmented { .params-item.col .ant-segmented {
width: 100%; width: 100%;
font-size: smaller;
div.ant-segmented-group { div.ant-segmented-group {
display: flex; display: flex;
justify-content: space-around; justify-content: space-around;
@ -910,6 +915,9 @@ onMounted(() => {
label.ant-segmented-item { label.ant-segmented-item {
flex: 1; flex: 1;
text-align: center; text-align: center;
div.ant-segmented-item-label > div > p {
font-size: small;
}
} }
} }
} }

View File

@ -145,9 +145,9 @@
</div> </div>
<div class="model-provider-card" v-for="(item, key) in modelKeys" :key="key"> <div class="model-provider-card" v-for="(item, key) in modelKeys" :key="key">
<div class="card-header"> <div class="card-header">
<h3>{{ modelNames[item].name }}</h3>
<a :href="modelNames[item].url" target="_blank">详情</a>
<div v-if="modelStatus[item]" class="success"></div> <div v-if="modelStatus[item]" class="success"></div>
<h3>{{ modelNames[item].name }}</h3>
<a :href="modelNames[item].url" target="_blank"><InfoCircleOutlined /></a>
</div> </div>
<div class="card-body" v-if="modelStatus[item]"> <div class="card-body" v-if="modelStatus[item]">
<div <div
@ -185,6 +185,7 @@ import {
FolderOutlined, FolderOutlined,
DeleteOutlined, DeleteOutlined,
EditOutlined, EditOutlined,
InfoCircleOutlined,
} from '@ant-design/icons-vue'; } from '@ant-design/icons-vue';
import HeaderComponent from '@/components/HeaderComponent.vue'; import HeaderComponent from '@/components/HeaderComponent.vue';
import { notification, Button } from 'ant-design-vue'; import { notification, Button } from 'ant-design-vue';
@ -452,12 +453,13 @@ const sendRestart = () => {
h3 { h3 {
margin: 0; margin: 0;
font-size: 1rem; font-size: 1rem;
font-weight: bold;
} }
a { a {
text-decoration: none; text-decoration: none;
color: var(--gray-700); color: var(--gray-500);
font-size: 14px; font-size: 12px;
transition: all 0.1s; transition: all 0.1s;
&:hover { &:hover {
@ -465,16 +467,16 @@ const sendRestart = () => {
} }
} }
.success, .missing-keys { .details, .missing-keys {
margin-left: auto; margin-left: auto;
} }
.success { .success {
width: 1rem; width: 0.75rem;
height: 1rem; height: 0.75rem;
background-color: rgb(91, 186, 91); background-color: rgb(91, 186, 91);
border-radius: 50%; border-radius: 50%;
box-shadow: 0 0 10px 1px rgba( 0,128, 0, 0.2); box-shadow: 0 0 10px 1px rgba( 0,128, 0, 0.1);
border: 2px solid white; border: 2px solid white;
} }
@ -482,6 +484,7 @@ const sendRestart = () => {
color: var(--gray-600); color: var(--gray-600);
& > span { & > span {
margin-left: 10px; margin-left: 10px;
user-select: all;
} }
} }
} }

View File

@ -2,16 +2,16 @@
<div class="tools-container layout-container"> <div class="tools-container layout-container">
<HeaderComponent <HeaderComponent
title="工具箱" title="工具箱"
description="这里展示了各种可用的工具。点击查看详情。" description="这里展示了各种可用的工具。"
> >
</HeaderComponent> </HeaderComponent>
<div class="tools-grid"> <div class="tools-grid">
<div v-for="tool in tools" :key="tool.id" class="tool-card" @click="navigateToTool(tool.name)"> <div v-for="tool in tools" :key="tool.id" class="tool-card" @click="navigateToTool(tool.name)">
<div class="tool-header"> <div class="tool-header">
<div class="tool-icon"> <!-- <div class="tool-icon">
<component :is="iconMap[tool.name]" /> <component :is="iconMap[tool.name]" />
</div> </div> -->
<h3>{{ tool.title }}</h3> <h3>{{ tool.title }}</h3>
</div> </div>
<div class="tool-info"> <div class="tool-info">