Retrieving the realtime livekit agents transcript and saving to file

Hi,
I have managed to retrieve users transcript and save it to a file however I want to also save the agents transcript to the file as well in order. This means the file will then have alternating text between the user and agent.
This is my code;

import logging

import datetime

from dotenv import load_dotenv

from livekit import agents

from livekit.agents import Agent, AgentServer, AgentSession, JobContext, room_io

from livekit.plugins import noise_cancellation, silero

load_dotenv()

class Assistant(Agent):

def _init_(self) → None:

super()._init_(

instructions=“You are a helpful voice AI assistant.”,

)

server = AgentServer()

@server.rtc_sessionserver.rtc_sessionserver.rtc_sessionserverserver.rtc_sessionserver.rtc_sessionserver.rtc_sessionserver.rtc_session()

async def entrypoint(ctx: JobContext):

session = AgentSession(

stt=“assemblyai/universal-streaming:en”,

llm=“openai/gpt-4.1-mini”,

tts=“cartesia/sonic-3”,

vad=silero.VAD.load(),

)

(at symbol here)session.on(“user_input_transcribed”)

def on_transcript(transcript):

if transcript.is_final:

timestamp = datetime.datetime.now().strftime(“%Y-%m-%d %H:%M:%S”)

with open(“user_speech_log.txt”, “a”) as f:

f.write(f"[{timestamp}] {transcript.transcript}\n")

await session.start(

agent=Assistant(),

room=ctx.room,

room_options=room_io.RoomOptions(

audio_input=room_io.AudioInputOptions(

noise_cancellation=noise_cancellation.BVC(), # Background voice cancellation

),

),

)

if _name_ == “_main_”:

logging.basicConfig(level=logging.INFO)

agents.cli.run_app(server)

If anyone knows about this I’d be super grateful. Thanks so much

Hi, you want to use conversation_item_added

but be aware of the caveats listed in that doc for realtime models.

@Archie_Enstone, conversation_item_added (Darryn’s pointer) is the one that gets you both sides: it fires for user and agent items as they’re committed, so writing from it gives the ordered, alternating log you want. Wired into your existing file-writer:

from livekit.agents.llm import ChatMessage

@session.on("conversation_item_added")
def on_item(ev):
    if not isinstance(ev.item, ChatMessage):
        return
    ts = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    with open("conversation_log.txt", "a") as f:
        f.write(f"[{ts}] {ev.item.role}: {ev.item.text_content}\n")

ev.item.role is user / assistant and ev.item.text_content is the text [ docs.livekit.io/agents/build/events; livekit/agents llm/chat_context.py ]. You can drop the separate user_input_transcribed writer, this covers both roles.

On the caveat Darryn flagged: it’s specific to realtime models. Your setup is an STT-LLM-TTS pipeline (AssemblyAI + OpenAI + Cartesia), so user transcriptions aren’t delayed or out-of-order the way they are with a realtime model, and the items land in conversational order.

Hi @Muhammad_Usman_Bashir , thanks so much for the help on this issue. I have now got it sorted and working just how I needed it for my project. Thanks so much!