chenpei d0dc94e36d feat: 将弹幕功能替换为AI聊天助手
新功能:
- 创建AI聊天助手组件(AIChatWidget)
- 支持文字+图片多模态对话
- 集成Gemini AI API
- 支持图片编辑和内容生成
- 实时对话历史管理
- 优雅的UI设计,支持黑夜模式

技术实现:
- 后端API代理Gemini API(/api/ai-chat)
- 支持最多5张图片上传
- 流式响应处理
- 对话历史管理
- Base64图片处理

配置:
- 在.env中添加Gemini API配置
- GEMINI_API_KEY
- GEMINI_API_BASE_URL
- GEMINI_MODEL

替换原弹幕功能,提供更强大的AI助手体验!
2025-10-27 17:45:37 +08:00

197 lines
10 KiB
Python
Executable File

# coding:utf-8
from .common import Field
import json
from .Doc import Doc
from .Point import Point
class Collection(object):
"""
KnowledgeBase Collection
"""
def __init__(self, viking_knowledgebase_service, collection_name, kwargs=None):
self.viking_knowledgebase_service = viking_knowledgebase_service
self.collection_name = collection_name
if kwargs is not None:
self.description = kwargs.get("description")
self.doc_num = kwargs.get("doc_num")
self.create_time = kwargs.get("create_time")
self.update_time = kwargs.get("update_time")
self.creator = kwargs.get("creator")
self.pipeline_list = kwargs.get("pipeline_list")
self.preprocessing = kwargs.get("preprocessing")
self.fields = [Field(field) for field in kwargs.get("fields", [])]
self.project = kwargs.get("project")
self.resource_id = kwargs.get("resource_id")
self.data_type = kwargs.get("data_type", "")
def add_doc(self, add_type, doc_id=None, doc_name=None, doc_type=None, tos_path=None, url=None, meta=None, project="default", resource_id=None, collection_name=None):
params = {"collection_name": self.collection_name, "add_type": add_type, "project":project}
if resource_id is not None:
params["resource_id"] = resource_id
if collection_name is not None:
params["collection_name"] = collection_name
if add_type == "tos" :
params["tos_path"] = tos_path
elif add_type == "url" :
params["doc_id"] = doc_id
params["doc_name"] = doc_name
params["doc_type"] = doc_type
params["url"] = url
if meta is not None:
params["meta"] = meta
self.viking_knowledgebase_service.json_exception("AddDoc", {}, json.dumps(params))
async def async_add_doc(self, add_type, doc_id=None, doc_name=None, doc_type=None, tos_path=None, url=None, meta=None, project="default", resource_id=None, collection_name=None):
params = {"collection_name": self.collection_name, "add_type": add_type, "project":project}
if resource_id is not None:
params["resource_id"] = resource_id
if collection_name is not None:
params["collection_name"] = collection_name
if add_type == "tos" :
params["tos_path"] = tos_path
elif add_type == "url" :
params["doc_id"] = doc_id
params["doc_name"] = doc_name
params["doc_type"] = doc_type
params["url"] = url
if meta != None:
params["meta"] = meta
await self.viking_knowledgebase_service.async_json_exception("AddDoc", {}, json.dumps(params))
def delete_doc(self, doc_id, project="default", resource_id=None, collection_name=None):
params = {"collection_name": self.collection_name, "doc_id": doc_id, "project":project}
if resource_id is not None:
params["resource_id"] = resource_id
if collection_name is not None:
params["collection_name"] = collection_name
self.viking_knowledgebase_service.json_exception("DeleteDoc", {}, json.dumps(params))
async def async_delete_doc(self, doc_id, project="default", resource_id=None, collection_name=None):
params = {"collection_name": self.collection_name, "doc_id": doc_id, "project":project}
if resource_id is not None:
params["resource_id"] = resource_id
if collection_name is not None:
params["collection_name"] = collection_name
await self.viking_knowledgebase_service.async_json_exception("DeleteDoc", {}, json.dumps(params))
def get_doc(self, doc_id, project="default", resource_id=None, collection_name=None):
params = {"collection_name": self.collection_name, "doc_id": doc_id, "project":project}
if resource_id is not None:
params["resource_id"] = resource_id
if collection_name is not None:
params["collection_name"] = collection_name
res = self.viking_knowledgebase_service.json_exception("GetDocInfo", {}, json.dumps(params))
data = json.loads(res)["data"]
data['project'] = project
if resource_id is not None :
data['resource_id'] = resource_id
return Doc(data)
async def async_get_doc(self, doc_id, project="default", resource_id=None, collection_name=None):
params = {"collection_name": self.collection_name, "doc_id": doc_id, "project":project}
if resource_id is not None:
params["resource_id"] = resource_id
if collection_name is not None:
params["collection_name"] = collection_name
res = await self.viking_knowledgebase_service.async_json_exception("GetDocInfo", {}, json.dumps(params))
data = json.loads(res)["data"]
data['project'] = project
if resource_id is not None :
data['resource_id'] = resource_id
return Doc(data)
def list_docs(self, offset=0, limit=-1, doc_type=None, project="default", collection_name=None):
params = {"collection_name": self.collection_name, "offset": offset, "limit": limit, "doc_type": doc_type, "project":project}
if collection_name is not None:
params["collection_name"] = collection_name
res = self.viking_knowledgebase_service.json_exception("ListDocs", {}, json.dumps(params))
data = json.loads(res)["data"]
docs = []
for item in data["doc_list"]:
item['project'] = project
docs.append(Doc(item))
return docs
async def async_list_docs(self, offset=0, limit=-1, doc_type=None, project="default", collection_name=None):
params = {"collection_name": self.collection_name, "offset": offset, "limit": limit, "doc_type": doc_type, "project":project}
if collection_name is not None:
params["collection_name"] = collection_name
res = await self.viking_knowledgebase_service.async_json_exception("ListDocs", {}, json.dumps(params))
data = json.loads(res)["data"]
docs = []
for item in data["doc_list"]:
item['project'] = project
docs.append(Doc(item))
return docs
def update_meta(self, doc_id, meta, project="default", resource_id=None, collection_name=None):
params = {"collection_name": self.collection_name, "doc_id": doc_id, "meta": meta, "project":project}
if collection_name is not None:
params["collection_name"] = collection_name
if resource_id is not None:
params["resource_id"] = resource_id
self.viking_knowledgebase_service.json_exception("UpdateDocMeta", {}, json.dumps(params))
async def async_update_meta(self, doc_id, meta, project="default", resource_id=None, collection_name=None):
params = {"collection_name": self.collection_name, "doc_id": doc_id, "meta": meta, "project":project}
if collection_name is not None:
params["collection_name"] = collection_name
if resource_id is not None:
params["resource_id"] = resource_id
await self.viking_knowledgebase_service.async_json_exception("UpdateDocMeta", {}, json.dumps(params))
def get_point(self, point_id, project="default", resource_id=None, collection_name=None):
params = {"collection_name": self.collection_name, "point_id": point_id, "project":project}
if collection_name is not None:
params["collection_name"] = collection_name
if resource_id is not None:
params["resource_id"] = resource_id
res = self.viking_knowledgebase_service.json_exception("GetPointInfo", {}, json.dumps(params))
res = json.loads(res)
res["data"]["project"] = project
if resource_id is not None :
res["data"]["resource_id"] = resource_id
return Point(res["data"])
async def async_get_point(self, point_id, project="default", resource_id=None, collection_name=None):
params = {"collection_name": self.collection_name, "point_id": point_id, "project":project}
if collection_name is not None:
params["collection_name"] = collection_name
if resource_id is not None:
params["resource_id"] = resource_id
res = await self.viking_knowledgebase_service.async_json_exception("GetPointInfo", {}, json.dumps(params))
res = json.loads(res)
res["data"]["project"] = project
if resource_id is not None :
res["data"]["resource_id"] = resource_id
return Point(res["data"])
def list_points(self, offset=0, limit=-1, doc_ids=None, project="default", resource_id=None, collection_name=None):
params = {"collection_name": self.collection_name, "offset": offset, "limit": limit, "doc_ids": doc_ids, "project":project}
if collection_name is not None:
params["collection_name"] = collection_name
if resource_id is not None:
params["resource_id"] = resource_id
res = self.viking_knowledgebase_service.json_exception("ListPoints", {}, json.dumps(params))
point_list = json.loads(res)["data"].get("point_list", [])
points = []
for item in point_list:
item["project"] = project
points.append(Point(item))
return points
async def async_list_points(self, offset=0, limit=-1, doc_ids=None, project="default", resource_id=None, collection_name=None):
params = {"collection_name": self.collection_name, "offset": offset, "limit": limit, "doc_ids": doc_ids, "project":project}
if collection_name is not None:
params["collection_name"] = collection_name
if resource_id is not None:
params["resource_id"] = resource_id
res = await self.viking_knowledgebase_service.async_json_exception("ListPoints", {}, json.dumps(params))
point_list = json.loads(res)["data"].get("point_list", [])
points = []
for item in point_list:
item["project"] = project
points.append(Point(item))
return points