mirror of
https://github.com/xinnan-tech/xiaozhi-esp32-server.git
synced 2026-07-26 00:53:54 +08:00
@@ -105,8 +105,7 @@ async def no_voice_close_connect(conn):
|
|||||||
return
|
return
|
||||||
prompt = end_prompt.get("prompt")
|
prompt = end_prompt.get("prompt")
|
||||||
if not prompt:
|
if not prompt:
|
||||||
conn.logger.bind(tag=TAG).warn("开启结束对话提示词功能,但未配置结束提示语!请确认配置文件end_prompt字段下是否包含prompt属性!")
|
prompt = "请你以“时间过得真快”未来头,用富有感情、依依不舍的话来结束这场对话吧。!"
|
||||||
prompt = '请你以“时间过得真快”未来头,用富有感情、依依不舍的话来结束这场对话吧。!'
|
|
||||||
await startToChat(conn, prompt)
|
await startToChat(conn, prompt)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ class ASRProvider(ASRProviderBase):
|
|||||||
) -> Tuple[Optional[str], Optional[str]]:
|
) -> Tuple[Optional[str], Optional[str]]:
|
||||||
"""将语音数据转换为文本"""
|
"""将语音数据转换为文本"""
|
||||||
if not opus_data:
|
if not opus_data:
|
||||||
logger.bind(tag=TAG).warn("音频数据为空!")
|
logger.bind(tag=TAG).warning("音频数据为空!")
|
||||||
return None, None
|
return None, None
|
||||||
|
|
||||||
file_path = None
|
file_path = None
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ class ASRProvider(ASRProviderBase):
|
|||||||
) -> Tuple[Optional[str], Optional[str]]:
|
) -> Tuple[Optional[str], Optional[str]]:
|
||||||
"""将语音数据转换为文本"""
|
"""将语音数据转换为文本"""
|
||||||
if not opus_data:
|
if not opus_data:
|
||||||
logger.bind(tag=TAG).warn("音频数据为空!")
|
logger.bind(tag=TAG).warning("音频数据为空!")
|
||||||
return None, None
|
return None, None
|
||||||
|
|
||||||
file_path = None
|
file_path = None
|
||||||
@@ -230,7 +230,7 @@ class ASRProvider(ASRProviderBase):
|
|||||||
if "Response" in response_json and "Result" in response_json["Response"]:
|
if "Response" in response_json and "Result" in response_json["Response"]:
|
||||||
return response_json["Response"]["Result"]
|
return response_json["Response"]["Result"]
|
||||||
else:
|
else:
|
||||||
logger.bind(tag=TAG).warn(f"响应中没有识别结果: {response_json}")
|
logger.bind(tag=TAG).warning(f"响应中没有识别结果: {response_json}")
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ def setup_proxy_env(http_proxy: str | None, https_proxy: str | None):
|
|||||||
os.environ["HTTP_PROXY"] = http_proxy
|
os.environ["HTTP_PROXY"] = http_proxy
|
||||||
log.bind(tag=TAG).info(f"配置提供的Gemini HTTPS代理连通成功: {http_proxy}")
|
log.bind(tag=TAG).info(f"配置提供的Gemini HTTPS代理连通成功: {http_proxy}")
|
||||||
else:
|
else:
|
||||||
log.bind(tag=TAG).warn(f"配置提供的Gemini HTTP代理不可用: {http_proxy}")
|
log.bind(tag=TAG).warning(f"配置提供的Gemini HTTP代理不可用: {http_proxy}")
|
||||||
|
|
||||||
if https_proxy:
|
if https_proxy:
|
||||||
ok_https = test_proxy(https_proxy, test_https_url)
|
ok_https = test_proxy(https_proxy, test_https_url)
|
||||||
@@ -48,7 +48,9 @@ def setup_proxy_env(http_proxy: str | None, https_proxy: str | None):
|
|||||||
os.environ["HTTPS_PROXY"] = https_proxy
|
os.environ["HTTPS_PROXY"] = https_proxy
|
||||||
log.bind(tag=TAG).info(f"配置提供的Gemini HTTPS代理连通成功: {https_proxy}")
|
log.bind(tag=TAG).info(f"配置提供的Gemini HTTPS代理连通成功: {https_proxy}")
|
||||||
else:
|
else:
|
||||||
log.bind(tag=TAG).warning(f"配置提供的Gemini HTTPS代理不可用: {https_proxy}")
|
log.bind(tag=TAG).warning(
|
||||||
|
f"配置提供的Gemini HTTPS代理不可用: {https_proxy}"
|
||||||
|
)
|
||||||
|
|
||||||
# 如果https_proxy不可用,但http_proxy可用且能走通https,则复用http_proxy作为https_proxy
|
# 如果https_proxy不可用,但http_proxy可用且能走通https,则复用http_proxy作为https_proxy
|
||||||
if ok_http and not ok_https:
|
if ok_http and not ok_https:
|
||||||
@@ -58,7 +60,9 @@ def setup_proxy_env(http_proxy: str | None, https_proxy: str | None):
|
|||||||
log.bind(tag=TAG).info(f"复用HTTP代理作为HTTPS代理: {http_proxy}")
|
log.bind(tag=TAG).info(f"复用HTTP代理作为HTTPS代理: {http_proxy}")
|
||||||
|
|
||||||
if not ok_http and not ok_https:
|
if not ok_http and not ok_https:
|
||||||
log.bind(tag=TAG).error(f"Gemini 代理设置失败: HTTP 和 HTTPS 代理都不可用,请检查配置")
|
log.bind(tag=TAG).error(
|
||||||
|
f"Gemini 代理设置失败: HTTP 和 HTTPS 代理都不可用,请检查配置"
|
||||||
|
)
|
||||||
raise RuntimeError("HTTP 和 HTTPS 代理都不可用,请检查配置")
|
raise RuntimeError("HTTP 和 HTTPS 代理都不可用,请检查配置")
|
||||||
|
|
||||||
|
|
||||||
@@ -73,9 +77,13 @@ class LLMProvider(LLMProviderBase):
|
|||||||
raise ValueError("无效的Gemini API Key,请检查是否配置正确")
|
raise ValueError("无效的Gemini API Key,请检查是否配置正确")
|
||||||
|
|
||||||
if http_proxy or https_proxy:
|
if http_proxy or https_proxy:
|
||||||
log.bind(tag=TAG).info(f"检测到Gemini代理配置,开始测试代理连通性和设置代理环境...")
|
log.bind(tag=TAG).info(
|
||||||
|
f"检测到Gemini代理配置,开始测试代理连通性和设置代理环境..."
|
||||||
|
)
|
||||||
setup_proxy_env(http_proxy, https_proxy)
|
setup_proxy_env(http_proxy, https_proxy)
|
||||||
log.bind(tag=TAG).info(f"Gemini 代理设置成功 - HTTP: {http_proxy}, HTTPS: {https_proxy}")
|
log.bind(tag=TAG).info(
|
||||||
|
f"Gemini 代理设置成功 - HTTP: {http_proxy}, HTTPS: {https_proxy}"
|
||||||
|
)
|
||||||
genai.configure(api_key=self.api_key)
|
genai.configure(api_key=self.api_key)
|
||||||
self.model = genai.GenerativeModel(self.model_name)
|
self.model = genai.GenerativeModel(self.model_name)
|
||||||
|
|
||||||
@@ -90,14 +98,18 @@ class LLMProvider(LLMProviderBase):
|
|||||||
def _build_tools(funcs: List[Dict[str, Any]] | None):
|
def _build_tools(funcs: List[Dict[str, Any]] | None):
|
||||||
if not funcs:
|
if not funcs:
|
||||||
return None
|
return None
|
||||||
return [types.Tool(function_declarations=[
|
return [
|
||||||
types.FunctionDeclaration(
|
types.Tool(
|
||||||
name=f["function"]["name"],
|
function_declarations=[
|
||||||
description=f["function"]["description"],
|
types.FunctionDeclaration(
|
||||||
parameters=f["function"]["parameters"],
|
name=f["function"]["name"],
|
||||||
|
description=f["function"]["description"],
|
||||||
|
parameters=f["function"]["parameters"],
|
||||||
|
)
|
||||||
|
for f in funcs
|
||||||
|
]
|
||||||
)
|
)
|
||||||
for f in funcs
|
]
|
||||||
])]
|
|
||||||
|
|
||||||
# Gemini文档提到,无需维护session-id,直接用dialogue拼接而成
|
# Gemini文档提到,无需维护session-id,直接用dialogue拼接而成
|
||||||
def response(self, session_id, dialogue):
|
def response(self, session_id, dialogue):
|
||||||
@@ -115,26 +127,36 @@ class LLMProvider(LLMProviderBase):
|
|||||||
|
|
||||||
if r == "assistant" and "tool_calls" in m:
|
if r == "assistant" and "tool_calls" in m:
|
||||||
tc = m["tool_calls"][0]
|
tc = m["tool_calls"][0]
|
||||||
contents.append({
|
contents.append(
|
||||||
"role": "model",
|
{
|
||||||
"parts": [{"function_call": {
|
"role": "model",
|
||||||
"name": tc["function"]["name"],
|
"parts": [
|
||||||
"args": json.loads(tc["function"]["arguments"]),
|
{
|
||||||
}}],
|
"function_call": {
|
||||||
})
|
"name": tc["function"]["name"],
|
||||||
|
"args": json.loads(tc["function"]["arguments"]),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
}
|
||||||
|
)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if r == "tool":
|
if r == "tool":
|
||||||
contents.append({
|
contents.append(
|
||||||
"role": "model",
|
{
|
||||||
"parts": [{"text": str(m.get("content", ""))}],
|
"role": "model",
|
||||||
})
|
"parts": [{"text": str(m.get("content", ""))}],
|
||||||
|
}
|
||||||
|
)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
contents.append({
|
contents.append(
|
||||||
"role": role_map.get(r, "user"),
|
{
|
||||||
"parts": [{"text": str(m.get("content", ""))}],
|
"role": role_map.get(r, "user"),
|
||||||
})
|
"parts": [{"text": str(m.get("content", ""))}],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
stream: GenerateContentResponse = self.model.generate_content(
|
stream: GenerateContentResponse = self.model.generate_content(
|
||||||
contents=contents,
|
contents=contents,
|
||||||
@@ -150,15 +172,18 @@ class LLMProvider(LLMProviderBase):
|
|||||||
# a) 函数调用-通常是最后一段话才是函数调用
|
# a) 函数调用-通常是最后一段话才是函数调用
|
||||||
if getattr(part, "function_call", None):
|
if getattr(part, "function_call", None):
|
||||||
fc = part.function_call
|
fc = part.function_call
|
||||||
yield None, [SimpleNamespace(
|
yield None, [
|
||||||
id=uuid.uuid4().hex,
|
SimpleNamespace(
|
||||||
type="function",
|
id=uuid.uuid4().hex,
|
||||||
function=SimpleNamespace(
|
type="function",
|
||||||
name=fc.name,
|
function=SimpleNamespace(
|
||||||
arguments=json.dumps(dict(fc.args),
|
name=fc.name,
|
||||||
ensure_ascii=False),
|
arguments=json.dumps(
|
||||||
),
|
dict(fc.args), ensure_ascii=False
|
||||||
)]
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
]
|
||||||
return
|
return
|
||||||
# b) 普通文本
|
# b) 普通文本
|
||||||
if getattr(part, "text", None):
|
if getattr(part, "text", None):
|
||||||
|
|||||||
Reference in New Issue
Block a user