mirror of
https://dev.azure.com/globalhealthx/EMR/_git/helix-engage
synced 2026-04-11 18:28:15 +00:00
fix: SIP driven by Agent entity, token refresh, network indicator
- SIP connection only for users with Agent entity (no env var fallback) - Supervisor no longer intercepts CC agent calls - Auth controller checks Agent entity for ALL roles, not just cc-agent - Token refresh handles GraphQL UNAUTHENTICATED errors (200 with error body) - Token refresh handles sidecar 400s from expired upstream tokens - Network quality indicator in sidebar (offline/unstable/good) - Ozonetel IDLE event mapped to ready state (fixes stuck calling after canceled call) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -14,27 +14,25 @@ import { registerSipStateUpdater, connectSip, disconnectSip, getSipClient, setOu
|
||||
import { apiClient } from '@/lib/api-client';
|
||||
import type { SIPConfig } from '@/types/sip';
|
||||
|
||||
const getSipConfig = (): SIPConfig => {
|
||||
// SIP config comes exclusively from the Agent entity (stored on login).
|
||||
// No env var fallback — users without an Agent entity don't connect SIP.
|
||||
const getSipConfig = (): SIPConfig | null => {
|
||||
try {
|
||||
const stored = localStorage.getItem('helix_agent_config');
|
||||
if (stored) {
|
||||
const config = JSON.parse(stored);
|
||||
return {
|
||||
displayName: 'Helix Agent',
|
||||
uri: config.sipUri,
|
||||
password: config.sipPassword,
|
||||
wsServer: config.sipWsServer,
|
||||
stunServers: 'stun:stun.l.google.com:19302',
|
||||
};
|
||||
if (config.sipUri && config.sipWsServer) {
|
||||
return {
|
||||
displayName: 'Helix Agent',
|
||||
uri: config.sipUri,
|
||||
password: config.sipPassword,
|
||||
wsServer: config.sipWsServer,
|
||||
stunServers: 'stun:stun.l.google.com:19302',
|
||||
};
|
||||
}
|
||||
}
|
||||
} catch {}
|
||||
return {
|
||||
displayName: import.meta.env.VITE_SIP_DISPLAY_NAME ?? 'Helix Agent',
|
||||
uri: import.meta.env.VITE_SIP_URI ?? '',
|
||||
password: import.meta.env.VITE_SIP_PASSWORD ?? '',
|
||||
wsServer: import.meta.env.VITE_SIP_WS_SERVER ?? '',
|
||||
stunServers: 'stun:stun.l.google.com:19302',
|
||||
};
|
||||
return null;
|
||||
};
|
||||
|
||||
export const SipProvider = ({ children }: PropsWithChildren) => {
|
||||
@@ -55,9 +53,14 @@ export const SipProvider = ({ children }: PropsWithChildren) => {
|
||||
});
|
||||
}, [setConnectionStatus, setCallState, setCallerNumber, setCallUcid]);
|
||||
|
||||
// Auto-connect SIP on mount
|
||||
// Auto-connect SIP on mount — only if Agent entity has SIP config
|
||||
useEffect(() => {
|
||||
connectSip(getSipConfig());
|
||||
const config = getSipConfig();
|
||||
if (config) {
|
||||
connectSip(config);
|
||||
} else {
|
||||
console.log('[SIP] No agent SIP config — skipping connection');
|
||||
}
|
||||
}, []);
|
||||
|
||||
// Call duration timer
|
||||
@@ -178,7 +181,7 @@ export const useSip = () => {
|
||||
isInCall: ['ringing-in', 'ringing-out', 'active'].includes(callState),
|
||||
ozonetelStatus: 'logged-in' as const,
|
||||
ozonetelError: null as string | null,
|
||||
connect: () => connectSip(getSipConfig()),
|
||||
connect: () => { const c = getSipConfig(); if (c) connectSip(c); },
|
||||
disconnect: disconnectSip,
|
||||
makeCall,
|
||||
dialOutbound,
|
||||
|
||||
Reference in New Issue
Block a user