mirror of
https://github.com/xszyou/Fay.git
synced 2026-11-04 23:31:50 +08:00
1、支持mcp sse服务管理及动态功具调用 --对摩搭社区提供的sse对接的mcp工具做过兼容测试 2、llm模块统一 --严格匹配openai兼容接口范式,包括token计算及流式控制等 --把认知模式作为llm对接的方式,并对认知模型进行了优化升级,可控制各用户聊天认知是否隔离 --使用qwen3-4b作为默认llm,可以平衡速度、角色模拟与MCP工具调用 3、提供配置管理中心,便于多个fay做配置管理 --当根目录中system.conf或config.json不存在,启动时会自动载入config_uitl.py中指定的配置 --配置中心代码支持多项目管理,单项目也支持多fay对接,源码地址:https://github.com/xszyou/fay_config_server 4、多个bug修复 --修复重复反思和重复保存的问题 --修正认知模型的反思和检索算法 --处理pygame报错程序不继续执行问题 --表情不进行tts --运行时再判断加载qt5 --修复文字交互接口流式输出时不会结束问题 --修复文字交互接口流式输出qa不输出问题
123 lines
4.5 KiB
Python
123 lines
4.5 KiB
Python
import threading
|
|
import time
|
|
from utils import stream_sentence
|
|
from scheduler.thread_manager import MyThread
|
|
import fay_booter
|
|
from core import member_db
|
|
from core.interact import Interact
|
|
|
|
# 全局变量,用于存储StreamManager的单例实例
|
|
__streams = None
|
|
# 线程锁,用于保护全局变量的访问
|
|
__streams_lock = threading.Lock()
|
|
|
|
def new_instance(max_sentences=1024):
|
|
"""
|
|
创建并返回StreamManager的单例实例
|
|
:param max_sentences: 最大句子缓存数量
|
|
:return: StreamManager实例
|
|
"""
|
|
global __streams
|
|
with __streams_lock:
|
|
if __streams is None:
|
|
__streams = StreamManager(max_sentences)
|
|
return __streams
|
|
|
|
class StreamManager:
|
|
"""
|
|
流管理器类,用于管理和处理文本流数据
|
|
"""
|
|
def __init__(self, max_sentences=3):
|
|
"""
|
|
初始化StreamManager
|
|
:param max_sentences: 每个流的最大句子缓存数量
|
|
"""
|
|
if hasattr(self, '_initialized') and self._initialized:
|
|
return
|
|
self.lock = threading.Lock() # 线程锁,用于保护streams字典的访问
|
|
self.streams = {} # 存储用户ID到句子缓存的映射
|
|
self.nlp_streams = {} # 存储用户ID到句子缓存的映射
|
|
self.max_sentences = max_sentences # 最大句子缓存数量
|
|
self.listener_threads = {} # 存储用户ID到监听线程的映射
|
|
self.running = True # 控制监听线程的运行状态
|
|
self._initialized = True # 标记是否已初始化
|
|
self.msgid = "" # 消息ID
|
|
|
|
def get_Stream(self, username):
|
|
"""
|
|
获取指定用户ID的文本流,如果不存在则创建新的
|
|
:param username: 用户名
|
|
:return: 对应的句子缓存对象
|
|
"""
|
|
need_start_thread = False
|
|
stream = None
|
|
nlp_stream = None
|
|
|
|
with self.lock:
|
|
if username not in self.streams or username not in self.nlp_streams:
|
|
self.streams[username] = stream_sentence.SentenceCache(self.max_sentences)
|
|
self.nlp_streams[username] = stream_sentence.SentenceCache(self.max_sentences)
|
|
need_start_thread = True
|
|
stream = self.streams[username]
|
|
nlp_stream = self.nlp_streams[username]
|
|
|
|
if need_start_thread:
|
|
thread = MyThread(target=self.listen, args=(username, stream, nlp_stream), daemon=True)
|
|
self.listener_threads[username] = thread
|
|
thread.start()
|
|
else:
|
|
stream = self.streams[username]
|
|
nlp_stream = self.nlp_streams[username]
|
|
|
|
return stream, nlp_stream
|
|
|
|
def write_sentence(self, username, sentence):
|
|
"""
|
|
写入句子到指定用户的文本流
|
|
:param username: 用户名
|
|
:param sentence: 要写入的句子
|
|
:return: 写入是否成功
|
|
"""
|
|
if sentence.endswith('_<isfirst>'):
|
|
self.clear_Stream(username)
|
|
Stream, nlp_Stream = self.get_Stream(username)
|
|
success = Stream.write(sentence)
|
|
nlp_success = nlp_Stream.write(sentence)
|
|
return success and nlp_success
|
|
|
|
def clear_Stream(self, username):
|
|
"""
|
|
清除指定用户ID的文本流数据
|
|
:param username: 用户名
|
|
"""
|
|
with self.lock:
|
|
if username in self.streams:
|
|
self.streams[username].clear()
|
|
if username in self.nlp_streams:
|
|
self.nlp_streams[username].clear()
|
|
|
|
def listen(self, username, stream, nlp_stream):
|
|
while self.running:
|
|
sentence = stream.read()
|
|
if sentence:
|
|
self.execute(username, sentence)
|
|
else:
|
|
time.sleep(0.1)
|
|
|
|
def execute(self, username, sentence):
|
|
"""
|
|
执行句子处理逻辑
|
|
:param username: 用户名
|
|
:param sentence: 要处理的句子
|
|
"""
|
|
fay_core = fay_booter.feiFei
|
|
# 处理普通消息,区分是否是会话的第一句
|
|
|
|
is_first = "_<isfirst>" in sentence
|
|
is_end = "_<isend>" in sentence
|
|
sentence = sentence.replace("_<isfirst>", "").replace("_<isend>", "")
|
|
|
|
if sentence or is_first or is_end :
|
|
interact = Interact("stream", 1, {"user": username, "msg": sentence, "isfirst" : is_first, "isend" : is_end})
|
|
fay_core.say(interact, sentence) # 调用核心处理模块进行响应
|
|
time.sleep(0.01) # 短暂休眠以控制处理频率 |