Add current stream operator status
This commit is contained in:
100
app/main.py
100
app/main.py
@@ -12,6 +12,7 @@ from app.config import settings
|
||||
from app.agent.orchestrator import AgentOrchestrator
|
||||
from app.memory.database import init_db
|
||||
from app.memory.database import get_session as get_db_session
|
||||
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
|
||||
@@ -286,6 +287,30 @@ def serialize_dashboard(dashboard) -> dict:
|
||||
return Repository.serialize_dashboard(dashboard)
|
||||
|
||||
|
||||
def dashboard_status(dashboard: dict | None) -> dict:
|
||||
"""Return a compact dashboard status for operator checks."""
|
||||
if not dashboard:
|
||||
return {
|
||||
"present": False,
|
||||
"stream_title": None,
|
||||
"game": None,
|
||||
"mood": None,
|
||||
"content_angle": None,
|
||||
"session_goal_count": 0,
|
||||
"updated_at": None,
|
||||
}
|
||||
|
||||
return {
|
||||
"present": True,
|
||||
"stream_title": dashboard.get("stream_title"),
|
||||
"game": dashboard.get("game"),
|
||||
"mood": dashboard.get("mood"),
|
||||
"content_angle": dashboard.get("content_angle"),
|
||||
"session_goal_count": len(dashboard.get("session_goals") or []),
|
||||
"updated_at": dashboard.get("updated_at"),
|
||||
}
|
||||
|
||||
|
||||
@app.post("/admin/session/dashboard", dependencies=[Depends(require_admin)])
|
||||
async def save_session_dashboard(request: DashboardRequest) -> dict:
|
||||
"""Create or update the approved dashboard for a stream session."""
|
||||
@@ -396,6 +421,81 @@ async def get_twitch_status() -> dict:
|
||||
}
|
||||
|
||||
|
||||
@app.get("/admin/stream/status", dependencies=[Depends(require_admin)])
|
||||
async def get_current_stream_status() -> dict:
|
||||
"""Get one operator view of the current Twitch stream runtime state."""
|
||||
if not orchestrator:
|
||||
raise HTTPException(status_code=503, detail="Orchestrator not initialized")
|
||||
|
||||
session_id = twitch_session_id
|
||||
if not session_id and len(orchestrator.active_sessions) == 1:
|
||||
session_id = next(iter(orchestrator.active_sessions))
|
||||
if not session_id or session_id not in orchestrator.active_sessions:
|
||||
raise HTTPException(status_code=404, detail="No active stream session found")
|
||||
|
||||
session_info = orchestrator.active_sessions[session_id]
|
||||
latest_human_message = None
|
||||
latest_hearthkeeper_action = None
|
||||
dashboard = None
|
||||
async for db_session in get_db_session():
|
||||
repo = Repository(db_session)
|
||||
dashboard = await repo.get_dashboard(session_id)
|
||||
latest_human_message = await repo.get_latest_human_message(session_id)
|
||||
latest_hearthkeeper_action = await repo.get_latest_action(
|
||||
session_id=session_id,
|
||||
action_type=AgentActionType.RESPONSE,
|
||||
mode="hearthkeeper",
|
||||
)
|
||||
|
||||
dashboard_data = serialize_dashboard(dashboard)
|
||||
runtime = orchestrator.get_hearthkeeper_runtime_status(session_id)
|
||||
twitch_status = twitch_chat_client.status() if twitch_chat_client else {}
|
||||
|
||||
return {
|
||||
"session": {
|
||||
"id": session_id,
|
||||
"channel": session_info["channel_name"],
|
||||
"started_at": session_info["started_at"].isoformat(),
|
||||
"uptime_seconds": (
|
||||
datetime.utcnow() - session_info["started_at"]
|
||||
).total_seconds(),
|
||||
"message_count": session_info["message_count"],
|
||||
"theme": session_info.get("theme"),
|
||||
},
|
||||
"twitch": {
|
||||
"configured": twitch_configured(),
|
||||
"running": bool(twitch_chat_task and not twitch_chat_task.done()),
|
||||
"session_id": twitch_session_id,
|
||||
**twitch_status,
|
||||
},
|
||||
"dashboard": dashboard_status(dashboard_data),
|
||||
"loop": {
|
||||
"running": bool(agent_loop_task and not agent_loop_task.done()),
|
||||
"interval_seconds": orchestrator.loop_interval_seconds,
|
||||
"active_session_count": len(orchestrator.active_sessions),
|
||||
},
|
||||
"hearthkeeper": {
|
||||
**runtime,
|
||||
"last_human_chat_at": (
|
||||
latest_human_message.timestamp.isoformat()
|
||||
if latest_human_message
|
||||
else None
|
||||
),
|
||||
"last_posted_at": (
|
||||
latest_hearthkeeper_action.timestamp.isoformat()
|
||||
if latest_hearthkeeper_action
|
||||
else None
|
||||
),
|
||||
"last_posted_message": (
|
||||
latest_hearthkeeper_action.description
|
||||
if latest_hearthkeeper_action
|
||||
else None
|
||||
),
|
||||
},
|
||||
"timestamp": datetime.utcnow().isoformat(),
|
||||
}
|
||||
|
||||
|
||||
@app.post("/admin/loop/frequency", dependencies=[Depends(require_admin)])
|
||||
async def set_loop_frequency(interval_seconds: float = Form(...)) -> dict:
|
||||
"""Set how frequently the background agent loop runs."""
|
||||
|
||||
Reference in New Issue
Block a user