is there a problem with this code to verify that s...
# ask-ai
s
is there a problem with this code to verify that someone answered?
Copy code
@ctx.room.on("participant_attributes_changed")
    def _on_participant_attributes_changed(
        changed_attributes: dict[str, str], participant: rtc.Participant
    ):
        if (
            participant.kind == rtc.ParticipantKind.PARTICIPANT_KIND_SIP
            and "sip.callStatus" in changed_attributes
        ):
            call_status = changed_attributes["sip.callStatus"]
            if call_status == "active":
                <http://logger.info|logger.info>(f"Callee answered the call (room: {ctx.room.name})")
                nonlocal call_was_answered
                call_was_answered = True
                nonlocal call_answered_at
                call_answered_at = datetime.now()

                async def say_first_sentence():
                    <http://logger.info|logger.info>(f"Generating first sentence: {first_sentence}")
                    await session.say(first_sentence)
                    <http://logger.info|logger.info>("First sentence delivered")

                task = asyncio.create_task(say_first_sentence())
                task.add_done_callback(
                    lambda t: <http://logger.info|logger.info>(f"First sentence task finished: {t.result()}")
                )
t
Thanks for reaching out, aric. I'm an AI assistant and I'm here to help. Give me a moment while I research this topic.
Thanks — I checked the snippet you shared (you're asking whether it correctly detects an answered SIP call and triggers the agent to speak). The logic is correct and will work, with a few optional improvements you may want to add. What’s correct • Listening for the
participant_attributes_changed
event and checking
participant.kind == rtc.ParticipantKind.PARTICIPANT_KIND_SIP
targets SIP participants. • Checking
"sip.callStatus"
in
changed_attributes
and testing for
"active"
correctly detects when the callee answered. • Creating an async task for
session.say(...)
avoids blocking the event handler; the
add_done_callback
provides completion logging. • Using
nonlocal
for
call_was_answered
and
call_answered_at
is valid if those variables are defined in the enclosing scope. Optional recommendations (not required to function) • Add a guard to avoid handling duplicate events: ◦ e.g.,
if call_was_answered: return
before you set it. • Add try/except around
session.say(...)
inside
say_first_sentence()
to catch TTS/network errors and log them. • Keep a reference to tasks (e.g., append to a list) until they finish to avoid accidental GC; your
add_done_callback
helps but storing tasks is more explicit. • Include identifying info in logs (like
participant.identity
or
ctx.room.name
) for easier debugging. • If timing matters, consider recording
call_answered_at
before creating the task. If you’d like, I can: • Show a short revised snippet with the try/except and idempotency guard. • Help add task-tracking boilerplate. Which would you prefer? Sources: Participant attributes and metadata | LiveKit docs | Handling events | LiveKit docs | SIP Lifecycle Management Agent | LiveKit docs | Job lifecycle | LiveKit docs | Agents telephony integration | LiveKit docs