[split-required] Split remaining 500-680 LOC files (final batch)
website (17 pages + 3 components): - multiplayer/wizard, middleware/wizard+test-wizard, communication - builds/wizard, staff-search, voice, sbom/wizard - foerderantrag, mail/tasks, tools/communication, sbom - compliance/evidence, uni-crawler, brandbook (already done) - CollectionsTab, IngestionTab, RiskHeatmap backend-lehrer (5 files): - letters_api (641 → 2), certificates_api (636 → 2) - alerts_agent/db/models (636 → 3) - llm_gateway/communication_service (614 → 2) - game/database already done in prior batch klausur-service (2 files): - hybrid_vocab_extractor (664 → 2) - klausur-service/frontend: api.ts (620 → 3), EHUploadWizard (591 → 2) voice-service (3 files): - bqas/rag_judge (618 → 3), runner (529 → 2) - enhanced_task_orchestrator (519 → 2) studio-v2 (6 files): - korrektur/[klausurId] (578 → 4), fairness (569 → 2) - AlertsWizard (552 → 2), OnboardingWizard (513 → 2) - korrektur/api.ts (506 → 3), geo-lernwelt (501 → 2) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
141
voice-service/services/enhanced_orchestrator_session.py
Normal file
141
voice-service/services/enhanced_orchestrator_session.py
Normal file
@@ -0,0 +1,141 @@
|
||||
"""
|
||||
Enhanced Orchestrator Session Management
|
||||
|
||||
Session lifecycle methods extracted from EnhancedTaskOrchestrator.
|
||||
"""
|
||||
import structlog
|
||||
from typing import Optional, Dict, Any
|
||||
|
||||
from sessions.session_manager import SessionManager, AgentSession, SessionState
|
||||
from sessions.heartbeat import HeartbeatMonitor, HeartbeatClient
|
||||
from brain.context_manager import ContextManager
|
||||
|
||||
logger = structlog.get_logger(__name__)
|
||||
|
||||
|
||||
async def create_session(
|
||||
session_manager: SessionManager,
|
||||
context_manager: ContextManager,
|
||||
heartbeat: HeartbeatMonitor,
|
||||
voice_sessions: Dict[str, AgentSession],
|
||||
heartbeat_clients: Dict[str, HeartbeatClient],
|
||||
voice_session_id: str,
|
||||
user_id: str = "",
|
||||
metadata: Optional[Dict[str, Any]] = None,
|
||||
system_prompt: str = "",
|
||||
) -> AgentSession:
|
||||
"""Creates a new agent session for a voice session."""
|
||||
session = await session_manager.create_session(
|
||||
agent_type="voice-orchestrator",
|
||||
user_id=user_id,
|
||||
context={"voice_session_id": voice_session_id},
|
||||
metadata=metadata
|
||||
)
|
||||
|
||||
context_manager.create_context(
|
||||
session_id=session.session_id,
|
||||
system_prompt=system_prompt,
|
||||
max_messages=50
|
||||
)
|
||||
|
||||
heartbeat_client = HeartbeatClient(
|
||||
session_id=session.session_id,
|
||||
monitor=heartbeat,
|
||||
interval_seconds=10
|
||||
)
|
||||
await heartbeat_client.start()
|
||||
heartbeat.register(session.session_id, "voice-orchestrator")
|
||||
|
||||
voice_sessions[voice_session_id] = session
|
||||
heartbeat_clients[session.session_id] = heartbeat_client
|
||||
|
||||
logger.info(
|
||||
"Created agent session",
|
||||
session_id=session.session_id[:8],
|
||||
voice_session_id=voice_session_id
|
||||
)
|
||||
return session
|
||||
|
||||
|
||||
async def end_session(
|
||||
session_manager: SessionManager,
|
||||
heartbeat: HeartbeatMonitor,
|
||||
voice_sessions: Dict[str, AgentSession],
|
||||
heartbeat_clients: Dict[str, HeartbeatClient],
|
||||
voice_session_id: str,
|
||||
) -> None:
|
||||
"""Ends an agent session."""
|
||||
session = voice_sessions.get(voice_session_id)
|
||||
if not session:
|
||||
return
|
||||
|
||||
if session.session_id in heartbeat_clients:
|
||||
await heartbeat_clients[session.session_id].stop()
|
||||
del heartbeat_clients[session.session_id]
|
||||
|
||||
heartbeat.unregister(session.session_id)
|
||||
session.complete()
|
||||
await session_manager.update_session(session)
|
||||
del voice_sessions[voice_session_id]
|
||||
|
||||
logger.info(
|
||||
"Ended agent session",
|
||||
session_id=session.session_id[:8],
|
||||
duration_seconds=session.get_duration().total_seconds()
|
||||
)
|
||||
|
||||
|
||||
async def recover_session(
|
||||
session_manager: SessionManager,
|
||||
heartbeat: HeartbeatMonitor,
|
||||
voice_sessions: Dict[str, AgentSession],
|
||||
heartbeat_clients: Dict[str, HeartbeatClient],
|
||||
tasks: Dict[str, Any],
|
||||
process_task_fn,
|
||||
voice_session_id: str,
|
||||
session_id: str,
|
||||
) -> Optional[AgentSession]:
|
||||
"""Recovers a session from checkpoint."""
|
||||
session = await session_manager.get_session(session_id)
|
||||
|
||||
if not session:
|
||||
logger.warning("Session not found for recovery", session_id=session_id)
|
||||
return None
|
||||
|
||||
if session.state != SessionState.ACTIVE:
|
||||
logger.warning(
|
||||
"Session not active for recovery",
|
||||
session_id=session_id, state=session.state.value
|
||||
)
|
||||
return None
|
||||
|
||||
session.resume()
|
||||
|
||||
heartbeat_client = HeartbeatClient(
|
||||
session_id=session.session_id,
|
||||
monitor=heartbeat,
|
||||
interval_seconds=10
|
||||
)
|
||||
await heartbeat_client.start()
|
||||
heartbeat.register(session.session_id, "voice-orchestrator")
|
||||
|
||||
voice_sessions[voice_session_id] = session
|
||||
heartbeat_clients[session.session_id] = heartbeat_client
|
||||
|
||||
# Recover pending tasks from checkpoints
|
||||
from models.task import TaskState
|
||||
for checkpoint in reversed(session.checkpoints):
|
||||
if checkpoint.name == "task_queued":
|
||||
task_id = checkpoint.data.get("task_id")
|
||||
if task_id and task_id in tasks:
|
||||
task = tasks[task_id]
|
||||
if task.state == TaskState.QUEUED:
|
||||
await process_task_fn(task)
|
||||
logger.info("Recovered pending task", task_id=task_id[:8])
|
||||
|
||||
logger.info(
|
||||
"Recovered session",
|
||||
session_id=session.session_id[:8],
|
||||
checkpoints=len(session.checkpoints)
|
||||
)
|
||||
return session
|
||||
Reference in New Issue
Block a user