mirror of
https://dev.azure.com/globalhealthx/EMR/_git/helix-engage-server
synced 2026-05-18 20:08:19 +00:00
feat(sidecar): supervisor barge endpoints — initiate, mode switch, end
Endpoints: - GET /api/supervisor/barge/sip-credentials — fetch SIP number from pool - POST /api/supervisor/barge — initiate barge via Ozonetel apiId 63 - POST /api/supervisor/barge/mode — update mode (listen/whisper/barge) - POST /api/supervisor/barge/end — cleanup session + Redis SupervisorService extended with barge session tracking (in-memory Map). Mode changes emit SSE events to agent: supervisor-whisper, supervisor-barge, supervisor-left. Listen mode is silent (no event to agent). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -34,7 +34,16 @@ export class SupervisorService implements OnModuleInit {
|
||||
private readonly activeCalls = new Map<string, ActiveCall>();
|
||||
private readonly agentStates = new Map<string, AgentStateEntry>();
|
||||
private readonly acwTimers = new Map<string, NodeJS.Timeout>();
|
||||
readonly agentStateSubject = new Subject<{ agentId: string; state: AgentOzonetelState; timestamp: string }>();
|
||||
readonly agentStateSubject = new Subject<{ agentId: string; state: AgentOzonetelState | string; timestamp: string }>();
|
||||
|
||||
// Barge session tracking — key is agentId
|
||||
private readonly bargeSessions = new Map<string, {
|
||||
supervisorId: string;
|
||||
agentId: string;
|
||||
sipNumber: string;
|
||||
mode: 'listen' | 'whisper' | 'barge';
|
||||
startedAt: string;
|
||||
}>();
|
||||
|
||||
constructor(
|
||||
private platform: PlatformGraphqlService,
|
||||
@@ -234,4 +243,42 @@ export class SupervisorService implements OnModuleInit {
|
||||
|
||||
return { date, agents: summaries, teamTotals };
|
||||
}
|
||||
|
||||
// --- Barge session management ---
|
||||
|
||||
getBargeSession(agentId: string) {
|
||||
return this.bargeSessions.get(agentId) ?? null;
|
||||
}
|
||||
|
||||
startBargeSession(session: { supervisorId: string; agentId: string; sipNumber: string; mode: 'listen' | 'whisper' | 'barge'; startedAt: string }) {
|
||||
this.bargeSessions.set(session.agentId, session);
|
||||
this.logger.log(`[BARGE] Started: ${session.supervisorId} → ${session.agentId} (${session.mode})`);
|
||||
}
|
||||
|
||||
updateBargeMode(agentId: string, mode: 'listen' | 'whisper' | 'barge') {
|
||||
const session = this.bargeSessions.get(agentId);
|
||||
if (!session) return;
|
||||
|
||||
const previousMode = session.mode;
|
||||
session.mode = mode;
|
||||
|
||||
// Emit SSE to agent — whisper/barge show indicator, listen is silent
|
||||
if (mode === 'whisper' || mode === 'barge') {
|
||||
this.agentStateSubject.next({ agentId, state: `supervisor-${mode}`, timestamp: new Date().toISOString() });
|
||||
} else if (previousMode !== 'listen') {
|
||||
// Switching back to listen from whisper/barge
|
||||
this.agentStateSubject.next({ agentId, state: 'supervisor-left', timestamp: new Date().toISOString() });
|
||||
}
|
||||
|
||||
this.logger.log(`[BARGE] Mode: ${agentId} → ${mode}`);
|
||||
}
|
||||
|
||||
endBargeSession(agentId: string) {
|
||||
const session = this.bargeSessions.get(agentId);
|
||||
if (!session) return;
|
||||
|
||||
this.bargeSessions.delete(agentId);
|
||||
this.agentStateSubject.next({ agentId, state: 'supervisor-left', timestamp: new Date().toISOString() });
|
||||
this.logger.log(`[BARGE] Ended: ${session.supervisorId} → ${agentId}`);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user