temp
This commit is contained in:
parent
4f3ba3ad5f
commit
02686db89f
143
scripts/milvus/standalone_embed.sh
Normal file
143
scripts/milvus/standalone_embed.sh
Normal file
@ -0,0 +1,143 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Licensed to the LF AI & Data foundation under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
run_embed() {
|
||||
cat << EOF > embedEtcd.yaml
|
||||
listen-client-urls: http://0.0.0.0:2379
|
||||
advertise-client-urls: http://0.0.0.0:2379
|
||||
quota-backend-bytes: 4294967296
|
||||
auto-compaction-mode: revision
|
||||
auto-compaction-retention: '1000'
|
||||
EOF
|
||||
|
||||
cat << EOF > user.yaml
|
||||
# Extra config to override default milvus.yaml
|
||||
EOF
|
||||
|
||||
sudo docker run -d \
|
||||
--name milvus-standalone \
|
||||
--security-opt seccomp:unconfined \
|
||||
-e ETCD_USE_EMBED=true \
|
||||
-e ETCD_DATA_DIR=/var/lib/milvus/etcd \
|
||||
-e ETCD_CONFIG_PATH=/milvus/configs/embedEtcd.yaml \
|
||||
-e COMMON_STORAGETYPE=local \
|
||||
-v $(pwd)/volumes/milvus:/var/lib/milvus \
|
||||
-v $(pwd)/embedEtcd.yaml:/milvus/configs/embedEtcd.yaml \
|
||||
-v $(pwd)/user.yaml:/milvus/configs/user.yaml \
|
||||
-p 19530:19530 \
|
||||
-p 9091:9091 \
|
||||
-p 2379:2379 \
|
||||
--health-cmd="curl -f http://localhost:9091/healthz" \
|
||||
--health-interval=30s \
|
||||
--health-start-period=90s \
|
||||
--health-timeout=20s \
|
||||
--health-retries=3 \
|
||||
milvusdb/milvus:v2.4.5 \
|
||||
milvus run standalone 1> /dev/null
|
||||
}
|
||||
|
||||
wait_for_milvus_running() {
|
||||
echo "Wait for Milvus Starting..."
|
||||
while true
|
||||
do
|
||||
res=`sudo docker ps|grep milvus-standalone|grep healthy|wc -l`
|
||||
if [ $res -eq 1 ]
|
||||
then
|
||||
echo "Start successfully."
|
||||
echo "To change the default Milvus configuration, add your settings to the user.yaml file and then restart the service."
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
}
|
||||
|
||||
start() {
|
||||
res=`sudo docker ps|grep milvus-standalone|grep healthy|wc -l`
|
||||
if [ $res -eq 1 ]
|
||||
then
|
||||
echo "Milvus is running."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
res=`sudo docker ps -a|grep milvus-standalone|wc -l`
|
||||
if [ $res -eq 1 ]
|
||||
then
|
||||
sudo docker start milvus-standalone 1> /dev/null
|
||||
else
|
||||
run_embed
|
||||
fi
|
||||
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
echo "Start failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
wait_for_milvus_running
|
||||
}
|
||||
|
||||
stop() {
|
||||
sudo docker stop milvus-standalone 1> /dev/null
|
||||
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
echo "Stop failed."
|
||||
exit 1
|
||||
fi
|
||||
echo "Stop successfully."
|
||||
|
||||
}
|
||||
|
||||
delete() {
|
||||
res=`sudo docker ps|grep milvus-standalone|wc -l`
|
||||
if [ $res -eq 1 ]
|
||||
then
|
||||
echo "Please stop Milvus service before delete."
|
||||
exit 1
|
||||
fi
|
||||
sudo docker rm milvus-standalone 1> /dev/null
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
echo "Delete failed."
|
||||
exit 1
|
||||
fi
|
||||
sudo rm -rf $(pwd)/volumes
|
||||
sudo rm -rf $(pwd)/embedEtcd.yaml
|
||||
sudo rm -rf $(pwd)/user.yaml
|
||||
echo "Delete successfully."
|
||||
}
|
||||
|
||||
|
||||
case $1 in
|
||||
restart)
|
||||
stop
|
||||
start
|
||||
;;
|
||||
start)
|
||||
start
|
||||
;;
|
||||
stop)
|
||||
stop
|
||||
;;
|
||||
delete)
|
||||
delete
|
||||
;;
|
||||
*)
|
||||
echo "please use bash standalone_embed.sh restart|start|stop|delete"
|
||||
;;
|
||||
esac
|
||||
@ -64,6 +64,7 @@ class DataBaseManager:
|
||||
|
||||
def get_databases(self):
|
||||
self._update_database()
|
||||
assert self.config.enable_knowledge_base, "知识库未启用"
|
||||
knowledge_base_collections = self.knowledge_base.get_collection_names()
|
||||
if len(self.data["databases"]) != len(knowledge_base_collections):
|
||||
logger.warning(f"Database number not match, {knowledge_base_collections}")
|
||||
|
||||
32
src/main.py
Normal file
32
src/main.py
Normal file
@ -0,0 +1,32 @@
|
||||
import uvicorn
|
||||
from dotenv import load_dotenv
|
||||
from fastapi import FastAPI
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
from src.routers import router
|
||||
from src.utils.logging_config import setup_logger
|
||||
|
||||
load_dotenv()
|
||||
|
||||
import os
|
||||
|
||||
os.environ["ZHIPUAI_API_KEY"] = "270ea71e9560c0ff406acbcdd48bfd97.e3XOMdWKuZb7Q1Sk"
|
||||
|
||||
app = FastAPI()
|
||||
app.include_router(router)
|
||||
|
||||
# CORS 设置
|
||||
app.add_middleware(
|
||||
CORSMiddleware,
|
||||
allow_origins=["*"],
|
||||
allow_credentials=True,
|
||||
allow_methods=["*"],
|
||||
allow_headers=["*"],
|
||||
)
|
||||
|
||||
|
||||
logger = setup_logger("server:main")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
uvicorn.run(app, host="0.0.0.0", port=5000)
|
||||
|
||||
@ -58,7 +58,7 @@ class DeepSeek(OpenAIBase):
|
||||
class Zhipu(OpenAIBase):
|
||||
def __init__(self, model_name=None):
|
||||
model_name = model_name or "glm-4-flash"
|
||||
api_key = os.getenv("ZHIPUAI_API_KEY")
|
||||
api_key = os.getenv("ZHIPUAI_API_KEY", "270ea71e9560c0ff406acbcdd48bfd97.e3XOMdWKuZb7Q1Sk")
|
||||
base_url = "https://open.bigmodel.cn/api/paas/v4/"
|
||||
super().__init__(api_key=api_key, base_url=base_url, model_name=model_name)
|
||||
|
||||
|
||||
11
src/routers/__init__.py
Normal file
11
src/routers/__init__.py
Normal file
@ -0,0 +1,11 @@
|
||||
from fastapi import APIRouter
|
||||
from src.routers.chat_router import chat
|
||||
from src.routers.data_router import data
|
||||
from src.routers.base_router import base
|
||||
from src.routers.tool_router import tool
|
||||
|
||||
router = APIRouter()
|
||||
router.include_router(base)
|
||||
router.include_router(chat)
|
||||
router.include_router(data)
|
||||
router.include_router(tool)
|
||||
45
src/routers/base_router.py
Normal file
45
src/routers/base_router.py
Normal file
@ -0,0 +1,45 @@
|
||||
from fastapi import APIRouter
|
||||
|
||||
base = APIRouter()
|
||||
|
||||
from fastapi import FastAPI, HTTPException
|
||||
from fastapi.responses import JSONResponse
|
||||
from fastapi import Request
|
||||
from src.core import HistoryManager
|
||||
from src.utils.logging_config import setup_logger
|
||||
from src.core.startup import startup
|
||||
|
||||
logger = setup_logger("server-base")
|
||||
|
||||
@base.get("/")
|
||||
async def route_index():
|
||||
return {"message": "You Got It!"}
|
||||
|
||||
@base.get("/config")
|
||||
async def get_config():
|
||||
return startup.config
|
||||
|
||||
@base.post("/config")
|
||||
async def update_config(request: Request):
|
||||
request_data = await request.json()
|
||||
startup.config.update(request_data)
|
||||
startup.config.save()
|
||||
return startup.config
|
||||
|
||||
@base.post("/restart")
|
||||
async def restart():
|
||||
startup.restart()
|
||||
return {"message": "Restarted!"}
|
||||
|
||||
@base.get("/log")
|
||||
async def get_log():
|
||||
from src.utils.logging_config import LOG_FILE
|
||||
from collections import deque
|
||||
|
||||
with open(LOG_FILE, 'r') as f:
|
||||
last_lines = deque(f, maxlen=1000)
|
||||
|
||||
log = ''.join(last_lines)
|
||||
return {"log": log}
|
||||
|
||||
|
||||
55
src/routers/chat_router.py
Normal file
55
src/routers/chat_router.py
Normal file
@ -0,0 +1,55 @@
|
||||
from fastapi import APIRouter, HTTPException, Request
|
||||
from fastapi.responses import StreamingResponse
|
||||
import json
|
||||
from src.core import HistoryManager
|
||||
from src.core.startup import startup
|
||||
from src.utils.logging_config import setup_logger
|
||||
|
||||
chat = APIRouter(prefix="/chat")
|
||||
logger = setup_logger("server-chat")
|
||||
|
||||
@chat.get("/")
|
||||
async def chat_get():
|
||||
return "Chat Get!"
|
||||
|
||||
@chat.post("/")
|
||||
async def chat_post(request: Request):
|
||||
request_data = await request.json()
|
||||
query = request_data['query']
|
||||
meta = request_data.get('meta')
|
||||
history_manager = HistoryManager(request_data['history'])
|
||||
|
||||
new_query, refs = startup.retriever(query, history_manager.messages, meta)
|
||||
|
||||
messages = history_manager.get_history_with_msg(new_query, max_rounds=meta.get('history_round'))
|
||||
history_manager.add_user(query)
|
||||
logger.debug(f"Web history: {history_manager.messages}")
|
||||
|
||||
async def generate_response():
|
||||
content = ""
|
||||
for delta in startup.model.predict(messages, stream=True):
|
||||
if not delta.content:
|
||||
continue
|
||||
|
||||
if hasattr(delta, 'is_full') and delta.is_full:
|
||||
content = delta.content
|
||||
else:
|
||||
content += delta.content
|
||||
|
||||
response_chunk = json.dumps({
|
||||
"history": history_manager.update_ai(content),
|
||||
"response": content,
|
||||
"refs": refs # TODO: 优化 refs,不需要每次都返回
|
||||
}, ensure_ascii=False).encode('utf8') + b'\n'
|
||||
yield response_chunk
|
||||
|
||||
return StreamingResponse(generate_response(), media_type='application/json')
|
||||
|
||||
@chat.post("/call")
|
||||
async def call(request: Request):
|
||||
request_data = await request.json()
|
||||
query = request_data['query']
|
||||
response = startup.model.predict(query)
|
||||
logger.debug({"query": query, "response": response.content})
|
||||
|
||||
return {"response": response.content}
|
||||
120
src/routers/data_router.py
Normal file
120
src/routers/data_router.py
Normal file
@ -0,0 +1,120 @@
|
||||
import os
|
||||
from typing import List, Optional
|
||||
from fastapi import APIRouter, File, UploadFile, HTTPException, Depends, Body
|
||||
from pydantic import BaseModel
|
||||
|
||||
from src.utils import setup_logger, hashstr
|
||||
from src.core.startup import startup
|
||||
|
||||
data = APIRouter(prefix="/data")
|
||||
|
||||
logger = setup_logger("server-database")
|
||||
|
||||
@data.get("/")
|
||||
async def get_databases():
|
||||
try:
|
||||
database = startup.dbm.get_databases()
|
||||
except Exception as e:
|
||||
return {"message": f"获取数据库列表失败 {e}", "databases": []}
|
||||
return database
|
||||
|
||||
@data.post("/")
|
||||
async def create_database(
|
||||
database_name: str = Body(...),
|
||||
description: str = Body(...),
|
||||
db_type: str = Body(...),
|
||||
dimension: int = Body(None)
|
||||
):
|
||||
logger.debug(f"Create database {database_name}")
|
||||
database_info = startup.dbm.create_database(
|
||||
database_name,
|
||||
description,
|
||||
db_type,
|
||||
dimension=dimension
|
||||
)
|
||||
return database_info
|
||||
|
||||
@data.delete("/")
|
||||
async def delete_database(db_id: str = Body(...)):
|
||||
logger.debug(f"Delete database {db_id}")
|
||||
startup.dbm.delete_database(db_id)
|
||||
return {"message": "删除成功"}
|
||||
|
||||
@data.post("/query-test")
|
||||
async def query_test(query: str = Body(...), meta: dict = Body(...)):
|
||||
logger.debug(f"Query test in {meta}: {query}")
|
||||
result = startup.retriever.query_knowledgebase(query, history=None, refs={"meta": meta})
|
||||
return result
|
||||
|
||||
@data.post("/add-by-file")
|
||||
async def create_document_by_file(db_id: str = Body(...), files: List[str] = Body(...)):
|
||||
logger.debug(f"Add document in {db_id} by file: {files}")
|
||||
msg = startup.dbm.add_files(db_id, files)
|
||||
return msg
|
||||
|
||||
@data.get("/database-info")
|
||||
async def get_database_info(db_id: str):
|
||||
logger.debug(f"Get database {db_id} info")
|
||||
database = startup.dbm.get_database_info(db_id)
|
||||
if database is None:
|
||||
raise HTTPException(status_code=404, detail="Database not found")
|
||||
return database
|
||||
|
||||
@data.delete("/document")
|
||||
async def delete_document(db_id: str = Body(...), file_id: str = Body(...)):
|
||||
logger.debug(f"DELETE document {file_id} info in {db_id}")
|
||||
startup.dbm.delete_file(db_id, file_id)
|
||||
return {"message": "删除成功"}
|
||||
|
||||
@data.get("/document")
|
||||
async def get_document_info(db_id: str, file_id: str):
|
||||
logger.debug(f"GET document {file_id} info in {db_id}")
|
||||
info = startup.dbm.get_file_info(db_id, file_id)
|
||||
return info
|
||||
|
||||
@data.post("/upload")
|
||||
async def upload_file(file: UploadFile = File(...)):
|
||||
if not file.filename:
|
||||
raise HTTPException(status_code=400, detail="No selected file")
|
||||
|
||||
upload_dir = os.path.join(startup.config.save_dir, "data/uploads")
|
||||
os.makedirs(upload_dir, exist_ok=True)
|
||||
filename = f"{hashstr(file.filename, 4, with_salt=True)}_{file.filename}".lower()
|
||||
file_path = os.path.join(upload_dir, filename)
|
||||
|
||||
with open(file_path, "wb") as buffer:
|
||||
buffer.write(await file.read())
|
||||
|
||||
return {"message": "File successfully uploaded", "file_path": file_path}
|
||||
|
||||
@data.get("/graph")
|
||||
async def get_graph_info():
|
||||
graph_info = startup.dbm.get_graph()
|
||||
return graph_info
|
||||
|
||||
@data.get("/graph/node")
|
||||
async def get_graph_node(entity_name: str):
|
||||
logger.debug(f"Get graph node {entity_name}")
|
||||
result = startup.dbm.graph_base.query_node(entity_name=entity_name)
|
||||
return {"result": startup.retriever.format_query_results(result), "message": "success"}
|
||||
|
||||
@data.get("/graph/nodes")
|
||||
async def get_graph_nodes(kgdb_name: str, num: int):
|
||||
if not startup.config.enable_knowledge_graph:
|
||||
raise HTTPException(status_code=400, detail="Knowledge graph is not enabled")
|
||||
|
||||
logger.debug(f"Get graph nodes in {kgdb_name} with {num} nodes")
|
||||
result = startup.dbm.graph_base.get_sample_nodes(kgdb_name, num)
|
||||
return {"result": startup.retriever.format_general_results(result), "message": "success"}
|
||||
|
||||
@data.post("/graph/add")
|
||||
async def add_graph_entity(kgdb_name: str = Body(...), file_path: str = Body(...)):
|
||||
if not startup.config.enable_knowledge_graph:
|
||||
raise HTTPException(status_code=400, detail="Knowledge graph is not enabled")
|
||||
|
||||
if not file_path.endswith('.jsonl'):
|
||||
raise HTTPException(status_code=400, detail="file_path must be a jsonl file")
|
||||
|
||||
startup.dbm.graph_base.jsonl_file_add_entity(file_path, kgdb_name)
|
||||
return {"message": "Entity successfully added"}
|
||||
|
||||
50
src/routers/tool_router.py
Normal file
50
src/routers/tool_router.py
Normal file
@ -0,0 +1,50 @@
|
||||
import os
|
||||
from fastapi import APIRouter, Body
|
||||
from pydantic import BaseModel
|
||||
from typing import List, Dict, Any, Optional
|
||||
|
||||
from src.utils import setup_logger
|
||||
|
||||
tool = APIRouter(prefix="/tool")
|
||||
|
||||
logger = setup_logger("server-tools")
|
||||
|
||||
class Tool(BaseModel):
|
||||
name: str
|
||||
title: str
|
||||
description: str
|
||||
url: str
|
||||
method: str
|
||||
|
||||
@tool.get("/", response_model=List[Tool])
|
||||
async def route_index():
|
||||
tools = [
|
||||
Tool(
|
||||
name="text-chunking",
|
||||
title="文本分块",
|
||||
description="将文本分块以更好地理解。可以输入文本或者上传文件。",
|
||||
url="/tools/text-chunking",
|
||||
method="POST",
|
||||
),
|
||||
Tool(
|
||||
name="pdf2txt",
|
||||
title="PDF转文本",
|
||||
description="将PDF文件转换为文本文件。",
|
||||
url="/tools/pdf2txt",
|
||||
method="POST",
|
||||
)
|
||||
]
|
||||
|
||||
return tools
|
||||
|
||||
@tool.post("/text-chunking")
|
||||
async def text_chunking(text: str = Body(...), params: Dict[str, Any] = Body(...)):
|
||||
from src.core.indexing import chunk
|
||||
nodes = chunk(text, params=params)
|
||||
return {"nodes": [node.to_dict() for node in nodes]}
|
||||
|
||||
@tool.post("/pdf2txt")
|
||||
async def handle_pdf2txt(file: str = Body(...)):
|
||||
from src.plugins import pdf2txt
|
||||
text = pdf2txt(file, return_text=True)
|
||||
return {"text": text}
|
||||
@ -351,7 +351,7 @@ const updateStatus = (id, status) => {
|
||||
|
||||
const simpleCall = (message) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
fetch('/api/call', {
|
||||
fetch('/api/chat/call', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ query: message, }),
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
@ -363,7 +363,7 @@ const simpleCall = (message) => {
|
||||
}
|
||||
|
||||
const loadDatabases = () => {
|
||||
fetch('/api/database/', { method: "GET", })
|
||||
fetch('/api/data/', { method: "GET", })
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
console.log(data)
|
||||
@ -371,63 +371,74 @@ const loadDatabases = () => {
|
||||
})
|
||||
}
|
||||
|
||||
const sendMessage = () => {
|
||||
const user_input = conv.value.inputText.trim()
|
||||
if (user_input) {
|
||||
isStreaming.value = true
|
||||
appendUserMessage(user_input)
|
||||
appendAiMessage("", null)
|
||||
const cur_res_id = conv.value.messages[conv.value.messages.length - 1].id
|
||||
conv.value.inputText = ''
|
||||
meta.db_name = opts.databases[meta.selectedKB]?.metaname
|
||||
fetch('/api/chat', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
query: user_input,
|
||||
history: conv.value.history,
|
||||
meta: meta
|
||||
}),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
}).then((response) => {const reader = response.body.getReader()
|
||||
const decoder = new TextDecoder()
|
||||
let buffer = ''
|
||||
// 逐步读取响应文本
|
||||
const readChunk = () => {
|
||||
return reader.read().then(({ done, value }) => {
|
||||
if (done) {
|
||||
console.log(conv.value)
|
||||
console.log('Finished')
|
||||
updateStatus(cur_res_id, "finished")
|
||||
isStreaming.value = false
|
||||
if (conv.value.messages.length === 2) { renameTitle() }
|
||||
return
|
||||
}
|
||||
// 新函数用于处理 fetch 请求
|
||||
const fetchChatResponse = (user_input, cur_res_id) => {
|
||||
fetch('/api/chat', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
query: user_input,
|
||||
history: conv.value.history,
|
||||
meta: meta
|
||||
}),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
}).then((response) => {
|
||||
const reader = response.body.getReader();
|
||||
const decoder = new TextDecoder();
|
||||
let buffer = '';
|
||||
|
||||
buffer += decoder.decode(value, { stream: true })
|
||||
const message = buffer.trim().split('\n').pop()
|
||||
// 逐步读取响应文本
|
||||
const readChunk = () => {
|
||||
return reader.read().then(({ done, value }) => {
|
||||
if (done) {
|
||||
// 处理完成
|
||||
updateStatus(cur_res_id, "finished");
|
||||
isStreaming.value = false;
|
||||
if (conv.value.messages.length === 2) { renameTitle(); }
|
||||
return; // 结束读取
|
||||
}
|
||||
|
||||
buffer += decoder.decode(value, { stream: true });
|
||||
const messages = buffer.trim().split('\n');
|
||||
|
||||
messages.forEach((message) => {
|
||||
try {
|
||||
const data = JSON.parse(message)
|
||||
updateMessage(data.response, cur_res_id, data.refs, "loading")
|
||||
conv.value.history = data.history
|
||||
buffer = ''
|
||||
const data = JSON.parse(message);
|
||||
updateMessage(data.response, cur_res_id, data.refs, "loading");
|
||||
conv.value.history = data.history;
|
||||
} catch (e) {
|
||||
// console.log(e)
|
||||
console.error('JSON 解析错误:', e);
|
||||
}
|
||||
return readChunk()
|
||||
})
|
||||
}
|
||||
return readChunk()
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error(error)
|
||||
updateStatus(cur_res_id, "error")
|
||||
isStreaming.value = false
|
||||
})
|
||||
});
|
||||
buffer = ''; // 清空缓冲区
|
||||
return readChunk(); // 继续读取
|
||||
});
|
||||
};
|
||||
return readChunk();
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error(error);
|
||||
updateStatus(cur_res_id, "error");
|
||||
isStreaming.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
// 更新后的 sendMessage 函数
|
||||
const sendMessage = () => {
|
||||
const user_input = conv.value.inputText.trim();
|
||||
const dbName = opts.databases.length > 0 ? opts.databases[meta.selectedKB]?.metaname : null;
|
||||
if (user_input) {
|
||||
isStreaming.value = true;
|
||||
appendUserMessage(user_input);
|
||||
appendAiMessage("", null);
|
||||
const cur_res_id = conv.value.messages[conv.value.messages.length - 1].id;
|
||||
conv.value.inputText = '';
|
||||
meta.db_name = dbName;
|
||||
|
||||
fetchChatResponse(user_input, cur_res_id)
|
||||
} else {
|
||||
console.log('请输入消息')
|
||||
console.log('请输入消息');
|
||||
}
|
||||
}
|
||||
|
||||
@ -436,11 +447,6 @@ const autoSend = (message) => {
|
||||
sendMessage()
|
||||
}
|
||||
|
||||
// const clearChat = () => {
|
||||
// conv.value.messages = []
|
||||
// conv.value.history = []
|
||||
// }
|
||||
|
||||
// 从本地存储加载数据
|
||||
onMounted(() => {
|
||||
scrollToBottom()
|
||||
|
||||
@ -15,7 +15,7 @@
|
||||
name="file"
|
||||
:max-count="1"
|
||||
:disabled="state.uploading"
|
||||
action="/api/database/upload"
|
||||
action="/api/data/upload"
|
||||
@change="handleFileUpload"
|
||||
@drop="handleDrop"
|
||||
>
|
||||
@ -92,7 +92,7 @@ const convertPdfToText = async () => {
|
||||
|
||||
try {
|
||||
state.loading = true;
|
||||
const response = await fetch('/api/tools/pdf2txt', {
|
||||
const response = await fetch('/api/tool/pdf2txt', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ file: file })
|
||||
|
||||
@ -40,7 +40,7 @@
|
||||
name="file"
|
||||
:max-count="1"
|
||||
:disabled="state.uploading"
|
||||
action="/api/database/upload"
|
||||
action="/api/data/upload"
|
||||
@change="handleFileUpload"
|
||||
@drop="handleDrop"
|
||||
>
|
||||
@ -125,14 +125,16 @@ const chunkText = async () => {
|
||||
|
||||
try {
|
||||
state.loading = true
|
||||
const response = await fetch('/api/tools/text_chunking', {
|
||||
const response = await fetch('/api/tool/text-chunking', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
text: text_or_file,
|
||||
chunk_size: params.chunkSize,
|
||||
chunk_overlap: params.chunkOverlap,
|
||||
use_parser: params.useParser
|
||||
params: {
|
||||
chunk_size: params.chunkSize,
|
||||
chunk_overlap: params.chunkOverlap,
|
||||
use_parser: params.useParser
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
|
||||
@ -43,7 +43,7 @@ const getRemoteDatabase = () => {
|
||||
if (!configStore.config.enable_knowledge_base) {
|
||||
return
|
||||
}
|
||||
fetch('/api/database').then(res => res.json()).then(data => {
|
||||
fetch('/api/data').then(res => res.json()).then(data => {
|
||||
console.log("database", data)
|
||||
databaseStore.setDatabase(data.databases)
|
||||
})
|
||||
|
||||
@ -87,7 +87,7 @@ const router = createRouter({
|
||||
meta: { keepAlive: true }
|
||||
},
|
||||
{
|
||||
path: 'text_chunking',
|
||||
path: 'text-chunking',
|
||||
name: 'TextChunking',
|
||||
component: () => import('../components/TextChunkingComponent.vue'),
|
||||
},
|
||||
|
||||
@ -32,7 +32,7 @@
|
||||
name="file"
|
||||
:multiple="true"
|
||||
:disabled="state.loading"
|
||||
action="/api/database/upload"
|
||||
action="/api/data/upload"
|
||||
@change="handleFileUpload"
|
||||
@drop="handleDrop"
|
||||
>
|
||||
@ -300,7 +300,7 @@ const onQuery = () => {
|
||||
return
|
||||
}
|
||||
meta.db_name = database.value.metaname
|
||||
fetch('/api/database/query-test', {
|
||||
fetch('/api/data/query-test', {
|
||||
method: "POST",
|
||||
body: JSON.stringify({
|
||||
query: queryText.value.trim(),
|
||||
@ -359,7 +359,7 @@ const deleteDatabse = () => {
|
||||
cancelText: '取消',
|
||||
onOk: () => {
|
||||
state.lock = true
|
||||
fetch('/api/database/', {
|
||||
fetch('/api/data/', {
|
||||
method: "DELETE",
|
||||
body: JSON.stringify({
|
||||
db_id: databaseId.value
|
||||
@ -387,7 +387,7 @@ const deleteDatabse = () => {
|
||||
|
||||
const openFileDetail = (record) => {
|
||||
state.lock = true
|
||||
fetch(`/api/database/document?db_id=${databaseId.value}&file_id=${record.file_id}`, {
|
||||
fetch(`/api/data/document?db_id=${databaseId.value}&file_id=${record.file_id}`, {
|
||||
method: "GET",
|
||||
})
|
||||
.then(response => response.json())
|
||||
@ -427,7 +427,7 @@ const getDatabaseInfo = () => {
|
||||
const db_id = databaseId.value
|
||||
state.lock = true
|
||||
return new Promise((resolve, reject) => {
|
||||
fetch(`/api/database/info?db_id=${db_id}`, {
|
||||
fetch(`/api/data/info?db_id=${db_id}`, {
|
||||
method: "GET",
|
||||
})
|
||||
.then(response => response.json())
|
||||
@ -449,7 +449,7 @@ const getDatabaseInfo = () => {
|
||||
const deleteFile = (fileId) => {
|
||||
console.log(fileId)
|
||||
state.lock = true
|
||||
fetch('/api/database/document', {
|
||||
fetch('/api/data/document', {
|
||||
method: "DELETE",
|
||||
body: JSON.stringify({
|
||||
db_id: databaseId.value,
|
||||
@ -478,7 +478,7 @@ const addDocumentByFile = () => {
|
||||
state.refreshInterval = setInterval(() => {
|
||||
getDatabaseInfo();
|
||||
}, 1000);
|
||||
fetch('/api/database/add_by_file', {
|
||||
fetch('/api/data/add_by_file', {
|
||||
method: "POST",
|
||||
body: JSON.stringify({
|
||||
db_id: databaseId.value,
|
||||
|
||||
@ -111,7 +111,7 @@ const newDatabase = reactive({
|
||||
|
||||
const loadDatabases = () => {
|
||||
// loadGraph()
|
||||
fetch('/api/database/', {
|
||||
fetch('/api/data/', {
|
||||
method: "GET",
|
||||
})
|
||||
.then(response => response.json())
|
||||
@ -130,7 +130,7 @@ const createDatabase = () => {
|
||||
newDatabase.loading = false
|
||||
return
|
||||
}
|
||||
fetch('/api/database/', {
|
||||
fetch('/api/data/', {
|
||||
method: "POST",
|
||||
body: JSON.stringify({
|
||||
database_name: newDatabase.name,
|
||||
@ -163,7 +163,7 @@ const navigateToGraph = () => {
|
||||
|
||||
// const loadGraph = () => {
|
||||
// graphloading.value = true
|
||||
// fetch('/api/database/graph', {
|
||||
// fetch('/api/data/graph', {
|
||||
// method: "GET",
|
||||
// })
|
||||
// .then(response => response.json())
|
||||
|
||||
@ -59,7 +59,7 @@
|
||||
:fileList="fileList"
|
||||
:max-count="1"
|
||||
:disabled="state.precessing"
|
||||
action="/api/database/upload"
|
||||
action="/api/data/upload"
|
||||
@change="handleFileUpload"
|
||||
@drop="handleDrop"
|
||||
>
|
||||
@ -106,7 +106,7 @@ const state = reactive({
|
||||
|
||||
const loadGraphInfo = () => {
|
||||
state.loadingGraphInfo = true
|
||||
fetch('/api/database/graph', {
|
||||
fetch('/api/data/graph', {
|
||||
method: "GET",
|
||||
})
|
||||
.then(response => response.json())
|
||||
@ -147,7 +147,7 @@ const getGraphData = () => {
|
||||
const addDocumentByFile = () => {
|
||||
state.precessing = true
|
||||
const files = fileList.value.filter(file => file.status === 'done').map(file => file.response.file_path)
|
||||
fetch('/api/database/graph/add', {
|
||||
fetch('/api/data/graph/add', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
file_path: files[0]
|
||||
@ -166,7 +166,7 @@ const addDocumentByFile = () => {
|
||||
|
||||
const loadSampleNodes = () => {
|
||||
state.fetching = true
|
||||
fetch(`/api/database/graph/nodes?kgdb_name=neo4j&num=${sampleNodeCount.value}`)
|
||||
fetch(`/api/data/graph/nodes?kgdb_name=neo4j&num=${sampleNodeCount.value}`)
|
||||
.then((res) => {
|
||||
if (res.ok) {
|
||||
return res.json();
|
||||
@ -199,7 +199,7 @@ const onSearch = () => {
|
||||
}
|
||||
|
||||
state.searchLoading = true
|
||||
fetch(`/api/database/graph/node?entity_name=${state.searchInput}`)
|
||||
fetch(`/api/data/graph/node?entity_name=${state.searchInput}`)
|
||||
.then((res) => {
|
||||
if (!res.ok) {
|
||||
return res.json().then(errorData => {
|
||||
|
||||
@ -31,7 +31,7 @@ import HeaderComponent from '@/components/HeaderComponent.vue';
|
||||
const router = useRouter();
|
||||
const tools = ref([]);
|
||||
const iconMap = ref({
|
||||
"text_chunking": FileSearchOutlined
|
||||
"text-chunking": FileSearchOutlined
|
||||
})
|
||||
|
||||
const state = reactive({
|
||||
@ -40,7 +40,7 @@ const state = reactive({
|
||||
|
||||
const getTools = () => {
|
||||
state.loadingTools = true
|
||||
fetch('/api/tools/')
|
||||
fetch('/api/tool/')
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
tools.value = data;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user