Skip to content

Global tool in Pipecat Flows triggers multiple responses when query contains multiple informational intents #3925

Description

@rohitkhatri

pipecat version

0.0.102

Python version

3.13.11

Operating System

macOS 26.3

Issue description

Description

I'm implementing a global knowledge query tool using Pipecat Flows that is automatically called whenever a user asks an informational question. The goal is for the agent to:

  1. Call the knowledge query tool
  2. Retrieve relevant context
  3. Generate a response based on that context

This works correctly for single-intent informational queries, but breaks when the user asks multiple informational questions in the same message.

Instead of aggregating the tool calls and generating one final response, the agent generates multiple responses — one for each tool invocation.


Example User Query

I would like to know if there's a swimming pool in the hotel and also what is the opening time for tennis court

Reproduction steps

Here's the agent code for reproducing:

https://gist.github.com/rohitkhatri/819871bcb6101469d876c263dab6667f

Expected behavior

The agent should:

  1. Detect multiple informational intents in the query
  2. Execute all required tool calls first
  3. Aggregate the tool results
  4. Generate a single final response including all retrieved information

Example expected response:

Yes, the hotel has a swimming pool available for guests.
The tennis court is open from 6:00 AM to 9:00 PM.

Actual behavior

  1. Agent detects two query_knowledge calls
    • Calling function [query_knowledge:call_4nmUrgtFzEkwd86VVDKHOvFR] with arguments {'query': 'Is there a swimming pool in the hotel?'}
    • Calling function [query_knowledge:call_5Eq0avypKt1rxI1VxHTYLSK5] with arguments {'query': 'What are the timings for the table tennis court?'}
  2. Calls query_knowledge tool handler for all tool calls detected.
  3. Generates response for each tool call detected instead one final generation.

Result: Two separate responses are produced.

Logs

