diff --git a/src/pipecat/adapters/services/perplexity_adapter.py b/src/pipecat/adapters/services/perplexity_adapter.py index 2055914e8..c5d7f1d6c 100644 --- a/src/pipecat/adapters/services/perplexity_adapter.py +++ b/src/pipecat/adapters/services/perplexity_adapter.py @@ -109,6 +109,12 @@ class PerplexityLLMAdapter(OpenAILLMAdapter): messages = copy.deepcopy(messages) + # Step 0: Convert "developer" messages to "user". + # Perplexity doesn't support the "developer" role. + for msg in messages: + if msg.get("role") == "developer": + msg["role"] = "user" + # Step 1: Convert non-initial system messages to "user". # Perplexity allows system messages at the start, but rejects them # after any non-system message. diff --git a/tests/test_get_llm_invocation_params.py b/tests/test_get_llm_invocation_params.py index e409e2cd3..6ad0af157 100644 --- a/tests/test_get_llm_invocation_params.py +++ b/tests/test_get_llm_invocation_params.py @@ -1585,6 +1585,41 @@ class TestPerplexityGetLLMInvocationParams(unittest.TestCase): self.assertEqual(params["messages"][2]["content"], "Sunny, 72F") self.assertEqual(params["messages"][3]["role"], "user") + def test_developer_message_converted_to_user(self): + """Developer messages are converted to user role.""" + messages: list[LLMStandardMessage] = [ + {"role": "developer", "content": "Extra context."}, + {"role": "assistant", "content": "Hi"}, + {"role": "user", "content": "Hello"}, + ] + + context = LLMContext(messages=messages) + params = self.adapter.get_llm_invocation_params(context) + + self.assertEqual(params["messages"][0]["role"], "user") + self.assertEqual(params["messages"][0]["content"], "Extra context.") + + def test_developer_message_merged_with_adjacent_user(self): + """Developer→user conversion merges with adjacent user messages.""" + messages: list[LLMStandardMessage] = [ + {"role": "developer", "content": "Be concise."}, + {"role": "user", "content": "Hello"}, + {"role": "assistant", "content": "Hi"}, + {"role": "user", "content": "Bye"}, + ] + + context = LLMContext(messages=messages) + params = self.adapter.get_llm_invocation_params(context) + + # developer→user merged with following user + self.assertEqual(len(params["messages"]), 3) + merged = params["messages"][0] + self.assertEqual(merged["role"], "user") + self.assertIsInstance(merged["content"], list) + self.assertEqual(len(merged["content"]), 2) + self.assertEqual(merged["content"][0]["text"], "Be concise.") + self.assertEqual(merged["content"][1]["text"], "Hello") + def test_empty_messages(self): """Test that empty messages list returns empty.""" context = LLMContext(messages=[])