From 39329aaddba24f73c347de35d3e686d84408817c Mon Sep 17 00:00:00 2001 From: Paul Kompfner Date: Tue, 24 Mar 2026 17:18:44 -0400 Subject: [PATCH] Prefer init-provided system instruction in Nova Sonic Add system_instruction parameter to the Nova Sonic adapter's get_llm_invocation_params() and call _resolve_system_instruction() to prefer init-provided over context-provided system instructions and warn on conflicts. Previously context-provided took precedence. Remove the service-side fallback logic, as the adapter now handles resolution. --- .../adapters/services/aws_nova_sonic_adapter.py | 14 ++++++++++---- src/pipecat/services/aws/nova_sonic/llm.py | 13 ++++++------- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/pipecat/adapters/services/aws_nova_sonic_adapter.py b/src/pipecat/adapters/services/aws_nova_sonic_adapter.py index 657c83bf9..492e02db6 100644 --- a/src/pipecat/adapters/services/aws_nova_sonic_adapter.py +++ b/src/pipecat/adapters/services/aws_nova_sonic_adapter.py @@ -72,20 +72,26 @@ class AWSNovaSonicLLMAdapter(BaseLLMAdapter[AWSNovaSonicLLMInvocationParams]): """Get the identifier used in LLMSpecificMessage instances for AWS Nova Sonic.""" return "aws-nova-sonic" - def get_llm_invocation_params(self, context: LLMContext) -> AWSNovaSonicLLMInvocationParams: + def get_llm_invocation_params( + self, context: LLMContext, *, system_instruction: Optional[str] = None + ) -> AWSNovaSonicLLMInvocationParams: """Get AWS Nova Sonic-specific LLM invocation parameters from a universal LLM context. - This is a placeholder until support for universal LLMContext machinery is added for AWS Nova Sonic. - Args: context: The LLM context containing messages, tools, etc. + system_instruction: Optional system instruction from service settings. Returns: Dictionary of parameters for invoking AWS Nova Sonic's LLM API. """ messages = self._from_universal_context_messages(self.get_messages(context)) + effective_system = self._resolve_system_instruction( + messages.system_instruction, + system_instruction, + discard_context_system=True, + ) return { - "system_instruction": messages.system_instruction, + "system_instruction": effective_system, "messages": messages.messages, # NOTE: LLMContext's tools are guaranteed to be a ToolsSchema (or NOT_GIVEN) "tools": self.from_standard_tools(context.tools) or [], diff --git a/src/pipecat/services/aws/nova_sonic/llm.py b/src/pipecat/services/aws/nova_sonic/llm.py index ffcbb5e5d..3541946c7 100644 --- a/src/pipecat/services/aws/nova_sonic/llm.py +++ b/src/pipecat/services/aws/nova_sonic/llm.py @@ -629,7 +629,9 @@ class AWSNovaSonicLLMService(LLMService): # Read context adapter: AWSNovaSonicLLMAdapter = self.get_llm_adapter() - llm_connection_params = adapter.get_llm_invocation_params(self._context) + llm_connection_params = adapter.get_llm_invocation_params( + self._context, system_instruction=self._settings.system_instruction + ) # Send prompt start event, specifying tools. # Tools from context take priority over self._tools. @@ -642,12 +644,9 @@ class AWSNovaSonicLLMService(LLMService): await self._send_prompt_start_event(tools) # Send system instruction. - # Instruction from context takes priority over self._settings.system_instruction. - system_instruction = ( - llm_connection_params["system_instruction"] - if llm_connection_params["system_instruction"] - else self._settings.system_instruction - ) + # The adapter resolves conflicts between init-provided and + # context-provided system instructions (preferring init-provided). + system_instruction = llm_connection_params["system_instruction"] logger.debug(f"Using system instruction: {system_instruction}") if system_instruction: await self._send_text_event(text=system_instruction, role=Role.SYSTEM)