Gate chat interaction on Twitch live status
This commit is contained in:
40
app/main.py
40
app/main.py
@@ -16,6 +16,7 @@ from app.memory.models import AgentActionType
|
||||
from app.memory.repository import Repository
|
||||
from app.exports.markdown import MarkdownExporter
|
||||
from app.twitch.chat import TwitchChatMessage, TwitchIRCClient, set_active_client
|
||||
from app.twitch.live import TwitchLiveStatusService
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -45,6 +46,7 @@ agent_loop_task: asyncio.Task | None = None
|
||||
twitch_chat_client: TwitchIRCClient | None = None
|
||||
twitch_chat_task: asyncio.Task | None = None
|
||||
twitch_session_id: str | None = None
|
||||
twitch_live_status: TwitchLiveStatusService | None = None
|
||||
|
||||
|
||||
async def require_admin(
|
||||
@@ -88,6 +90,16 @@ def twitch_configured() -> bool:
|
||||
)
|
||||
|
||||
|
||||
async def channel_is_live_for_chat(channel_name: str) -> bool:
|
||||
"""Return whether the agent may interact with chat for a channel."""
|
||||
if not settings.TWITCH_REQUIRE_LIVE_STREAM:
|
||||
return True
|
||||
if not twitch_live_status:
|
||||
return False
|
||||
status = await twitch_live_status.get_status(channel_name)
|
||||
return status.is_live
|
||||
|
||||
|
||||
async def get_or_create_twitch_session(channel_name: str) -> str:
|
||||
"""Use an active session for the Twitch channel, or create one."""
|
||||
if not orchestrator:
|
||||
@@ -140,12 +152,16 @@ async def start_twitch_chat() -> None:
|
||||
@app.on_event("startup")
|
||||
async def startup_event():
|
||||
"""Initialize database and services on startup."""
|
||||
global orchestrator, agent_loop_task
|
||||
global orchestrator, agent_loop_task, twitch_live_status
|
||||
try:
|
||||
await init_db()
|
||||
twitch_live_status = TwitchLiveStatusService(
|
||||
cache_seconds=settings.TWITCH_LIVE_STATUS_CACHE_SECONDS
|
||||
)
|
||||
orchestrator = AgentOrchestrator(
|
||||
loop_interval_seconds=settings.AGENT_LOOP_INTERVAL_SECONDS
|
||||
)
|
||||
orchestrator.set_chat_interaction_gate(channel_is_live_for_chat)
|
||||
await orchestrator.restore_active_sessions()
|
||||
await start_twitch_chat()
|
||||
agent_loop_task = asyncio.create_task(agent_loop())
|
||||
@@ -158,7 +174,7 @@ async def startup_event():
|
||||
@app.on_event("shutdown")
|
||||
async def shutdown_event():
|
||||
"""Clean up resources on shutdown."""
|
||||
global twitch_chat_client
|
||||
global twitch_chat_client, twitch_live_status
|
||||
|
||||
if twitch_chat_task:
|
||||
twitch_chat_task.cancel()
|
||||
@@ -168,6 +184,7 @@ async def shutdown_event():
|
||||
await twitch_chat_client.disconnect()
|
||||
set_active_client(None)
|
||||
twitch_chat_client = None
|
||||
twitch_live_status = None
|
||||
if agent_loop_task:
|
||||
agent_loop_task.cancel()
|
||||
with suppress(asyncio.CancelledError):
|
||||
@@ -470,9 +487,16 @@ async def get_twitch_status() -> dict:
|
||||
"""Get Twitch chat connection status."""
|
||||
configured = twitch_configured()
|
||||
client_status = twitch_chat_client.status() if twitch_chat_client else {}
|
||||
live_status = None
|
||||
if twitch_live_status and settings.TWITCH_CHANNEL_NAME:
|
||||
live_status = (
|
||||
await twitch_live_status.get_status(settings.TWITCH_CHANNEL_NAME)
|
||||
).to_dict()
|
||||
return {
|
||||
"configured": configured,
|
||||
"running": bool(twitch_chat_task and not twitch_chat_task.done()),
|
||||
"require_live_stream": settings.TWITCH_REQUIRE_LIVE_STREAM,
|
||||
"live_status": live_status,
|
||||
"session_id": twitch_session_id,
|
||||
**client_status,
|
||||
"timestamp": datetime.utcnow().isoformat(),
|
||||
@@ -508,6 +532,15 @@ async def get_current_stream_status() -> dict:
|
||||
dashboard_data = serialize_dashboard(dashboard)
|
||||
runtime = orchestrator.get_hearthkeeper_runtime_status(session_id)
|
||||
twitch_status = twitch_chat_client.status() if twitch_chat_client else {}
|
||||
live_status = None
|
||||
if twitch_live_status:
|
||||
live_status = (
|
||||
await twitch_live_status.get_status(session_info["channel_name"])
|
||||
).to_dict()
|
||||
chat_interaction_allowed = (
|
||||
not settings.TWITCH_REQUIRE_LIVE_STREAM
|
||||
or bool(live_status and live_status["is_live"])
|
||||
)
|
||||
|
||||
return {
|
||||
"session": {
|
||||
@@ -523,6 +556,8 @@ async def get_current_stream_status() -> dict:
|
||||
"twitch": {
|
||||
"configured": twitch_configured(),
|
||||
"running": bool(twitch_chat_task and not twitch_chat_task.done()),
|
||||
"require_live_stream": settings.TWITCH_REQUIRE_LIVE_STREAM,
|
||||
"live_status": live_status,
|
||||
"session_id": twitch_session_id,
|
||||
**twitch_status,
|
||||
},
|
||||
@@ -534,6 +569,7 @@ async def get_current_stream_status() -> dict:
|
||||
},
|
||||
"hearthkeeper": {
|
||||
**runtime,
|
||||
"chat_interaction_allowed": chat_interaction_allowed,
|
||||
"last_human_chat_at": (
|
||||
latest_human_message.timestamp.isoformat()
|
||||
if latest_human_message
|
||||
|
||||
Reference in New Issue
Block a user