Skip to content

Commit f4ba962

Browse files
d-rushmaDharmitha22avinash-palleti
authored
updated VideoMonitoring (open-edge-platform#2508)
Co-authored-by: Dharmitha22 <dharmitha.s.shetty@intel.com> Co-authored-by: Avinash Reddy Palleti <avinash.reddy.palleti@intel.com>
1 parent d44bdb3 commit f4ba962

2 files changed

Lines changed: 89 additions & 9 deletions

File tree

education-ai-suite/smart-classroom/components/segmentation/content_segmentation.py

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from components.base_component import PipelineComponent
22
import openvino_genai as ov_genai
33
import logging
4+
import re
45
from utils.config_loader import config
56

67
logger = logging.getLogger(__name__)
@@ -48,6 +49,78 @@ def _build_messages(self, transcript_text):
4849
}
4950
]
5051

52+
@staticmethod
53+
def _extract_json_array(text: str) -> str | None:
54+
"""Extract the first balanced [...] block from a string."""
55+
start = text.find("[")
56+
if start == -1:
57+
return None
58+
depth = 0
59+
in_string = False
60+
escape = False
61+
for i in range(start, len(text)):
62+
ch = text[i]
63+
if escape:
64+
escape = False
65+
continue
66+
if ch == "\\" and in_string:
67+
escape = True
68+
continue
69+
if ch == '"':
70+
in_string = not in_string
71+
continue
72+
if in_string:
73+
continue
74+
if ch == "[":
75+
depth += 1
76+
elif ch == "]":
77+
depth -= 1
78+
if depth == 0:
79+
return text[start:i + 1]
80+
return None
81+
82+
@staticmethod
83+
def _clean_topics_output(raw: str) -> str:
84+
"""
85+
Clean the raw output from the model to extract a valid JSON array string.
86+
"""
87+
import json
88+
89+
def try_parse(s: str):
90+
try:
91+
parsed = json.loads(s)
92+
if isinstance(parsed, list):
93+
return s
94+
except Exception:
95+
pass
96+
return None
97+
98+
text = raw.strip()
99+
100+
result = try_parse(text)
101+
if result:
102+
return result
103+
104+
stripped = re.sub(r"```[a-zA-Z]*\n?([\s\S]*?)```", r"\1", text).strip()
105+
result = try_parse(stripped)
106+
if result:
107+
return result
108+
109+
extracted = ContentSegmentationComponent._extract_json_array(stripped)
110+
if extracted:
111+
result = try_parse(extracted)
112+
if result:
113+
return result
114+
115+
extracted = ContentSegmentationComponent._extract_json_array(text)
116+
if extracted:
117+
result = try_parse(extracted)
118+
if result:
119+
return result
120+
121+
logger.error("_clean_topics_output: all strategies failed. Preview: %s", raw[:200])
122+
raise ValueError("INVALID_TOPICS_FORMAT")
123+
51124
def generate_topics(self, transcript_text):
52125
try:
53126
logger.info("Generating topic segmentation...")
@@ -59,8 +132,9 @@ def generate_topics(self, transcript_text):
59132
)
60133

61134
full_output = self.model.generate(prompt, False)
135+
clean_output = self._clean_topics_output(full_output)
62136
logger.info("Topic segmentation completed.")
63-
return full_output
137+
return clean_output
64138

65139
except Exception as e:
66140
logger.error(f"Topic segmentation failed: {e}")

education-ai-suite/smart-classroom/ui/src/redux/videoMonitor.ts

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,20 +34,26 @@ export function useVideoPipelineMonitor() {
3434
if (!update?.pipelines) continue;
3535

3636
let running = 0;
37-
let failed = false;
3837

3938
for (const p of update.pipelines) {
4039
if (p.status === "running") running++;
41-
if (p.status === "stopped_error") failed = true;
42-
}
43-
44-
if (failed) {
45-
handleStop("failed");
46-
return;
40+
// Log transient errors but don't fail — the backend restarts automatically.
41+
if (p.errors && p.errors.length > 0) {
42+
console.warn(
43+
`⚠️ Pipeline '${p.pipeline_name}' (PID ${p.pid}) reported errors: ${p.errors.join(", ")}. Waiting for restart...`
44+
);
45+
}
4746
}
4847

48+
// Only stop monitoring when no pipelines are running at all.
49+
// A single pipeline exiting and restarting will keep running > 0.
4950
if (running === 0) {
50-
handleStop("completed");
51+
const hasErrors = update.pipelines.some(
52+
(p: any) =>
53+
p.status === "stopped_error" ||
54+
(p.errors && p.errors.length > 0)
55+
);
56+
handleStop(hasErrors ? "failed" : "completed");
5157
return;
5258
}
5359

0 commit comments

Comments
 (0)