Merge pull request #3354 from pipecat-ai/pk/fix-aws-nova-sonic-example-for-nova-2-sonic

Fix the 20e example to use the proper conversation-start pattern for …
This commit is contained in:
kompfner
2026-01-05 11:17:57 -05:00
committed by GitHub

View File

@@ -105,15 +105,18 @@ async def load_conversation(params: FunctionCallParams):
try: try:
with open(filename, "r") as file: with open(filename, "r") as file:
messages = json.load(file) messages = json.load(file)
messages.append( # HACK: if using the older Nova Sonic (pre-2) model, you need a special way of
{ # triggering the first assistant response. The call to trigger_assistant_response(),
"role": "user", # commented out below, is part of this.
"content": f"{AWSNovaSonicLLMService.AWAIT_TRIGGER_ASSISTANT_RESPONSE_INSTRUCTION}", # messages.append(
} # {
) # "role": "user",
# "content": f"{AWSNovaSonicLLMService.AWAIT_TRIGGER_ASSISTANT_RESPONSE_INSTRUCTION}",
# }
# )
params.context.set_messages(messages) params.context.set_messages(messages)
await params.llm.reset_conversation() await params.llm.reset_conversation()
await params.llm.trigger_assistant_response() # await params.llm.trigger_assistant_response()
except Exception as e: except Exception as e:
await params.result_callback({"success": False, "error": str(e)}) await params.result_callback({"success": False, "error": str(e)})
@@ -199,14 +202,14 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments):
logger.info(f"Starting bot") logger.info(f"Starting bot")
# Specify initial system instruction. # Specify initial system instruction.
# HACK: note that, for now, we need to inject a special bit of text into this instruction to
# allow the first assistant response to be programmatically triggered (which happens in the
# on_client_connected handler, below)
system_instruction = ( system_instruction = (
"You are a friendly assistant. The user and you will engage in a spoken dialog exchanging " "You are a friendly assistant. The user and you will engage in a spoken dialog exchanging "
"the transcripts of a natural real-time conversation. Keep your responses short, generally " "the transcripts of a natural real-time conversation. Keep your responses short, generally "
"two or three sentences for chatty scenarios. " "two or three sentences for chatty scenarios. "
f"{AWSNovaSonicLLMService.AWAIT_TRIGGER_ASSISTANT_RESPONSE_INSTRUCTION}" # HACK: if using the older Nova Sonic (pre-2) model, note that you need to inject a special
# bit of text into this instruction to allow the first assistant response to be
# programmatically triggered (which happens in the on_client_connected handler)
# f"{AWSNovaSonicLLMService.AWAIT_TRIGGER_ASSISTANT_RESPONSE_INSTRUCTION}"
) )
llm = AWSNovaSonicLLMService( llm = AWSNovaSonicLLMService(
@@ -228,6 +231,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments):
context = LLMContext( context = LLMContext(
messages=[ messages=[
{"role": "system", "content": f"{system_instruction}"}, {"role": "system", "content": f"{system_instruction}"},
{"role": "user", "content": "Hello!"},
], ],
tools=tools, tools=tools,
) )
@@ -257,10 +261,10 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments):
logger.info(f"Client connected") logger.info(f"Client connected")
# Kick off the conversation. # Kick off the conversation.
await task.queue_frames([LLMRunFrame()]) await task.queue_frames([LLMRunFrame()])
# HACK: for now, we need this special way of triggering the first assistant response in AWS # HACK: if using the older Nova Sonic (pre-2) model, you need this special way of
# Nova Sonic. Note that this trigger requires a special corresponding bit of text in the # triggering the first assistant response. Note that this trigger requires a special
# system instruction. In the future, simply queueing the context frame should be sufficient. # corresponding bit of text in the system instruction.
await llm.trigger_assistant_response() # await llm.trigger_assistant_response()
@transport.event_handler("on_client_disconnected") @transport.event_handler("on_client_disconnected")
async def on_client_disconnected(transport, client): async def on_client_disconnected(transport, client):