salmon-belgium-62133
12/29/2025, 1:36 PMtall-airline-16756
12/29/2025, 1:36 PMtall-airline-16756
12/29/2025, 1:36 PMsession.history. It contains all transcript items (user and assistant) with metadata like role and timestamps.
◦ Python example:
history = session.history
for item in history:
print(f"{item.role}: {item.text}")
• Node/TS: const history = session.history;
• For real-time consumption, listen to the conversation_item_added event to react as new messages arrive:
◦ Example handler: on("conversation_item_added", item => { /* handle item */ })
• Important limitations and best practice:
◦ Realtime models maintain conversation context internally; you don’t manually append to a ChatContext the same way you would for a non-realtime LLM.
◦ Loading prior history into a realtime session is supported only in text form and can cause the model to respond in text-only (loss of audio behavior). If you need precise control over full history and multimodal behavior, use the half-cascade approach:
▪︎ Use the realtime model for speech understanding (modalities = ["text"]),
▪︎ Use a separate TTS plugin for audio output,
▪︎ Store transcripts in a standalone ChatContext,
▪︎ Pass that context to an LLM instance when you need full history control.
If you want, tell me:
• which SDK/language you’re using (Python/Node/etc.), and
• whether you need audio output preserved when reloading history — I’ll give exact code snippets for your case. Sources: Gemini Live API plugin | LiveKit docs | Agents and handoffs | LiveKit docs | Text and transcriptions | LiveKit docs | Realtime model plugins | LiveKit Docssalmon-belgium-62133
12/29/2025, 1:48 PMtall-airline-16756
12/29/2025, 1:48 PMconversation_item_added to capture each message).
• Extract role, text, timestamps, and any metadata from the event’s ChatItem.
• Send that payload to your external service (HTTP POST, DB insert, publish to queue).
• Optionally persist incremental transcripts as they arrive (for near-real-time storage) and reconcile with final messages on turn completion.
Python example (async):
from livekit.agents import AgentSession
import aiohttp
session = AgentSession(...) # your realtime Gemini agent session
@session.on("conversation_item_added")
async def on_conversation_item(item):
role = item.message.role
timestamp = item.message.created_at
content = ""
for part in item.message.content:
if isinstance(part, str):
content += part
elif hasattr(part, "text"):
content += part.text
payload = {"role": role, "text": content, "timestamp": timestamp}
async with aiohttp.ClientSession() as http:
await <http://http.post|http.post>("<https://your-external-service.example.com/chat>", json=payload)
Node/TypeScript sketch:
const session = new AgentSession(...);
session.on("conversation_item_added", async (item) => {
const role = item.message.role;
const timestamp = item.message.created_at;
let text = "";
for (const part of item.message.content) {
if (typeof part === "string") text += part;
else if (part.text) text += part.text;
}
await fetch("<https://your-external-service.example.com/chat>", {
method: "POST",
headers: {"Content-Type":"application/json"},
body: JSON.stringify({ role, text, timestamp })
});
});
Notes & best practices
• The event includes user and assistant messages and metadata (role, timestamps).
• If you need audio or richer multimodal data, include relevant fields from the ChatItem (images, attachments) when available.
• If you must reload history later, store text-based transcripts; realtime models only support loading history in text form and loading large histories can affect audio behavior.
• To avoid duplicates, include a unique message ID or use the item’s created timestamp when upserting into your storage.
If you tell me which SDK/language and which external service (Postgres, Firebase, S3, HTTP API, etc.) you plan to use, I’ll give a tailored example and schema.
Sources: Text and transcriptions | LiveKit docs | Agent session | LiveKit docs | How to capture real-time agent transcriptions during conversations | Agent speech and audio | LiveKit docssalmon-belgium-62133
12/29/2025, 1:49 PMtall-airline-16756
12/29/2025, 1:49 PMsession.history when the room/session is closing and then store it externally.
What I’m addressing: retrieving full chat history at shutdown and persisting it.
How to do it (summary)
• Add a shutdown callback or listen for your session/room-close event.
• In that handler, iterate session.history (contains items with role, text, timestamps, metadata).
• Send the assembled payload to your external service (HTTP endpoint, DB insert, S3, etc.) and handle retries/upsserts to avoid data loss.
Python shutdown example:
async def on_shutdown():
records = []
for item in session.history:
records.append({
"id": item.message.id,
"role": item.message.role,
"text": "".join(part if isinstance(part, str) else getattr(part, "text", "") for part in item.message.content),
"timestamp": item.message.created_at,
})
# send `records` to your external service
await send_to_external_service(records)
ctx.add_shutdown_callback(on_shutdown)
Notes and best practices
• session.history contains the complete transcript up to close — use it for a final, authoritative export.
• Include message IDs or timestamps to avoid duplicates when upserting.
• If you need near-real-time backup too, combine this final export with streaming writes from conversation_item_added.
• If you require audio/multimodal artifacts, make sure you also persist those files/refs during the session (history is text-first).
Tell me which SDK/language and which external storage you’ll use (Postgres, Firebase, S3, HTTP API, etc.), and I’ll provide a concrete example and schema.
Sources: Agents and handoffs | LiveKit docs | Collect recording consent with tasks | LiveKit docssalmon-belgium-62133
12/29/2025, 2:06 PMtall-airline-16756
12/29/2025, 2:07 PM.messages list (or text_content() helpers) instead. Then serialize/send that list to your external service in your shutdown handler.
If you want, tell me:
• which SDK/language (Python or Node/TS), and
• the code snippet where the error occurs (the handler you added for room close),
and I’ll give a corrected, copy-paste example that writes session.history.messages to your storage (HTTP, Postgres, S3, etc.).
Sources: Text and transcriptions | LiveKit docs | Agents and handoffs | LiveKit docs | Vision | LiveKit docs