How do I manually add messages to the chat from an...
# ask-ai
b
How do I manually add messages to the chat from an rpc_method?
t
Thanks for reaching out, aile. I'm an AI assistant and I'm here to help. Give me a moment while I research this topic.
Could you clarify your use case for adding messages to the chat from an
rpc_method
? For example, are you trying to send system messages, or are you implementing a custom feature? Additionally, are you using any specific SDK or API for this?
b
@ctx.room.local_participant.register_rpc_method("artwork_description") async def artwork_description(data: rtc.RpcInvocationData): await artwork_handler.handle_artwork_description(data, session) async def handle_artwork_description(self, data: rtc.RpcInvocationData, session): """Handle artwork description RPC request.""" payload = data.payload payload = json.loads(payload) tile_number = payload.get("tileNumber") language = payload.get("language", "en-US") # Default to English profile = payload.get("profile", "adult") # Default to adult self.logger.info( f"Description requested for element {tile_number} by {data.caller_identity}" ) # Get artwork information from database artwork_info = self.artwork_db.get_artwork_info( artwork_id=str(tile_number), language=language, preset=profile ) if artwork_info: # Add the user's question to chat context user_question = f"Tell me about {artwork_info.name} by {artwork_info.artist}" user_message = ChatMessage(role="user", content=[user_question]) session.history.insert(user_message) description_message = artwork_info.description self.logger.info( f"Retrieved artwork info: {artwork_info.name} by {artwork_info.artist} " f"(Language: {artwork_info.language}, Preset: {artwork_info.preset})" ) # Check for precomputed audio file audio_filename = ( f"{artwork_info.artwork_id}_{artwork_info.language}_{artwork_info.preset}.mp3" ) audio_path = os.path.join( os.path.dirname(os.path.dirname(os.path.abspath(file))), "media", "precomputed_answers", "audio", audio_filename, ) self.logger.info(f"Checking for precomputed audio file: {audio_path}") if os.path.exists(audio_path): try: # Load MP3 file using pydub audio_segment = AudioSegment.from_mp3(audio_path) # Convert to raw audio data # pydub exports as 16-bit PCM by default audio_segment = audio_segment.set_frame_rate(48000).set_channels(1) raw_audio = audio_segment.raw_data # Get audio properties sample_rate = audio_segment.frame_rate num_channels = audio_segment.channels samples_per_channel = len(audio_segment.get_array_of_samples()) audio_frame = rtc.AudioFrame( data=raw_audio, sample_rate=sample_rate, num_channels=num_channels, samples_per_channel=samples_per_channel, ) async def audio_generator(): yield audio_frame self.logger.info( f"Using precomputed audio for artwork {tile_number}: {audio_filename}" ) # Add the assistant's response to chat context first assistant_message = ChatMessage(role="assistant", content=[description_message]) session.history.insert(assistant_message) await session.say( artwork_info.description, audio=audio_generator(), add_to_chat_ctx=False ) return except Exception as e: self.logger.error(f"Error reading MP3 file {audio_path}: {e}") self.logger.info("Falling back to text-to-speech synthesis") else: # Fallback message if artwork not found user_question = f"Tell me about artwork number {tile_number}" user_message = ChatMessage(role="user", content=[user_question]) session.history.insert(user_message) description_message = f"I don't have information about artwork number {tile_number} yet. What would you like to know about it?" self.logger.warning(f"No artwork information found for ID {tile_number}") # Add the assistant's response to chat context first assistant_message = ChatMessage(role="assistant", content=[description_message]) session.history.insert(assistant_message) await session.say( description_message, allow_interruptions=True, add_to_chat_ctx=False, )
t
Hey! If you want to manually add messages to the chat from an
rpc_method
, you can use the
session.history.insert()
method to add a
ChatMessage
object. Looks like you’re already doing this just right in your code: • For the user's question, you create a
ChatMessage
with the role "user" and add it to the session history like this:
Copy code
user_message = ChatMessage(role="user", content=[user_question])
session.history.insert(user_message)
• Then, for the assistant's response, you create another
ChatMessage
with the role "assistant" and insert it the same way:
Copy code
assistant_message = ChatMessage(role="assistant", content=[description_message])
session.history.insert(assistant_message)
This way, both what the user says and what the assistant replies get added to the chat history smoothly. If you want me to walk you through anything else or have more questions, just let me know—I’m here to help!
b
class MuseMindAgent(Agent): def __init__(self, agent_config: AgentConfigLoader) -> None: if agent_config is None: raise ValueError("agent_config must not be None") super().__init__( instructions=""" You are a helpful MuseMind agent specializing in art and cultural experiences. You can provide detailed information about artworks, artists, and cultural contexts. """, stt=agent_config.get_stt_service(), llm=agent_config.get_llm_service(), tts=agent_config.get_tts_service(), vad=silero.VAD.load(), turn_detection="manual", # @green-gpu-45299 some refs here: https://github.com/livekit/agents/blob/9c76e2e67f9817dc63b5db07540bec3ef1b55ae1/examples/voice_agents/push_to_talk.py#L1-L58 use_tts_aligned_transcript=True, ) async def on_user_turn_completed(self, turn_ctx: ChatContext, new_message: ChatMessage) -> None: if not new_message.text_content: logger.warning("No text content in user turn, ignoring empty user turn") raise StopResponse() async def llm_node( self, chat_ctx: llm.ChatContext, tools: list[FunctionTool], model_settings: ModelSettings ) -> AsyncIterable[llm.ChatChunk]: # log the current chat context for item in chat_ctx.items: if isinstance(item, ChatMessage): logger.info(f"Chat context item: {item.role} - {item.content}") # Insert custom preprocessing here async for chunk in Agent.default.llm_node(self, chat_ctx, tools, model_settings): # Insert custom postprocessing here yield chunk Ok but then in my custom agent when I log the chat context, such messages added are not there!
t
I don't have the answer you're looking for. You could also try asking your question: • in one of the other Slack channels or • to https://deepwiki.com/livekit/livekit_composite which is trained on all LiveKit source code If you find the answer, please post it here to help others!