2026-03-05 20:57:31.409 | DEBUG    | pipecat.audio.vad.silero:__init__:147 - Loading Silero VAD model...
2026-03-05 20:57:31.461 | DEBUG    | pipecat.audio.vad.silero:__init__:169 - Loaded Silero VAD
2026-03-05 20:57:31.462 | DEBUG    | pipecat.audio.turn.smart_turn.local_smart_turn_v3:__init__:74 - Loading Local Smart Turn v3.x model from /.venv/lib/python3.13/site-packages/pipecat/audio/turn/smart_turn/data/smart-turn-v3.2-cpu.onnx...
2026-03-05 20:57:31.499 | DEBUG    | pipecat.audio.turn.smart_turn.local_smart_turn_v3:__init__:85 - Loaded Local Smart Turn v3.x
2026-03-05 20:57:31.499 | DEBUG    | pipecat.processors.frame_processor:link:561 - Linking Pipeline#0::Source -> FastAPIWebsocketInputTransport#0
2026-03-05 20:57:31.499 | DEBUG    | pipecat.processors.frame_processor:link:561 - Linking FastAPIWebsocketInputTransport#0 -> OpenAISTTService#0
2026-03-05 20:57:31.499 | DEBUG    | pipecat.processors.frame_processor:link:561 - Linking OpenAISTTService#0 -> LLMUserAggregator#0
2026-03-05 20:57:31.499 | DEBUG    | pipecat.processors.frame_processor:link:561 - Linking LLMUserAggregator#0 -> OpenAILLMService#0
2026-03-05 20:57:31.499 | DEBUG    | pipecat.processors.frame_processor:link:561 - Linking OpenAILLMService#0 -> OpenAITTSService#0
2026-03-05 20:57:31.499 | DEBUG    | pipecat.processors.frame_processor:link:561 - Linking OpenAITTSService#0 -> FastAPIWebsocketOutputTransport#0
2026-03-05 20:57:31.499 | DEBUG    | pipecat.processors.frame_processor:link:561 - Linking FastAPIWebsocketOutputTransport#0 -> LLMAssistantAggregator#0
2026-03-05 20:57:31.499 | DEBUG    | pipecat.processors.frame_processor:link:561 - Linking LLMAssistantAggregator#0 -> Pipeline#0::Sink
2026-03-05 20:57:31.499 | DEBUG    | pipecat.processors.frame_processor:link:561 - Linking PipelineTask#0::Source -> RTVIProcessor#0
2026-03-05 20:57:31.499 | DEBUG    | pipecat.processors.frame_processor:link:561 - Linking RTVIProcessor#0 -> Pipeline#0
2026-03-05 20:57:31.499 | DEBUG    | pipecat.processors.frame_processor:link:561 - Linking Pipeline#0 -> PipelineTask#0::Sink
2026-03-05 20:57:31.499 | DEBUG    | pipecat_flows.actions:_register_action:139 - Registered handler for action type: tts_say
2026-03-05 20:57:31.499 | DEBUG    | pipecat_flows.actions:_register_action:139 - Registered handler for action type: end_conversation
2026-03-05 20:57:31.499 | DEBUG    | pipecat_flows.actions:_register_action:139 - Registered handler for action type: function
2026-03-05 20:57:31.499 | DEBUG    | pipecat_flows.adapters:create_adapter:669 - Creating universal adapter
2026-03-05 20:57:31.499 | DEBUG    | pipecat_flows.manager:__init__:170 - Initialized in dynamic mode
2026-03-05 20:57:31.500 | DEBUG    | pipecat.pipeline.runner:run:71 - Runner PipelineRunner#0 started running PipelineTask#0
INFO:     connection open
2026-03-05 20:57:31.500 | DEBUG    | pipecat.pipeline.task:_wait_for_pipeline_start:718 - PipelineTask#0: Starting. Waiting for StartFrame#0 to reach the end of the pipeline...
2026-03-05 20:57:31.501 | INFO     | __main__:on_client_connected:156 - Client connected
2026-03-05 20:57:31.501 | DEBUG    | pipecat_flows.manager:initialize:345 - Initialized FlowManager
2026-03-05 20:57:31.501 | DEBUG    | pipecat_flows.manager:initialize:365 - Setting initial node: initial
2026-03-05 20:57:31.501 | DEBUG    | pipecat_flows.manager:_set_node:769 - Setting node: initial
2026-03-05 20:57:31.501 | DEBUG    | pipecat_flows.manager:_register_function:688 - Registered function: query_knowledge
2026-03-05 20:57:31.501 | DEBUG    | pipecat_flows.manager:_update_llm_context:973 - Updated LLM context using LLMMessagesUpdateFrame with strategy ContextStrategy.APPEND
2026-03-05 20:57:31.501 | DEBUG    | pipecat_flows.manager:_set_node:861 - Updated LLM context
2026-03-05 20:57:31.501 | DEBUG    | pipecat_flows.manager:_set_node:880 - Successfully set node: initial
2026-03-05 20:57:31.501 | DEBUG    | pipecat.audio.vad.vad_analyzer:set_params:156 - Setting VAD params to: confidence=0.7 start_secs=0.2 stop_secs=0.2 min_volume=0.6
2026-03-05 20:57:31.502 | DEBUG    | pipecat.pipeline.task:_wait_for_pipeline_start:721 - PipelineTask#0: StartFrame#0 reached the end of the pipeline, pipeline is now ready.
2026-03-05 20:57:31.503 | DEBUG    | pipecat.serializers.protobuf:deserialize:141 - ProtobufFrameSerializer: Transport message InputTransportMessageFrame#0(message: {'label': 'rtvi-ai', 'type': 'client-ready', 'data': {'version': '1.0.0', 'about': {'library': '@pipecat-ai/client-js', 'library_version': '1.4.0', 'platform_details': {'browser': 'Chrome', 'browser_version': '145.0.0.0', 'platform_type': 'desktop', 'engine': 'Blink'}, 'platform': 'macOS', 'platform_version': '10.15.7'}}, 'id': '69a46a02'})
2026-03-05 20:57:31.504 | DEBUG    | pipecat.processors.frameworks.rtvi:_handle_client_ready:1877 - Received client-ready: version 1.0.0
2026-03-05 20:57:31.504 | DEBUG    | pipecat.processors.frameworks.rtvi:_handle_client_ready:1884 - Client Details: library='@pipecat-ai/client-js' library_version='1.4.0' platform='macOS' platform_version='10.15.7' platform_details={'browser': 'Chrome', 'browser_version': '145.0.0.0', 'platform_type': 'desktop', 'engine': 'Blink'}
2026-03-05 20:57:31.505 | DEBUG    | pipecat.services.openai.base_llm:_stream_chat_completions_universal_context:350 - OpenAILLMService#0: Generating chat from universal context [{'role': 'system', 'content': 'You are operating as a **hotel operator AI agent**, serving as the **first point of contact** for guests and potential guests.\n### Hotel Information Queries\n- For **any question about hotel services, facilities, amenities, dining, policies, inclusion details, or general hotel information**:\n  - You **MUST call `query_hotel_info`** before responding.\n  - Do **NOT** answer from memory or assumptions.\n'}, {'role': 'user', 'content': 'Hi, I wanted to know if there is a swimming pool in the hotel and also the table tennis court timing.'}]
2026-03-05 20:57:31.505 | DEBUG    | pipecat.adapters.base_llm_adapter:from_standard_tools:127 - Retrieving the tools using the adapter: <class 'pipecat.adapters.services.open_ai_adapter.OpenAILLMAdapter'>
2026-03-05 20:57:34.260 | DEBUG    | pipecat.processors.metrics.frame_processor_metrics:stop_ttfb_metrics:131 - OpenAILLMService#0 TTFB: 2.7548530101776123
2026-03-05 20:57:34.550 | DEBUG    | pipecat.processors.metrics.frame_processor_metrics:start_llm_usage_metrics:173 - OpenAILLMService#0 prompt tokens: 199, completion tokens: 63
2026-03-05 20:57:34.551 | DEBUG    | pipecat.processors.metrics.frame_processor_metrics:stop_processing_metrics:152 - OpenAILLMService#0 processing time: 3.0459814071655273
2026-03-05 20:57:34.552 | DEBUG    | pipecat.services.llm_service:_run_function_call:764 - OpenAILLMService#0 Calling function [query_knowledge:call_4nmUrgtFzEkwd86VVDKHOvFR] with arguments {'query': 'Is there a swimming pool in the hotel?'}
2026-03-05 20:57:34.553 | DEBUG    | pipecat.services.llm_service:_run_function_call:764 - OpenAILLMService#0 Calling function [query_knowledge:call_5Eq0avypKt1rxI1VxHTYLSK5] with arguments {'query': 'What are the timings for the table tennis court?'}
2026-03-05 20:57:34.554 | DEBUG    | pipecat_flows.manager:transition_func:499 - Function called: query_knowledge
2026-03-05 20:57:34.554 | DEBUG    | pipecat_flows.manager:transition_func:499 - Function called: query_knowledge
2026-03-05 20:57:34.555 | DEBUG    | pipecat.processors.aggregators.llm_response_universal:_handle_function_calls_started:964 - LLMAssistantAggregator#0 FunctionCallsStartedFrame: ['query_knowledge:call_4nmUrgtFzEkwd86VVDKHOvFR', 'query_knowledge:call_5Eq0avypKt1rxI1VxHTYLSK5']
2026-03-05 20:57:34.557 | DEBUG    | pipecat.processors.aggregators.llm_response_universal:_handle_function_call_in_progress:969 - LLMAssistantAggregator#0 FunctionCallInProgressFrame: [query_knowledge:call_4nmUrgtFzEkwd86VVDKHOvFR]
2026-03-05 20:57:34.558 | DEBUG    | pipecat.processors.aggregators.llm_response_universal:_handle_function_call_in_progress:969 - LLMAssistantAggregator#0 FunctionCallInProgressFrame: [query_knowledge:call_5Eq0avypKt1rxI1VxHTYLSK5]
2026-03-05 20:57:36.555 | DEBUG    | pipecat_flows.manager:transition_func:530 - Function handler completed for query_knowledge
2026-03-05 20:57:36.556 | DEBUG    | pipecat_flows.manager:transition_func:530 - Function handler completed for query_knowledge
2026-03-05 20:57:36.560 | DEBUG    | pipecat.processors.aggregators.llm_response_universal:_handle_function_call_result:1000 - LLMAssistantAggregator#0 FunctionCallResultFrame: [query_knowledge:call_4nmUrgtFzEkwd86VVDKHOvFR]
2026-03-05 20:57:36.560 | DEBUG    | pipecat.processors.aggregators.llm_response_universal:_handle_function_call_result:1000 - LLMAssistantAggregator#0 FunctionCallResultFrame: [query_knowledge:call_5Eq0avypKt1rxI1VxHTYLSK5]
2026-03-05 20:57:36.561 | DEBUG    | pipecat.services.openai.base_llm:_stream_chat_completions_universal_context:350 - OpenAILLMService#0: Generating chat from universal context [{'role': 'system', 'content': 'You are operating as a **hotel operator AI agent**, serving as the **first point of contact** for guests and potential guests.\n### Hotel Information Queries\n- For **any question about hotel services, facilities, amenities, dining, policies, inclusion details, or general hotel information**:\n  - You **MUST call `query_hotel_info`** before responding.\n  - Do **NOT** answer from memory or assumptions.\n'}, {'role': 'user', 'content': 'Hi, I wanted to know if there is a swimming pool in the hotel and also the table tennis court timing.'}, {'role': 'assistant', 'tool_calls': [{'id': 'call_4nmUrgtFzEkwd86VVDKHOvFR', 'function': {'name': 'query_knowledge', 'arguments': '{"query": "Is there a swimming pool in the hotel?"}'}, 'type': 'function'}]}, {'role': 'tool', 'content': '{"context": "The swimming pool opening time is 7AM to 9PM."}', 'tool_call_id': 'call_4nmUrgtFzEkwd86VVDKHOvFR'}, {'role': 'assistant', 'tool_calls': [{'id': 'call_5Eq0avypKt1rxI1VxHTYLSK5', 'function': {'name': 'query_knowledge', 'arguments': '{"query": "What are the timings for the table tennis court?"}'}, 'type': 'function'}]}, {'role': 'tool', 'content': '{"context": "The swimming pool opening time is 7AM to 9PM."}', 'tool_call_id': 'call_5Eq0avypKt1rxI1VxHTYLSK5'}]
2026-03-05 20:57:36.561 | DEBUG    | pipecat.adapters.base_llm_adapter:from_standard_tools:127 - Retrieving the tools using the adapter: <class 'pipecat.adapters.services.open_ai_adapter.OpenAILLMAdapter'>
2026-03-05 20:57:37.352 | DEBUG    | pipecat.processors.metrics.frame_processor_metrics:stop_ttfb_metrics:131 - OpenAILLMService#0 TTFB: 0.7909040451049805
2026-03-05 20:57:37.758 | DEBUG    | pipecat.services.openai.tts:run_tts:181 - OpenAITTSService#0: Generating TTS [Yes, the hotel has a swimming pool which is open from 7 AM to 9 PM.]
2026-03-05 20:57:38.168 | DEBUG    | pipecat.processors.metrics.frame_processor_metrics:start_llm_usage_metrics:173 - OpenAILLMService#0 prompt tokens: 302, completion tokens: 46
2026-03-05 20:57:38.171 | DEBUG    | pipecat.processors.metrics.frame_processor_metrics:stop_processing_metrics:152 - OpenAILLMService#0 processing time: 1.6101179122924805
2026-03-05 20:57:38.171 | DEBUG    | pipecat.services.openai.base_llm:_stream_chat_completions_universal_context:350 - OpenAILLMService#0: Generating chat from universal context [{'role': 'system', 'content': 'You are operating as a **hotel operator AI agent**, serving as the **first point of contact** for guests and potential guests.\n### Hotel Information Queries\n- For **any question about hotel services, facilities, amenities, dining, policies, inclusion details, or general hotel information**:\n  - You **MUST call `query_hotel_info`** before responding.\n  - Do **NOT** answer from memory or assumptions.\n'}, {'role': 'user', 'content': 'Hi, I wanted to know if there is a swimming pool in the hotel and also the table tennis court timing.'}, {'role': 'assistant', 'tool_calls': [{'id': 'call_4nmUrgtFzEkwd86VVDKHOvFR', 'function': {'name': 'query_knowledge', 'arguments': '{"query": "Is there a swimming pool in the hotel?"}'}, 'type': 'function'}]}, {'role': 'tool', 'content': '{"context": "The swimming pool opening time is 7AM to 9PM."}', 'tool_call_id': 'call_4nmUrgtFzEkwd86VVDKHOvFR'}, {'role': 'assistant', 'tool_calls': [{'id': 'call_5Eq0avypKt1rxI1VxHTYLSK5', 'function': {'name': 'query_knowledge', 'arguments': '{"query": "What are the timings for the table tennis court?"}'}, 'type': 'function'}]}, {'role': 'tool', 'content': '{"context": "The swimming pool opening time is 7AM to 9PM."}', 'tool_call_id': 'call_5Eq0avypKt1rxI1VxHTYLSK5'}]
2026-03-05 20:57:38.171 | DEBUG    | pipecat.adapters.base_llm_adapter:from_standard_tools:127 - Retrieving the tools using the adapter: <class 'pipecat.adapters.services.open_ai_adapter.OpenAILLMAdapter'>
2026-03-05 20:57:38.694 | DEBUG    | pipecat.processors.metrics.frame_processor_metrics:start_tts_usage_metrics:191 - OpenAITTSService#0 usage characters: 67
2026-03-05 20:57:39.159 | DEBUG    | pipecat.processors.metrics.frame_processor_metrics:stop_ttfb_metrics:131 - OpenAITTSService#0 TTFB: 1.400209903717041
2026-03-05 20:57:39.160 | DEBUG    | pipecat.transports.base_output:_bot_started_speaking:608 - Bot started speaking
2026-03-05 20:57:39.540 | DEBUG    | pipecat.processors.metrics.frame_processor_metrics:stop_ttfb_metrics:131 - OpenAILLMService#0 TTFB: 1.3691587448120117
2026-03-05 20:57:39.956 | DEBUG    | pipecat.services.tts_service:push_frame:524 - OpenAITTSService#0 cleaning up TTS context 0ad7fbd7-80aa-4c3e-95c1-17eb610cdcdb
2026-03-05 20:57:39.957 | DEBUG    | pipecat.processors.metrics.frame_processor_metrics:stop_processing_metrics:152 - OpenAITTSService#0 processing time: 2.1984851360321045
2026-03-05 20:57:39.957 | DEBUG    | pipecat.services.openai.tts:run_tts:181 - OpenAITTSService#0: Generating TTS [However, I couldn't find specific information on the table tennis court timings.]
2026-03-05 20:57:40.564 | DEBUG    | pipecat.processors.metrics.frame_processor_metrics:start_llm_usage_metrics:173 - OpenAILLMService#0 prompt tokens: 302, completion tokens: 56
2026-03-05 20:57:40.566 | DEBUG    | pipecat.processors.metrics.frame_processor_metrics:stop_processing_metrics:152 - OpenAILLMService#0 processing time: 2.3943169116973877
2026-03-05 20:57:41.189 | DEBUG    | pipecat.processors.metrics.frame_processor_metrics:start_tts_usage_metrics:191 - OpenAITTSService#0 usage characters: 80
2026-03-05 20:57:41.553 | DEBUG    | pipecat.processors.metrics.frame_processor_metrics:stop_ttfb_metrics:131 - OpenAITTSService#0 TTFB: 1.5953352451324463
2026-03-05 20:57:42.391 | DEBUG    | pipecat.services.tts_service:push_frame:524 - OpenAITTSService#0 cleaning up TTS context ffb72c82-14cd-474b-90f2-883180e07702
2026-03-05 20:57:42.392 | DEBUG    | pipecat.processors.metrics.frame_processor_metrics:stop_processing_metrics:152 - OpenAITTSService#0 processing time: 2.434558868408203
2026-03-05 20:57:42.392 | DEBUG    | pipecat.services.openai.tts:run_tts:181 - OpenAITTSService#0: Generating TTS [Would you like me to assist you with anything else?]
2026-03-05 20:57:43.821 | DEBUG    | pipecat.processors.metrics.frame_processor_metrics:start_tts_usage_metrics:191 - OpenAITTSService#0 usage characters: 51
2026-03-05 20:57:44.274 | DEBUG    | pipecat.processors.metrics.frame_processor_metrics:stop_ttfb_metrics:131 - OpenAITTSService#0 TTFB: 1.8819670677185059
2026-03-05 20:57:45.037 | DEBUG    | pipecat.services.tts_service:push_frame:524 - OpenAITTSService#0 cleaning up TTS context a5e29c29-5dcf-4dfb-84ab-7858dd282b7f
2026-03-05 20:57:45.037 | DEBUG    | pipecat.processors.metrics.frame_processor_metrics:stop_processing_metrics:152 - OpenAITTSService#0 processing time: 2.6449928283691406
2026-03-05 20:57:45.037 | DEBUG    | pipecat.services.openai.tts:run_tts:181 - OpenAITTSService#0: Generating TTS [Yes, the hotel has a swimming pool which is open from 7 AM to 9 PM.]
2026-03-05 20:57:46.334 | DEBUG    | pipecat.processors.metrics.frame_processor_metrics:start_tts_usage_metrics:191 - OpenAITTSService#0 usage characters: 67
2026-03-05 20:57:46.671 | DEBUG    | pipecat.processors.metrics.frame_processor_metrics:stop_ttfb_metrics:131 - OpenAITTSService#0 TTFB: 1.6339597702026367
INFO:     connection closed
2026-03-05 20:57:47.070 | INFO     | __main__:on_client_disconnected:161 - Client disconnected
2026-03-05 20:57:47.070 | DEBUG    | pipecat.pipeline.task:_cancel:646 - Cancelling pipeline task PipelineTask#0
2026-03-05 20:57:47.073 | DEBUG    | pipecat.pipeline.task:_wait_for_pipeline_end:740 - PipelineTask#0: Closing. Waiting for CancelFrame#0(reason: None) to reach the end of the pipeline...
2026-03-05 20:57:47.077 | DEBUG    | pipecat.pipeline.task:wait_for_cancel:731 - PipelineTask#0: CancelFrame#0(reason: None) reached the end of the pipeline.
2026-03-05 20:57:47.078 | DEBUG    | pipecat.pipeline.task:run:611 - Pipeline task PipelineTask#0 is finishing...
2026-03-05 20:57:47.078 | DEBUG    | pipecat.pipeline.task:run:616 - Pipeline task PipelineTask#0 has finished
2026-03-05 20:57:47.078 | DEBUG    | pipecat.pipeline.runner:run:95 - Runner PipelineRunner#0 finished running PipelineTask#0

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions