fix(llm): adapt async tool results for compatible APIs
This commit is contained in:
@@ -117,7 +117,7 @@ def create_llm(cfg: AssistantConfig):
|
||||
raise ValueError(f"不支持的 LLM 接口类型: {cfg.llm_interface_type}")
|
||||
extra_body = cfg.llm_values.get("extraBody")
|
||||
extra = {"extra_body": extra_body} if isinstance(extra_body, dict) else {}
|
||||
return OpenAILLMService(
|
||||
service = OpenAILLMService(
|
||||
api_key=_require(cfg.llm_api_key, "LLM apiKey"),
|
||||
base_url=_require(cfg.llm_base_url, "LLM apiUrl"),
|
||||
settings=OpenAILLMService.Settings(
|
||||
@@ -125,6 +125,15 @@ def create_llm(cfg: AssistantConfig):
|
||||
extra=extra,
|
||||
),
|
||||
)
|
||||
# Pipecat represents late async-tool results with the newer `developer`
|
||||
# role. Most OpenAI-compatible providers (including DeepSeek) only accept
|
||||
# system/assistant/user/tool. This flag uses Pipecat's built-in adapter to
|
||||
# downgrade developer messages before sending the request. Official or
|
||||
# otherwise compatible endpoints can opt in through the resource values.
|
||||
service.supports_developer_role = (
|
||||
cfg.llm_values.get("supportsDeveloperRole") is True
|
||||
)
|
||||
return service
|
||||
|
||||
|
||||
def create_tts(cfg: AssistantConfig):
|
||||
|
||||
@@ -4,13 +4,61 @@ import unittest
|
||||
from unittest.mock import patch
|
||||
|
||||
from models import AssistantConfig
|
||||
from pipecat.processors.aggregators.llm_context import LLMContext
|
||||
from services.pipecat.service_factory import (
|
||||
HTTP_TTS_STOP_FRAME_TIMEOUT_S,
|
||||
WEBSOCKET_TTS_STOP_FRAME_TIMEOUT_S,
|
||||
create_llm,
|
||||
create_tts,
|
||||
)
|
||||
|
||||
|
||||
class LLMServiceFactoryTest(unittest.TestCase):
|
||||
def test_openai_compatible_llm_converts_async_tool_developer_result(self):
|
||||
service = create_llm(
|
||||
AssistantConfig(
|
||||
llm_interface_type="openai-llm",
|
||||
model="deepseek-chat",
|
||||
llm_api_key="test-key",
|
||||
llm_base_url="https://llm.example.test/v1",
|
||||
)
|
||||
)
|
||||
context = LLMContext(
|
||||
messages=[
|
||||
{"role": "system", "content": "你是助手"},
|
||||
{
|
||||
"role": "developer",
|
||||
"content": '{"type":"async_tool","status":"finished"}',
|
||||
},
|
||||
{"role": "user", "content": "ok"},
|
||||
]
|
||||
)
|
||||
|
||||
params = service.get_llm_adapter().get_llm_invocation_params(
|
||||
context,
|
||||
convert_developer_to_user=not service.supports_developer_role,
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
[message["role"] for message in params["messages"]],
|
||||
["system", "user", "user"],
|
||||
)
|
||||
self.assertNotIn("developer", str(params["messages"]))
|
||||
|
||||
def test_provider_can_explicitly_enable_developer_role(self):
|
||||
service = create_llm(
|
||||
AssistantConfig(
|
||||
llm_interface_type="openai-llm",
|
||||
model="gpt-compatible",
|
||||
llm_api_key="test-key",
|
||||
llm_base_url="https://llm.example.test/v1",
|
||||
llm_values={"supportsDeveloperRole": True},
|
||||
)
|
||||
)
|
||||
|
||||
self.assertTrue(service.supports_developer_role)
|
||||
|
||||
|
||||
class TTSServiceFactoryTest(unittest.TestCase):
|
||||
def test_http_tts_keeps_wider_audio_chunk_timeout(self):
|
||||
config = AssistantConfig(
|
||||
|
||||
Reference in New Issue
Block a user