Changes related to Nova 2 Sonic's support for the model speaking first
This commit is contained in:
@@ -91,14 +91,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}"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Create the AWS Nova Sonic LLM service
|
# Create the AWS Nova Sonic LLM service
|
||||||
@@ -167,10 +167,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()
|
||||||
|
|
||||||
# Handle client disconnection events
|
# Handle client disconnection events
|
||||||
@transport.event_handler("on_client_disconnected")
|
@transport.event_handler("on_client_disconnected")
|
||||||
|
|||||||
@@ -618,10 +618,18 @@ class AWSNovaSonicLLMService(LLMService):
|
|||||||
)
|
)
|
||||||
return BedrockRuntimeClient(config=config)
|
return BedrockRuntimeClient(config=config)
|
||||||
|
|
||||||
|
def _is_first_generation_sonic_model(self) -> bool:
|
||||||
|
# Nova Sonic (the older model) is identified by "amazon.nova-sonic-v1:0"
|
||||||
|
return self._model == "amazon.nova-sonic-v1:0"
|
||||||
|
|
||||||
def _is_endpointing_sensitivity_supported(self) -> bool:
|
def _is_endpointing_sensitivity_supported(self) -> bool:
|
||||||
# endpointing_sensitivity is only supported with Nova 2 Sonic (and,
|
# endpointing_sensitivity is only supported with Nova 2 Sonic (and,
|
||||||
# presumably, future models)
|
# presumably, future models)
|
||||||
return self._model != "amazon.nova-sonic-v1:0"
|
return not self._is_first_generation_sonic_model()
|
||||||
|
|
||||||
|
def _is_assistant_response_trigger_needed(self) -> bool:
|
||||||
|
# Assistant response trigger audio is only needed with the older model
|
||||||
|
return self._is_first_generation_sonic_model()
|
||||||
|
|
||||||
#
|
#
|
||||||
# LLM communication: input events (pipecat -> LLM)
|
# LLM communication: input events (pipecat -> LLM)
|
||||||
@@ -1230,7 +1238,8 @@ class AWSNovaSonicLLMService(LLMService):
|
|||||||
)
|
)
|
||||||
|
|
||||||
#
|
#
|
||||||
# assistant response trigger (HACK)
|
# assistant response trigger
|
||||||
|
# HACK: only needed for the older Nova Sonic (as opposed to Nova 2 Sonic) model
|
||||||
#
|
#
|
||||||
|
|
||||||
# Class variable
|
# Class variable
|
||||||
@@ -1244,12 +1253,17 @@ class AWSNovaSonicLLMService(LLMService):
|
|||||||
|
|
||||||
Sends a pre-recorded "ready" audio trigger to prompt the assistant
|
Sends a pre-recorded "ready" audio trigger to prompt the assistant
|
||||||
to start speaking. This is useful for controlling conversation flow.
|
to start speaking. This is useful for controlling conversation flow.
|
||||||
|
|
||||||
Returns:
|
|
||||||
False if already triggering a response, True otherwise.
|
|
||||||
"""
|
"""
|
||||||
|
if not self._is_assistant_response_trigger_needed():
|
||||||
|
logger.warning(
|
||||||
|
f"Assistant response trigger not needed for model '{self._model}'; skipping. "
|
||||||
|
"An LLMRunFrame() should be sufficient to prompt the assistant to respond, "
|
||||||
|
"assuming the context ends in a user message."
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
if self._triggering_assistant_response:
|
if self._triggering_assistant_response:
|
||||||
return False
|
return
|
||||||
|
|
||||||
self._triggering_assistant_response = True
|
self._triggering_assistant_response = True
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user