diff --git a/src/api/jaeger-types.ts b/src/api/jaeger-types.ts index 4ed6d13..929113f 100644 --- a/src/api/jaeger-types.ts +++ b/src/api/jaeger-types.ts @@ -51,6 +51,11 @@ export interface WaveSurferTtsLatencyResult { isCached: string; } +export interface WaveSurferGatherSpeechVerbHookLatencyResult { + statusCode: number; + latency: string; +} + export interface WaveSurferDtmfResult { dtmf: string; duration: string; diff --git a/src/containers/internal/views/recent-calls/player.tsx b/src/containers/internal/views/recent-calls/player.tsx index cba4b5e..5b627bc 100644 --- a/src/containers/internal/views/recent-calls/player.tsx +++ b/src/containers/internal/views/recent-calls/player.tsx @@ -13,6 +13,7 @@ import { JaegerRoot, JaegerSpan, WaveSurferDtmfResult, + WaveSurferGatherSpeechVerbHookLatencyResult, WaveSurferSttResult, WaveSurferTtsLatencyResult, } from "src/api/jaeger-types"; @@ -45,6 +46,11 @@ export const Player = ({ call }: PlayerProps) => { const [waveSurferTtsLatencyData, setWaveSurferTtsLatencyData] = useState(); + + const [ + waveSurferGatherSpeechVerbHookLatencyData, + setWaveSurferGatherSpeechVerbHookLatencyData, + ] = useState(); const [regionChecked, setRegionChecked] = useState(false); const wavesurferId = `wavesurfer--${call_sid}`; @@ -269,8 +275,7 @@ export const Player = ({ call }: PlayerProps) => { content: `${(end - start).toFixed(2)} sec`, }); - changeRegionMouseStyle(latencyRegion, 2); - console.log(ttsCache.value.boolValue); + changeRegionMouseStyle(latencyRegion, 1); latencyRegion.on("click", () => { setWaveSurferTtsLatencyData({ @@ -284,6 +289,43 @@ export const Player = ({ call }: PlayerProps) => { } }; + const drawVerbHookDelayRegion = (s: JaegerSpan, startPoint: JaegerSpan) => { + if (waveSurferRegionsPluginRef.current) { + const r = waveSurferRegionsPluginRef.current + .getRegions() + .find((r) => r.id === s.spanId); + + if (!r) { + const start = + (s.startTimeUnixNano - startPoint.startTimeUnixNano) / 1_000_000_000; + const end = + (s.endTimeUnixNano - startPoint.startTimeUnixNano) / 1_000_000_000; + const tmpEnd = end - start < 0.05 ? start + 0.05 : end; + + const latencyRegion = waveSurferRegionsPluginRef.current.addRegion({ + id: s.spanId, + start: start, + end: tmpEnd, + color: "rgba(255, 3, 180, 0.55)", + drag: false, + resize: false, + content: `${(end - start).toFixed(2)} sec`, + }); + const [statusCode] = getSpanAttributeByName( + s.attributes, + "http.statusCode" + ); + changeRegionMouseStyle(latencyRegion, 0); + latencyRegion.on("click", () => { + setWaveSurferGatherSpeechVerbHookLatencyData({ + statusCode: statusCode ? Number(statusCode.value.doubleValue) : 404, + latency: `${(end - start).toFixed(2)} sec`, + }); + }); + } + } + }; + const buildWavesurferRegion = () => { if (jaegerRoot) { const spans = getSpansFromJaegerRoot(jaegerRoot); @@ -296,6 +338,7 @@ export const Player = ({ call }: PlayerProps) => { drawSttRegionForSpan(s, startPoint); }); + // Trasscription const transcribeSpans = getSpansByNameRegex(spans, /stt-listen:/); transcribeSpans.forEach((cs) => { // Channel start from 0 @@ -306,16 +349,34 @@ export const Player = ({ call }: PlayerProps) => { channel > 0 ? channel - 1 : channel ); }); - + // DTMF const dtmfSpans = getSpansByNameRegex(spans, /dtmf:/); dtmfSpans.forEach((ds) => { drawDtmfRegionForSpan(ds, startPoint); }); - + // TTS delay const ttsSpans = getSpansByNameRegex(spans, /tts-generation/); ttsSpans.forEach((tts) => { drawTtsLatencyRegion(tts, startPoint); }); + // Gather verb hook delay + const verbHookSpans = getSpansByNameRegex(spans, /verb:hook/); + verbHookSpans + .filter((s) => { + const [httpBody] = getSpanAttributeByName( + s.attributes, + "http.body" + ); + return ( + httpBody.value.stringValue.includes( + '"reason":"speechDetected"' + ) || + httpBody.value.stringValue.includes('"reason":"dtmfDetected"') + ); + }) + .forEach((s) => { + drawVerbHookDelayRegion(s, startPoint); + }); } } }; @@ -535,7 +596,7 @@ export const Player = ({ call }: PlayerProps) => { } }} /> -
Overlay STT, TTS latency and DTMF events
+
Show latencies
{waveSurferRegionData && ( @@ -670,6 +731,38 @@ export const Player = ({ call }: PlayerProps) => { )} + {waveSurferGatherSpeechVerbHookLatencyData && ( + setWaveSurferGatherSpeechVerbHookLatencyData(null)} + > +
+

+ Application Response Latency +

+
+
+
+
+
+ Status Code: +
+
+ {waveSurferGatherSpeechVerbHookLatencyData.statusCode} +
+
+ +
+
+ Latency: +
+
+ {waveSurferGatherSpeechVerbHookLatencyData.latency} +
+
+
+
+
+ )} {deleteRecordUrl && ( setDeleteRecordUrl("")}