Skip to content

fix(perplexity): keep tool calls when merging consecutive assistant messages - #5855

Open
BlueX888 wants to merge 1 commit into
pipecat-ai:mainfrom
BlueX888:fix/prep-perplexity-merge-drops-tool-call-messages
Open

BlueX888 wants to merge 1 commit into
pipecat-ai:mainfrom
BlueX888:fix/prep-perplexity-merge-drops-tool-call-messages

Conversation

@BlueX888

Copy link
Copy Markdown

PerplexityLLMAdapter merges consecutive same-role messages so the request satisfies Perplexity's strict role alternation. The merge moved only content off the message it absorbed before dropping it, so a message carrying tool_calls lost them — and two consecutive tool messages collapsed into one that answers only the first call.

Why

In step 2 of _transform_messages (src/pipecat/adapters/services/perplexity_adapter.py:151), any two adjacent same-role messages are merged: next_msg["content"] is extended into current (:158-161), then next_msg is popped (:162). Nothing carries tool_calls across the merge, and nothing treats a tool message specially — yet its tool_call_id is the only thing tying its result to a call.

A history in OpenAI message shape therefore comes out of the adapter wrong in two ways:

  • [assistant(text), assistant(tool_calls: c1), tool(c1)] -> [assistant(text), tool(c1)]. The tool message answers a call that is no longer in the request.
  • [assistant(tool_calls: c1, c2), tool(c1), tool(c2)] -> [assistant(tool_calls: c1, c2), tool(c1)]. Both results land on c1, and c2 is left unanswered.

Changes

  • The merge carries tool_calls from the absorbed message onto the surviving one, and moves content into it when the surviving message has none — the call can precede the text it was made alongside.
  • Consecutive tool messages are left as they are, since merging them would leave both results on the first call's id.

Testing

On the tree with the source change reverted, the three new tests fail:

FAILED ...::test_merging_assistants_keeps_tool_calls            # KeyError: 'tool_calls'
FAILED ...::test_consecutive_tool_messages_keep_their_own_ids   # AssertionError: 4 != 5
FAILED ...::test_merging_tool_call_only_assistant_keeps_content # KeyError: 'content'
===================== 3 failed, 13 passed in 0.68s ===================

With the change:

$ uv run pytest tests/test_get_llm_invocation_params.py::TestPerplexityGetLLMInvocationParams
16 passed

$ uv run pytest tests/test_get_llm_invocation_params.py
179 passed

$ uv run pytest tests/test_get_llm_invocation_params.py tests/test_openai_compatible_token_usage.py
228 passed

$ uv run ruff check            -> All checks passed!
$ uv run ruff format --check   -> 1412 files already formatted
$ uv run pyright               -> no findings in the changed file

Notes

No issue to reference; this is not from a report. I left changelog/ alone because the fragment filename is the PR number — say the word and I'll add <this PR>.fixed.md.

@BlueX888
BlueX888 force-pushed the fix/prep-perplexity-merge-drops-tool-call-messages branch from cded9a7 to 9e70409 Compare October 8, 2026 10:13
…essages

Merging two consecutive same-role messages keeps the tool_calls and the
content carried by the message it absorbs, so a tool message that answers a
call still finds that call in the request. Consecutive tool messages are
left as they are, since each names the call its result answers in
tool_call_id and a merge would leave both results on the first call's id.
@BlueX888
BlueX888 force-pushed the fix/prep-perplexity-merge-drops-tool-call-messages branch from 9e70409 to 420f80f Compare October 8, 2026 10:16

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant