mirror of
https://github.com/xinnan-tech/xiaozhi-esp32-server.git
synced 2026-07-22 07:03:53 +08:00
update:优化空密钥的提示提示方式
This commit is contained in:
@@ -23,7 +23,9 @@ class LLMProvider(LLMProviderBase):
|
||||
self.bot_id = str(config.get("bot_id"))
|
||||
self.user_id = str(config.get("user_id"))
|
||||
self.session_conversation_map = {} # 存储session_id和conversation_id的映射
|
||||
check_model_key("CozeLLM", self.personal_access_token)
|
||||
model_key_msg = check_model_key("CozeLLM", self.personal_access_token)
|
||||
if model_key_msg:
|
||||
logger.bind(tag=TAG).error(model_key_msg)
|
||||
|
||||
def response(self, session_id, dialogue, **kwargs):
|
||||
coze_api_token = self.personal_access_token
|
||||
|
||||
@@ -15,7 +15,9 @@ class LLMProvider(LLMProviderBase):
|
||||
self.mode = config.get("mode", "chat-messages")
|
||||
self.base_url = config.get("base_url", "https://api.dify.ai/v1").rstrip("/")
|
||||
self.session_conversation_map = {} # 存储session_id和conversation_id的映射
|
||||
check_model_key("DifyLLM", self.api_key)
|
||||
model_key_msg = check_model_key("DifyLLM", self.api_key)
|
||||
if model_key_msg:
|
||||
logger.bind(tag=TAG).error(model_key_msg)
|
||||
|
||||
def response(self, session_id, dialogue, **kwargs):
|
||||
try:
|
||||
|
||||
@@ -14,7 +14,9 @@ class LLMProvider(LLMProviderBase):
|
||||
self.base_url = config.get("base_url")
|
||||
self.detail = config.get("detail", False)
|
||||
self.variables = config.get("variables", {})
|
||||
check_model_key("FastGPTLLM", self.api_key)
|
||||
model_key_msg = check_model_key("FastGPTLLM", self.api_key)
|
||||
if model_key_msg:
|
||||
logger.bind(tag=TAG).error(model_key_msg)
|
||||
|
||||
def response(self, session_id, dialogue, **kwargs):
|
||||
try:
|
||||
|
||||
@@ -73,8 +73,9 @@ class LLMProvider(LLMProviderBase):
|
||||
http_proxy = cfg.get("http_proxy")
|
||||
https_proxy = cfg.get("https_proxy")
|
||||
|
||||
if not check_model_key("LLM", self.api_key):
|
||||
raise ValueError("无效的Gemini API Key,请检查是否配置正确")
|
||||
model_key_msg = check_model_key("LLM", self.api_key)
|
||||
if model_key_msg:
|
||||
log.bind(tag=TAG).error(model_key_msg)
|
||||
|
||||
if http_proxy or https_proxy:
|
||||
log.bind(tag=TAG).info(
|
||||
|
||||
@@ -21,20 +21,27 @@ class LLMProvider(LLMProviderBase):
|
||||
"max_tokens": (500, int),
|
||||
"temperature": (0.7, lambda x: round(float(x), 1)),
|
||||
"top_p": (1.0, lambda x: round(float(x), 1)),
|
||||
"frequency_penalty": (0, lambda x: round(float(x), 1))
|
||||
"frequency_penalty": (0, lambda x: round(float(x), 1)),
|
||||
}
|
||||
|
||||
for param, (default, converter) in param_defaults.items():
|
||||
value = config.get(param)
|
||||
try:
|
||||
setattr(self, param, converter(value) if value not in (None, "") else default)
|
||||
setattr(
|
||||
self,
|
||||
param,
|
||||
converter(value) if value not in (None, "") else default,
|
||||
)
|
||||
except (ValueError, TypeError):
|
||||
setattr(self, param, default)
|
||||
|
||||
logger.debug(
|
||||
f"意图识别参数初始化: {self.temperature}, {self.max_tokens}, {self.top_p}, {self.frequency_penalty}")
|
||||
f"意图识别参数初始化: {self.temperature}, {self.max_tokens}, {self.top_p}, {self.frequency_penalty}"
|
||||
)
|
||||
|
||||
check_model_key("LLM", self.api_key)
|
||||
model_key_msg = check_model_key("LLM", self.api_key)
|
||||
if model_key_msg:
|
||||
logger.bind(tag=TAG).error(model_key_msg)
|
||||
self.client = openai.OpenAI(api_key=self.api_key, base_url=self.base_url)
|
||||
|
||||
def response(self, session_id, dialogue, **kwargs):
|
||||
@@ -46,7 +53,9 @@ class LLMProvider(LLMProviderBase):
|
||||
max_tokens=kwargs.get("max_tokens", self.max_tokens),
|
||||
temperature=kwargs.get("temperature", self.temperature),
|
||||
top_p=kwargs.get("top_p", self.top_p),
|
||||
frequency_penalty=kwargs.get("frequency_penalty", self.frequency_penalty),
|
||||
frequency_penalty=kwargs.get(
|
||||
"frequency_penalty", self.frequency_penalty
|
||||
),
|
||||
)
|
||||
|
||||
is_active = True
|
||||
@@ -84,12 +93,14 @@ class LLMProvider(LLMProviderBase):
|
||||
for chunk in stream:
|
||||
# 检查是否存在有效的choice且content不为空
|
||||
if getattr(chunk, "choices", None):
|
||||
yield chunk.choices[0].delta.content, chunk.choices[0].delta.tool_calls
|
||||
yield chunk.choices[0].delta.content, chunk.choices[
|
||||
0
|
||||
].delta.tool_calls
|
||||
# 存在 CompletionUsage 消息时,生成 Token 消耗 log
|
||||
elif isinstance(getattr(chunk, 'usage', None), CompletionUsage):
|
||||
usage_info = getattr(chunk, 'usage', None)
|
||||
elif isinstance(getattr(chunk, "usage", None), CompletionUsage):
|
||||
usage_info = getattr(chunk, "usage", None)
|
||||
logger.bind(tag=TAG).info(
|
||||
f"Token 消耗:输入 {getattr(usage_info, 'prompt_tokens', '未知')},"
|
||||
f"Token 消耗:输入 {getattr(usage_info, 'prompt_tokens', '未知')},"
|
||||
f"输出 {getattr(usage_info, 'completion_tokens', '未知')},"
|
||||
f"共计 {getattr(usage_info, 'total_tokens', '未知')}"
|
||||
)
|
||||
|
||||
@@ -12,12 +12,14 @@ class MemoryProvider(MemoryProviderBase):
|
||||
super().__init__(config)
|
||||
self.api_key = config.get("api_key", "")
|
||||
self.api_version = config.get("api_version", "v1.1")
|
||||
have_key = check_model_key("Mem0ai", self.api_key)
|
||||
if not have_key:
|
||||
model_key_msg = check_model_key("Mem0ai", self.api_key)
|
||||
if model_key_msg:
|
||||
logger.bind(tag=TAG).error(model_key_msg)
|
||||
self.use_mem0 = False
|
||||
return
|
||||
else:
|
||||
self.use_mem0 = True
|
||||
|
||||
try:
|
||||
self.client = MemoryClient(api_key=self.api_key)
|
||||
logger.bind(tag=TAG).info("成功连接到 Mem0ai 服务")
|
||||
|
||||
@@ -37,7 +37,9 @@ class TTSProvider(TTSProviderBase):
|
||||
self.api_url = config.get("api_url")
|
||||
self.authorization = config.get("authorization")
|
||||
self.header = {"Authorization": f"{self.authorization}{self.access_token}"}
|
||||
check_model_key("TTS", self.access_token)
|
||||
model_key_msg = check_model_key("TTS", self.access_token)
|
||||
if model_key_msg:
|
||||
logger.bind(tag=TAG).error(model_key_msg)
|
||||
|
||||
async def text_to_speak(self, text, output_file):
|
||||
request_json = {
|
||||
|
||||
@@ -90,8 +90,9 @@ class TTSProvider(TTSProviderBase):
|
||||
self.format = config.get("response_format", "wav")
|
||||
self.audio_file_type = config.get("response_format", "wav")
|
||||
self.api_key = config.get("api_key", "YOUR_API_KEY")
|
||||
have_key = check_model_key("FishSpeech TTS", self.api_key)
|
||||
if not have_key:
|
||||
model_key_msg = check_model_key("FishSpeech TTS", self.api_key)
|
||||
if model_key_msg:
|
||||
logger.bind(tag=TAG).error(model_key_msg)
|
||||
return
|
||||
self.normalize = str(config.get("normalize", True)).lower() in (
|
||||
"true",
|
||||
|
||||
@@ -157,7 +157,9 @@ class TTSProvider(TTSProviderBase):
|
||||
self.opus_encoder = opus_encoder_utils.OpusEncoderUtils(
|
||||
sample_rate=16000, channels=1, frame_size_ms=60
|
||||
)
|
||||
check_model_key("TTS", self.access_token)
|
||||
model_key_msg = check_model_key("TTS", self.access_token)
|
||||
if model_key_msg:
|
||||
logger.bind(tag=TAG).error(model_key_msg)
|
||||
|
||||
async def open_audio_channels(self, conn):
|
||||
try:
|
||||
@@ -267,7 +269,7 @@ class TTSProvider(TTSProviderBase):
|
||||
await handleAbortMessage(self.conn)
|
||||
logger.bind(tag=TAG).error(f"WebSocket连接不存在,终止发送文本")
|
||||
return
|
||||
|
||||
|
||||
# 过滤Markdown
|
||||
filtered_text = MarkdownCleaner.clean_markdown(text)
|
||||
|
||||
|
||||
@@ -166,7 +166,9 @@ class TTSProvider(TTSProviderBase):
|
||||
) as resp:
|
||||
|
||||
if resp.status != 200:
|
||||
logger.error(f"TTS请求失败: {resp.status}, {await resp.text()}")
|
||||
logger.bind(tag=TAG).error(
|
||||
f"TTS请求失败: {resp.status}, {await resp.text()}"
|
||||
)
|
||||
self.tts_audio_queue.put((SentenceType.LAST, [], None))
|
||||
return
|
||||
|
||||
@@ -229,7 +231,7 @@ class TTSProvider(TTSProviderBase):
|
||||
self._process_before_stop_play_files()
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"TTS请求异常: {e}")
|
||||
logger.bind(tag=TAG).error(f"TTS请求异常: {e}")
|
||||
self.tts_audio_queue.put((SentenceType.LAST, [], None))
|
||||
|
||||
def to_tts(self, text: str) -> list:
|
||||
@@ -263,7 +265,7 @@ class TTSProvider(TTSProviderBase):
|
||||
self.api_url, params=params, headers=headers, timeout=5
|
||||
) as response:
|
||||
if response.status_code != 200:
|
||||
logger.error(
|
||||
logger.bind(tag=TAG).error(
|
||||
f"TTS请求失败: {response.status_code}, {response.text}"
|
||||
)
|
||||
return []
|
||||
@@ -299,5 +301,5 @@ class TTSProvider(TTSProviderBase):
|
||||
return opus_datas
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"TTS请求异常: {e}")
|
||||
logger.bind(tag=TAG).error(f"TTS请求异常: {e}")
|
||||
return []
|
||||
|
||||
@@ -25,7 +25,9 @@ class TTSProvider(TTSProviderBase):
|
||||
self.speed = float(speed) if speed else 1.0
|
||||
|
||||
self.output_file = config.get("output_dir", "tmp/")
|
||||
check_model_key("TTS", self.api_key)
|
||||
model_key_msg = check_model_key("TTS", self.api_key)
|
||||
if model_key_msg:
|
||||
logger.bind(tag=TAG).error(model_key_msg)
|
||||
|
||||
async def text_to_speak(self, text, output_file):
|
||||
headers = {
|
||||
|
||||
@@ -34,7 +34,9 @@ class VLLMProvider(VLLMProviderBase):
|
||||
except (ValueError, TypeError):
|
||||
setattr(self, param, default)
|
||||
|
||||
check_model_key("VLLM", self.api_key)
|
||||
model_key_msg = check_model_key("VLLM", self.api_key)
|
||||
if model_key_msg:
|
||||
logger.bind(tag=TAG).error(model_key_msg)
|
||||
self.client = openai.OpenAI(api_key=self.api_key, base_url=self.base_url)
|
||||
|
||||
def response(self, question, base64_image):
|
||||
|
||||
@@ -186,10 +186,8 @@ def remove_punctuation_and_length(text):
|
||||
|
||||
def check_model_key(modelType, modelKey):
|
||||
if "你" in modelKey:
|
||||
raise ValueError(
|
||||
"你还没配置" + modelType + "的密钥,请检查一下所使用的LLM是否配置了密钥"
|
||||
)
|
||||
return True
|
||||
return f"配置错误: {modelType} 的 API key 未设置,当前值为: {modelKey}"
|
||||
return None
|
||||
|
||||
|
||||
def parse_string_to_list(value, separator=";"):
|
||||
@@ -785,7 +783,9 @@ def audio_bytes_to_data(audio_bytes, file_type, is_opus=True):
|
||||
return p3.decode_opus_from_bytes(audio_bytes)
|
||||
else:
|
||||
# 其他格式用pydub
|
||||
audio = AudioSegment.from_file(BytesIO(audio_bytes), format=file_type, parameters=["-nostdin"])
|
||||
audio = AudioSegment.from_file(
|
||||
BytesIO(audio_bytes), format=file_type, parameters=["-nostdin"]
|
||||
)
|
||||
audio = audio.set_channels(1).set_frame_rate(16000).set_sample_width(2)
|
||||
duration = len(audio) / 1000.0
|
||||
raw_data = audio.raw_data
|
||||
@@ -838,11 +838,11 @@ def opus_datas_to_wav_bytes(opus_datas, sample_rate=16000, channels=1):
|
||||
pcm = decoder.decode(opus_frame, frame_size)
|
||||
pcm_datas.append(pcm)
|
||||
|
||||
pcm_bytes = b''.join(pcm_datas)
|
||||
pcm_bytes = b"".join(pcm_datas)
|
||||
|
||||
# 写入wav字节流
|
||||
wav_buffer = BytesIO()
|
||||
with wave.open(wav_buffer, 'wb') as wf:
|
||||
with wave.open(wav_buffer, "wb") as wf:
|
||||
wf.setnchannels(channels)
|
||||
wf.setsampwidth(2) # 16bit
|
||||
wf.setframerate(sample_rate)
|
||||
|
||||
@@ -10,9 +10,17 @@ def append_devices_to_prompt(conn):
|
||||
funcs = conn.config["Intent"][conn.config["selected_module"]["Intent"]].get(
|
||||
"functions", []
|
||||
)
|
||||
|
||||
config_source = (
|
||||
"home_assistant"
|
||||
if conn.config["plugins"].get("home_assistant")
|
||||
else "hass_get_state"
|
||||
)
|
||||
|
||||
if "hass_get_state" in funcs or "hass_set_state" in funcs:
|
||||
prompt = "\n下面是我家智能设备列表(位置,设备名,entity_id),可以通过homeassistant控制\n"
|
||||
devices = conn.config["plugins"]["home_assistant"].get("devices", [])
|
||||
# TODO 分割被控设备
|
||||
devices = conn.config["plugins"].get(config_source, {}).get("devices", [])
|
||||
if len(devices) == 0:
|
||||
return
|
||||
for device in devices:
|
||||
@@ -24,21 +32,26 @@ def append_devices_to_prompt(conn):
|
||||
|
||||
def initialize_hass_handler(conn):
|
||||
ha_config = {}
|
||||
if conn.load_function_plugin:
|
||||
if conn.config["plugins"].get("home_assistant"):
|
||||
ha_config["base_url"] = conn.config["plugins"]["home_assistant"].get(
|
||||
"base_url"
|
||||
)
|
||||
ha_config["api_key"] = conn.config["plugins"]["home_assistant"].get(
|
||||
"api_key"
|
||||
)
|
||||
check_model_key("home_assistant", ha_config.get("api_key"))
|
||||
elif conn.config["plugins"].get("hass_get_state"):
|
||||
ha_config["base_url"] = conn.config["plugins"]["hass_get_state"].get(
|
||||
"base_url"
|
||||
)
|
||||
ha_config["api_key"] = conn.config["plugins"]["hass_get_state"].get(
|
||||
"api_key"
|
||||
)
|
||||
check_model_key("home_assistant", ha_config.get("api_key"))
|
||||
if not conn.load_function_plugin:
|
||||
return ha_config
|
||||
|
||||
# 确定配置来源
|
||||
config_source = (
|
||||
"home_assistant"
|
||||
if conn.config["plugins"].get("home_assistant")
|
||||
else "hass_get_state"
|
||||
)
|
||||
if not conn.config["plugins"].get(config_source):
|
||||
return ha_config
|
||||
|
||||
# 统一获取配置
|
||||
plugin_config = conn.config["plugins"][config_source]
|
||||
ha_config["base_url"] = plugin_config.get("base_url")
|
||||
ha_config["api_key"] = plugin_config.get("api_key")
|
||||
|
||||
# 统一检查API密钥
|
||||
model_key_msg = check_model_key("home_assistant", ha_config.get("api_key"))
|
||||
if model_key_msg:
|
||||
logger.bind(tag=TAG).error(model_key_msg)
|
||||
|
||||
return ha_config
|
||||
|
||||
Reference in New Issue
Block a user