Merge pull request #4374 from pipecat-ai/mb/fix-daily-runner-room-props

Expire runner-created Daily rooms after 4h
This commit is contained in:
Mark Backman
2026-04-27 09:07:31 -04:00
committed by GitHub
2 changed files with 21 additions and 4 deletions

View File

@@ -0,0 +1 @@
- Daily rooms created by the development runner (`pipecat.runner.run`) now expire after 4 hours with `eject_at_room_exp=True`, mirroring Pipecat Cloud's max session limit. Previously, runner-created rooms inherited a 2-hour expiration on the default code paths and had no expiration at all when callers posted partial `dailyRoomProperties` (e.g. `{"start_video_off": true}`) to `/start`, causing rooms to accumulate indefinitely. Explicit `exp` and `eject_at_room_exp` values in `dailyRoomProperties` are still respected.

View File

@@ -70,6 +70,7 @@ import asyncio
import mimetypes import mimetypes
import os import os
import sys import sys
import time
import uuid import uuid
from contextlib import asynccontextmanager from contextlib import asynccontextmanager
from http import HTTPMethod from http import HTTPMethod
@@ -106,6 +107,9 @@ os.environ["ENV"] = "local"
TELEPHONY_TRANSPORTS = ["twilio", "telnyx", "plivo", "exotel"] TELEPHONY_TRANSPORTS = ["twilio", "telnyx", "plivo", "exotel"]
# Mirror Pipecat Cloud's 4-hour max session limit so dev rooms get cleaned up.
PIPECAT_ROOM_EXP_HOURS = 4.0
RUNNER_DOWNLOADS_FOLDER: str | None = None RUNNER_DOWNLOADS_FOLDER: str | None = None
RUNNER_HOST: str = "localhost" RUNNER_HOST: str = "localhost"
RUNNER_PORT: int = 7860 RUNNER_PORT: int = 7860
@@ -546,7 +550,7 @@ def _setup_daily_routes(app: FastAPI, args: argparse.Namespace):
from pipecat.runner.daily import configure from pipecat.runner.daily import configure
async with aiohttp.ClientSession() as session: async with aiohttp.ClientSession() as session:
room_url, token = await configure(session) room_url, token = await configure(session, room_exp_duration=PIPECAT_ROOM_EXP_HOURS)
# Start the bot in the background with empty body for GET requests # Start the bot in the background with empty body for GET requests
bot_module = _get_bot_module() bot_module = _get_bot_module()
@@ -604,6 +608,11 @@ def _setup_daily_routes(app: FastAPI, args: argparse.Namespace):
# Parse dailyRoomProperties if provided # Parse dailyRoomProperties if provided
room_properties = None room_properties = None
if daily_room_properties_dict: if daily_room_properties_dict:
# Apply Pipecat Cloud's session policy if caller didn't override.
daily_room_properties_dict.setdefault(
"exp", time.time() + PIPECAT_ROOM_EXP_HOURS * 3600
)
daily_room_properties_dict.setdefault("eject_at_room_exp", True)
try: try:
room_properties = DailyRoomProperties(**daily_room_properties_dict) room_properties = DailyRoomProperties(**daily_room_properties_dict)
logger.debug(f"Using custom room properties: {room_properties}") logger.debug(f"Using custom room properties: {room_properties}")
@@ -624,7 +633,10 @@ def _setup_daily_routes(app: FastAPI, args: argparse.Namespace):
# Continue without custom properties # Continue without custom properties
room_url, token = await configure( room_url, token = await configure(
session, room_properties=room_properties, token_properties=token_properties session,
room_exp_duration=PIPECAT_ROOM_EXP_HOURS,
room_properties=room_properties,
token_properties=token_properties,
) )
runner_args = DailyRunnerArguments(room_url=room_url, token=token, body=body) runner_args = DailyRunnerArguments(room_url=room_url, token=token, body=body)
result = { result = {
@@ -699,7 +711,11 @@ def _setup_daily_routes(app: FastAPI, args: argparse.Namespace):
# Create Daily room with SIP capabilities # Create Daily room with SIP capabilities
async with aiohttp.ClientSession() as session: async with aiohttp.ClientSession() as session:
try: try:
room_config = await configure(session, sip_caller_phone=data.get("From")) room_config = await configure(
session,
sip_caller_phone=data.get("From"),
room_exp_duration=PIPECAT_ROOM_EXP_HOURS,
)
except Exception as e: except Exception as e:
logger.error(f"Failed to create Daily room: {e}") logger.error(f"Failed to create Daily room: {e}")
raise HTTPException( raise HTTPException(
@@ -819,7 +835,7 @@ async def _run_daily_direct(args: argparse.Namespace):
logger.info("Running with direct Daily connection...") logger.info("Running with direct Daily connection...")
async with aiohttp.ClientSession() as session: async with aiohttp.ClientSession() as session:
room_url, token = await configure(session) room_url, token = await configure(session, room_exp_duration=PIPECAT_ROOM_EXP_HOURS)
# Direct connections have no request body, so use empty dict # Direct connections have no request body, so use empty dict
runner_args = DailyRunnerArguments(room_url=room_url, token=token) runner_args = DailyRunnerArguments(room_url=room_url, token=token)