PlanOpticon

planopticon / api / analyzers / index.html
1
2
<!doctype html>
3
<html lang="en" class="no-js">
4
<head>
5
6
<meta charset="utf-8">
7
<meta name="viewport" content="width=device-width,initial-scale=1">
8
9
<meta name="description" content="AI-powered video analysis and knowledge extraction">
10
11
12
<meta name="author" content="CONFLICT LLC">
13
14
15
<link rel="canonical" href="https://planopticon.dev/api/analyzers/">
16
17
18
<link rel="prev" href="../providers/">
19
20
21
<link rel="next" href="../agent/">
22
23
24
25
26
27
<link rel="icon" href="../../assets/images/favicon.png">
28
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.4">
29
30
31
32
<title>Analyzers - PlanOpticon</title>
33
34
35
36
<link rel="stylesheet" href="../../assets/stylesheets/main.484c7ddc.min.css">
37
38
39
<link rel="stylesheet" href="../../assets/stylesheets/palette.ab4e12ef.min.css">
40
41
42
43
44
45
46
47
48
49
50
51
52
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
53
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&display=fallback">
54
<style>:root{--md-text-font:"Roboto";--md-code-font:"Roboto Mono"}</style>
55
56
57
58
<link rel="stylesheet" href="../../assets/_mkdocstrings.css">
59
60
<link rel="stylesheet" href="../../assets/css/custom.css">
61
62
<script>__md_scope=new URL("../..",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
63
64
65
66
67
68
</head>
69
70
71
72
73
74
75
76
77
78
<body dir="ltr" data-md-color-scheme="slate" data-md-color-primary="custom" data-md-color-accent="custom">
79
80
81
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
82
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
83
<label class="md-overlay" for="__drawer"></label>
84
<div data-md-component="skip">
85
86
87
<a href="#analyzers-api-reference" class="md-skip">
88
Skip to content
89
</a>
90
91
</div>
92
<div data-md-component="announce">
93
94
</div>
95
96
97
98
99
<header class="md-header" data-md-component="header">
100
<nav class="md-header__inner md-grid" aria-label="Header">
101
<a href="../.." title="PlanOpticon" class="md-header__button md-logo" aria-label="PlanOpticon" data-md-component="logo">
102
103
<img src="../../assets/images/conflict-logo.svg" alt="logo">
104
105
</a>
106
<label class="md-header__button md-icon" for="__drawer">
107
108
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z"/></svg>
109
</label>
110
<div class="md-header__title" data-md-component="header-title">
111
<div class="md-header__ellipsis">
112
<div class="md-header__topic">
113
<span class="md-ellipsis">
114
PlanOpticon
115
</span>
116
</div>
117
<div class="md-header__topic" data-md-component="header-topic">
118
<span class="md-ellipsis">
119
120
Analyzers
121
122
</span>
123
</div>
124
</div>
125
</div>
126
127
128
<form class="md-header__option" data-md-component="palette">
129
130
131
132
133
<input class="md-option" data-md-color-media="(prefers-color-scheme: dark)" data-md-color-scheme="slate" data-md-color-primary="custom" data-md-color-accent="custom" aria-label="Switch to light mode" type="radio" name="__palette" id="__palette_0">
134
135
<label class="md-header__button md-icon" title="Switch to light mode" for="__palette_1" hidden>
136
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 18c-.89 0-1.74-.2-2.5-.55C11.56 16.5 13 14.42 13 12s-1.44-4.5-3.5-5.45C10.26 6.2 11.11 6 12 6a6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z"/></svg>
137
</label>
138
139
140
141
142
143
<input class="md-option" data-md-color-media="(prefers-color-scheme: light)" data-md-color-scheme="default" data-md-color-primary="custom" data-md-color-accent="custom" aria-label="Switch to dark mode" type="radio" name="__palette" id="__palette_1">
144
145
<label class="md-header__button md-icon" title="Switch to dark mode" for="__palette_0" hidden>
146
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a4 4 0 0 0-4 4 4 4 0 0 0 4 4 4 4 0 0 0 4-4 4 4 0 0 0-4-4m0 10a6 6 0 0 1-6-6 6 6 0 0 1 6-6 6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z"/></svg>
147
</label>
148
149
150
</form>
151
152
153
154
<script>var palette=__md_get("__palette");if(palette&&palette.color){if("(prefers-color-scheme)"===palette.color.media){var media=matchMedia("(prefers-color-scheme: light)"),input=document.querySelector(media.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");palette.color.media=input.getAttribute("data-md-color-media"),palette.color.scheme=input.getAttribute("data-md-color-scheme"),palette.color.primary=input.getAttribute("data-md-color-primary"),palette.color.accent=input.getAttribute("data-md-color-accent")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute("data-md-color-"+key,value)}</script>
155
156
157
158
159
160
<label class="md-header__button md-icon" for="__search">
161
162
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
163
</label>
164
<div class="md-search" data-md-component="search" role="dialog">
165
<label class="md-search__overlay" for="__search"></label>
166
<div class="md-search__inner" role="search">
167
<form class="md-search__form" name="search">
168
<input type="text" class="md-search__input" name="query" aria-label="Search" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" required>
169
<label class="md-search__icon md-icon" for="__search">
170
171
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
172
173
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"/></svg>
174
</label>
175
<nav class="md-search__options" aria-label="Search">
176
177
<button type="reset" class="md-search__icon md-icon" title="Clear" aria-label="Clear" tabindex="-1">
178
179
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>
180
</button>
181
</nav>
182
183
<div class="md-search__suggest" data-md-component="search-suggest"></div>
184
185
</form>
186
<div class="md-search__output">
187
<div class="md-search__scrollwrap" tabindex="0" data-md-scrollfix>
188
<div class="md-search-result" data-md-component="search-result">
189
<div class="md-search-result__meta">
190
Initializing search
191
</div>
192
<ol class="md-search-result__list" role="presentation"></ol>
193
</div>
194
</div>
195
</div>
196
</div>
197
</div>
198
199
200
201
<div class="md-header__source">
202
<a href="https://github.com/ConflictHQ/PlanOpticon" title="Go to repository" class="md-source" data-md-component="source">
203
<div class="md-source__icon md-icon">
204
205
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d="M173.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M252.8 8C114.1 8 8 113.3 8 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C436.2 457.8 504 362.9 504 252 504 113.3 391.5 8 252.8 8M105.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2"/></svg>
206
</div>
207
<div class="md-source__repository">
208
ConflictHQ/PlanOpticon
209
</div>
210
</a>
211
</div>
212
213
</nav>
214
215
</header>
216
217
<div class="md-container" data-md-component="container">
218
219
220
221
222
223
<nav class="md-tabs" aria-label="Tabs" data-md-component="tabs">
224
<div class="md-grid">
225
<ul class="md-tabs__list">
226
227
228
229
230
231
232
<li class="md-tabs__item">
233
<a href="../.." class="md-tabs__link">
234
235
236
237
238
239
Home
240
241
</a>
242
</li>
243
244
245
246
247
248
249
250
251
252
253
<li class="md-tabs__item">
254
<a href="../../getting-started/installation/" class="md-tabs__link">
255
256
257
258
Getting Started
259
260
</a>
261
</li>
262
263
264
265
266
267
268
269
270
271
272
273
<li class="md-tabs__item">
274
<a href="../../guide/single-video/" class="md-tabs__link">
275
276
277
278
User Guide
279
280
</a>
281
</li>
282
283
284
285
286
287
288
289
290
291
<li class="md-tabs__item">
292
<a href="../../use-cases/" class="md-tabs__link">
293
294
295
296
297
298
Use Cases
299
300
</a>
301
</li>
302
303
304
305
306
307
308
309
310
<li class="md-tabs__item">
311
<a href="../../cli-reference/" class="md-tabs__link">
312
313
314
315
316
317
CLI Reference
318
319
</a>
320
</li>
321
322
323
324
325
326
327
328
329
330
331
<li class="md-tabs__item">
332
<a href="../../architecture/overview/" class="md-tabs__link">
333
334
335
336
Architecture
337
338
</a>
339
</li>
340
341
342
343
344
345
346
347
348
349
350
351
352
353
<li class="md-tabs__item md-tabs__item--active">
354
<a href="../models/" class="md-tabs__link">
355
356
357
358
API Reference
359
360
</a>
361
</li>
362
363
364
365
366
367
368
369
370
371
<li class="md-tabs__item">
372
<a href="../../faq/" class="md-tabs__link">
373
374
375
376
377
378
FAQ & Troubleshooting
379
380
</a>
381
</li>
382
383
384
385
386
387
388
389
390
<li class="md-tabs__item">
391
<a href="../../contributing/" class="md-tabs__link">
392
393
394
395
396
397
Contributing
398
399
</a>
400
</li>
401
402
403
404
</ul>
405
</div>
406
</nav>
407
408
409
410
<main class="md-main" data-md-component="main">
411
<div class="md-main__inner md-grid">
412
413
414
415
<div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" >
416
<div class="md-sidebar__scrollwrap">
417
<div class="md-sidebar__inner">
418
419
420
421
422
423
424
<nav class="md-nav md-nav--primary md-nav--lifted" aria-label="Navigation" data-md-level="0">
425
<label class="md-nav__title" for="__drawer">
426
<a href="../.." title="PlanOpticon" class="md-nav__button md-logo" aria-label="PlanOpticon" data-md-component="logo">
427
428
<img src="../../assets/images/conflict-logo.svg" alt="logo">
429
430
</a>
431
PlanOpticon
432
</label>
433
434
<div class="md-nav__source">
435
<a href="https://github.com/ConflictHQ/PlanOpticon" title="Go to repository" class="md-source" data-md-component="source">
436
<div class="md-source__icon md-icon">
437
438
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d="M173.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M252.8 8C114.1 8 8 113.3 8 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C436.2 457.8 504 362.9 504 252 504 113.3 391.5 8 252.8 8M105.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2"/></svg>
439
</div>
440
<div class="md-source__repository">
441
ConflictHQ/PlanOpticon
442
</div>
443
</a>
444
</div>
445
446
<ul class="md-nav__list" data-md-scrollfix>
447
448
449
450
451
452
453
454
<li class="md-nav__item">
455
<a href="../.." class="md-nav__link">
456
457
458
459
<span class="md-ellipsis">
460
461
462
Home
463
464
465
466
</span>
467
468
469
470
</a>
471
</li>
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
<li class="md-nav__item md-nav__item--nested">
492
493
494
495
496
497
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_2" >
498
499
500
<label class="md-nav__link" for="__nav_2" id="__nav_2_label" tabindex="0">
501
502
503
504
<span class="md-ellipsis">
505
506
507
Getting Started
508
509
510
511
</span>
512
513
514
515
<span class="md-nav__icon md-icon"></span>
516
</label>
517
518
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_2_label" aria-expanded="false">
519
<label class="md-nav__title" for="__nav_2">
520
<span class="md-nav__icon md-icon"></span>
521
522
523
Getting Started
524
525
526
</label>
527
<ul class="md-nav__list" data-md-scrollfix>
528
529
530
531
532
533
534
535
<li class="md-nav__item">
536
<a href="../../getting-started/installation/" class="md-nav__link">
537
538
539
540
<span class="md-ellipsis">
541
542
543
Installation
544
545
546
547
</span>
548
549
550
551
</a>
552
</li>
553
554
555
556
557
558
559
560
561
562
563
<li class="md-nav__item">
564
<a href="../../getting-started/quickstart/" class="md-nav__link">
565
566
567
568
<span class="md-ellipsis">
569
570
571
Quick Start
572
573
574
575
</span>
576
577
578
579
</a>
580
</li>
581
582
583
584
585
586
587
588
589
590
591
<li class="md-nav__item">
592
<a href="../../getting-started/configuration/" class="md-nav__link">
593
594
595
596
<span class="md-ellipsis">
597
598
599
Configuration
600
601
602
603
</span>
604
605
606
607
</a>
608
</li>
609
610
611
612
613
</ul>
614
</nav>
615
616
</li>
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
<li class="md-nav__item md-nav__item--nested">
637
638
639
640
641
642
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_3" >
643
644
645
<label class="md-nav__link" for="__nav_3" id="__nav_3_label" tabindex="0">
646
647
648
649
<span class="md-ellipsis">
650
651
652
User Guide
653
654
655
656
</span>
657
658
659
660
<span class="md-nav__icon md-icon"></span>
661
</label>
662
663
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_3_label" aria-expanded="false">
664
<label class="md-nav__title" for="__nav_3">
665
<span class="md-nav__icon md-icon"></span>
666
667
668
User Guide
669
670
671
</label>
672
<ul class="md-nav__list" data-md-scrollfix>
673
674
675
676
677
678
679
680
<li class="md-nav__item">
681
<a href="../../guide/single-video/" class="md-nav__link">
682
683
684
685
<span class="md-ellipsis">
686
687
688
Single Video Analysis
689
690
691
692
</span>
693
694
695
696
</a>
697
</li>
698
699
700
701
702
703
704
705
706
707
708
<li class="md-nav__item">
709
<a href="../../guide/batch/" class="md-nav__link">
710
711
712
713
<span class="md-ellipsis">
714
715
716
Batch Processing
717
718
719
720
</span>
721
722
723
724
</a>
725
</li>
726
727
728
729
730
731
732
733
734
735
736
<li class="md-nav__item">
737
<a href="../../guide/document-ingestion/" class="md-nav__link">
738
739
740
741
<span class="md-ellipsis">
742
743
744
Document Ingestion
745
746
747
748
</span>
749
750
751
752
</a>
753
</li>
754
755
756
757
758
759
760
761
762
763
764
<li class="md-nav__item">
765
<a href="../../guide/cloud-sources/" class="md-nav__link">
766
767
768
769
<span class="md-ellipsis">
770
771
772
Cloud Sources
773
774
775
776
</span>
777
778
779
780
</a>
781
</li>
782
783
784
785
786
787
788
789
790
791
792
<li class="md-nav__item">
793
<a href="../../guide/knowledge-graphs/" class="md-nav__link">
794
795
796
797
<span class="md-ellipsis">
798
799
800
Knowledge Graphs
801
802
803
804
</span>
805
806
807
808
</a>
809
</li>
810
811
812
813
814
815
816
817
818
819
820
<li class="md-nav__item">
821
<a href="../../guide/companion/" class="md-nav__link">
822
823
824
825
<span class="md-ellipsis">
826
827
828
Interactive Companion
829
830
831
832
</span>
833
834
835
836
</a>
837
</li>
838
839
840
841
842
843
844
845
846
847
848
<li class="md-nav__item">
849
<a href="../../guide/planning-agent/" class="md-nav__link">
850
851
852
853
<span class="md-ellipsis">
854
855
856
Planning Agent
857
858
859
860
</span>
861
862
863
864
</a>
865
</li>
866
867
868
869
870
871
872
873
874
875
876
<li class="md-nav__item">
877
<a href="../../guide/authentication/" class="md-nav__link">
878
879
880
881
<span class="md-ellipsis">
882
883
884
Authentication
885
886
887
888
</span>
889
890
891
892
</a>
893
</li>
894
895
896
897
898
899
900
901
902
903
904
<li class="md-nav__item">
905
<a href="../../guide/export/" class="md-nav__link">
906
907
908
909
<span class="md-ellipsis">
910
911
912
Export & Documents
913
914
915
916
</span>
917
918
919
920
</a>
921
</li>
922
923
924
925
926
927
928
929
930
931
932
<li class="md-nav__item">
933
<a href="../../guide/output-formats/" class="md-nav__link">
934
935
936
937
<span class="md-ellipsis">
938
939
940
Output Formats
941
942
943
944
</span>
945
946
947
948
</a>
949
</li>
950
951
952
953
954
</ul>
955
</nav>
956
957
</li>
958
959
960
961
962
963
964
965
966
967
<li class="md-nav__item">
968
<a href="../../use-cases/" class="md-nav__link">
969
970
971
972
<span class="md-ellipsis">
973
974
975
Use Cases
976
977
978
979
</span>
980
981
982
983
</a>
984
</li>
985
986
987
988
989
990
991
992
993
994
<li class="md-nav__item">
995
<a href="../../cli-reference/" class="md-nav__link">
996
997
998
999
<span class="md-ellipsis">
1000
1001
1002
CLI Reference
1003
1004
1005
1006
</span>
1007
1008
1009
1010
</a>
1011
</li>
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
<li class="md-nav__item md-nav__item--nested">
1032
1033
1034
1035
1036
1037
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_6" >
1038
1039
1040
<label class="md-nav__link" for="__nav_6" id="__nav_6_label" tabindex="0">
1041
1042
1043
1044
<span class="md-ellipsis">
1045
1046
1047
Architecture
1048
1049
1050
1051
</span>
1052
1053
1054
1055
<span class="md-nav__icon md-icon"></span>
1056
</label>
1057
1058
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_6_label" aria-expanded="false">
1059
<label class="md-nav__title" for="__nav_6">
1060
<span class="md-nav__icon md-icon"></span>
1061
1062
1063
Architecture
1064
1065
1066
</label>
1067
<ul class="md-nav__list" data-md-scrollfix>
1068
1069
1070
1071
1072
1073
1074
1075
<li class="md-nav__item">
1076
<a href="../../architecture/overview/" class="md-nav__link">
1077
1078
1079
1080
<span class="md-ellipsis">
1081
1082
1083
Overview
1084
1085
1086
1087
</span>
1088
1089
1090
1091
</a>
1092
</li>
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
<li class="md-nav__item">
1104
<a href="../../architecture/providers/" class="md-nav__link">
1105
1106
1107
1108
<span class="md-ellipsis">
1109
1110
1111
Provider System
1112
1113
1114
1115
</span>
1116
1117
1118
1119
</a>
1120
</li>
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
<li class="md-nav__item">
1132
<a href="../../architecture/pipeline/" class="md-nav__link">
1133
1134
1135
1136
<span class="md-ellipsis">
1137
1138
1139
Processing Pipeline
1140
1141
1142
1143
</span>
1144
1145
1146
1147
</a>
1148
</li>
1149
1150
1151
1152
1153
</ul>
1154
</nav>
1155
1156
</li>
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
<li class="md-nav__item md-nav__item--active md-nav__item--section md-nav__item--nested">
1182
1183
1184
1185
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_7" checked>
1186
1187
1188
<label class="md-nav__link" for="__nav_7" id="__nav_7_label" tabindex="">
1189
1190
1191
1192
<span class="md-ellipsis">
1193
1194
1195
API Reference
1196
1197
1198
1199
</span>
1200
1201
1202
1203
<span class="md-nav__icon md-icon"></span>
1204
</label>
1205
1206
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_7_label" aria-expanded="true">
1207
<label class="md-nav__title" for="__nav_7">
1208
<span class="md-nav__icon md-icon"></span>
1209
1210
1211
API Reference
1212
1213
1214
</label>
1215
<ul class="md-nav__list" data-md-scrollfix>
1216
1217
1218
1219
1220
1221
1222
1223
<li class="md-nav__item">
1224
<a href="../models/" class="md-nav__link">
1225
1226
1227
1228
<span class="md-ellipsis">
1229
1230
1231
Models
1232
1233
1234
1235
</span>
1236
1237
1238
1239
</a>
1240
</li>
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
<li class="md-nav__item">
1252
<a href="../providers/" class="md-nav__link">
1253
1254
1255
1256
<span class="md-ellipsis">
1257
1258
1259
Providers
1260
1261
1262
1263
</span>
1264
1265
1266
1267
</a>
1268
</li>
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
<li class="md-nav__item md-nav__item--active">
1282
1283
<input class="md-nav__toggle md-toggle" type="checkbox" id="__toc">
1284
1285
1286
1287
1288
1289
<label class="md-nav__link md-nav__link--active" for="__toc">
1290
1291
1292
1293
<span class="md-ellipsis">
1294
1295
1296
Analyzers
1297
1298
1299
1300
</span>
1301
1302
1303
1304
<span class="md-nav__icon md-icon"></span>
1305
</label>
1306
1307
<a href="./" class="md-nav__link md-nav__link--active">
1308
1309
1310
1311
<span class="md-ellipsis">
1312
1313
1314
Analyzers
1315
1316
1317
1318
</span>
1319
1320
1321
1322
</a>
1323
1324
1325
1326
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
1327
1328
1329
1330
1331
1332
1333
<label class="md-nav__title" for="__toc">
1334
<span class="md-nav__icon md-icon"></span>
1335
Table of contents
1336
</label>
1337
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
1338
1339
<li class="md-nav__item">
1340
<a href="#video_processor.analyzers.diagram_analyzer" class="md-nav__link">
1341
<span class="md-ellipsis">
1342
1343
diagram_analyzer
1344
1345
</span>
1346
</a>
1347
1348
<nav class="md-nav" aria-label="diagram_analyzer">
1349
<ul class="md-nav__list">
1350
1351
<li class="md-nav__item">
1352
<a href="#video_processor.analyzers.diagram_analyzer.DiagramAnalyzer" class="md-nav__link">
1353
<span class="md-ellipsis">
1354
1355
DiagramAnalyzer
1356
1357
</span>
1358
</a>
1359
1360
<nav class="md-nav" aria-label="DiagramAnalyzer">
1361
<ul class="md-nav__list">
1362
1363
<li class="md-nav__item">
1364
<a href="#video_processor.analyzers.diagram_analyzer.DiagramAnalyzer.analyze_diagram_single_pass" class="md-nav__link">
1365
<span class="md-ellipsis">
1366
1367
analyze_diagram_single_pass
1368
1369
</span>
1370
</a>
1371
1372
</li>
1373
1374
<li class="md-nav__item">
1375
<a href="#video_processor.analyzers.diagram_analyzer.DiagramAnalyzer.caption_frame" class="md-nav__link">
1376
<span class="md-ellipsis">
1377
1378
caption_frame
1379
1380
</span>
1381
</a>
1382
1383
</li>
1384
1385
<li class="md-nav__item">
1386
<a href="#video_processor.analyzers.diagram_analyzer.DiagramAnalyzer.classify_frame" class="md-nav__link">
1387
<span class="md-ellipsis">
1388
1389
classify_frame
1390
1391
</span>
1392
</a>
1393
1394
</li>
1395
1396
<li class="md-nav__item">
1397
<a href="#video_processor.analyzers.diagram_analyzer.DiagramAnalyzer.process_frames" class="md-nav__link">
1398
<span class="md-ellipsis">
1399
1400
process_frames
1401
1402
</span>
1403
</a>
1404
1405
</li>
1406
1407
</ul>
1408
</nav>
1409
1410
</li>
1411
1412
</ul>
1413
</nav>
1414
1415
</li>
1416
1417
<li class="md-nav__item">
1418
<a href="#video_processor.analyzers.content_analyzer" class="md-nav__link">
1419
<span class="md-ellipsis">
1420
1421
content_analyzer
1422
1423
</span>
1424
</a>
1425
1426
<nav class="md-nav" aria-label="content_analyzer">
1427
<ul class="md-nav__list">
1428
1429
<li class="md-nav__item">
1430
<a href="#video_processor.analyzers.content_analyzer.ContentAnalyzer" class="md-nav__link">
1431
<span class="md-ellipsis">
1432
1433
ContentAnalyzer
1434
1435
</span>
1436
</a>
1437
1438
<nav class="md-nav" aria-label="ContentAnalyzer">
1439
<ul class="md-nav__list">
1440
1441
<li class="md-nav__item">
1442
<a href="#video_processor.analyzers.content_analyzer.ContentAnalyzer.cross_reference" class="md-nav__link">
1443
<span class="md-ellipsis">
1444
1445
cross_reference
1446
1447
</span>
1448
</a>
1449
1450
</li>
1451
1452
<li class="md-nav__item">
1453
<a href="#video_processor.analyzers.content_analyzer.ContentAnalyzer.enrich_key_points" class="md-nav__link">
1454
<span class="md-ellipsis">
1455
1456
enrich_key_points
1457
1458
</span>
1459
</a>
1460
1461
</li>
1462
1463
</ul>
1464
</nav>
1465
1466
</li>
1467
1468
</ul>
1469
</nav>
1470
1471
</li>
1472
1473
<li class="md-nav__item">
1474
<a href="#video_processor.analyzers.action_detector" class="md-nav__link">
1475
<span class="md-ellipsis">
1476
1477
action_detector
1478
1479
</span>
1480
</a>
1481
1482
<nav class="md-nav" aria-label="action_detector">
1483
<ul class="md-nav__list">
1484
1485
<li class="md-nav__item">
1486
<a href="#video_processor.analyzers.action_detector.ActionDetector" class="md-nav__link">
1487
<span class="md-ellipsis">
1488
1489
ActionDetector
1490
1491
</span>
1492
</a>
1493
1494
<nav class="md-nav" aria-label="ActionDetector">
1495
<ul class="md-nav__list">
1496
1497
<li class="md-nav__item">
1498
<a href="#video_processor.analyzers.action_detector.ActionDetector.detect_from_diagrams" class="md-nav__link">
1499
<span class="md-ellipsis">
1500
1501
detect_from_diagrams
1502
1503
</span>
1504
</a>
1505
1506
</li>
1507
1508
<li class="md-nav__item">
1509
<a href="#video_processor.analyzers.action_detector.ActionDetector.detect_from_transcript" class="md-nav__link">
1510
<span class="md-ellipsis">
1511
1512
detect_from_transcript
1513
1514
</span>
1515
</a>
1516
1517
</li>
1518
1519
<li class="md-nav__item">
1520
<a href="#video_processor.analyzers.action_detector.ActionDetector.merge_action_items" class="md-nav__link">
1521
<span class="md-ellipsis">
1522
1523
merge_action_items
1524
1525
</span>
1526
</a>
1527
1528
</li>
1529
1530
</ul>
1531
</nav>
1532
1533
</li>
1534
1535
</ul>
1536
</nav>
1537
1538
</li>
1539
1540
<li class="md-nav__item">
1541
<a href="#overview" class="md-nav__link">
1542
<span class="md-ellipsis">
1543
1544
Overview
1545
1546
</span>
1547
</a>
1548
1549
</li>
1550
1551
<li class="md-nav__item">
1552
<a href="#diagramanalyzer" class="md-nav__link">
1553
<span class="md-ellipsis">
1554
1555
DiagramAnalyzer
1556
1557
</span>
1558
</a>
1559
1560
<nav class="md-nav" aria-label="DiagramAnalyzer">
1561
<ul class="md-nav__list">
1562
1563
<li class="md-nav__item">
1564
<a href="#constructor" class="md-nav__link">
1565
<span class="md-ellipsis">
1566
1567
Constructor
1568
1569
</span>
1570
</a>
1571
1572
</li>
1573
1574
<li class="md-nav__item">
1575
<a href="#classify_frame" class="md-nav__link">
1576
<span class="md-ellipsis">
1577
1578
classify_frame()
1579
1580
</span>
1581
</a>
1582
1583
</li>
1584
1585
<li class="md-nav__item">
1586
<a href="#analyze_diagram_single_pass" class="md-nav__link">
1587
<span class="md-ellipsis">
1588
1589
analyze_diagram_single_pass()
1590
1591
</span>
1592
</a>
1593
1594
</li>
1595
1596
<li class="md-nav__item">
1597
<a href="#caption_frame" class="md-nav__link">
1598
<span class="md-ellipsis">
1599
1600
caption_frame()
1601
1602
</span>
1603
</a>
1604
1605
</li>
1606
1607
<li class="md-nav__item">
1608
<a href="#process_frames" class="md-nav__link">
1609
<span class="md-ellipsis">
1610
1611
process_frames()
1612
1613
</span>
1614
</a>
1615
1616
</li>
1617
1618
</ul>
1619
</nav>
1620
1621
</li>
1622
1623
<li class="md-nav__item">
1624
<a href="#contentanalyzer" class="md-nav__link">
1625
<span class="md-ellipsis">
1626
1627
ContentAnalyzer
1628
1629
</span>
1630
</a>
1631
1632
<nav class="md-nav" aria-label="ContentAnalyzer">
1633
<ul class="md-nav__list">
1634
1635
<li class="md-nav__item">
1636
<a href="#constructor_1" class="md-nav__link">
1637
<span class="md-ellipsis">
1638
1639
Constructor
1640
1641
</span>
1642
</a>
1643
1644
</li>
1645
1646
<li class="md-nav__item">
1647
<a href="#cross_reference" class="md-nav__link">
1648
<span class="md-ellipsis">
1649
1650
cross_reference()
1651
1652
</span>
1653
</a>
1654
1655
</li>
1656
1657
<li class="md-nav__item">
1658
<a href="#enrich_key_points" class="md-nav__link">
1659
<span class="md-ellipsis">
1660
1661
enrich_key_points()
1662
1663
</span>
1664
</a>
1665
1666
</li>
1667
1668
</ul>
1669
</nav>
1670
1671
</li>
1672
1673
<li class="md-nav__item">
1674
<a href="#actiondetector" class="md-nav__link">
1675
<span class="md-ellipsis">
1676
1677
ActionDetector
1678
1679
</span>
1680
</a>
1681
1682
<nav class="md-nav" aria-label="ActionDetector">
1683
<ul class="md-nav__list">
1684
1685
<li class="md-nav__item">
1686
<a href="#constructor_2" class="md-nav__link">
1687
<span class="md-ellipsis">
1688
1689
Constructor
1690
1691
</span>
1692
</a>
1693
1694
</li>
1695
1696
<li class="md-nav__item">
1697
<a href="#detect_from_transcript" class="md-nav__link">
1698
<span class="md-ellipsis">
1699
1700
detect_from_transcript()
1701
1702
</span>
1703
</a>
1704
1705
</li>
1706
1707
<li class="md-nav__item">
1708
<a href="#detect_from_diagrams" class="md-nav__link">
1709
<span class="md-ellipsis">
1710
1711
detect_from_diagrams()
1712
1713
</span>
1714
</a>
1715
1716
</li>
1717
1718
<li class="md-nav__item">
1719
<a href="#merge_action_items" class="md-nav__link">
1720
<span class="md-ellipsis">
1721
1722
merge_action_items()
1723
1724
</span>
1725
</a>
1726
1727
</li>
1728
1729
<li class="md-nav__item">
1730
<a href="#usage-example" class="md-nav__link">
1731
<span class="md-ellipsis">
1732
1733
Usage example
1734
1735
</span>
1736
</a>
1737
1738
</li>
1739
1740
<li class="md-nav__item">
1741
<a href="#pattern-fallback-no-llm" class="md-nav__link">
1742
<span class="md-ellipsis">
1743
1744
Pattern fallback (no LLM)
1745
1746
</span>
1747
</a>
1748
1749
</li>
1750
1751
</ul>
1752
</nav>
1753
1754
</li>
1755
1756
</ul>
1757
1758
</nav>
1759
1760
</li>
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
<li class="md-nav__item">
1772
<a href="../agent/" class="md-nav__link">
1773
1774
1775
1776
<span class="md-ellipsis">
1777
1778
1779
Agent & Skills
1780
1781
1782
1783
</span>
1784
1785
1786
1787
</a>
1788
</li>
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
<li class="md-nav__item">
1800
<a href="../sources/" class="md-nav__link">
1801
1802
1803
1804
<span class="md-ellipsis">
1805
1806
1807
Sources
1808
1809
1810
1811
</span>
1812
1813
1814
1815
</a>
1816
</li>
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
<li class="md-nav__item">
1828
<a href="../auth/" class="md-nav__link">
1829
1830
1831
1832
<span class="md-ellipsis">
1833
1834
1835
Authentication
1836
1837
1838
1839
</span>
1840
1841
1842
1843
</a>
1844
</li>
1845
1846
1847
1848
1849
</ul>
1850
</nav>
1851
1852
</li>
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
<li class="md-nav__item">
1863
<a href="../../faq/" class="md-nav__link">
1864
1865
1866
1867
<span class="md-ellipsis">
1868
1869
1870
FAQ & Troubleshooting
1871
1872
1873
1874
</span>
1875
1876
1877
1878
</a>
1879
</li>
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
<li class="md-nav__item">
1890
<a href="../../contributing/" class="md-nav__link">
1891
1892
1893
1894
<span class="md-ellipsis">
1895
1896
1897
Contributing
1898
1899
1900
1901
</span>
1902
1903
1904
1905
</a>
1906
</li>
1907
1908
1909
1910
</ul>
1911
</nav>
1912
</div>
1913
</div>
1914
</div>
1915
1916
1917
1918
<div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc" >
1919
<div class="md-sidebar__scrollwrap">
1920
<div class="md-sidebar__inner">
1921
1922
1923
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
1924
1925
1926
1927
1928
1929
1930
<label class="md-nav__title" for="__toc">
1931
<span class="md-nav__icon md-icon"></span>
1932
Table of contents
1933
</label>
1934
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
1935
1936
<li class="md-nav__item">
1937
<a href="#video_processor.analyzers.diagram_analyzer" class="md-nav__link">
1938
<span class="md-ellipsis">
1939
1940
diagram_analyzer
1941
1942
</span>
1943
</a>
1944
1945
<nav class="md-nav" aria-label="diagram_analyzer">
1946
<ul class="md-nav__list">
1947
1948
<li class="md-nav__item">
1949
<a href="#video_processor.analyzers.diagram_analyzer.DiagramAnalyzer" class="md-nav__link">
1950
<span class="md-ellipsis">
1951
1952
DiagramAnalyzer
1953
1954
</span>
1955
</a>
1956
1957
<nav class="md-nav" aria-label="DiagramAnalyzer">
1958
<ul class="md-nav__list">
1959
1960
<li class="md-nav__item">
1961
<a href="#video_processor.analyzers.diagram_analyzer.DiagramAnalyzer.analyze_diagram_single_pass" class="md-nav__link">
1962
<span class="md-ellipsis">
1963
1964
analyze_diagram_single_pass
1965
1966
</span>
1967
</a>
1968
1969
</li>
1970
1971
<li class="md-nav__item">
1972
<a href="#video_processor.analyzers.diagram_analyzer.DiagramAnalyzer.caption_frame" class="md-nav__link">
1973
<span class="md-ellipsis">
1974
1975
caption_frame
1976
1977
</span>
1978
</a>
1979
1980
</li>
1981
1982
<li class="md-nav__item">
1983
<a href="#video_processor.analyzers.diagram_analyzer.DiagramAnalyzer.classify_frame" class="md-nav__link">
1984
<span class="md-ellipsis">
1985
1986
classify_frame
1987
1988
</span>
1989
</a>
1990
1991
</li>
1992
1993
<li class="md-nav__item">
1994
<a href="#video_processor.analyzers.diagram_analyzer.DiagramAnalyzer.process_frames" class="md-nav__link">
1995
<span class="md-ellipsis">
1996
1997
process_frames
1998
1999
</span>
2000
</a>
2001
2002
</li>
2003
2004
</ul>
2005
</nav>
2006
2007
</li>
2008
2009
</ul>
2010
</nav>
2011
2012
</li>
2013
2014
<li class="md-nav__item">
2015
<a href="#video_processor.analyzers.content_analyzer" class="md-nav__link">
2016
<span class="md-ellipsis">
2017
2018
content_analyzer
2019
2020
</span>
2021
</a>
2022
2023
<nav class="md-nav" aria-label="content_analyzer">
2024
<ul class="md-nav__list">
2025
2026
<li class="md-nav__item">
2027
<a href="#video_processor.analyzers.content_analyzer.ContentAnalyzer" class="md-nav__link">
2028
<span class="md-ellipsis">
2029
2030
ContentAnalyzer
2031
2032
</span>
2033
</a>
2034
2035
<nav class="md-nav" aria-label="ContentAnalyzer">
2036
<ul class="md-nav__list">
2037
2038
<li class="md-nav__item">
2039
<a href="#video_processor.analyzers.content_analyzer.ContentAnalyzer.cross_reference" class="md-nav__link">
2040
<span class="md-ellipsis">
2041
2042
cross_reference
2043
2044
</span>
2045
</a>
2046
2047
</li>
2048
2049
<li class="md-nav__item">
2050
<a href="#video_processor.analyzers.content_analyzer.ContentAnalyzer.enrich_key_points" class="md-nav__link">
2051
<span class="md-ellipsis">
2052
2053
enrich_key_points
2054
2055
</span>
2056
</a>
2057
2058
</li>
2059
2060
</ul>
2061
</nav>
2062
2063
</li>
2064
2065
</ul>
2066
</nav>
2067
2068
</li>
2069
2070
<li class="md-nav__item">
2071
<a href="#video_processor.analyzers.action_detector" class="md-nav__link">
2072
<span class="md-ellipsis">
2073
2074
action_detector
2075
2076
</span>
2077
</a>
2078
2079
<nav class="md-nav" aria-label="action_detector">
2080
<ul class="md-nav__list">
2081
2082
<li class="md-nav__item">
2083
<a href="#video_processor.analyzers.action_detector.ActionDetector" class="md-nav__link">
2084
<span class="md-ellipsis">
2085
2086
ActionDetector
2087
2088
</span>
2089
</a>
2090
2091
<nav class="md-nav" aria-label="ActionDetector">
2092
<ul class="md-nav__list">
2093
2094
<li class="md-nav__item">
2095
<a href="#video_processor.analyzers.action_detector.ActionDetector.detect_from_diagrams" class="md-nav__link">
2096
<span class="md-ellipsis">
2097
2098
detect_from_diagrams
2099
2100
</span>
2101
</a>
2102
2103
</li>
2104
2105
<li class="md-nav__item">
2106
<a href="#video_processor.analyzers.action_detector.ActionDetector.detect_from_transcript" class="md-nav__link">
2107
<span class="md-ellipsis">
2108
2109
detect_from_transcript
2110
2111
</span>
2112
</a>
2113
2114
</li>
2115
2116
<li class="md-nav__item">
2117
<a href="#video_processor.analyzers.action_detector.ActionDetector.merge_action_items" class="md-nav__link">
2118
<span class="md-ellipsis">
2119
2120
merge_action_items
2121
2122
</span>
2123
</a>
2124
2125
</li>
2126
2127
</ul>
2128
</nav>
2129
2130
</li>
2131
2132
</ul>
2133
</nav>
2134
2135
</li>
2136
2137
<li class="md-nav__item">
2138
<a href="#overview" class="md-nav__link">
2139
<span class="md-ellipsis">
2140
2141
Overview
2142
2143
</span>
2144
</a>
2145
2146
</li>
2147
2148
<li class="md-nav__item">
2149
<a href="#diagramanalyzer" class="md-nav__link">
2150
<span class="md-ellipsis">
2151
2152
DiagramAnalyzer
2153
2154
</span>
2155
</a>
2156
2157
<nav class="md-nav" aria-label="DiagramAnalyzer">
2158
<ul class="md-nav__list">
2159
2160
<li class="md-nav__item">
2161
<a href="#constructor" class="md-nav__link">
2162
<span class="md-ellipsis">
2163
2164
Constructor
2165
2166
</span>
2167
</a>
2168
2169
</li>
2170
2171
<li class="md-nav__item">
2172
<a href="#classify_frame" class="md-nav__link">
2173
<span class="md-ellipsis">
2174
2175
classify_frame()
2176
2177
</span>
2178
</a>
2179
2180
</li>
2181
2182
<li class="md-nav__item">
2183
<a href="#analyze_diagram_single_pass" class="md-nav__link">
2184
<span class="md-ellipsis">
2185
2186
analyze_diagram_single_pass()
2187
2188
</span>
2189
</a>
2190
2191
</li>
2192
2193
<li class="md-nav__item">
2194
<a href="#caption_frame" class="md-nav__link">
2195
<span class="md-ellipsis">
2196
2197
caption_frame()
2198
2199
</span>
2200
</a>
2201
2202
</li>
2203
2204
<li class="md-nav__item">
2205
<a href="#process_frames" class="md-nav__link">
2206
<span class="md-ellipsis">
2207
2208
process_frames()
2209
2210
</span>
2211
</a>
2212
2213
</li>
2214
2215
</ul>
2216
</nav>
2217
2218
</li>
2219
2220
<li class="md-nav__item">
2221
<a href="#contentanalyzer" class="md-nav__link">
2222
<span class="md-ellipsis">
2223
2224
ContentAnalyzer
2225
2226
</span>
2227
</a>
2228
2229
<nav class="md-nav" aria-label="ContentAnalyzer">
2230
<ul class="md-nav__list">
2231
2232
<li class="md-nav__item">
2233
<a href="#constructor_1" class="md-nav__link">
2234
<span class="md-ellipsis">
2235
2236
Constructor
2237
2238
</span>
2239
</a>
2240
2241
</li>
2242
2243
<li class="md-nav__item">
2244
<a href="#cross_reference" class="md-nav__link">
2245
<span class="md-ellipsis">
2246
2247
cross_reference()
2248
2249
</span>
2250
</a>
2251
2252
</li>
2253
2254
<li class="md-nav__item">
2255
<a href="#enrich_key_points" class="md-nav__link">
2256
<span class="md-ellipsis">
2257
2258
enrich_key_points()
2259
2260
</span>
2261
</a>
2262
2263
</li>
2264
2265
</ul>
2266
</nav>
2267
2268
</li>
2269
2270
<li class="md-nav__item">
2271
<a href="#actiondetector" class="md-nav__link">
2272
<span class="md-ellipsis">
2273
2274
ActionDetector
2275
2276
</span>
2277
</a>
2278
2279
<nav class="md-nav" aria-label="ActionDetector">
2280
<ul class="md-nav__list">
2281
2282
<li class="md-nav__item">
2283
<a href="#constructor_2" class="md-nav__link">
2284
<span class="md-ellipsis">
2285
2286
Constructor
2287
2288
</span>
2289
</a>
2290
2291
</li>
2292
2293
<li class="md-nav__item">
2294
<a href="#detect_from_transcript" class="md-nav__link">
2295
<span class="md-ellipsis">
2296
2297
detect_from_transcript()
2298
2299
</span>
2300
</a>
2301
2302
</li>
2303
2304
<li class="md-nav__item">
2305
<a href="#detect_from_diagrams" class="md-nav__link">
2306
<span class="md-ellipsis">
2307
2308
detect_from_diagrams()
2309
2310
</span>
2311
</a>
2312
2313
</li>
2314
2315
<li class="md-nav__item">
2316
<a href="#merge_action_items" class="md-nav__link">
2317
<span class="md-ellipsis">
2318
2319
merge_action_items()
2320
2321
</span>
2322
</a>
2323
2324
</li>
2325
2326
<li class="md-nav__item">
2327
<a href="#usage-example" class="md-nav__link">
2328
<span class="md-ellipsis">
2329
2330
Usage example
2331
2332
</span>
2333
</a>
2334
2335
</li>
2336
2337
<li class="md-nav__item">
2338
<a href="#pattern-fallback-no-llm" class="md-nav__link">
2339
<span class="md-ellipsis">
2340
2341
Pattern fallback (no LLM)
2342
2343
</span>
2344
</a>
2345
2346
</li>
2347
2348
</ul>
2349
</nav>
2350
2351
</li>
2352
2353
</ul>
2354
2355
</nav>
2356
</div>
2357
</div>
2358
</div>
2359
2360
2361
2362
<div class="md-content" data-md-component="content">
2363
2364
<article class="md-content__inner md-typeset">
2365
2366
2367
2368
2369
2370
2371
2372
2373
<h1 id="analyzers-api-reference">Analyzers API Reference<a class="headerlink" href="#analyzers-api-reference" title="Permanent link">&para;</a></h1>
2374
2375
2376
<div class="doc doc-object doc-module">
2377
2378
2379
2380
<h2 id="video_processor.analyzers.diagram_analyzer" class="doc doc-heading">
2381
<code>video_processor.analyzers.diagram_analyzer</code>
2382
2383
2384
<a href="#video_processor.analyzers.diagram_analyzer" class="headerlink" title="Permanent link">&para;</a></h2>
2385
2386
<div class="doc doc-contents first">
2387
2388
<p>Diagram analysis using vision model classification and single-pass extraction.</p>
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
<div class="doc doc-children">
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
<div class="doc doc-object doc-class">
2410
2411
2412
2413
<h3 id="video_processor.analyzers.diagram_analyzer.DiagramAnalyzer" class="doc doc-heading">
2414
<code>DiagramAnalyzer</code>
2415
2416
2417
<a href="#video_processor.analyzers.diagram_analyzer.DiagramAnalyzer" class="headerlink" title="Permanent link">&para;</a></h3>
2418
2419
2420
<div class="doc doc-contents ">
2421
2422
2423
2424
<p>Vision model-based diagram detection and analysis.</p>
2425
2426
2427
2428
2429
2430
2431
2432
2433
<details class="mkdocstrings-source">
2434
<summary>Source code in <code>video_processor/analyzers/diagram_analyzer.py</code></summary>
2435
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-90"> 90</a></span>
2436
<span class="normal"><a href="#__codelineno-0-91"> 91</a></span>
2437
<span class="normal"><a href="#__codelineno-0-92"> 92</a></span>
2438
<span class="normal"><a href="#__codelineno-0-93"> 93</a></span>
2439
<span class="normal"><a href="#__codelineno-0-94"> 94</a></span>
2440
<span class="normal"><a href="#__codelineno-0-95"> 95</a></span>
2441
<span class="normal"><a href="#__codelineno-0-96"> 96</a></span>
2442
<span class="normal"><a href="#__codelineno-0-97"> 97</a></span>
2443
<span class="normal"><a href="#__codelineno-0-98"> 98</a></span>
2444
<span class="normal"><a href="#__codelineno-0-99"> 99</a></span>
2445
<span class="normal"><a href="#__codelineno-0-100">100</a></span>
2446
<span class="normal"><a href="#__codelineno-0-101">101</a></span>
2447
<span class="normal"><a href="#__codelineno-0-102">102</a></span>
2448
<span class="normal"><a href="#__codelineno-0-103">103</a></span>
2449
<span class="normal"><a href="#__codelineno-0-104">104</a></span>
2450
<span class="normal"><a href="#__codelineno-0-105">105</a></span>
2451
<span class="normal"><a href="#__codelineno-0-106">106</a></span>
2452
<span class="normal"><a href="#__codelineno-0-107">107</a></span>
2453
<span class="normal"><a href="#__codelineno-0-108">108</a></span>
2454
<span class="normal"><a href="#__codelineno-0-109">109</a></span>
2455
<span class="normal"><a href="#__codelineno-0-110">110</a></span>
2456
<span class="normal"><a href="#__codelineno-0-111">111</a></span>
2457
<span class="normal"><a href="#__codelineno-0-112">112</a></span>
2458
<span class="normal"><a href="#__codelineno-0-113">113</a></span>
2459
<span class="normal"><a href="#__codelineno-0-114">114</a></span>
2460
<span class="normal"><a href="#__codelineno-0-115">115</a></span>
2461
<span class="normal"><a href="#__codelineno-0-116">116</a></span>
2462
<span class="normal"><a href="#__codelineno-0-117">117</a></span>
2463
<span class="normal"><a href="#__codelineno-0-118">118</a></span>
2464
<span class="normal"><a href="#__codelineno-0-119">119</a></span>
2465
<span class="normal"><a href="#__codelineno-0-120">120</a></span>
2466
<span class="normal"><a href="#__codelineno-0-121">121</a></span>
2467
<span class="normal"><a href="#__codelineno-0-122">122</a></span>
2468
<span class="normal"><a href="#__codelineno-0-123">123</a></span>
2469
<span class="normal"><a href="#__codelineno-0-124">124</a></span>
2470
<span class="normal"><a href="#__codelineno-0-125">125</a></span>
2471
<span class="normal"><a href="#__codelineno-0-126">126</a></span>
2472
<span class="normal"><a href="#__codelineno-0-127">127</a></span>
2473
<span class="normal"><a href="#__codelineno-0-128">128</a></span>
2474
<span class="normal"><a href="#__codelineno-0-129">129</a></span>
2475
<span class="normal"><a href="#__codelineno-0-130">130</a></span>
2476
<span class="normal"><a href="#__codelineno-0-131">131</a></span>
2477
<span class="normal"><a href="#__codelineno-0-132">132</a></span>
2478
<span class="normal"><a href="#__codelineno-0-133">133</a></span>
2479
<span class="normal"><a href="#__codelineno-0-134">134</a></span>
2480
<span class="normal"><a href="#__codelineno-0-135">135</a></span>
2481
<span class="normal"><a href="#__codelineno-0-136">136</a></span>
2482
<span class="normal"><a href="#__codelineno-0-137">137</a></span>
2483
<span class="normal"><a href="#__codelineno-0-138">138</a></span>
2484
<span class="normal"><a href="#__codelineno-0-139">139</a></span>
2485
<span class="normal"><a href="#__codelineno-0-140">140</a></span>
2486
<span class="normal"><a href="#__codelineno-0-141">141</a></span>
2487
<span class="normal"><a href="#__codelineno-0-142">142</a></span>
2488
<span class="normal"><a href="#__codelineno-0-143">143</a></span>
2489
<span class="normal"><a href="#__codelineno-0-144">144</a></span>
2490
<span class="normal"><a href="#__codelineno-0-145">145</a></span>
2491
<span class="normal"><a href="#__codelineno-0-146">146</a></span>
2492
<span class="normal"><a href="#__codelineno-0-147">147</a></span>
2493
<span class="normal"><a href="#__codelineno-0-148">148</a></span>
2494
<span class="normal"><a href="#__codelineno-0-149">149</a></span>
2495
<span class="normal"><a href="#__codelineno-0-150">150</a></span>
2496
<span class="normal"><a href="#__codelineno-0-151">151</a></span>
2497
<span class="normal"><a href="#__codelineno-0-152">152</a></span>
2498
<span class="normal"><a href="#__codelineno-0-153">153</a></span>
2499
<span class="normal"><a href="#__codelineno-0-154">154</a></span>
2500
<span class="normal"><a href="#__codelineno-0-155">155</a></span>
2501
<span class="normal"><a href="#__codelineno-0-156">156</a></span>
2502
<span class="normal"><a href="#__codelineno-0-157">157</a></span>
2503
<span class="normal"><a href="#__codelineno-0-158">158</a></span>
2504
<span class="normal"><a href="#__codelineno-0-159">159</a></span>
2505
<span class="normal"><a href="#__codelineno-0-160">160</a></span>
2506
<span class="normal"><a href="#__codelineno-0-161">161</a></span>
2507
<span class="normal"><a href="#__codelineno-0-162">162</a></span>
2508
<span class="normal"><a href="#__codelineno-0-163">163</a></span>
2509
<span class="normal"><a href="#__codelineno-0-164">164</a></span>
2510
<span class="normal"><a href="#__codelineno-0-165">165</a></span>
2511
<span class="normal"><a href="#__codelineno-0-166">166</a></span>
2512
<span class="normal"><a href="#__codelineno-0-167">167</a></span>
2513
<span class="normal"><a href="#__codelineno-0-168">168</a></span>
2514
<span class="normal"><a href="#__codelineno-0-169">169</a></span>
2515
<span class="normal"><a href="#__codelineno-0-170">170</a></span>
2516
<span class="normal"><a href="#__codelineno-0-171">171</a></span>
2517
<span class="normal"><a href="#__codelineno-0-172">172</a></span>
2518
<span class="normal"><a href="#__codelineno-0-173">173</a></span>
2519
<span class="normal"><a href="#__codelineno-0-174">174</a></span>
2520
<span class="normal"><a href="#__codelineno-0-175">175</a></span>
2521
<span class="normal"><a href="#__codelineno-0-176">176</a></span>
2522
<span class="normal"><a href="#__codelineno-0-177">177</a></span>
2523
<span class="normal"><a href="#__codelineno-0-178">178</a></span>
2524
<span class="normal"><a href="#__codelineno-0-179">179</a></span>
2525
<span class="normal"><a href="#__codelineno-0-180">180</a></span>
2526
<span class="normal"><a href="#__codelineno-0-181">181</a></span>
2527
<span class="normal"><a href="#__codelineno-0-182">182</a></span>
2528
<span class="normal"><a href="#__codelineno-0-183">183</a></span>
2529
<span class="normal"><a href="#__codelineno-0-184">184</a></span>
2530
<span class="normal"><a href="#__codelineno-0-185">185</a></span>
2531
<span class="normal"><a href="#__codelineno-0-186">186</a></span>
2532
<span class="normal"><a href="#__codelineno-0-187">187</a></span>
2533
<span class="normal"><a href="#__codelineno-0-188">188</a></span>
2534
<span class="normal"><a href="#__codelineno-0-189">189</a></span>
2535
<span class="normal"><a href="#__codelineno-0-190">190</a></span>
2536
<span class="normal"><a href="#__codelineno-0-191">191</a></span>
2537
<span class="normal"><a href="#__codelineno-0-192">192</a></span>
2538
<span class="normal"><a href="#__codelineno-0-193">193</a></span>
2539
<span class="normal"><a href="#__codelineno-0-194">194</a></span>
2540
<span class="normal"><a href="#__codelineno-0-195">195</a></span>
2541
<span class="normal"><a href="#__codelineno-0-196">196</a></span>
2542
<span class="normal"><a href="#__codelineno-0-197">197</a></span>
2543
<span class="normal"><a href="#__codelineno-0-198">198</a></span>
2544
<span class="normal"><a href="#__codelineno-0-199">199</a></span>
2545
<span class="normal"><a href="#__codelineno-0-200">200</a></span>
2546
<span class="normal"><a href="#__codelineno-0-201">201</a></span>
2547
<span class="normal"><a href="#__codelineno-0-202">202</a></span>
2548
<span class="normal"><a href="#__codelineno-0-203">203</a></span>
2549
<span class="normal"><a href="#__codelineno-0-204">204</a></span>
2550
<span class="normal"><a href="#__codelineno-0-205">205</a></span>
2551
<span class="normal"><a href="#__codelineno-0-206">206</a></span>
2552
<span class="normal"><a href="#__codelineno-0-207">207</a></span>
2553
<span class="normal"><a href="#__codelineno-0-208">208</a></span>
2554
<span class="normal"><a href="#__codelineno-0-209">209</a></span>
2555
<span class="normal"><a href="#__codelineno-0-210">210</a></span>
2556
<span class="normal"><a href="#__codelineno-0-211">211</a></span>
2557
<span class="normal"><a href="#__codelineno-0-212">212</a></span>
2558
<span class="normal"><a href="#__codelineno-0-213">213</a></span>
2559
<span class="normal"><a href="#__codelineno-0-214">214</a></span>
2560
<span class="normal"><a href="#__codelineno-0-215">215</a></span>
2561
<span class="normal"><a href="#__codelineno-0-216">216</a></span>
2562
<span class="normal"><a href="#__codelineno-0-217">217</a></span>
2563
<span class="normal"><a href="#__codelineno-0-218">218</a></span>
2564
<span class="normal"><a href="#__codelineno-0-219">219</a></span>
2565
<span class="normal"><a href="#__codelineno-0-220">220</a></span>
2566
<span class="normal"><a href="#__codelineno-0-221">221</a></span>
2567
<span class="normal"><a href="#__codelineno-0-222">222</a></span>
2568
<span class="normal"><a href="#__codelineno-0-223">223</a></span>
2569
<span class="normal"><a href="#__codelineno-0-224">224</a></span>
2570
<span class="normal"><a href="#__codelineno-0-225">225</a></span>
2571
<span class="normal"><a href="#__codelineno-0-226">226</a></span>
2572
<span class="normal"><a href="#__codelineno-0-227">227</a></span>
2573
<span class="normal"><a href="#__codelineno-0-228">228</a></span>
2574
<span class="normal"><a href="#__codelineno-0-229">229</a></span>
2575
<span class="normal"><a href="#__codelineno-0-230">230</a></span>
2576
<span class="normal"><a href="#__codelineno-0-231">231</a></span>
2577
<span class="normal"><a href="#__codelineno-0-232">232</a></span>
2578
<span class="normal"><a href="#__codelineno-0-233">233</a></span>
2579
<span class="normal"><a href="#__codelineno-0-234">234</a></span>
2580
<span class="normal"><a href="#__codelineno-0-235">235</a></span>
2581
<span class="normal"><a href="#__codelineno-0-236">236</a></span>
2582
<span class="normal"><a href="#__codelineno-0-237">237</a></span>
2583
<span class="normal"><a href="#__codelineno-0-238">238</a></span>
2584
<span class="normal"><a href="#__codelineno-0-239">239</a></span>
2585
<span class="normal"><a href="#__codelineno-0-240">240</a></span>
2586
<span class="normal"><a href="#__codelineno-0-241">241</a></span>
2587
<span class="normal"><a href="#__codelineno-0-242">242</a></span>
2588
<span class="normal"><a href="#__codelineno-0-243">243</a></span>
2589
<span class="normal"><a href="#__codelineno-0-244">244</a></span>
2590
<span class="normal"><a href="#__codelineno-0-245">245</a></span>
2591
<span class="normal"><a href="#__codelineno-0-246">246</a></span>
2592
<span class="normal"><a href="#__codelineno-0-247">247</a></span>
2593
<span class="normal"><a href="#__codelineno-0-248">248</a></span>
2594
<span class="normal"><a href="#__codelineno-0-249">249</a></span>
2595
<span class="normal"><a href="#__codelineno-0-250">250</a></span>
2596
<span class="normal"><a href="#__codelineno-0-251">251</a></span>
2597
<span class="normal"><a href="#__codelineno-0-252">252</a></span>
2598
<span class="normal"><a href="#__codelineno-0-253">253</a></span>
2599
<span class="normal"><a href="#__codelineno-0-254">254</a></span>
2600
<span class="normal"><a href="#__codelineno-0-255">255</a></span>
2601
<span class="normal"><a href="#__codelineno-0-256">256</a></span>
2602
<span class="normal"><a href="#__codelineno-0-257">257</a></span>
2603
<span class="normal"><a href="#__codelineno-0-258">258</a></span>
2604
<span class="normal"><a href="#__codelineno-0-259">259</a></span>
2605
<span class="normal"><a href="#__codelineno-0-260">260</a></span>
2606
<span class="normal"><a href="#__codelineno-0-261">261</a></span>
2607
<span class="normal"><a href="#__codelineno-0-262">262</a></span>
2608
<span class="normal"><a href="#__codelineno-0-263">263</a></span>
2609
<span class="normal"><a href="#__codelineno-0-264">264</a></span>
2610
<span class="normal"><a href="#__codelineno-0-265">265</a></span>
2611
<span class="normal"><a href="#__codelineno-0-266">266</a></span>
2612
<span class="normal"><a href="#__codelineno-0-267">267</a></span>
2613
<span class="normal"><a href="#__codelineno-0-268">268</a></span>
2614
<span class="normal"><a href="#__codelineno-0-269">269</a></span>
2615
<span class="normal"><a href="#__codelineno-0-270">270</a></span>
2616
<span class="normal"><a href="#__codelineno-0-271">271</a></span>
2617
<span class="normal"><a href="#__codelineno-0-272">272</a></span>
2618
<span class="normal"><a href="#__codelineno-0-273">273</a></span>
2619
<span class="normal"><a href="#__codelineno-0-274">274</a></span>
2620
<span class="normal"><a href="#__codelineno-0-275">275</a></span>
2621
<span class="normal"><a href="#__codelineno-0-276">276</a></span>
2622
<span class="normal"><a href="#__codelineno-0-277">277</a></span>
2623
<span class="normal"><a href="#__codelineno-0-278">278</a></span>
2624
<span class="normal"><a href="#__codelineno-0-279">279</a></span>
2625
<span class="normal"><a href="#__codelineno-0-280">280</a></span>
2626
<span class="normal"><a href="#__codelineno-0-281">281</a></span>
2627
<span class="normal"><a href="#__codelineno-0-282">282</a></span>
2628
<span class="normal"><a href="#__codelineno-0-283">283</a></span>
2629
<span class="normal"><a href="#__codelineno-0-284">284</a></span>
2630
<span class="normal"><a href="#__codelineno-0-285">285</a></span>
2631
<span class="normal"><a href="#__codelineno-0-286">286</a></span>
2632
<span class="normal"><a href="#__codelineno-0-287">287</a></span>
2633
<span class="normal"><a href="#__codelineno-0-288">288</a></span>
2634
<span class="normal"><a href="#__codelineno-0-289">289</a></span>
2635
<span class="normal"><a href="#__codelineno-0-290">290</a></span>
2636
<span class="normal"><a href="#__codelineno-0-291">291</a></span>
2637
<span class="normal"><a href="#__codelineno-0-292">292</a></span>
2638
<span class="normal"><a href="#__codelineno-0-293">293</a></span>
2639
<span class="normal"><a href="#__codelineno-0-294">294</a></span>
2640
<span class="normal"><a href="#__codelineno-0-295">295</a></span>
2641
<span class="normal"><a href="#__codelineno-0-296">296</a></span>
2642
<span class="normal"><a href="#__codelineno-0-297">297</a></span>
2643
<span class="normal"><a href="#__codelineno-0-298">298</a></span>
2644
<span class="normal"><a href="#__codelineno-0-299">299</a></span>
2645
<span class="normal"><a href="#__codelineno-0-300">300</a></span>
2646
<span class="normal"><a href="#__codelineno-0-301">301</a></span>
2647
<span class="normal"><a href="#__codelineno-0-302">302</a></span>
2648
<span class="normal"><a href="#__codelineno-0-303">303</a></span>
2649
<span class="normal"><a href="#__codelineno-0-304">304</a></span>
2650
<span class="normal"><a href="#__codelineno-0-305">305</a></span>
2651
<span class="normal"><a href="#__codelineno-0-306">306</a></span>
2652
<span class="normal"><a href="#__codelineno-0-307">307</a></span>
2653
<span class="normal"><a href="#__codelineno-0-308">308</a></span>
2654
<span class="normal"><a href="#__codelineno-0-309">309</a></span>
2655
<span class="normal"><a href="#__codelineno-0-310">310</a></span>
2656
<span class="normal"><a href="#__codelineno-0-311">311</a></span>
2657
<span class="normal"><a href="#__codelineno-0-312">312</a></span>
2658
<span class="normal"><a href="#__codelineno-0-313">313</a></span>
2659
<span class="normal"><a href="#__codelineno-0-314">314</a></span>
2660
<span class="normal"><a href="#__codelineno-0-315">315</a></span>
2661
<span class="normal"><a href="#__codelineno-0-316">316</a></span>
2662
<span class="normal"><a href="#__codelineno-0-317">317</a></span>
2663
<span class="normal"><a href="#__codelineno-0-318">318</a></span>
2664
<span class="normal"><a href="#__codelineno-0-319">319</a></span>
2665
<span class="normal"><a href="#__codelineno-0-320">320</a></span>
2666
<span class="normal"><a href="#__codelineno-0-321">321</a></span>
2667
<span class="normal"><a href="#__codelineno-0-322">322</a></span>
2668
<span class="normal"><a href="#__codelineno-0-323">323</a></span>
2669
<span class="normal"><a href="#__codelineno-0-324">324</a></span>
2670
<span class="normal"><a href="#__codelineno-0-325">325</a></span>
2671
<span class="normal"><a href="#__codelineno-0-326">326</a></span>
2672
<span class="normal"><a href="#__codelineno-0-327">327</a></span>
2673
<span class="normal"><a href="#__codelineno-0-328">328</a></span>
2674
<span class="normal"><a href="#__codelineno-0-329">329</a></span>
2675
<span class="normal"><a href="#__codelineno-0-330">330</a></span>
2676
<span class="normal"><a href="#__codelineno-0-331">331</a></span>
2677
<span class="normal"><a href="#__codelineno-0-332">332</a></span>
2678
<span class="normal"><a href="#__codelineno-0-333">333</a></span>
2679
<span class="normal"><a href="#__codelineno-0-334">334</a></span>
2680
<span class="normal"><a href="#__codelineno-0-335">335</a></span>
2681
<span class="normal"><a href="#__codelineno-0-336">336</a></span>
2682
<span class="normal"><a href="#__codelineno-0-337">337</a></span>
2683
<span class="normal"><a href="#__codelineno-0-338">338</a></span>
2684
<span class="normal"><a href="#__codelineno-0-339">339</a></span>
2685
<span class="normal"><a href="#__codelineno-0-340">340</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-90" name="__codelineno-0-90"></a><span class="k">class</span><span class="w"> </span><span class="nc">DiagramAnalyzer</span><span class="p">:</span>
2686
<a id="__codelineno-0-91" name="__codelineno-0-91"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Vision model-based diagram detection and analysis.&quot;&quot;&quot;</span>
2687
<a id="__codelineno-0-92" name="__codelineno-0-92"></a>
2688
<a id="__codelineno-0-93" name="__codelineno-0-93"></a> <span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span>
2689
<a id="__codelineno-0-94" name="__codelineno-0-94"></a> <span class="bp">self</span><span class="p">,</span>
2690
<a id="__codelineno-0-95" name="__codelineno-0-95"></a> <span class="n">provider_manager</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">ProviderManager</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
2691
<a id="__codelineno-0-96" name="__codelineno-0-96"></a> <span class="n">confidence_threshold</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="mf">0.3</span><span class="p">,</span>
2692
<a id="__codelineno-0-97" name="__codelineno-0-97"></a> <span class="p">):</span>
2693
<a id="__codelineno-0-98" name="__codelineno-0-98"></a> <span class="bp">self</span><span class="o">.</span><span class="n">pm</span> <span class="o">=</span> <span class="n">provider_manager</span> <span class="ow">or</span> <span class="n">ProviderManager</span><span class="p">()</span>
2694
<a id="__codelineno-0-99" name="__codelineno-0-99"></a> <span class="bp">self</span><span class="o">.</span><span class="n">confidence_threshold</span> <span class="o">=</span> <span class="n">confidence_threshold</span>
2695
<a id="__codelineno-0-100" name="__codelineno-0-100"></a>
2696
<a id="__codelineno-0-101" name="__codelineno-0-101"></a> <span class="k">def</span><span class="w"> </span><span class="nf">classify_frame</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">image_path</span><span class="p">:</span> <span class="n">Union</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Path</span><span class="p">])</span> <span class="o">-&gt;</span> <span class="nb">dict</span><span class="p">:</span>
2697
<a id="__codelineno-0-102" name="__codelineno-0-102"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
2698
<a id="__codelineno-0-103" name="__codelineno-0-103"></a><span class="sd"> Classify a single frame using vision model.</span>
2699
<a id="__codelineno-0-104" name="__codelineno-0-104"></a>
2700
<a id="__codelineno-0-105" name="__codelineno-0-105"></a><span class="sd"> Returns dict with is_diagram, diagram_type, confidence, brief_description.</span>
2701
<a id="__codelineno-0-106" name="__codelineno-0-106"></a><span class="sd"> &quot;&quot;&quot;</span>
2702
<a id="__codelineno-0-107" name="__codelineno-0-107"></a> <span class="n">image_bytes</span> <span class="o">=</span> <span class="n">_read_image_bytes</span><span class="p">(</span><span class="n">image_path</span><span class="p">)</span>
2703
<a id="__codelineno-0-108" name="__codelineno-0-108"></a> <span class="n">raw</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">pm</span><span class="o">.</span><span class="n">analyze_image</span><span class="p">(</span><span class="n">image_bytes</span><span class="p">,</span> <span class="n">_CLASSIFY_PROMPT</span><span class="p">,</span> <span class="n">max_tokens</span><span class="o">=</span><span class="mi">512</span><span class="p">)</span>
2704
<a id="__codelineno-0-109" name="__codelineno-0-109"></a> <span class="n">result</span> <span class="o">=</span> <span class="n">_parse_json_response</span><span class="p">(</span><span class="n">raw</span><span class="p">)</span>
2705
<a id="__codelineno-0-110" name="__codelineno-0-110"></a> <span class="k">if</span> <span class="n">result</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
2706
<a id="__codelineno-0-111" name="__codelineno-0-111"></a> <span class="k">return</span> <span class="p">{</span>
2707
<a id="__codelineno-0-112" name="__codelineno-0-112"></a> <span class="s2">&quot;is_diagram&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
2708
<a id="__codelineno-0-113" name="__codelineno-0-113"></a> <span class="s2">&quot;diagram_type&quot;</span><span class="p">:</span> <span class="s2">&quot;unknown&quot;</span><span class="p">,</span>
2709
<a id="__codelineno-0-114" name="__codelineno-0-114"></a> <span class="s2">&quot;confidence&quot;</span><span class="p">:</span> <span class="mf">0.0</span><span class="p">,</span>
2710
<a id="__codelineno-0-115" name="__codelineno-0-115"></a> <span class="s2">&quot;brief_description&quot;</span><span class="p">:</span> <span class="s2">&quot;&quot;</span><span class="p">,</span>
2711
<a id="__codelineno-0-116" name="__codelineno-0-116"></a> <span class="p">}</span>
2712
<a id="__codelineno-0-117" name="__codelineno-0-117"></a> <span class="k">return</span> <span class="n">result</span>
2713
<a id="__codelineno-0-118" name="__codelineno-0-118"></a>
2714
<a id="__codelineno-0-119" name="__codelineno-0-119"></a> <span class="k">def</span><span class="w"> </span><span class="nf">analyze_diagram_single_pass</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">image_path</span><span class="p">:</span> <span class="n">Union</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Path</span><span class="p">])</span> <span class="o">-&gt;</span> <span class="nb">dict</span><span class="p">:</span>
2715
<a id="__codelineno-0-120" name="__codelineno-0-120"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
2716
<a id="__codelineno-0-121" name="__codelineno-0-121"></a><span class="sd"> Full single-pass diagram analysis — description, text, mermaid, chart data.</span>
2717
<a id="__codelineno-0-122" name="__codelineno-0-122"></a>
2718
<a id="__codelineno-0-123" name="__codelineno-0-123"></a><span class="sd"> Returns parsed dict or empty dict on failure.</span>
2719
<a id="__codelineno-0-124" name="__codelineno-0-124"></a><span class="sd"> &quot;&quot;&quot;</span>
2720
<a id="__codelineno-0-125" name="__codelineno-0-125"></a> <span class="n">image_bytes</span> <span class="o">=</span> <span class="n">_read_image_bytes</span><span class="p">(</span><span class="n">image_path</span><span class="p">)</span>
2721
<a id="__codelineno-0-126" name="__codelineno-0-126"></a> <span class="n">raw</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">pm</span><span class="o">.</span><span class="n">analyze_image</span><span class="p">(</span><span class="n">image_bytes</span><span class="p">,</span> <span class="n">_ANALYSIS_PROMPT</span><span class="p">,</span> <span class="n">max_tokens</span><span class="o">=</span><span class="mi">4096</span><span class="p">)</span>
2722
<a id="__codelineno-0-127" name="__codelineno-0-127"></a> <span class="n">result</span> <span class="o">=</span> <span class="n">_parse_json_response</span><span class="p">(</span><span class="n">raw</span><span class="p">)</span>
2723
<a id="__codelineno-0-128" name="__codelineno-0-128"></a> <span class="k">return</span> <span class="n">result</span> <span class="ow">or</span> <span class="p">{}</span>
2724
<a id="__codelineno-0-129" name="__codelineno-0-129"></a>
2725
<a id="__codelineno-0-130" name="__codelineno-0-130"></a> <span class="k">def</span><span class="w"> </span><span class="nf">caption_frame</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">image_path</span><span class="p">:</span> <span class="n">Union</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Path</span><span class="p">])</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
2726
<a id="__codelineno-0-131" name="__codelineno-0-131"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Get a brief caption for a screengrab fallback.&quot;&quot;&quot;</span>
2727
<a id="__codelineno-0-132" name="__codelineno-0-132"></a> <span class="n">image_bytes</span> <span class="o">=</span> <span class="n">_read_image_bytes</span><span class="p">(</span><span class="n">image_path</span><span class="p">)</span>
2728
<a id="__codelineno-0-133" name="__codelineno-0-133"></a> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">pm</span><span class="o">.</span><span class="n">analyze_image</span><span class="p">(</span><span class="n">image_bytes</span><span class="p">,</span> <span class="n">_CAPTION_PROMPT</span><span class="p">,</span> <span class="n">max_tokens</span><span class="o">=</span><span class="mi">256</span><span class="p">)</span>
2729
<a id="__codelineno-0-134" name="__codelineno-0-134"></a>
2730
<a id="__codelineno-0-135" name="__codelineno-0-135"></a> <span class="k">def</span><span class="w"> </span><span class="nf">process_frames</span><span class="p">(</span>
2731
<a id="__codelineno-0-136" name="__codelineno-0-136"></a> <span class="bp">self</span><span class="p">,</span>
2732
<a id="__codelineno-0-137" name="__codelineno-0-137"></a> <span class="n">frame_paths</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="n">Union</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Path</span><span class="p">]],</span>
2733
<a id="__codelineno-0-138" name="__codelineno-0-138"></a> <span class="n">diagrams_dir</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">Path</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
2734
<a id="__codelineno-0-139" name="__codelineno-0-139"></a> <span class="n">captures_dir</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">Path</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
2735
<a id="__codelineno-0-140" name="__codelineno-0-140"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Tuple</span><span class="p">[</span><span class="n">List</span><span class="p">[</span><span class="n">DiagramResult</span><span class="p">],</span> <span class="n">List</span><span class="p">[</span><span class="n">ScreenCapture</span><span class="p">]]:</span>
2736
<a id="__codelineno-0-141" name="__codelineno-0-141"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
2737
<a id="__codelineno-0-142" name="__codelineno-0-142"></a><span class="sd"> Process a list of extracted frames: classify, analyze diagrams, screengrab fallback.</span>
2738
<a id="__codelineno-0-143" name="__codelineno-0-143"></a>
2739
<a id="__codelineno-0-144" name="__codelineno-0-144"></a><span class="sd"> Thresholds:</span>
2740
<a id="__codelineno-0-145" name="__codelineno-0-145"></a><span class="sd"> - confidence &gt;= 0.7 → full diagram analysis (story 3.2)</span>
2741
<a id="__codelineno-0-146" name="__codelineno-0-146"></a><span class="sd"> - 0.3 &lt;= confidence &lt; 0.7 → screengrab fallback (story 3.3)</span>
2742
<a id="__codelineno-0-147" name="__codelineno-0-147"></a><span class="sd"> - confidence &lt; 0.3 → skip</span>
2743
<a id="__codelineno-0-148" name="__codelineno-0-148"></a>
2744
<a id="__codelineno-0-149" name="__codelineno-0-149"></a><span class="sd"> Returns (diagrams, screen_captures).</span>
2745
<a id="__codelineno-0-150" name="__codelineno-0-150"></a><span class="sd"> &quot;&quot;&quot;</span>
2746
<a id="__codelineno-0-151" name="__codelineno-0-151"></a> <span class="n">diagrams</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="n">DiagramResult</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span>
2747
<a id="__codelineno-0-152" name="__codelineno-0-152"></a> <span class="n">captures</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="n">ScreenCapture</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span>
2748
<a id="__codelineno-0-153" name="__codelineno-0-153"></a> <span class="n">diagram_idx</span> <span class="o">=</span> <span class="mi">0</span>
2749
<a id="__codelineno-0-154" name="__codelineno-0-154"></a> <span class="n">capture_idx</span> <span class="o">=</span> <span class="mi">0</span>
2750
<a id="__codelineno-0-155" name="__codelineno-0-155"></a>
2751
<a id="__codelineno-0-156" name="__codelineno-0-156"></a> <span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">fp</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">tqdm</span><span class="p">(</span><span class="n">frame_paths</span><span class="p">,</span> <span class="n">desc</span><span class="o">=</span><span class="s2">&quot;Analyzing frames&quot;</span><span class="p">,</span> <span class="n">unit</span><span class="o">=</span><span class="s2">&quot;frame&quot;</span><span class="p">)):</span>
2752
<a id="__codelineno-0-157" name="__codelineno-0-157"></a> <span class="n">fp</span> <span class="o">=</span> <span class="n">Path</span><span class="p">(</span><span class="n">fp</span><span class="p">)</span>
2753
<a id="__codelineno-0-158" name="__codelineno-0-158"></a> <span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Classifying frame </span><span class="si">{</span><span class="n">i</span><span class="si">}</span><span class="s2">/</span><span class="si">{</span><span class="nb">len</span><span class="p">(</span><span class="n">frame_paths</span><span class="p">)</span><span class="si">}</span><span class="s2">: </span><span class="si">{</span><span class="n">fp</span><span class="o">.</span><span class="n">name</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
2754
<a id="__codelineno-0-159" name="__codelineno-0-159"></a>
2755
<a id="__codelineno-0-160" name="__codelineno-0-160"></a> <span class="k">try</span><span class="p">:</span>
2756
<a id="__codelineno-0-161" name="__codelineno-0-161"></a> <span class="n">classification</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">classify_frame</span><span class="p">(</span><span class="n">fp</span><span class="p">)</span>
2757
<a id="__codelineno-0-162" name="__codelineno-0-162"></a> <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
2758
<a id="__codelineno-0-163" name="__codelineno-0-163"></a> <span class="n">logger</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Classification failed for frame </span><span class="si">{</span><span class="n">i</span><span class="si">}</span><span class="s2">: </span><span class="si">{</span><span class="n">e</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
2759
<a id="__codelineno-0-164" name="__codelineno-0-164"></a> <span class="k">continue</span>
2760
<a id="__codelineno-0-165" name="__codelineno-0-165"></a>
2761
<a id="__codelineno-0-166" name="__codelineno-0-166"></a> <span class="n">confidence</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="n">classification</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;confidence&quot;</span><span class="p">,</span> <span class="mf">0.0</span><span class="p">))</span>
2762
<a id="__codelineno-0-167" name="__codelineno-0-167"></a>
2763
<a id="__codelineno-0-168" name="__codelineno-0-168"></a> <span class="k">if</span> <span class="n">confidence</span> <span class="o">&lt;</span> <span class="bp">self</span><span class="o">.</span><span class="n">confidence_threshold</span><span class="p">:</span>
2764
<a id="__codelineno-0-169" name="__codelineno-0-169"></a> <span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Frame </span><span class="si">{</span><span class="n">i</span><span class="si">}</span><span class="s2">: confidence </span><span class="si">{</span><span class="n">confidence</span><span class="si">:</span><span class="s2">.2f</span><span class="si">}</span><span class="s2"> below threshold, skipping&quot;</span><span class="p">)</span>
2765
<a id="__codelineno-0-170" name="__codelineno-0-170"></a> <span class="k">continue</span>
2766
<a id="__codelineno-0-171" name="__codelineno-0-171"></a>
2767
<a id="__codelineno-0-172" name="__codelineno-0-172"></a> <span class="k">if</span> <span class="n">confidence</span> <span class="o">&gt;=</span> <span class="mf">0.7</span><span class="p">:</span>
2768
<a id="__codelineno-0-173" name="__codelineno-0-173"></a> <span class="c1"># Full diagram analysis</span>
2769
<a id="__codelineno-0-174" name="__codelineno-0-174"></a> <span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span>
2770
<a id="__codelineno-0-175" name="__codelineno-0-175"></a> <span class="sa">f</span><span class="s2">&quot;Frame </span><span class="si">{</span><span class="n">i</span><span class="si">}</span><span class="s2">: diagram detected (confidence </span><span class="si">{</span><span class="n">confidence</span><span class="si">:</span><span class="s2">.2f</span><span class="si">}</span><span class="s2">), analyzing...&quot;</span>
2771
<a id="__codelineno-0-176" name="__codelineno-0-176"></a> <span class="p">)</span>
2772
<a id="__codelineno-0-177" name="__codelineno-0-177"></a> <span class="k">try</span><span class="p">:</span>
2773
<a id="__codelineno-0-178" name="__codelineno-0-178"></a> <span class="n">analysis</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">analyze_diagram_single_pass</span><span class="p">(</span><span class="n">fp</span><span class="p">)</span>
2774
<a id="__codelineno-0-179" name="__codelineno-0-179"></a> <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
2775
<a id="__codelineno-0-180" name="__codelineno-0-180"></a> <span class="n">logger</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span>
2776
<a id="__codelineno-0-181" name="__codelineno-0-181"></a> <span class="sa">f</span><span class="s2">&quot;Diagram analysis failed for frame </span><span class="si">{</span><span class="n">i</span><span class="si">}</span><span class="s2">: </span><span class="si">{</span><span class="n">e</span><span class="si">}</span><span class="s2">, falling back to screengrab&quot;</span>
2777
<a id="__codelineno-0-182" name="__codelineno-0-182"></a> <span class="p">)</span>
2778
<a id="__codelineno-0-183" name="__codelineno-0-183"></a> <span class="n">analysis</span> <span class="o">=</span> <span class="p">{}</span>
2779
<a id="__codelineno-0-184" name="__codelineno-0-184"></a>
2780
<a id="__codelineno-0-185" name="__codelineno-0-185"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">analysis</span><span class="p">:</span>
2781
<a id="__codelineno-0-186" name="__codelineno-0-186"></a> <span class="c1"># Analysis failed — fall back to screengrab</span>
2782
<a id="__codelineno-0-187" name="__codelineno-0-187"></a> <span class="n">capture</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_save_screengrab</span><span class="p">(</span><span class="n">fp</span><span class="p">,</span> <span class="n">i</span><span class="p">,</span> <span class="n">capture_idx</span><span class="p">,</span> <span class="n">captures_dir</span><span class="p">,</span> <span class="n">confidence</span><span class="p">)</span>
2783
<a id="__codelineno-0-188" name="__codelineno-0-188"></a> <span class="n">captures</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">capture</span><span class="p">)</span>
2784
<a id="__codelineno-0-189" name="__codelineno-0-189"></a> <span class="n">capture_idx</span> <span class="o">+=</span> <span class="mi">1</span>
2785
<a id="__codelineno-0-190" name="__codelineno-0-190"></a> <span class="k">continue</span>
2786
<a id="__codelineno-0-191" name="__codelineno-0-191"></a>
2787
<a id="__codelineno-0-192" name="__codelineno-0-192"></a> <span class="c1"># Build DiagramResult</span>
2788
<a id="__codelineno-0-193" name="__codelineno-0-193"></a> <span class="n">dtype</span> <span class="o">=</span> <span class="n">analysis</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;diagram_type&quot;</span><span class="p">,</span> <span class="n">classification</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;diagram_type&quot;</span><span class="p">,</span> <span class="s2">&quot;unknown&quot;</span><span class="p">))</span>
2789
<a id="__codelineno-0-194" name="__codelineno-0-194"></a> <span class="k">try</span><span class="p">:</span>
2790
<a id="__codelineno-0-195" name="__codelineno-0-195"></a> <span class="n">diagram_type</span> <span class="o">=</span> <span class="n">DiagramType</span><span class="p">(</span><span class="n">dtype</span><span class="p">)</span>
2791
<a id="__codelineno-0-196" name="__codelineno-0-196"></a> <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
2792
<a id="__codelineno-0-197" name="__codelineno-0-197"></a> <span class="n">diagram_type</span> <span class="o">=</span> <span class="n">DiagramType</span><span class="o">.</span><span class="n">unknown</span>
2793
<a id="__codelineno-0-198" name="__codelineno-0-198"></a>
2794
<a id="__codelineno-0-199" name="__codelineno-0-199"></a> <span class="c1"># Normalize relationships: llava sometimes returns dicts instead of strings</span>
2795
<a id="__codelineno-0-200" name="__codelineno-0-200"></a> <span class="n">raw_rels</span> <span class="o">=</span> <span class="n">analysis</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;relationships&quot;</span><span class="p">)</span> <span class="ow">or</span> <span class="p">[]</span>
2796
<a id="__codelineno-0-201" name="__codelineno-0-201"></a> <span class="n">relationships</span> <span class="o">=</span> <span class="p">[]</span>
2797
<a id="__codelineno-0-202" name="__codelineno-0-202"></a> <span class="k">for</span> <span class="n">rel</span> <span class="ow">in</span> <span class="n">raw_rels</span><span class="p">:</span>
2798
<a id="__codelineno-0-203" name="__codelineno-0-203"></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">rel</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
2799
<a id="__codelineno-0-204" name="__codelineno-0-204"></a> <span class="n">relationships</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">rel</span><span class="p">)</span>
2800
<a id="__codelineno-0-205" name="__codelineno-0-205"></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">rel</span><span class="p">,</span> <span class="nb">dict</span><span class="p">):</span>
2801
<a id="__codelineno-0-206" name="__codelineno-0-206"></a> <span class="n">src</span> <span class="o">=</span> <span class="n">rel</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;source&quot;</span><span class="p">,</span> <span class="n">rel</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;from&quot;</span><span class="p">,</span> <span class="s2">&quot;?&quot;</span><span class="p">))</span>
2802
<a id="__codelineno-0-207" name="__codelineno-0-207"></a> <span class="n">dst</span> <span class="o">=</span> <span class="n">rel</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;destination&quot;</span><span class="p">,</span> <span class="n">rel</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;to&quot;</span><span class="p">,</span> <span class="s2">&quot;?&quot;</span><span class="p">))</span>
2803
<a id="__codelineno-0-208" name="__codelineno-0-208"></a> <span class="n">label</span> <span class="o">=</span> <span class="n">rel</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;label&quot;</span><span class="p">,</span> <span class="n">rel</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;relationship&quot;</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">))</span>
2804
<a id="__codelineno-0-209" name="__codelineno-0-209"></a> <span class="n">relationships</span><span class="o">.</span><span class="n">append</span><span class="p">(</span>
2805
<a id="__codelineno-0-210" name="__codelineno-0-210"></a> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">src</span><span class="si">}</span><span class="s2"> -&gt; </span><span class="si">{</span><span class="n">dst</span><span class="si">}</span><span class="s2">: </span><span class="si">{</span><span class="n">label</span><span class="si">}</span><span class="s2">&quot;</span> <span class="k">if</span> <span class="n">label</span> <span class="k">else</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">src</span><span class="si">}</span><span class="s2"> -&gt; </span><span class="si">{</span><span class="n">dst</span><span class="si">}</span><span class="s2">&quot;</span>
2806
<a id="__codelineno-0-211" name="__codelineno-0-211"></a> <span class="p">)</span>
2807
<a id="__codelineno-0-212" name="__codelineno-0-212"></a> <span class="k">else</span><span class="p">:</span>
2808
<a id="__codelineno-0-213" name="__codelineno-0-213"></a> <span class="n">relationships</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">rel</span><span class="p">))</span>
2809
<a id="__codelineno-0-214" name="__codelineno-0-214"></a>
2810
<a id="__codelineno-0-215" name="__codelineno-0-215"></a> <span class="c1"># Normalize elements: llava may return dicts or nested lists</span>
2811
<a id="__codelineno-0-216" name="__codelineno-0-216"></a> <span class="n">raw_elements</span> <span class="o">=</span> <span class="n">analysis</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;elements&quot;</span><span class="p">)</span> <span class="ow">or</span> <span class="p">[]</span>
2812
<a id="__codelineno-0-217" name="__codelineno-0-217"></a> <span class="n">elements</span> <span class="o">=</span> <span class="p">[]</span>
2813
<a id="__codelineno-0-218" name="__codelineno-0-218"></a> <span class="k">for</span> <span class="n">elem</span> <span class="ow">in</span> <span class="n">raw_elements</span><span class="p">:</span>
2814
<a id="__codelineno-0-219" name="__codelineno-0-219"></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">elem</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
2815
<a id="__codelineno-0-220" name="__codelineno-0-220"></a> <span class="n">elements</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">elem</span><span class="p">)</span>
2816
<a id="__codelineno-0-221" name="__codelineno-0-221"></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">elem</span><span class="p">,</span> <span class="nb">dict</span><span class="p">):</span>
2817
<a id="__codelineno-0-222" name="__codelineno-0-222"></a> <span class="n">name</span> <span class="o">=</span> <span class="n">elem</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;name&quot;</span><span class="p">,</span> <span class="n">elem</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;element&quot;</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">))</span>
2818
<a id="__codelineno-0-223" name="__codelineno-0-223"></a> <span class="n">etype</span> <span class="o">=</span> <span class="n">elem</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;type&quot;</span><span class="p">,</span> <span class="n">elem</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;element_type&quot;</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">))</span>
2819
<a id="__codelineno-0-224" name="__codelineno-0-224"></a> <span class="k">if</span> <span class="n">name</span> <span class="ow">and</span> <span class="n">etype</span><span class="p">:</span>
2820
<a id="__codelineno-0-225" name="__codelineno-0-225"></a> <span class="n">elements</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">etype</span><span class="si">}</span><span class="s2">: </span><span class="si">{</span><span class="n">name</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
2821
<a id="__codelineno-0-226" name="__codelineno-0-226"></a> <span class="k">elif</span> <span class="n">name</span><span class="p">:</span>
2822
<a id="__codelineno-0-227" name="__codelineno-0-227"></a> <span class="n">elements</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
2823
<a id="__codelineno-0-228" name="__codelineno-0-228"></a> <span class="k">else</span><span class="p">:</span>
2824
<a id="__codelineno-0-229" name="__codelineno-0-229"></a> <span class="n">elements</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="n">elem</span><span class="p">))</span>
2825
<a id="__codelineno-0-230" name="__codelineno-0-230"></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">elem</span><span class="p">,</span> <span class="nb">list</span><span class="p">):</span>
2826
<a id="__codelineno-0-231" name="__codelineno-0-231"></a> <span class="n">elements</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">)</span> <span class="k">for</span> <span class="n">e</span> <span class="ow">in</span> <span class="n">elem</span><span class="p">)</span>
2827
<a id="__codelineno-0-232" name="__codelineno-0-232"></a> <span class="k">else</span><span class="p">:</span>
2828
<a id="__codelineno-0-233" name="__codelineno-0-233"></a> <span class="n">elements</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">elem</span><span class="p">))</span>
2829
<a id="__codelineno-0-234" name="__codelineno-0-234"></a>
2830
<a id="__codelineno-0-235" name="__codelineno-0-235"></a> <span class="c1"># Normalize text_content: llava may return dict instead of string</span>
2831
<a id="__codelineno-0-236" name="__codelineno-0-236"></a> <span class="n">raw_text</span> <span class="o">=</span> <span class="n">analysis</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;text_content&quot;</span><span class="p">)</span>
2832
<a id="__codelineno-0-237" name="__codelineno-0-237"></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">raw_text</span><span class="p">,</span> <span class="nb">dict</span><span class="p">):</span>
2833
<a id="__codelineno-0-238" name="__codelineno-0-238"></a> <span class="n">parts</span> <span class="o">=</span> <span class="p">[]</span>
2834
<a id="__codelineno-0-239" name="__codelineno-0-239"></a> <span class="k">for</span> <span class="n">k</span><span class="p">,</span> <span class="n">v</span> <span class="ow">in</span> <span class="n">raw_text</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
2835
<a id="__codelineno-0-240" name="__codelineno-0-240"></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="nb">list</span><span class="p">):</span>
2836
<a id="__codelineno-0-241" name="__codelineno-0-241"></a> <span class="n">parts</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">k</span><span class="si">}</span><span class="s2">: </span><span class="si">{</span><span class="s1">&#39;, &#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">x</span><span class="p">)</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="ow">in</span><span class="w"> </span><span class="n">v</span><span class="p">)</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
2837
<a id="__codelineno-0-242" name="__codelineno-0-242"></a> <span class="k">else</span><span class="p">:</span>
2838
<a id="__codelineno-0-243" name="__codelineno-0-243"></a> <span class="n">parts</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">k</span><span class="si">}</span><span class="s2">: </span><span class="si">{</span><span class="n">v</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
2839
<a id="__codelineno-0-244" name="__codelineno-0-244"></a> <span class="n">text_content</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">parts</span><span class="p">)</span>
2840
<a id="__codelineno-0-245" name="__codelineno-0-245"></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">raw_text</span><span class="p">,</span> <span class="nb">list</span><span class="p">):</span>
2841
<a id="__codelineno-0-246" name="__codelineno-0-246"></a> <span class="n">text_content</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">x</span><span class="p">)</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">raw_text</span><span class="p">)</span>
2842
<a id="__codelineno-0-247" name="__codelineno-0-247"></a> <span class="k">else</span><span class="p">:</span>
2843
<a id="__codelineno-0-248" name="__codelineno-0-248"></a> <span class="n">text_content</span> <span class="o">=</span> <span class="n">raw_text</span>
2844
<a id="__codelineno-0-249" name="__codelineno-0-249"></a>
2845
<a id="__codelineno-0-250" name="__codelineno-0-250"></a> <span class="k">try</span><span class="p">:</span>
2846
<a id="__codelineno-0-251" name="__codelineno-0-251"></a> <span class="n">dr</span> <span class="o">=</span> <span class="n">DiagramResult</span><span class="p">(</span>
2847
<a id="__codelineno-0-252" name="__codelineno-0-252"></a> <span class="n">frame_index</span><span class="o">=</span><span class="n">i</span><span class="p">,</span>
2848
<a id="__codelineno-0-253" name="__codelineno-0-253"></a> <span class="n">diagram_type</span><span class="o">=</span><span class="n">diagram_type</span><span class="p">,</span>
2849
<a id="__codelineno-0-254" name="__codelineno-0-254"></a> <span class="n">confidence</span><span class="o">=</span><span class="n">confidence</span><span class="p">,</span>
2850
<a id="__codelineno-0-255" name="__codelineno-0-255"></a> <span class="n">description</span><span class="o">=</span><span class="n">analysis</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;description&quot;</span><span class="p">),</span>
2851
<a id="__codelineno-0-256" name="__codelineno-0-256"></a> <span class="n">text_content</span><span class="o">=</span><span class="n">text_content</span><span class="p">,</span>
2852
<a id="__codelineno-0-257" name="__codelineno-0-257"></a> <span class="n">elements</span><span class="o">=</span><span class="n">elements</span><span class="p">,</span>
2853
<a id="__codelineno-0-258" name="__codelineno-0-258"></a> <span class="n">relationships</span><span class="o">=</span><span class="n">relationships</span><span class="p">,</span>
2854
<a id="__codelineno-0-259" name="__codelineno-0-259"></a> <span class="n">mermaid</span><span class="o">=</span><span class="n">analysis</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;mermaid&quot;</span><span class="p">),</span>
2855
<a id="__codelineno-0-260" name="__codelineno-0-260"></a> <span class="n">chart_data</span><span class="o">=</span><span class="n">analysis</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;chart_data&quot;</span><span class="p">),</span>
2856
<a id="__codelineno-0-261" name="__codelineno-0-261"></a> <span class="p">)</span>
2857
<a id="__codelineno-0-262" name="__codelineno-0-262"></a> <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
2858
<a id="__codelineno-0-263" name="__codelineno-0-263"></a> <span class="n">logger</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span>
2859
<a id="__codelineno-0-264" name="__codelineno-0-264"></a> <span class="sa">f</span><span class="s2">&quot;DiagramResult validation failed for frame </span><span class="si">{</span><span class="n">i</span><span class="si">}</span><span class="s2">: </span><span class="si">{</span><span class="n">e</span><span class="si">}</span><span class="s2">, &quot;</span>
2860
<a id="__codelineno-0-265" name="__codelineno-0-265"></a> <span class="s2">&quot;falling back to screengrab&quot;</span>
2861
<a id="__codelineno-0-266" name="__codelineno-0-266"></a> <span class="p">)</span>
2862
<a id="__codelineno-0-267" name="__codelineno-0-267"></a> <span class="n">capture</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_save_screengrab</span><span class="p">(</span><span class="n">fp</span><span class="p">,</span> <span class="n">i</span><span class="p">,</span> <span class="n">capture_idx</span><span class="p">,</span> <span class="n">captures_dir</span><span class="p">,</span> <span class="n">confidence</span><span class="p">)</span>
2863
<a id="__codelineno-0-268" name="__codelineno-0-268"></a> <span class="n">captures</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">capture</span><span class="p">)</span>
2864
<a id="__codelineno-0-269" name="__codelineno-0-269"></a> <span class="n">capture_idx</span> <span class="o">+=</span> <span class="mi">1</span>
2865
<a id="__codelineno-0-270" name="__codelineno-0-270"></a> <span class="k">continue</span>
2866
<a id="__codelineno-0-271" name="__codelineno-0-271"></a>
2867
<a id="__codelineno-0-272" name="__codelineno-0-272"></a> <span class="c1"># Save outputs (story 3.4)</span>
2868
<a id="__codelineno-0-273" name="__codelineno-0-273"></a> <span class="k">if</span> <span class="n">diagrams_dir</span><span class="p">:</span>
2869
<a id="__codelineno-0-274" name="__codelineno-0-274"></a> <span class="n">diagrams_dir</span><span class="o">.</span><span class="n">mkdir</span><span class="p">(</span><span class="n">parents</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">exist_ok</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
2870
<a id="__codelineno-0-275" name="__codelineno-0-275"></a> <span class="n">prefix</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;diagram_</span><span class="si">{</span><span class="n">diagram_idx</span><span class="si">}</span><span class="s2">&quot;</span>
2871
<a id="__codelineno-0-276" name="__codelineno-0-276"></a>
2872
<a id="__codelineno-0-277" name="__codelineno-0-277"></a> <span class="c1"># Original frame</span>
2873
<a id="__codelineno-0-278" name="__codelineno-0-278"></a> <span class="n">img_dest</span> <span class="o">=</span> <span class="n">diagrams_dir</span> <span class="o">/</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">prefix</span><span class="si">}</span><span class="s2">.jpg&quot;</span>
2874
<a id="__codelineno-0-279" name="__codelineno-0-279"></a> <span class="n">shutil</span><span class="o">.</span><span class="n">copy2</span><span class="p">(</span><span class="n">fp</span><span class="p">,</span> <span class="n">img_dest</span><span class="p">)</span>
2875
<a id="__codelineno-0-280" name="__codelineno-0-280"></a> <span class="n">dr</span><span class="o">.</span><span class="n">image_path</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;diagrams/</span><span class="si">{</span><span class="n">prefix</span><span class="si">}</span><span class="s2">.jpg&quot;</span>
2876
<a id="__codelineno-0-281" name="__codelineno-0-281"></a>
2877
<a id="__codelineno-0-282" name="__codelineno-0-282"></a> <span class="c1"># Mermaid source</span>
2878
<a id="__codelineno-0-283" name="__codelineno-0-283"></a> <span class="k">if</span> <span class="n">dr</span><span class="o">.</span><span class="n">mermaid</span><span class="p">:</span>
2879
<a id="__codelineno-0-284" name="__codelineno-0-284"></a> <span class="n">mermaid_dest</span> <span class="o">=</span> <span class="n">diagrams_dir</span> <span class="o">/</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">prefix</span><span class="si">}</span><span class="s2">.mermaid&quot;</span>
2880
<a id="__codelineno-0-285" name="__codelineno-0-285"></a> <span class="n">mermaid_dest</span><span class="o">.</span><span class="n">write_text</span><span class="p">(</span><span class="n">dr</span><span class="o">.</span><span class="n">mermaid</span><span class="p">)</span>
2881
<a id="__codelineno-0-286" name="__codelineno-0-286"></a> <span class="n">dr</span><span class="o">.</span><span class="n">mermaid_path</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;diagrams/</span><span class="si">{</span><span class="n">prefix</span><span class="si">}</span><span class="s2">.mermaid&quot;</span>
2882
<a id="__codelineno-0-287" name="__codelineno-0-287"></a>
2883
<a id="__codelineno-0-288" name="__codelineno-0-288"></a> <span class="c1"># Analysis JSON</span>
2884
<a id="__codelineno-0-289" name="__codelineno-0-289"></a> <span class="n">json_dest</span> <span class="o">=</span> <span class="n">diagrams_dir</span> <span class="o">/</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">prefix</span><span class="si">}</span><span class="s2">.json&quot;</span>
2885
<a id="__codelineno-0-290" name="__codelineno-0-290"></a> <span class="n">json_dest</span><span class="o">.</span><span class="n">write_text</span><span class="p">(</span><span class="n">dr</span><span class="o">.</span><span class="n">model_dump_json</span><span class="p">(</span><span class="n">indent</span><span class="o">=</span><span class="mi">2</span><span class="p">))</span>
2886
<a id="__codelineno-0-291" name="__codelineno-0-291"></a>
2887
<a id="__codelineno-0-292" name="__codelineno-0-292"></a> <span class="n">diagrams</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">dr</span><span class="p">)</span>
2888
<a id="__codelineno-0-293" name="__codelineno-0-293"></a> <span class="n">diagram_idx</span> <span class="o">+=</span> <span class="mi">1</span>
2889
<a id="__codelineno-0-294" name="__codelineno-0-294"></a>
2890
<a id="__codelineno-0-295" name="__codelineno-0-295"></a> <span class="k">else</span><span class="p">:</span>
2891
<a id="__codelineno-0-296" name="__codelineno-0-296"></a> <span class="c1"># Screengrab fallback (0.3 &lt;= confidence &lt; 0.7)</span>
2892
<a id="__codelineno-0-297" name="__codelineno-0-297"></a> <span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span>
2893
<a id="__codelineno-0-298" name="__codelineno-0-298"></a> <span class="sa">f</span><span class="s2">&quot;Frame </span><span class="si">{</span><span class="n">i</span><span class="si">}</span><span class="s2">: uncertain (confidence </span><span class="si">{</span><span class="n">confidence</span><span class="si">:</span><span class="s2">.2f</span><span class="si">}</span><span class="s2">), saving as screengrab&quot;</span>
2894
<a id="__codelineno-0-299" name="__codelineno-0-299"></a> <span class="p">)</span>
2895
<a id="__codelineno-0-300" name="__codelineno-0-300"></a> <span class="n">capture</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_save_screengrab</span><span class="p">(</span><span class="n">fp</span><span class="p">,</span> <span class="n">i</span><span class="p">,</span> <span class="n">capture_idx</span><span class="p">,</span> <span class="n">captures_dir</span><span class="p">,</span> <span class="n">confidence</span><span class="p">)</span>
2896
<a id="__codelineno-0-301" name="__codelineno-0-301"></a> <span class="n">captures</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">capture</span><span class="p">)</span>
2897
<a id="__codelineno-0-302" name="__codelineno-0-302"></a> <span class="n">capture_idx</span> <span class="o">+=</span> <span class="mi">1</span>
2898
<a id="__codelineno-0-303" name="__codelineno-0-303"></a>
2899
<a id="__codelineno-0-304" name="__codelineno-0-304"></a> <span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span>
2900
<a id="__codelineno-0-305" name="__codelineno-0-305"></a> <span class="sa">f</span><span class="s2">&quot;Diagram processing complete: </span><span class="si">{</span><span class="nb">len</span><span class="p">(</span><span class="n">diagrams</span><span class="p">)</span><span class="si">}</span><span class="s2"> diagrams, </span><span class="si">{</span><span class="nb">len</span><span class="p">(</span><span class="n">captures</span><span class="p">)</span><span class="si">}</span><span class="s2"> screengrabs&quot;</span>
2901
<a id="__codelineno-0-306" name="__codelineno-0-306"></a> <span class="p">)</span>
2902
<a id="__codelineno-0-307" name="__codelineno-0-307"></a> <span class="k">return</span> <span class="n">diagrams</span><span class="p">,</span> <span class="n">captures</span>
2903
<a id="__codelineno-0-308" name="__codelineno-0-308"></a>
2904
<a id="__codelineno-0-309" name="__codelineno-0-309"></a> <span class="k">def</span><span class="w"> </span><span class="nf">_save_screengrab</span><span class="p">(</span>
2905
<a id="__codelineno-0-310" name="__codelineno-0-310"></a> <span class="bp">self</span><span class="p">,</span>
2906
<a id="__codelineno-0-311" name="__codelineno-0-311"></a> <span class="n">frame_path</span><span class="p">:</span> <span class="n">Path</span><span class="p">,</span>
2907
<a id="__codelineno-0-312" name="__codelineno-0-312"></a> <span class="n">frame_index</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span>
2908
<a id="__codelineno-0-313" name="__codelineno-0-313"></a> <span class="n">capture_index</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span>
2909
<a id="__codelineno-0-314" name="__codelineno-0-314"></a> <span class="n">captures_dir</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">Path</span><span class="p">],</span>
2910
<a id="__codelineno-0-315" name="__codelineno-0-315"></a> <span class="n">confidence</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
2911
<a id="__codelineno-0-316" name="__codelineno-0-316"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ScreenCapture</span><span class="p">:</span>
2912
<a id="__codelineno-0-317" name="__codelineno-0-317"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Save a frame as a captioned screengrab.&quot;&quot;&quot;</span>
2913
<a id="__codelineno-0-318" name="__codelineno-0-318"></a> <span class="n">caption</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
2914
<a id="__codelineno-0-319" name="__codelineno-0-319"></a> <span class="k">try</span><span class="p">:</span>
2915
<a id="__codelineno-0-320" name="__codelineno-0-320"></a> <span class="n">caption</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">caption_frame</span><span class="p">(</span><span class="n">frame_path</span><span class="p">)</span>
2916
<a id="__codelineno-0-321" name="__codelineno-0-321"></a> <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
2917
<a id="__codelineno-0-322" name="__codelineno-0-322"></a> <span class="n">logger</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Caption failed for frame </span><span class="si">{</span><span class="n">frame_index</span><span class="si">}</span><span class="s2">: </span><span class="si">{</span><span class="n">e</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
2918
<a id="__codelineno-0-323" name="__codelineno-0-323"></a>
2919
<a id="__codelineno-0-324" name="__codelineno-0-324"></a> <span class="n">sc</span> <span class="o">=</span> <span class="n">ScreenCapture</span><span class="p">(</span>
2920
<a id="__codelineno-0-325" name="__codelineno-0-325"></a> <span class="n">frame_index</span><span class="o">=</span><span class="n">frame_index</span><span class="p">,</span>
2921
<a id="__codelineno-0-326" name="__codelineno-0-326"></a> <span class="n">caption</span><span class="o">=</span><span class="n">caption</span><span class="p">,</span>
2922
<a id="__codelineno-0-327" name="__codelineno-0-327"></a> <span class="n">confidence</span><span class="o">=</span><span class="n">confidence</span><span class="p">,</span>
2923
<a id="__codelineno-0-328" name="__codelineno-0-328"></a> <span class="p">)</span>
2924
<a id="__codelineno-0-329" name="__codelineno-0-329"></a>
2925
<a id="__codelineno-0-330" name="__codelineno-0-330"></a> <span class="k">if</span> <span class="n">captures_dir</span><span class="p">:</span>
2926
<a id="__codelineno-0-331" name="__codelineno-0-331"></a> <span class="n">captures_dir</span><span class="o">.</span><span class="n">mkdir</span><span class="p">(</span><span class="n">parents</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">exist_ok</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
2927
<a id="__codelineno-0-332" name="__codelineno-0-332"></a> <span class="n">prefix</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;capture_</span><span class="si">{</span><span class="n">capture_index</span><span class="si">}</span><span class="s2">&quot;</span>
2928
<a id="__codelineno-0-333" name="__codelineno-0-333"></a> <span class="n">img_dest</span> <span class="o">=</span> <span class="n">captures_dir</span> <span class="o">/</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">prefix</span><span class="si">}</span><span class="s2">.jpg&quot;</span>
2929
<a id="__codelineno-0-334" name="__codelineno-0-334"></a> <span class="n">shutil</span><span class="o">.</span><span class="n">copy2</span><span class="p">(</span><span class="n">frame_path</span><span class="p">,</span> <span class="n">img_dest</span><span class="p">)</span>
2930
<a id="__codelineno-0-335" name="__codelineno-0-335"></a> <span class="n">sc</span><span class="o">.</span><span class="n">image_path</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;captures/</span><span class="si">{</span><span class="n">prefix</span><span class="si">}</span><span class="s2">.jpg&quot;</span>
2931
<a id="__codelineno-0-336" name="__codelineno-0-336"></a>
2932
<a id="__codelineno-0-337" name="__codelineno-0-337"></a> <span class="n">json_dest</span> <span class="o">=</span> <span class="n">captures_dir</span> <span class="o">/</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">prefix</span><span class="si">}</span><span class="s2">.json&quot;</span>
2933
<a id="__codelineno-0-338" name="__codelineno-0-338"></a> <span class="n">json_dest</span><span class="o">.</span><span class="n">write_text</span><span class="p">(</span><span class="n">sc</span><span class="o">.</span><span class="n">model_dump_json</span><span class="p">(</span><span class="n">indent</span><span class="o">=</span><span class="mi">2</span><span class="p">))</span>
2934
<a id="__codelineno-0-339" name="__codelineno-0-339"></a>
2935
<a id="__codelineno-0-340" name="__codelineno-0-340"></a> <span class="k">return</span> <span class="n">sc</span>
2936
</code></pre></div></td></tr></table></div>
2937
</details>
2938
2939
2940
2941
<div class="doc doc-children">
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
<div class="doc doc-object doc-function">
2953
2954
2955
<h4 id="video_processor.analyzers.diagram_analyzer.DiagramAnalyzer.analyze_diagram_single_pass" class="doc doc-heading">
2956
<code class="highlight language-python"><span class="n">analyze_diagram_single_pass</span><span class="p">(</span><span class="n">image_path</span><span class="p">)</span></code>
2957
2958
<a href="#video_processor.analyzers.diagram_analyzer.DiagramAnalyzer.analyze_diagram_single_pass" class="headerlink" title="Permanent link">&para;</a></h4>
2959
2960
2961
<div class="doc doc-contents ">
2962
2963
<p>Full single-pass diagram analysis — description, text, mermaid, chart data.</p>
2964
<p>Returns parsed dict or empty dict on failure.</p>
2965
2966
2967
<details class="mkdocstrings-source">
2968
<summary>Source code in <code>video_processor/analyzers/diagram_analyzer.py</code></summary>
2969
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-119">119</a></span>
2970
<span class="normal"><a href="#__codelineno-0-120">120</a></span>
2971
<span class="normal"><a href="#__codelineno-0-121">121</a></span>
2972
<span class="normal"><a href="#__codelineno-0-122">122</a></span>
2973
<span class="normal"><a href="#__codelineno-0-123">123</a></span>
2974
<span class="normal"><a href="#__codelineno-0-124">124</a></span>
2975
<span class="normal"><a href="#__codelineno-0-125">125</a></span>
2976
<span class="normal"><a href="#__codelineno-0-126">126</a></span>
2977
<span class="normal"><a href="#__codelineno-0-127">127</a></span>
2978
<span class="normal"><a href="#__codelineno-0-128">128</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-119" name="__codelineno-0-119"></a><span class="k">def</span><span class="w"> </span><span class="nf">analyze_diagram_single_pass</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">image_path</span><span class="p">:</span> <span class="n">Union</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Path</span><span class="p">])</span> <span class="o">-&gt;</span> <span class="nb">dict</span><span class="p">:</span>
2979
<a id="__codelineno-0-120" name="__codelineno-0-120"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
2980
<a id="__codelineno-0-121" name="__codelineno-0-121"></a><span class="sd"> Full single-pass diagram analysis — description, text, mermaid, chart data.</span>
2981
<a id="__codelineno-0-122" name="__codelineno-0-122"></a>
2982
<a id="__codelineno-0-123" name="__codelineno-0-123"></a><span class="sd"> Returns parsed dict or empty dict on failure.</span>
2983
<a id="__codelineno-0-124" name="__codelineno-0-124"></a><span class="sd"> &quot;&quot;&quot;</span>
2984
<a id="__codelineno-0-125" name="__codelineno-0-125"></a> <span class="n">image_bytes</span> <span class="o">=</span> <span class="n">_read_image_bytes</span><span class="p">(</span><span class="n">image_path</span><span class="p">)</span>
2985
<a id="__codelineno-0-126" name="__codelineno-0-126"></a> <span class="n">raw</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">pm</span><span class="o">.</span><span class="n">analyze_image</span><span class="p">(</span><span class="n">image_bytes</span><span class="p">,</span> <span class="n">_ANALYSIS_PROMPT</span><span class="p">,</span> <span class="n">max_tokens</span><span class="o">=</span><span class="mi">4096</span><span class="p">)</span>
2986
<a id="__codelineno-0-127" name="__codelineno-0-127"></a> <span class="n">result</span> <span class="o">=</span> <span class="n">_parse_json_response</span><span class="p">(</span><span class="n">raw</span><span class="p">)</span>
2987
<a id="__codelineno-0-128" name="__codelineno-0-128"></a> <span class="k">return</span> <span class="n">result</span> <span class="ow">or</span> <span class="p">{}</span>
2988
</code></pre></div></td></tr></table></div>
2989
</details>
2990
</div>
2991
2992
</div>
2993
2994
<div class="doc doc-object doc-function">
2995
2996
2997
<h4 id="video_processor.analyzers.diagram_analyzer.DiagramAnalyzer.caption_frame" class="doc doc-heading">
2998
<code class="highlight language-python"><span class="n">caption_frame</span><span class="p">(</span><span class="n">image_path</span><span class="p">)</span></code>
2999
3000
<a href="#video_processor.analyzers.diagram_analyzer.DiagramAnalyzer.caption_frame" class="headerlink" title="Permanent link">&para;</a></h4>
3001
3002
3003
<div class="doc doc-contents ">
3004
3005
<p>Get a brief caption for a screengrab fallback.</p>
3006
3007
3008
<details class="mkdocstrings-source">
3009
<summary>Source code in <code>video_processor/analyzers/diagram_analyzer.py</code></summary>
3010
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-130">130</a></span>
3011
<span class="normal"><a href="#__codelineno-0-131">131</a></span>
3012
<span class="normal"><a href="#__codelineno-0-132">132</a></span>
3013
<span class="normal"><a href="#__codelineno-0-133">133</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-130" name="__codelineno-0-130"></a><span class="k">def</span><span class="w"> </span><span class="nf">caption_frame</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">image_path</span><span class="p">:</span> <span class="n">Union</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Path</span><span class="p">])</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
3014
<a id="__codelineno-0-131" name="__codelineno-0-131"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Get a brief caption for a screengrab fallback.&quot;&quot;&quot;</span>
3015
<a id="__codelineno-0-132" name="__codelineno-0-132"></a> <span class="n">image_bytes</span> <span class="o">=</span> <span class="n">_read_image_bytes</span><span class="p">(</span><span class="n">image_path</span><span class="p">)</span>
3016
<a id="__codelineno-0-133" name="__codelineno-0-133"></a> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">pm</span><span class="o">.</span><span class="n">analyze_image</span><span class="p">(</span><span class="n">image_bytes</span><span class="p">,</span> <span class="n">_CAPTION_PROMPT</span><span class="p">,</span> <span class="n">max_tokens</span><span class="o">=</span><span class="mi">256</span><span class="p">)</span>
3017
</code></pre></div></td></tr></table></div>
3018
</details>
3019
</div>
3020
3021
</div>
3022
3023
<div class="doc doc-object doc-function">
3024
3025
3026
<h4 id="video_processor.analyzers.diagram_analyzer.DiagramAnalyzer.classify_frame" class="doc doc-heading">
3027
<code class="highlight language-python"><span class="n">classify_frame</span><span class="p">(</span><span class="n">image_path</span><span class="p">)</span></code>
3028
3029
<a href="#video_processor.analyzers.diagram_analyzer.DiagramAnalyzer.classify_frame" class="headerlink" title="Permanent link">&para;</a></h4>
3030
3031
3032
<div class="doc doc-contents ">
3033
3034
<p>Classify a single frame using vision model.</p>
3035
<p>Returns dict with is_diagram, diagram_type, confidence, brief_description.</p>
3036
3037
3038
<details class="mkdocstrings-source">
3039
<summary>Source code in <code>video_processor/analyzers/diagram_analyzer.py</code></summary>
3040
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-101">101</a></span>
3041
<span class="normal"><a href="#__codelineno-0-102">102</a></span>
3042
<span class="normal"><a href="#__codelineno-0-103">103</a></span>
3043
<span class="normal"><a href="#__codelineno-0-104">104</a></span>
3044
<span class="normal"><a href="#__codelineno-0-105">105</a></span>
3045
<span class="normal"><a href="#__codelineno-0-106">106</a></span>
3046
<span class="normal"><a href="#__codelineno-0-107">107</a></span>
3047
<span class="normal"><a href="#__codelineno-0-108">108</a></span>
3048
<span class="normal"><a href="#__codelineno-0-109">109</a></span>
3049
<span class="normal"><a href="#__codelineno-0-110">110</a></span>
3050
<span class="normal"><a href="#__codelineno-0-111">111</a></span>
3051
<span class="normal"><a href="#__codelineno-0-112">112</a></span>
3052
<span class="normal"><a href="#__codelineno-0-113">113</a></span>
3053
<span class="normal"><a href="#__codelineno-0-114">114</a></span>
3054
<span class="normal"><a href="#__codelineno-0-115">115</a></span>
3055
<span class="normal"><a href="#__codelineno-0-116">116</a></span>
3056
<span class="normal"><a href="#__codelineno-0-117">117</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-101" name="__codelineno-0-101"></a><span class="k">def</span><span class="w"> </span><span class="nf">classify_frame</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">image_path</span><span class="p">:</span> <span class="n">Union</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Path</span><span class="p">])</span> <span class="o">-&gt;</span> <span class="nb">dict</span><span class="p">:</span>
3057
<a id="__codelineno-0-102" name="__codelineno-0-102"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
3058
<a id="__codelineno-0-103" name="__codelineno-0-103"></a><span class="sd"> Classify a single frame using vision model.</span>
3059
<a id="__codelineno-0-104" name="__codelineno-0-104"></a>
3060
<a id="__codelineno-0-105" name="__codelineno-0-105"></a><span class="sd"> Returns dict with is_diagram, diagram_type, confidence, brief_description.</span>
3061
<a id="__codelineno-0-106" name="__codelineno-0-106"></a><span class="sd"> &quot;&quot;&quot;</span>
3062
<a id="__codelineno-0-107" name="__codelineno-0-107"></a> <span class="n">image_bytes</span> <span class="o">=</span> <span class="n">_read_image_bytes</span><span class="p">(</span><span class="n">image_path</span><span class="p">)</span>
3063
<a id="__codelineno-0-108" name="__codelineno-0-108"></a> <span class="n">raw</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">pm</span><span class="o">.</span><span class="n">analyze_image</span><span class="p">(</span><span class="n">image_bytes</span><span class="p">,</span> <span class="n">_CLASSIFY_PROMPT</span><span class="p">,</span> <span class="n">max_tokens</span><span class="o">=</span><span class="mi">512</span><span class="p">)</span>
3064
<a id="__codelineno-0-109" name="__codelineno-0-109"></a> <span class="n">result</span> <span class="o">=</span> <span class="n">_parse_json_response</span><span class="p">(</span><span class="n">raw</span><span class="p">)</span>
3065
<a id="__codelineno-0-110" name="__codelineno-0-110"></a> <span class="k">if</span> <span class="n">result</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
3066
<a id="__codelineno-0-111" name="__codelineno-0-111"></a> <span class="k">return</span> <span class="p">{</span>
3067
<a id="__codelineno-0-112" name="__codelineno-0-112"></a> <span class="s2">&quot;is_diagram&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
3068
<a id="__codelineno-0-113" name="__codelineno-0-113"></a> <span class="s2">&quot;diagram_type&quot;</span><span class="p">:</span> <span class="s2">&quot;unknown&quot;</span><span class="p">,</span>
3069
<a id="__codelineno-0-114" name="__codelineno-0-114"></a> <span class="s2">&quot;confidence&quot;</span><span class="p">:</span> <span class="mf">0.0</span><span class="p">,</span>
3070
<a id="__codelineno-0-115" name="__codelineno-0-115"></a> <span class="s2">&quot;brief_description&quot;</span><span class="p">:</span> <span class="s2">&quot;&quot;</span><span class="p">,</span>
3071
<a id="__codelineno-0-116" name="__codelineno-0-116"></a> <span class="p">}</span>
3072
<a id="__codelineno-0-117" name="__codelineno-0-117"></a> <span class="k">return</span> <span class="n">result</span>
3073
</code></pre></div></td></tr></table></div>
3074
</details>
3075
</div>
3076
3077
</div>
3078
3079
<div class="doc doc-object doc-function">
3080
3081
3082
<h4 id="video_processor.analyzers.diagram_analyzer.DiagramAnalyzer.process_frames" class="doc doc-heading">
3083
<code class="highlight language-python"><span class="n">process_frames</span><span class="p">(</span><span class="n">frame_paths</span><span class="p">,</span> <span class="n">diagrams_dir</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">captures_dir</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span></code>
3084
3085
<a href="#video_processor.analyzers.diagram_analyzer.DiagramAnalyzer.process_frames" class="headerlink" title="Permanent link">&para;</a></h4>
3086
3087
3088
<div class="doc doc-contents ">
3089
3090
<p>Process a list of extracted frames: classify, analyze diagrams, screengrab fallback.</p>
3091
3092
3093
<details class="thresholds" open>
3094
<summary>Thresholds</summary>
3095
<ul>
3096
<li>confidence &gt;= 0.7 → full diagram analysis (story 3.2)</li>
3097
<li>0.3 &lt;= confidence &lt; 0.7 → screengrab fallback (story 3.3)</li>
3098
<li>confidence &lt; 0.3 → skip</li>
3099
</ul>
3100
</details> <p>Returns (diagrams, screen_captures).</p>
3101
3102
3103
<details class="mkdocstrings-source">
3104
<summary>Source code in <code>video_processor/analyzers/diagram_analyzer.py</code></summary>
3105
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-135">135</a></span>
3106
<span class="normal"><a href="#__codelineno-0-136">136</a></span>
3107
<span class="normal"><a href="#__codelineno-0-137">137</a></span>
3108
<span class="normal"><a href="#__codelineno-0-138">138</a></span>
3109
<span class="normal"><a href="#__codelineno-0-139">139</a></span>
3110
<span class="normal"><a href="#__codelineno-0-140">140</a></span>
3111
<span class="normal"><a href="#__codelineno-0-141">141</a></span>
3112
<span class="normal"><a href="#__codelineno-0-142">142</a></span>
3113
<span class="normal"><a href="#__codelineno-0-143">143</a></span>
3114
<span class="normal"><a href="#__codelineno-0-144">144</a></span>
3115
<span class="normal"><a href="#__codelineno-0-145">145</a></span>
3116
<span class="normal"><a href="#__codelineno-0-146">146</a></span>
3117
<span class="normal"><a href="#__codelineno-0-147">147</a></span>
3118
<span class="normal"><a href="#__codelineno-0-148">148</a></span>
3119
<span class="normal"><a href="#__codelineno-0-149">149</a></span>
3120
<span class="normal"><a href="#__codelineno-0-150">150</a></span>
3121
<span class="normal"><a href="#__codelineno-0-151">151</a></span>
3122
<span class="normal"><a href="#__codelineno-0-152">152</a></span>
3123
<span class="normal"><a href="#__codelineno-0-153">153</a></span>
3124
<span class="normal"><a href="#__codelineno-0-154">154</a></span>
3125
<span class="normal"><a href="#__codelineno-0-155">155</a></span>
3126
<span class="normal"><a href="#__codelineno-0-156">156</a></span>
3127
<span class="normal"><a href="#__codelineno-0-157">157</a></span>
3128
<span class="normal"><a href="#__codelineno-0-158">158</a></span>
3129
<span class="normal"><a href="#__codelineno-0-159">159</a></span>
3130
<span class="normal"><a href="#__codelineno-0-160">160</a></span>
3131
<span class="normal"><a href="#__codelineno-0-161">161</a></span>
3132
<span class="normal"><a href="#__codelineno-0-162">162</a></span>
3133
<span class="normal"><a href="#__codelineno-0-163">163</a></span>
3134
<span class="normal"><a href="#__codelineno-0-164">164</a></span>
3135
<span class="normal"><a href="#__codelineno-0-165">165</a></span>
3136
<span class="normal"><a href="#__codelineno-0-166">166</a></span>
3137
<span class="normal"><a href="#__codelineno-0-167">167</a></span>
3138
<span class="normal"><a href="#__codelineno-0-168">168</a></span>
3139
<span class="normal"><a href="#__codelineno-0-169">169</a></span>
3140
<span class="normal"><a href="#__codelineno-0-170">170</a></span>
3141
<span class="normal"><a href="#__codelineno-0-171">171</a></span>
3142
<span class="normal"><a href="#__codelineno-0-172">172</a></span>
3143
<span class="normal"><a href="#__codelineno-0-173">173</a></span>
3144
<span class="normal"><a href="#__codelineno-0-174">174</a></span>
3145
<span class="normal"><a href="#__codelineno-0-175">175</a></span>
3146
<span class="normal"><a href="#__codelineno-0-176">176</a></span>
3147
<span class="normal"><a href="#__codelineno-0-177">177</a></span>
3148
<span class="normal"><a href="#__codelineno-0-178">178</a></span>
3149
<span class="normal"><a href="#__codelineno-0-179">179</a></span>
3150
<span class="normal"><a href="#__codelineno-0-180">180</a></span>
3151
<span class="normal"><a href="#__codelineno-0-181">181</a></span>
3152
<span class="normal"><a href="#__codelineno-0-182">182</a></span>
3153
<span class="normal"><a href="#__codelineno-0-183">183</a></span>
3154
<span class="normal"><a href="#__codelineno-0-184">184</a></span>
3155
<span class="normal"><a href="#__codelineno-0-185">185</a></span>
3156
<span class="normal"><a href="#__codelineno-0-186">186</a></span>
3157
<span class="normal"><a href="#__codelineno-0-187">187</a></span>
3158
<span class="normal"><a href="#__codelineno-0-188">188</a></span>
3159
<span class="normal"><a href="#__codelineno-0-189">189</a></span>
3160
<span class="normal"><a href="#__codelineno-0-190">190</a></span>
3161
<span class="normal"><a href="#__codelineno-0-191">191</a></span>
3162
<span class="normal"><a href="#__codelineno-0-192">192</a></span>
3163
<span class="normal"><a href="#__codelineno-0-193">193</a></span>
3164
<span class="normal"><a href="#__codelineno-0-194">194</a></span>
3165
<span class="normal"><a href="#__codelineno-0-195">195</a></span>
3166
<span class="normal"><a href="#__codelineno-0-196">196</a></span>
3167
<span class="normal"><a href="#__codelineno-0-197">197</a></span>
3168
<span class="normal"><a href="#__codelineno-0-198">198</a></span>
3169
<span class="normal"><a href="#__codelineno-0-199">199</a></span>
3170
<span class="normal"><a href="#__codelineno-0-200">200</a></span>
3171
<span class="normal"><a href="#__codelineno-0-201">201</a></span>
3172
<span class="normal"><a href="#__codelineno-0-202">202</a></span>
3173
<span class="normal"><a href="#__codelineno-0-203">203</a></span>
3174
<span class="normal"><a href="#__codelineno-0-204">204</a></span>
3175
<span class="normal"><a href="#__codelineno-0-205">205</a></span>
3176
<span class="normal"><a href="#__codelineno-0-206">206</a></span>
3177
<span class="normal"><a href="#__codelineno-0-207">207</a></span>
3178
<span class="normal"><a href="#__codelineno-0-208">208</a></span>
3179
<span class="normal"><a href="#__codelineno-0-209">209</a></span>
3180
<span class="normal"><a href="#__codelineno-0-210">210</a></span>
3181
<span class="normal"><a href="#__codelineno-0-211">211</a></span>
3182
<span class="normal"><a href="#__codelineno-0-212">212</a></span>
3183
<span class="normal"><a href="#__codelineno-0-213">213</a></span>
3184
<span class="normal"><a href="#__codelineno-0-214">214</a></span>
3185
<span class="normal"><a href="#__codelineno-0-215">215</a></span>
3186
<span class="normal"><a href="#__codelineno-0-216">216</a></span>
3187
<span class="normal"><a href="#__codelineno-0-217">217</a></span>
3188
<span class="normal"><a href="#__codelineno-0-218">218</a></span>
3189
<span class="normal"><a href="#__codelineno-0-219">219</a></span>
3190
<span class="normal"><a href="#__codelineno-0-220">220</a></span>
3191
<span class="normal"><a href="#__codelineno-0-221">221</a></span>
3192
<span class="normal"><a href="#__codelineno-0-222">222</a></span>
3193
<span class="normal"><a href="#__codelineno-0-223">223</a></span>
3194
<span class="normal"><a href="#__codelineno-0-224">224</a></span>
3195
<span class="normal"><a href="#__codelineno-0-225">225</a></span>
3196
<span class="normal"><a href="#__codelineno-0-226">226</a></span>
3197
<span class="normal"><a href="#__codelineno-0-227">227</a></span>
3198
<span class="normal"><a href="#__codelineno-0-228">228</a></span>
3199
<span class="normal"><a href="#__codelineno-0-229">229</a></span>
3200
<span class="normal"><a href="#__codelineno-0-230">230</a></span>
3201
<span class="normal"><a href="#__codelineno-0-231">231</a></span>
3202
<span class="normal"><a href="#__codelineno-0-232">232</a></span>
3203
<span class="normal"><a href="#__codelineno-0-233">233</a></span>
3204
<span class="normal"><a href="#__codelineno-0-234">234</a></span>
3205
<span class="normal"><a href="#__codelineno-0-235">235</a></span>
3206
<span class="normal"><a href="#__codelineno-0-236">236</a></span>
3207
<span class="normal"><a href="#__codelineno-0-237">237</a></span>
3208
<span class="normal"><a href="#__codelineno-0-238">238</a></span>
3209
<span class="normal"><a href="#__codelineno-0-239">239</a></span>
3210
<span class="normal"><a href="#__codelineno-0-240">240</a></span>
3211
<span class="normal"><a href="#__codelineno-0-241">241</a></span>
3212
<span class="normal"><a href="#__codelineno-0-242">242</a></span>
3213
<span class="normal"><a href="#__codelineno-0-243">243</a></span>
3214
<span class="normal"><a href="#__codelineno-0-244">244</a></span>
3215
<span class="normal"><a href="#__codelineno-0-245">245</a></span>
3216
<span class="normal"><a href="#__codelineno-0-246">246</a></span>
3217
<span class="normal"><a href="#__codelineno-0-247">247</a></span>
3218
<span class="normal"><a href="#__codelineno-0-248">248</a></span>
3219
<span class="normal"><a href="#__codelineno-0-249">249</a></span>
3220
<span class="normal"><a href="#__codelineno-0-250">250</a></span>
3221
<span class="normal"><a href="#__codelineno-0-251">251</a></span>
3222
<span class="normal"><a href="#__codelineno-0-252">252</a></span>
3223
<span class="normal"><a href="#__codelineno-0-253">253</a></span>
3224
<span class="normal"><a href="#__codelineno-0-254">254</a></span>
3225
<span class="normal"><a href="#__codelineno-0-255">255</a></span>
3226
<span class="normal"><a href="#__codelineno-0-256">256</a></span>
3227
<span class="normal"><a href="#__codelineno-0-257">257</a></span>
3228
<span class="normal"><a href="#__codelineno-0-258">258</a></span>
3229
<span class="normal"><a href="#__codelineno-0-259">259</a></span>
3230
<span class="normal"><a href="#__codelineno-0-260">260</a></span>
3231
<span class="normal"><a href="#__codelineno-0-261">261</a></span>
3232
<span class="normal"><a href="#__codelineno-0-262">262</a></span>
3233
<span class="normal"><a href="#__codelineno-0-263">263</a></span>
3234
<span class="normal"><a href="#__codelineno-0-264">264</a></span>
3235
<span class="normal"><a href="#__codelineno-0-265">265</a></span>
3236
<span class="normal"><a href="#__codelineno-0-266">266</a></span>
3237
<span class="normal"><a href="#__codelineno-0-267">267</a></span>
3238
<span class="normal"><a href="#__codelineno-0-268">268</a></span>
3239
<span class="normal"><a href="#__codelineno-0-269">269</a></span>
3240
<span class="normal"><a href="#__codelineno-0-270">270</a></span>
3241
<span class="normal"><a href="#__codelineno-0-271">271</a></span>
3242
<span class="normal"><a href="#__codelineno-0-272">272</a></span>
3243
<span class="normal"><a href="#__codelineno-0-273">273</a></span>
3244
<span class="normal"><a href="#__codelineno-0-274">274</a></span>
3245
<span class="normal"><a href="#__codelineno-0-275">275</a></span>
3246
<span class="normal"><a href="#__codelineno-0-276">276</a></span>
3247
<span class="normal"><a href="#__codelineno-0-277">277</a></span>
3248
<span class="normal"><a href="#__codelineno-0-278">278</a></span>
3249
<span class="normal"><a href="#__codelineno-0-279">279</a></span>
3250
<span class="normal"><a href="#__codelineno-0-280">280</a></span>
3251
<span class="normal"><a href="#__codelineno-0-281">281</a></span>
3252
<span class="normal"><a href="#__codelineno-0-282">282</a></span>
3253
<span class="normal"><a href="#__codelineno-0-283">283</a></span>
3254
<span class="normal"><a href="#__codelineno-0-284">284</a></span>
3255
<span class="normal"><a href="#__codelineno-0-285">285</a></span>
3256
<span class="normal"><a href="#__codelineno-0-286">286</a></span>
3257
<span class="normal"><a href="#__codelineno-0-287">287</a></span>
3258
<span class="normal"><a href="#__codelineno-0-288">288</a></span>
3259
<span class="normal"><a href="#__codelineno-0-289">289</a></span>
3260
<span class="normal"><a href="#__codelineno-0-290">290</a></span>
3261
<span class="normal"><a href="#__codelineno-0-291">291</a></span>
3262
<span class="normal"><a href="#__codelineno-0-292">292</a></span>
3263
<span class="normal"><a href="#__codelineno-0-293">293</a></span>
3264
<span class="normal"><a href="#__codelineno-0-294">294</a></span>
3265
<span class="normal"><a href="#__codelineno-0-295">295</a></span>
3266
<span class="normal"><a href="#__codelineno-0-296">296</a></span>
3267
<span class="normal"><a href="#__codelineno-0-297">297</a></span>
3268
<span class="normal"><a href="#__codelineno-0-298">298</a></span>
3269
<span class="normal"><a href="#__codelineno-0-299">299</a></span>
3270
<span class="normal"><a href="#__codelineno-0-300">300</a></span>
3271
<span class="normal"><a href="#__codelineno-0-301">301</a></span>
3272
<span class="normal"><a href="#__codelineno-0-302">302</a></span>
3273
<span class="normal"><a href="#__codelineno-0-303">303</a></span>
3274
<span class="normal"><a href="#__codelineno-0-304">304</a></span>
3275
<span class="normal"><a href="#__codelineno-0-305">305</a></span>
3276
<span class="normal"><a href="#__codelineno-0-306">306</a></span>
3277
<span class="normal"><a href="#__codelineno-0-307">307</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-135" name="__codelineno-0-135"></a><span class="k">def</span><span class="w"> </span><span class="nf">process_frames</span><span class="p">(</span>
3278
<a id="__codelineno-0-136" name="__codelineno-0-136"></a> <span class="bp">self</span><span class="p">,</span>
3279
<a id="__codelineno-0-137" name="__codelineno-0-137"></a> <span class="n">frame_paths</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="n">Union</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Path</span><span class="p">]],</span>
3280
<a id="__codelineno-0-138" name="__codelineno-0-138"></a> <span class="n">diagrams_dir</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">Path</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
3281
<a id="__codelineno-0-139" name="__codelineno-0-139"></a> <span class="n">captures_dir</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">Path</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
3282
<a id="__codelineno-0-140" name="__codelineno-0-140"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Tuple</span><span class="p">[</span><span class="n">List</span><span class="p">[</span><span class="n">DiagramResult</span><span class="p">],</span> <span class="n">List</span><span class="p">[</span><span class="n">ScreenCapture</span><span class="p">]]:</span>
3283
<a id="__codelineno-0-141" name="__codelineno-0-141"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
3284
<a id="__codelineno-0-142" name="__codelineno-0-142"></a><span class="sd"> Process a list of extracted frames: classify, analyze diagrams, screengrab fallback.</span>
3285
<a id="__codelineno-0-143" name="__codelineno-0-143"></a>
3286
<a id="__codelineno-0-144" name="__codelineno-0-144"></a><span class="sd"> Thresholds:</span>
3287
<a id="__codelineno-0-145" name="__codelineno-0-145"></a><span class="sd"> - confidence &gt;= 0.7 → full diagram analysis (story 3.2)</span>
3288
<a id="__codelineno-0-146" name="__codelineno-0-146"></a><span class="sd"> - 0.3 &lt;= confidence &lt; 0.7 → screengrab fallback (story 3.3)</span>
3289
<a id="__codelineno-0-147" name="__codelineno-0-147"></a><span class="sd"> - confidence &lt; 0.3 → skip</span>
3290
<a id="__codelineno-0-148" name="__codelineno-0-148"></a>
3291
<a id="__codelineno-0-149" name="__codelineno-0-149"></a><span class="sd"> Returns (diagrams, screen_captures).</span>
3292
<a id="__codelineno-0-150" name="__codelineno-0-150"></a><span class="sd"> &quot;&quot;&quot;</span>
3293
<a id="__codelineno-0-151" name="__codelineno-0-151"></a> <span class="n">diagrams</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="n">DiagramResult</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span>
3294
<a id="__codelineno-0-152" name="__codelineno-0-152"></a> <span class="n">captures</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="n">ScreenCapture</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span>
3295
<a id="__codelineno-0-153" name="__codelineno-0-153"></a> <span class="n">diagram_idx</span> <span class="o">=</span> <span class="mi">0</span>
3296
<a id="__codelineno-0-154" name="__codelineno-0-154"></a> <span class="n">capture_idx</span> <span class="o">=</span> <span class="mi">0</span>
3297
<a id="__codelineno-0-155" name="__codelineno-0-155"></a>
3298
<a id="__codelineno-0-156" name="__codelineno-0-156"></a> <span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">fp</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">tqdm</span><span class="p">(</span><span class="n">frame_paths</span><span class="p">,</span> <span class="n">desc</span><span class="o">=</span><span class="s2">&quot;Analyzing frames&quot;</span><span class="p">,</span> <span class="n">unit</span><span class="o">=</span><span class="s2">&quot;frame&quot;</span><span class="p">)):</span>
3299
<a id="__codelineno-0-157" name="__codelineno-0-157"></a> <span class="n">fp</span> <span class="o">=</span> <span class="n">Path</span><span class="p">(</span><span class="n">fp</span><span class="p">)</span>
3300
<a id="__codelineno-0-158" name="__codelineno-0-158"></a> <span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Classifying frame </span><span class="si">{</span><span class="n">i</span><span class="si">}</span><span class="s2">/</span><span class="si">{</span><span class="nb">len</span><span class="p">(</span><span class="n">frame_paths</span><span class="p">)</span><span class="si">}</span><span class="s2">: </span><span class="si">{</span><span class="n">fp</span><span class="o">.</span><span class="n">name</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
3301
<a id="__codelineno-0-159" name="__codelineno-0-159"></a>
3302
<a id="__codelineno-0-160" name="__codelineno-0-160"></a> <span class="k">try</span><span class="p">:</span>
3303
<a id="__codelineno-0-161" name="__codelineno-0-161"></a> <span class="n">classification</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">classify_frame</span><span class="p">(</span><span class="n">fp</span><span class="p">)</span>
3304
<a id="__codelineno-0-162" name="__codelineno-0-162"></a> <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
3305
<a id="__codelineno-0-163" name="__codelineno-0-163"></a> <span class="n">logger</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Classification failed for frame </span><span class="si">{</span><span class="n">i</span><span class="si">}</span><span class="s2">: </span><span class="si">{</span><span class="n">e</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
3306
<a id="__codelineno-0-164" name="__codelineno-0-164"></a> <span class="k">continue</span>
3307
<a id="__codelineno-0-165" name="__codelineno-0-165"></a>
3308
<a id="__codelineno-0-166" name="__codelineno-0-166"></a> <span class="n">confidence</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="n">classification</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;confidence&quot;</span><span class="p">,</span> <span class="mf">0.0</span><span class="p">))</span>
3309
<a id="__codelineno-0-167" name="__codelineno-0-167"></a>
3310
<a id="__codelineno-0-168" name="__codelineno-0-168"></a> <span class="k">if</span> <span class="n">confidence</span> <span class="o">&lt;</span> <span class="bp">self</span><span class="o">.</span><span class="n">confidence_threshold</span><span class="p">:</span>
3311
<a id="__codelineno-0-169" name="__codelineno-0-169"></a> <span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Frame </span><span class="si">{</span><span class="n">i</span><span class="si">}</span><span class="s2">: confidence </span><span class="si">{</span><span class="n">confidence</span><span class="si">:</span><span class="s2">.2f</span><span class="si">}</span><span class="s2"> below threshold, skipping&quot;</span><span class="p">)</span>
3312
<a id="__codelineno-0-170" name="__codelineno-0-170"></a> <span class="k">continue</span>
3313
<a id="__codelineno-0-171" name="__codelineno-0-171"></a>
3314
<a id="__codelineno-0-172" name="__codelineno-0-172"></a> <span class="k">if</span> <span class="n">confidence</span> <span class="o">&gt;=</span> <span class="mf">0.7</span><span class="p">:</span>
3315
<a id="__codelineno-0-173" name="__codelineno-0-173"></a> <span class="c1"># Full diagram analysis</span>
3316
<a id="__codelineno-0-174" name="__codelineno-0-174"></a> <span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span>
3317
<a id="__codelineno-0-175" name="__codelineno-0-175"></a> <span class="sa">f</span><span class="s2">&quot;Frame </span><span class="si">{</span><span class="n">i</span><span class="si">}</span><span class="s2">: diagram detected (confidence </span><span class="si">{</span><span class="n">confidence</span><span class="si">:</span><span class="s2">.2f</span><span class="si">}</span><span class="s2">), analyzing...&quot;</span>
3318
<a id="__codelineno-0-176" name="__codelineno-0-176"></a> <span class="p">)</span>
3319
<a id="__codelineno-0-177" name="__codelineno-0-177"></a> <span class="k">try</span><span class="p">:</span>
3320
<a id="__codelineno-0-178" name="__codelineno-0-178"></a> <span class="n">analysis</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">analyze_diagram_single_pass</span><span class="p">(</span><span class="n">fp</span><span class="p">)</span>
3321
<a id="__codelineno-0-179" name="__codelineno-0-179"></a> <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
3322
<a id="__codelineno-0-180" name="__codelineno-0-180"></a> <span class="n">logger</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span>
3323
<a id="__codelineno-0-181" name="__codelineno-0-181"></a> <span class="sa">f</span><span class="s2">&quot;Diagram analysis failed for frame </span><span class="si">{</span><span class="n">i</span><span class="si">}</span><span class="s2">: </span><span class="si">{</span><span class="n">e</span><span class="si">}</span><span class="s2">, falling back to screengrab&quot;</span>
3324
<a id="__codelineno-0-182" name="__codelineno-0-182"></a> <span class="p">)</span>
3325
<a id="__codelineno-0-183" name="__codelineno-0-183"></a> <span class="n">analysis</span> <span class="o">=</span> <span class="p">{}</span>
3326
<a id="__codelineno-0-184" name="__codelineno-0-184"></a>
3327
<a id="__codelineno-0-185" name="__codelineno-0-185"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">analysis</span><span class="p">:</span>
3328
<a id="__codelineno-0-186" name="__codelineno-0-186"></a> <span class="c1"># Analysis failed — fall back to screengrab</span>
3329
<a id="__codelineno-0-187" name="__codelineno-0-187"></a> <span class="n">capture</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_save_screengrab</span><span class="p">(</span><span class="n">fp</span><span class="p">,</span> <span class="n">i</span><span class="p">,</span> <span class="n">capture_idx</span><span class="p">,</span> <span class="n">captures_dir</span><span class="p">,</span> <span class="n">confidence</span><span class="p">)</span>
3330
<a id="__codelineno-0-188" name="__codelineno-0-188"></a> <span class="n">captures</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">capture</span><span class="p">)</span>
3331
<a id="__codelineno-0-189" name="__codelineno-0-189"></a> <span class="n">capture_idx</span> <span class="o">+=</span> <span class="mi">1</span>
3332
<a id="__codelineno-0-190" name="__codelineno-0-190"></a> <span class="k">continue</span>
3333
<a id="__codelineno-0-191" name="__codelineno-0-191"></a>
3334
<a id="__codelineno-0-192" name="__codelineno-0-192"></a> <span class="c1"># Build DiagramResult</span>
3335
<a id="__codelineno-0-193" name="__codelineno-0-193"></a> <span class="n">dtype</span> <span class="o">=</span> <span class="n">analysis</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;diagram_type&quot;</span><span class="p">,</span> <span class="n">classification</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;diagram_type&quot;</span><span class="p">,</span> <span class="s2">&quot;unknown&quot;</span><span class="p">))</span>
3336
<a id="__codelineno-0-194" name="__codelineno-0-194"></a> <span class="k">try</span><span class="p">:</span>
3337
<a id="__codelineno-0-195" name="__codelineno-0-195"></a> <span class="n">diagram_type</span> <span class="o">=</span> <span class="n">DiagramType</span><span class="p">(</span><span class="n">dtype</span><span class="p">)</span>
3338
<a id="__codelineno-0-196" name="__codelineno-0-196"></a> <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
3339
<a id="__codelineno-0-197" name="__codelineno-0-197"></a> <span class="n">diagram_type</span> <span class="o">=</span> <span class="n">DiagramType</span><span class="o">.</span><span class="n">unknown</span>
3340
<a id="__codelineno-0-198" name="__codelineno-0-198"></a>
3341
<a id="__codelineno-0-199" name="__codelineno-0-199"></a> <span class="c1"># Normalize relationships: llava sometimes returns dicts instead of strings</span>
3342
<a id="__codelineno-0-200" name="__codelineno-0-200"></a> <span class="n">raw_rels</span> <span class="o">=</span> <span class="n">analysis</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;relationships&quot;</span><span class="p">)</span> <span class="ow">or</span> <span class="p">[]</span>
3343
<a id="__codelineno-0-201" name="__codelineno-0-201"></a> <span class="n">relationships</span> <span class="o">=</span> <span class="p">[]</span>
3344
<a id="__codelineno-0-202" name="__codelineno-0-202"></a> <span class="k">for</span> <span class="n">rel</span> <span class="ow">in</span> <span class="n">raw_rels</span><span class="p">:</span>
3345
<a id="__codelineno-0-203" name="__codelineno-0-203"></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">rel</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
3346
<a id="__codelineno-0-204" name="__codelineno-0-204"></a> <span class="n">relationships</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">rel</span><span class="p">)</span>
3347
<a id="__codelineno-0-205" name="__codelineno-0-205"></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">rel</span><span class="p">,</span> <span class="nb">dict</span><span class="p">):</span>
3348
<a id="__codelineno-0-206" name="__codelineno-0-206"></a> <span class="n">src</span> <span class="o">=</span> <span class="n">rel</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;source&quot;</span><span class="p">,</span> <span class="n">rel</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;from&quot;</span><span class="p">,</span> <span class="s2">&quot;?&quot;</span><span class="p">))</span>
3349
<a id="__codelineno-0-207" name="__codelineno-0-207"></a> <span class="n">dst</span> <span class="o">=</span> <span class="n">rel</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;destination&quot;</span><span class="p">,</span> <span class="n">rel</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;to&quot;</span><span class="p">,</span> <span class="s2">&quot;?&quot;</span><span class="p">))</span>
3350
<a id="__codelineno-0-208" name="__codelineno-0-208"></a> <span class="n">label</span> <span class="o">=</span> <span class="n">rel</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;label&quot;</span><span class="p">,</span> <span class="n">rel</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;relationship&quot;</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">))</span>
3351
<a id="__codelineno-0-209" name="__codelineno-0-209"></a> <span class="n">relationships</span><span class="o">.</span><span class="n">append</span><span class="p">(</span>
3352
<a id="__codelineno-0-210" name="__codelineno-0-210"></a> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">src</span><span class="si">}</span><span class="s2"> -&gt; </span><span class="si">{</span><span class="n">dst</span><span class="si">}</span><span class="s2">: </span><span class="si">{</span><span class="n">label</span><span class="si">}</span><span class="s2">&quot;</span> <span class="k">if</span> <span class="n">label</span> <span class="k">else</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">src</span><span class="si">}</span><span class="s2"> -&gt; </span><span class="si">{</span><span class="n">dst</span><span class="si">}</span><span class="s2">&quot;</span>
3353
<a id="__codelineno-0-211" name="__codelineno-0-211"></a> <span class="p">)</span>
3354
<a id="__codelineno-0-212" name="__codelineno-0-212"></a> <span class="k">else</span><span class="p">:</span>
3355
<a id="__codelineno-0-213" name="__codelineno-0-213"></a> <span class="n">relationships</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">rel</span><span class="p">))</span>
3356
<a id="__codelineno-0-214" name="__codelineno-0-214"></a>
3357
<a id="__codelineno-0-215" name="__codelineno-0-215"></a> <span class="c1"># Normalize elements: llava may return dicts or nested lists</span>
3358
<a id="__codelineno-0-216" name="__codelineno-0-216"></a> <span class="n">raw_elements</span> <span class="o">=</span> <span class="n">analysis</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;elements&quot;</span><span class="p">)</span> <span class="ow">or</span> <span class="p">[]</span>
3359
<a id="__codelineno-0-217" name="__codelineno-0-217"></a> <span class="n">elements</span> <span class="o">=</span> <span class="p">[]</span>
3360
<a id="__codelineno-0-218" name="__codelineno-0-218"></a> <span class="k">for</span> <span class="n">elem</span> <span class="ow">in</span> <span class="n">raw_elements</span><span class="p">:</span>
3361
<a id="__codelineno-0-219" name="__codelineno-0-219"></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">elem</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
3362
<a id="__codelineno-0-220" name="__codelineno-0-220"></a> <span class="n">elements</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">elem</span><span class="p">)</span>
3363
<a id="__codelineno-0-221" name="__codelineno-0-221"></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">elem</span><span class="p">,</span> <span class="nb">dict</span><span class="p">):</span>
3364
<a id="__codelineno-0-222" name="__codelineno-0-222"></a> <span class="n">name</span> <span class="o">=</span> <span class="n">elem</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;name&quot;</span><span class="p">,</span> <span class="n">elem</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;element&quot;</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">))</span>
3365
<a id="__codelineno-0-223" name="__codelineno-0-223"></a> <span class="n">etype</span> <span class="o">=</span> <span class="n">elem</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;type&quot;</span><span class="p">,</span> <span class="n">elem</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;element_type&quot;</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">))</span>
3366
<a id="__codelineno-0-224" name="__codelineno-0-224"></a> <span class="k">if</span> <span class="n">name</span> <span class="ow">and</span> <span class="n">etype</span><span class="p">:</span>
3367
<a id="__codelineno-0-225" name="__codelineno-0-225"></a> <span class="n">elements</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">etype</span><span class="si">}</span><span class="s2">: </span><span class="si">{</span><span class="n">name</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
3368
<a id="__codelineno-0-226" name="__codelineno-0-226"></a> <span class="k">elif</span> <span class="n">name</span><span class="p">:</span>
3369
<a id="__codelineno-0-227" name="__codelineno-0-227"></a> <span class="n">elements</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
3370
<a id="__codelineno-0-228" name="__codelineno-0-228"></a> <span class="k">else</span><span class="p">:</span>
3371
<a id="__codelineno-0-229" name="__codelineno-0-229"></a> <span class="n">elements</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="n">elem</span><span class="p">))</span>
3372
<a id="__codelineno-0-230" name="__codelineno-0-230"></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">elem</span><span class="p">,</span> <span class="nb">list</span><span class="p">):</span>
3373
<a id="__codelineno-0-231" name="__codelineno-0-231"></a> <span class="n">elements</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">)</span> <span class="k">for</span> <span class="n">e</span> <span class="ow">in</span> <span class="n">elem</span><span class="p">)</span>
3374
<a id="__codelineno-0-232" name="__codelineno-0-232"></a> <span class="k">else</span><span class="p">:</span>
3375
<a id="__codelineno-0-233" name="__codelineno-0-233"></a> <span class="n">elements</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">elem</span><span class="p">))</span>
3376
<a id="__codelineno-0-234" name="__codelineno-0-234"></a>
3377
<a id="__codelineno-0-235" name="__codelineno-0-235"></a> <span class="c1"># Normalize text_content: llava may return dict instead of string</span>
3378
<a id="__codelineno-0-236" name="__codelineno-0-236"></a> <span class="n">raw_text</span> <span class="o">=</span> <span class="n">analysis</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;text_content&quot;</span><span class="p">)</span>
3379
<a id="__codelineno-0-237" name="__codelineno-0-237"></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">raw_text</span><span class="p">,</span> <span class="nb">dict</span><span class="p">):</span>
3380
<a id="__codelineno-0-238" name="__codelineno-0-238"></a> <span class="n">parts</span> <span class="o">=</span> <span class="p">[]</span>
3381
<a id="__codelineno-0-239" name="__codelineno-0-239"></a> <span class="k">for</span> <span class="n">k</span><span class="p">,</span> <span class="n">v</span> <span class="ow">in</span> <span class="n">raw_text</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
3382
<a id="__codelineno-0-240" name="__codelineno-0-240"></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="nb">list</span><span class="p">):</span>
3383
<a id="__codelineno-0-241" name="__codelineno-0-241"></a> <span class="n">parts</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">k</span><span class="si">}</span><span class="s2">: </span><span class="si">{</span><span class="s1">&#39;, &#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">x</span><span class="p">)</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="ow">in</span><span class="w"> </span><span class="n">v</span><span class="p">)</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
3384
<a id="__codelineno-0-242" name="__codelineno-0-242"></a> <span class="k">else</span><span class="p">:</span>
3385
<a id="__codelineno-0-243" name="__codelineno-0-243"></a> <span class="n">parts</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">k</span><span class="si">}</span><span class="s2">: </span><span class="si">{</span><span class="n">v</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
3386
<a id="__codelineno-0-244" name="__codelineno-0-244"></a> <span class="n">text_content</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">parts</span><span class="p">)</span>
3387
<a id="__codelineno-0-245" name="__codelineno-0-245"></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">raw_text</span><span class="p">,</span> <span class="nb">list</span><span class="p">):</span>
3388
<a id="__codelineno-0-246" name="__codelineno-0-246"></a> <span class="n">text_content</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">x</span><span class="p">)</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">raw_text</span><span class="p">)</span>
3389
<a id="__codelineno-0-247" name="__codelineno-0-247"></a> <span class="k">else</span><span class="p">:</span>
3390
<a id="__codelineno-0-248" name="__codelineno-0-248"></a> <span class="n">text_content</span> <span class="o">=</span> <span class="n">raw_text</span>
3391
<a id="__codelineno-0-249" name="__codelineno-0-249"></a>
3392
<a id="__codelineno-0-250" name="__codelineno-0-250"></a> <span class="k">try</span><span class="p">:</span>
3393
<a id="__codelineno-0-251" name="__codelineno-0-251"></a> <span class="n">dr</span> <span class="o">=</span> <span class="n">DiagramResult</span><span class="p">(</span>
3394
<a id="__codelineno-0-252" name="__codelineno-0-252"></a> <span class="n">frame_index</span><span class="o">=</span><span class="n">i</span><span class="p">,</span>
3395
<a id="__codelineno-0-253" name="__codelineno-0-253"></a> <span class="n">diagram_type</span><span class="o">=</span><span class="n">diagram_type</span><span class="p">,</span>
3396
<a id="__codelineno-0-254" name="__codelineno-0-254"></a> <span class="n">confidence</span><span class="o">=</span><span class="n">confidence</span><span class="p">,</span>
3397
<a id="__codelineno-0-255" name="__codelineno-0-255"></a> <span class="n">description</span><span class="o">=</span><span class="n">analysis</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;description&quot;</span><span class="p">),</span>
3398
<a id="__codelineno-0-256" name="__codelineno-0-256"></a> <span class="n">text_content</span><span class="o">=</span><span class="n">text_content</span><span class="p">,</span>
3399
<a id="__codelineno-0-257" name="__codelineno-0-257"></a> <span class="n">elements</span><span class="o">=</span><span class="n">elements</span><span class="p">,</span>
3400
<a id="__codelineno-0-258" name="__codelineno-0-258"></a> <span class="n">relationships</span><span class="o">=</span><span class="n">relationships</span><span class="p">,</span>
3401
<a id="__codelineno-0-259" name="__codelineno-0-259"></a> <span class="n">mermaid</span><span class="o">=</span><span class="n">analysis</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;mermaid&quot;</span><span class="p">),</span>
3402
<a id="__codelineno-0-260" name="__codelineno-0-260"></a> <span class="n">chart_data</span><span class="o">=</span><span class="n">analysis</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;chart_data&quot;</span><span class="p">),</span>
3403
<a id="__codelineno-0-261" name="__codelineno-0-261"></a> <span class="p">)</span>
3404
<a id="__codelineno-0-262" name="__codelineno-0-262"></a> <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
3405
<a id="__codelineno-0-263" name="__codelineno-0-263"></a> <span class="n">logger</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span>
3406
<a id="__codelineno-0-264" name="__codelineno-0-264"></a> <span class="sa">f</span><span class="s2">&quot;DiagramResult validation failed for frame </span><span class="si">{</span><span class="n">i</span><span class="si">}</span><span class="s2">: </span><span class="si">{</span><span class="n">e</span><span class="si">}</span><span class="s2">, &quot;</span>
3407
<a id="__codelineno-0-265" name="__codelineno-0-265"></a> <span class="s2">&quot;falling back to screengrab&quot;</span>
3408
<a id="__codelineno-0-266" name="__codelineno-0-266"></a> <span class="p">)</span>
3409
<a id="__codelineno-0-267" name="__codelineno-0-267"></a> <span class="n">capture</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_save_screengrab</span><span class="p">(</span><span class="n">fp</span><span class="p">,</span> <span class="n">i</span><span class="p">,</span> <span class="n">capture_idx</span><span class="p">,</span> <span class="n">captures_dir</span><span class="p">,</span> <span class="n">confidence</span><span class="p">)</span>
3410
<a id="__codelineno-0-268" name="__codelineno-0-268"></a> <span class="n">captures</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">capture</span><span class="p">)</span>
3411
<a id="__codelineno-0-269" name="__codelineno-0-269"></a> <span class="n">capture_idx</span> <span class="o">+=</span> <span class="mi">1</span>
3412
<a id="__codelineno-0-270" name="__codelineno-0-270"></a> <span class="k">continue</span>
3413
<a id="__codelineno-0-271" name="__codelineno-0-271"></a>
3414
<a id="__codelineno-0-272" name="__codelineno-0-272"></a> <span class="c1"># Save outputs (story 3.4)</span>
3415
<a id="__codelineno-0-273" name="__codelineno-0-273"></a> <span class="k">if</span> <span class="n">diagrams_dir</span><span class="p">:</span>
3416
<a id="__codelineno-0-274" name="__codelineno-0-274"></a> <span class="n">diagrams_dir</span><span class="o">.</span><span class="n">mkdir</span><span class="p">(</span><span class="n">parents</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">exist_ok</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
3417
<a id="__codelineno-0-275" name="__codelineno-0-275"></a> <span class="n">prefix</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;diagram_</span><span class="si">{</span><span class="n">diagram_idx</span><span class="si">}</span><span class="s2">&quot;</span>
3418
<a id="__codelineno-0-276" name="__codelineno-0-276"></a>
3419
<a id="__codelineno-0-277" name="__codelineno-0-277"></a> <span class="c1"># Original frame</span>
3420
<a id="__codelineno-0-278" name="__codelineno-0-278"></a> <span class="n">img_dest</span> <span class="o">=</span> <span class="n">diagrams_dir</span> <span class="o">/</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">prefix</span><span class="si">}</span><span class="s2">.jpg&quot;</span>
3421
<a id="__codelineno-0-279" name="__codelineno-0-279"></a> <span class="n">shutil</span><span class="o">.</span><span class="n">copy2</span><span class="p">(</span><span class="n">fp</span><span class="p">,</span> <span class="n">img_dest</span><span class="p">)</span>
3422
<a id="__codelineno-0-280" name="__codelineno-0-280"></a> <span class="n">dr</span><span class="o">.</span><span class="n">image_path</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;diagrams/</span><span class="si">{</span><span class="n">prefix</span><span class="si">}</span><span class="s2">.jpg&quot;</span>
3423
<a id="__codelineno-0-281" name="__codelineno-0-281"></a>
3424
<a id="__codelineno-0-282" name="__codelineno-0-282"></a> <span class="c1"># Mermaid source</span>
3425
<a id="__codelineno-0-283" name="__codelineno-0-283"></a> <span class="k">if</span> <span class="n">dr</span><span class="o">.</span><span class="n">mermaid</span><span class="p">:</span>
3426
<a id="__codelineno-0-284" name="__codelineno-0-284"></a> <span class="n">mermaid_dest</span> <span class="o">=</span> <span class="n">diagrams_dir</span> <span class="o">/</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">prefix</span><span class="si">}</span><span class="s2">.mermaid&quot;</span>
3427
<a id="__codelineno-0-285" name="__codelineno-0-285"></a> <span class="n">mermaid_dest</span><span class="o">.</span><span class="n">write_text</span><span class="p">(</span><span class="n">dr</span><span class="o">.</span><span class="n">mermaid</span><span class="p">)</span>
3428
<a id="__codelineno-0-286" name="__codelineno-0-286"></a> <span class="n">dr</span><span class="o">.</span><span class="n">mermaid_path</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;diagrams/</span><span class="si">{</span><span class="n">prefix</span><span class="si">}</span><span class="s2">.mermaid&quot;</span>
3429
<a id="__codelineno-0-287" name="__codelineno-0-287"></a>
3430
<a id="__codelineno-0-288" name="__codelineno-0-288"></a> <span class="c1"># Analysis JSON</span>
3431
<a id="__codelineno-0-289" name="__codelineno-0-289"></a> <span class="n">json_dest</span> <span class="o">=</span> <span class="n">diagrams_dir</span> <span class="o">/</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">prefix</span><span class="si">}</span><span class="s2">.json&quot;</span>
3432
<a id="__codelineno-0-290" name="__codelineno-0-290"></a> <span class="n">json_dest</span><span class="o">.</span><span class="n">write_text</span><span class="p">(</span><span class="n">dr</span><span class="o">.</span><span class="n">model_dump_json</span><span class="p">(</span><span class="n">indent</span><span class="o">=</span><span class="mi">2</span><span class="p">))</span>
3433
<a id="__codelineno-0-291" name="__codelineno-0-291"></a>
3434
<a id="__codelineno-0-292" name="__codelineno-0-292"></a> <span class="n">diagrams</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">dr</span><span class="p">)</span>
3435
<a id="__codelineno-0-293" name="__codelineno-0-293"></a> <span class="n">diagram_idx</span> <span class="o">+=</span> <span class="mi">1</span>
3436
<a id="__codelineno-0-294" name="__codelineno-0-294"></a>
3437
<a id="__codelineno-0-295" name="__codelineno-0-295"></a> <span class="k">else</span><span class="p">:</span>
3438
<a id="__codelineno-0-296" name="__codelineno-0-296"></a> <span class="c1"># Screengrab fallback (0.3 &lt;= confidence &lt; 0.7)</span>
3439
<a id="__codelineno-0-297" name="__codelineno-0-297"></a> <span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span>
3440
<a id="__codelineno-0-298" name="__codelineno-0-298"></a> <span class="sa">f</span><span class="s2">&quot;Frame </span><span class="si">{</span><span class="n">i</span><span class="si">}</span><span class="s2">: uncertain (confidence </span><span class="si">{</span><span class="n">confidence</span><span class="si">:</span><span class="s2">.2f</span><span class="si">}</span><span class="s2">), saving as screengrab&quot;</span>
3441
<a id="__codelineno-0-299" name="__codelineno-0-299"></a> <span class="p">)</span>
3442
<a id="__codelineno-0-300" name="__codelineno-0-300"></a> <span class="n">capture</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_save_screengrab</span><span class="p">(</span><span class="n">fp</span><span class="p">,</span> <span class="n">i</span><span class="p">,</span> <span class="n">capture_idx</span><span class="p">,</span> <span class="n">captures_dir</span><span class="p">,</span> <span class="n">confidence</span><span class="p">)</span>
3443
<a id="__codelineno-0-301" name="__codelineno-0-301"></a> <span class="n">captures</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">capture</span><span class="p">)</span>
3444
<a id="__codelineno-0-302" name="__codelineno-0-302"></a> <span class="n">capture_idx</span> <span class="o">+=</span> <span class="mi">1</span>
3445
<a id="__codelineno-0-303" name="__codelineno-0-303"></a>
3446
<a id="__codelineno-0-304" name="__codelineno-0-304"></a> <span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span>
3447
<a id="__codelineno-0-305" name="__codelineno-0-305"></a> <span class="sa">f</span><span class="s2">&quot;Diagram processing complete: </span><span class="si">{</span><span class="nb">len</span><span class="p">(</span><span class="n">diagrams</span><span class="p">)</span><span class="si">}</span><span class="s2"> diagrams, </span><span class="si">{</span><span class="nb">len</span><span class="p">(</span><span class="n">captures</span><span class="p">)</span><span class="si">}</span><span class="s2"> screengrabs&quot;</span>
3448
<a id="__codelineno-0-306" name="__codelineno-0-306"></a> <span class="p">)</span>
3449
<a id="__codelineno-0-307" name="__codelineno-0-307"></a> <span class="k">return</span> <span class="n">diagrams</span><span class="p">,</span> <span class="n">captures</span>
3450
</code></pre></div></td></tr></table></div>
3451
</details>
3452
</div>
3453
3454
</div>
3455
3456
3457
3458
</div>
3459
3460
</div>
3461
3462
</div>
3463
3464
3465
3466
3467
</div>
3468
3469
</div>
3470
3471
</div>
3472
3473
<div class="doc doc-object doc-module">
3474
3475
3476
3477
<h2 id="video_processor.analyzers.content_analyzer" class="doc doc-heading">
3478
<code>video_processor.analyzers.content_analyzer</code>
3479
3480
3481
<a href="#video_processor.analyzers.content_analyzer" class="headerlink" title="Permanent link">&para;</a></h2>
3482
3483
<div class="doc doc-contents first">
3484
3485
<p>Content cross-referencing between transcript and diagram entities.</p>
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
<div class="doc doc-children">
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
<div class="doc doc-object doc-class">
3507
3508
3509
3510
<h3 id="video_processor.analyzers.content_analyzer.ContentAnalyzer" class="doc doc-heading">
3511
<code>ContentAnalyzer</code>
3512
3513
3514
<a href="#video_processor.analyzers.content_analyzer.ContentAnalyzer" class="headerlink" title="Permanent link">&para;</a></h3>
3515
3516
3517
<div class="doc doc-contents ">
3518
3519
3520
3521
<p>Cross-references transcript and diagram entities for richer knowledge.</p>
3522
3523
3524
3525
3526
3527
3528
3529
3530
<details class="mkdocstrings-source">
3531
<summary>Source code in <code>video_processor/analyzers/content_analyzer.py</code></summary>
3532
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-13"> 13</a></span>
3533
<span class="normal"><a href="#__codelineno-0-14"> 14</a></span>
3534
<span class="normal"><a href="#__codelineno-0-15"> 15</a></span>
3535
<span class="normal"><a href="#__codelineno-0-16"> 16</a></span>
3536
<span class="normal"><a href="#__codelineno-0-17"> 17</a></span>
3537
<span class="normal"><a href="#__codelineno-0-18"> 18</a></span>
3538
<span class="normal"><a href="#__codelineno-0-19"> 19</a></span>
3539
<span class="normal"><a href="#__codelineno-0-20"> 20</a></span>
3540
<span class="normal"><a href="#__codelineno-0-21"> 21</a></span>
3541
<span class="normal"><a href="#__codelineno-0-22"> 22</a></span>
3542
<span class="normal"><a href="#__codelineno-0-23"> 23</a></span>
3543
<span class="normal"><a href="#__codelineno-0-24"> 24</a></span>
3544
<span class="normal"><a href="#__codelineno-0-25"> 25</a></span>
3545
<span class="normal"><a href="#__codelineno-0-26"> 26</a></span>
3546
<span class="normal"><a href="#__codelineno-0-27"> 27</a></span>
3547
<span class="normal"><a href="#__codelineno-0-28"> 28</a></span>
3548
<span class="normal"><a href="#__codelineno-0-29"> 29</a></span>
3549
<span class="normal"><a href="#__codelineno-0-30"> 30</a></span>
3550
<span class="normal"><a href="#__codelineno-0-31"> 31</a></span>
3551
<span class="normal"><a href="#__codelineno-0-32"> 32</a></span>
3552
<span class="normal"><a href="#__codelineno-0-33"> 33</a></span>
3553
<span class="normal"><a href="#__codelineno-0-34"> 34</a></span>
3554
<span class="normal"><a href="#__codelineno-0-35"> 35</a></span>
3555
<span class="normal"><a href="#__codelineno-0-36"> 36</a></span>
3556
<span class="normal"><a href="#__codelineno-0-37"> 37</a></span>
3557
<span class="normal"><a href="#__codelineno-0-38"> 38</a></span>
3558
<span class="normal"><a href="#__codelineno-0-39"> 39</a></span>
3559
<span class="normal"><a href="#__codelineno-0-40"> 40</a></span>
3560
<span class="normal"><a href="#__codelineno-0-41"> 41</a></span>
3561
<span class="normal"><a href="#__codelineno-0-42"> 42</a></span>
3562
<span class="normal"><a href="#__codelineno-0-43"> 43</a></span>
3563
<span class="normal"><a href="#__codelineno-0-44"> 44</a></span>
3564
<span class="normal"><a href="#__codelineno-0-45"> 45</a></span>
3565
<span class="normal"><a href="#__codelineno-0-46"> 46</a></span>
3566
<span class="normal"><a href="#__codelineno-0-47"> 47</a></span>
3567
<span class="normal"><a href="#__codelineno-0-48"> 48</a></span>
3568
<span class="normal"><a href="#__codelineno-0-49"> 49</a></span>
3569
<span class="normal"><a href="#__codelineno-0-50"> 50</a></span>
3570
<span class="normal"><a href="#__codelineno-0-51"> 51</a></span>
3571
<span class="normal"><a href="#__codelineno-0-52"> 52</a></span>
3572
<span class="normal"><a href="#__codelineno-0-53"> 53</a></span>
3573
<span class="normal"><a href="#__codelineno-0-54"> 54</a></span>
3574
<span class="normal"><a href="#__codelineno-0-55"> 55</a></span>
3575
<span class="normal"><a href="#__codelineno-0-56"> 56</a></span>
3576
<span class="normal"><a href="#__codelineno-0-57"> 57</a></span>
3577
<span class="normal"><a href="#__codelineno-0-58"> 58</a></span>
3578
<span class="normal"><a href="#__codelineno-0-59"> 59</a></span>
3579
<span class="normal"><a href="#__codelineno-0-60"> 60</a></span>
3580
<span class="normal"><a href="#__codelineno-0-61"> 61</a></span>
3581
<span class="normal"><a href="#__codelineno-0-62"> 62</a></span>
3582
<span class="normal"><a href="#__codelineno-0-63"> 63</a></span>
3583
<span class="normal"><a href="#__codelineno-0-64"> 64</a></span>
3584
<span class="normal"><a href="#__codelineno-0-65"> 65</a></span>
3585
<span class="normal"><a href="#__codelineno-0-66"> 66</a></span>
3586
<span class="normal"><a href="#__codelineno-0-67"> 67</a></span>
3587
<span class="normal"><a href="#__codelineno-0-68"> 68</a></span>
3588
<span class="normal"><a href="#__codelineno-0-69"> 69</a></span>
3589
<span class="normal"><a href="#__codelineno-0-70"> 70</a></span>
3590
<span class="normal"><a href="#__codelineno-0-71"> 71</a></span>
3591
<span class="normal"><a href="#__codelineno-0-72"> 72</a></span>
3592
<span class="normal"><a href="#__codelineno-0-73"> 73</a></span>
3593
<span class="normal"><a href="#__codelineno-0-74"> 74</a></span>
3594
<span class="normal"><a href="#__codelineno-0-75"> 75</a></span>
3595
<span class="normal"><a href="#__codelineno-0-76"> 76</a></span>
3596
<span class="normal"><a href="#__codelineno-0-77"> 77</a></span>
3597
<span class="normal"><a href="#__codelineno-0-78"> 78</a></span>
3598
<span class="normal"><a href="#__codelineno-0-79"> 79</a></span>
3599
<span class="normal"><a href="#__codelineno-0-80"> 80</a></span>
3600
<span class="normal"><a href="#__codelineno-0-81"> 81</a></span>
3601
<span class="normal"><a href="#__codelineno-0-82"> 82</a></span>
3602
<span class="normal"><a href="#__codelineno-0-83"> 83</a></span>
3603
<span class="normal"><a href="#__codelineno-0-84"> 84</a></span>
3604
<span class="normal"><a href="#__codelineno-0-85"> 85</a></span>
3605
<span class="normal"><a href="#__codelineno-0-86"> 86</a></span>
3606
<span class="normal"><a href="#__codelineno-0-87"> 87</a></span>
3607
<span class="normal"><a href="#__codelineno-0-88"> 88</a></span>
3608
<span class="normal"><a href="#__codelineno-0-89"> 89</a></span>
3609
<span class="normal"><a href="#__codelineno-0-90"> 90</a></span>
3610
<span class="normal"><a href="#__codelineno-0-91"> 91</a></span>
3611
<span class="normal"><a href="#__codelineno-0-92"> 92</a></span>
3612
<span class="normal"><a href="#__codelineno-0-93"> 93</a></span>
3613
<span class="normal"><a href="#__codelineno-0-94"> 94</a></span>
3614
<span class="normal"><a href="#__codelineno-0-95"> 95</a></span>
3615
<span class="normal"><a href="#__codelineno-0-96"> 96</a></span>
3616
<span class="normal"><a href="#__codelineno-0-97"> 97</a></span>
3617
<span class="normal"><a href="#__codelineno-0-98"> 98</a></span>
3618
<span class="normal"><a href="#__codelineno-0-99"> 99</a></span>
3619
<span class="normal"><a href="#__codelineno-0-100">100</a></span>
3620
<span class="normal"><a href="#__codelineno-0-101">101</a></span>
3621
<span class="normal"><a href="#__codelineno-0-102">102</a></span>
3622
<span class="normal"><a href="#__codelineno-0-103">103</a></span>
3623
<span class="normal"><a href="#__codelineno-0-104">104</a></span>
3624
<span class="normal"><a href="#__codelineno-0-105">105</a></span>
3625
<span class="normal"><a href="#__codelineno-0-106">106</a></span>
3626
<span class="normal"><a href="#__codelineno-0-107">107</a></span>
3627
<span class="normal"><a href="#__codelineno-0-108">108</a></span>
3628
<span class="normal"><a href="#__codelineno-0-109">109</a></span>
3629
<span class="normal"><a href="#__codelineno-0-110">110</a></span>
3630
<span class="normal"><a href="#__codelineno-0-111">111</a></span>
3631
<span class="normal"><a href="#__codelineno-0-112">112</a></span>
3632
<span class="normal"><a href="#__codelineno-0-113">113</a></span>
3633
<span class="normal"><a href="#__codelineno-0-114">114</a></span>
3634
<span class="normal"><a href="#__codelineno-0-115">115</a></span>
3635
<span class="normal"><a href="#__codelineno-0-116">116</a></span>
3636
<span class="normal"><a href="#__codelineno-0-117">117</a></span>
3637
<span class="normal"><a href="#__codelineno-0-118">118</a></span>
3638
<span class="normal"><a href="#__codelineno-0-119">119</a></span>
3639
<span class="normal"><a href="#__codelineno-0-120">120</a></span>
3640
<span class="normal"><a href="#__codelineno-0-121">121</a></span>
3641
<span class="normal"><a href="#__codelineno-0-122">122</a></span>
3642
<span class="normal"><a href="#__codelineno-0-123">123</a></span>
3643
<span class="normal"><a href="#__codelineno-0-124">124</a></span>
3644
<span class="normal"><a href="#__codelineno-0-125">125</a></span>
3645
<span class="normal"><a href="#__codelineno-0-126">126</a></span>
3646
<span class="normal"><a href="#__codelineno-0-127">127</a></span>
3647
<span class="normal"><a href="#__codelineno-0-128">128</a></span>
3648
<span class="normal"><a href="#__codelineno-0-129">129</a></span>
3649
<span class="normal"><a href="#__codelineno-0-130">130</a></span>
3650
<span class="normal"><a href="#__codelineno-0-131">131</a></span>
3651
<span class="normal"><a href="#__codelineno-0-132">132</a></span>
3652
<span class="normal"><a href="#__codelineno-0-133">133</a></span>
3653
<span class="normal"><a href="#__codelineno-0-134">134</a></span>
3654
<span class="normal"><a href="#__codelineno-0-135">135</a></span>
3655
<span class="normal"><a href="#__codelineno-0-136">136</a></span>
3656
<span class="normal"><a href="#__codelineno-0-137">137</a></span>
3657
<span class="normal"><a href="#__codelineno-0-138">138</a></span>
3658
<span class="normal"><a href="#__codelineno-0-139">139</a></span>
3659
<span class="normal"><a href="#__codelineno-0-140">140</a></span>
3660
<span class="normal"><a href="#__codelineno-0-141">141</a></span>
3661
<span class="normal"><a href="#__codelineno-0-142">142</a></span>
3662
<span class="normal"><a href="#__codelineno-0-143">143</a></span>
3663
<span class="normal"><a href="#__codelineno-0-144">144</a></span>
3664
<span class="normal"><a href="#__codelineno-0-145">145</a></span>
3665
<span class="normal"><a href="#__codelineno-0-146">146</a></span>
3666
<span class="normal"><a href="#__codelineno-0-147">147</a></span>
3667
<span class="normal"><a href="#__codelineno-0-148">148</a></span>
3668
<span class="normal"><a href="#__codelineno-0-149">149</a></span>
3669
<span class="normal"><a href="#__codelineno-0-150">150</a></span>
3670
<span class="normal"><a href="#__codelineno-0-151">151</a></span>
3671
<span class="normal"><a href="#__codelineno-0-152">152</a></span>
3672
<span class="normal"><a href="#__codelineno-0-153">153</a></span>
3673
<span class="normal"><a href="#__codelineno-0-154">154</a></span>
3674
<span class="normal"><a href="#__codelineno-0-155">155</a></span>
3675
<span class="normal"><a href="#__codelineno-0-156">156</a></span>
3676
<span class="normal"><a href="#__codelineno-0-157">157</a></span>
3677
<span class="normal"><a href="#__codelineno-0-158">158</a></span>
3678
<span class="normal"><a href="#__codelineno-0-159">159</a></span>
3679
<span class="normal"><a href="#__codelineno-0-160">160</a></span>
3680
<span class="normal"><a href="#__codelineno-0-161">161</a></span>
3681
<span class="normal"><a href="#__codelineno-0-162">162</a></span>
3682
<span class="normal"><a href="#__codelineno-0-163">163</a></span>
3683
<span class="normal"><a href="#__codelineno-0-164">164</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-13" name="__codelineno-0-13"></a><span class="k">class</span><span class="w"> </span><span class="nc">ContentAnalyzer</span><span class="p">:</span>
3684
<a id="__codelineno-0-14" name="__codelineno-0-14"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Cross-references transcript and diagram entities for richer knowledge.&quot;&quot;&quot;</span>
3685
<a id="__codelineno-0-15" name="__codelineno-0-15"></a>
3686
<a id="__codelineno-0-16" name="__codelineno-0-16"></a> <span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">provider_manager</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">ProviderManager</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">):</span>
3687
<a id="__codelineno-0-17" name="__codelineno-0-17"></a> <span class="bp">self</span><span class="o">.</span><span class="n">pm</span> <span class="o">=</span> <span class="n">provider_manager</span>
3688
<a id="__codelineno-0-18" name="__codelineno-0-18"></a>
3689
<a id="__codelineno-0-19" name="__codelineno-0-19"></a> <span class="k">def</span><span class="w"> </span><span class="nf">cross_reference</span><span class="p">(</span>
3690
<a id="__codelineno-0-20" name="__codelineno-0-20"></a> <span class="bp">self</span><span class="p">,</span>
3691
<a id="__codelineno-0-21" name="__codelineno-0-21"></a> <span class="n">transcript_entities</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="n">Entity</span><span class="p">],</span>
3692
<a id="__codelineno-0-22" name="__codelineno-0-22"></a> <span class="n">diagram_entities</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="n">Entity</span><span class="p">],</span>
3693
<a id="__codelineno-0-23" name="__codelineno-0-23"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="n">List</span><span class="p">[</span><span class="n">Entity</span><span class="p">]:</span>
3694
<a id="__codelineno-0-24" name="__codelineno-0-24"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
3695
<a id="__codelineno-0-25" name="__codelineno-0-25"></a><span class="sd"> Merge entities from transcripts and diagrams.</span>
3696
<a id="__codelineno-0-26" name="__codelineno-0-26"></a>
3697
<a id="__codelineno-0-27" name="__codelineno-0-27"></a><span class="sd"> Merges by exact name overlap first, then uses LLM for fuzzy matching</span>
3698
<a id="__codelineno-0-28" name="__codelineno-0-28"></a><span class="sd"> of remaining entities. Adds source attribution.</span>
3699
<a id="__codelineno-0-29" name="__codelineno-0-29"></a><span class="sd"> &quot;&quot;&quot;</span>
3700
<a id="__codelineno-0-30" name="__codelineno-0-30"></a> <span class="n">merged</span><span class="p">:</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Entity</span><span class="p">]</span> <span class="o">=</span> <span class="p">{}</span>
3701
<a id="__codelineno-0-31" name="__codelineno-0-31"></a>
3702
<a id="__codelineno-0-32" name="__codelineno-0-32"></a> <span class="c1"># Index transcript entities</span>
3703
<a id="__codelineno-0-33" name="__codelineno-0-33"></a> <span class="k">for</span> <span class="n">e</span> <span class="ow">in</span> <span class="n">transcript_entities</span><span class="p">:</span>
3704
<a id="__codelineno-0-34" name="__codelineno-0-34"></a> <span class="n">key</span> <span class="o">=</span> <span class="n">e</span><span class="o">.</span><span class="n">name</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
3705
<a id="__codelineno-0-35" name="__codelineno-0-35"></a> <span class="n">merged</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">Entity</span><span class="p">(</span>
3706
<a id="__codelineno-0-36" name="__codelineno-0-36"></a> <span class="n">name</span><span class="o">=</span><span class="n">e</span><span class="o">.</span><span class="n">name</span><span class="p">,</span>
3707
<a id="__codelineno-0-37" name="__codelineno-0-37"></a> <span class="nb">type</span><span class="o">=</span><span class="n">e</span><span class="o">.</span><span class="n">type</span><span class="p">,</span>
3708
<a id="__codelineno-0-38" name="__codelineno-0-38"></a> <span class="n">descriptions</span><span class="o">=</span><span class="nb">list</span><span class="p">(</span><span class="n">e</span><span class="o">.</span><span class="n">descriptions</span><span class="p">),</span>
3709
<a id="__codelineno-0-39" name="__codelineno-0-39"></a> <span class="n">source</span><span class="o">=</span><span class="s2">&quot;transcript&quot;</span><span class="p">,</span>
3710
<a id="__codelineno-0-40" name="__codelineno-0-40"></a> <span class="n">occurrences</span><span class="o">=</span><span class="nb">list</span><span class="p">(</span><span class="n">e</span><span class="o">.</span><span class="n">occurrences</span><span class="p">),</span>
3711
<a id="__codelineno-0-41" name="__codelineno-0-41"></a> <span class="p">)</span>
3712
<a id="__codelineno-0-42" name="__codelineno-0-42"></a>
3713
<a id="__codelineno-0-43" name="__codelineno-0-43"></a> <span class="c1"># Merge diagram entities</span>
3714
<a id="__codelineno-0-44" name="__codelineno-0-44"></a> <span class="k">for</span> <span class="n">e</span> <span class="ow">in</span> <span class="n">diagram_entities</span><span class="p">:</span>
3715
<a id="__codelineno-0-45" name="__codelineno-0-45"></a> <span class="n">key</span> <span class="o">=</span> <span class="n">e</span><span class="o">.</span><span class="n">name</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
3716
<a id="__codelineno-0-46" name="__codelineno-0-46"></a> <span class="k">if</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">merged</span><span class="p">:</span>
3717
<a id="__codelineno-0-47" name="__codelineno-0-47"></a> <span class="n">existing</span> <span class="o">=</span> <span class="n">merged</span><span class="p">[</span><span class="n">key</span><span class="p">]</span>
3718
<a id="__codelineno-0-48" name="__codelineno-0-48"></a> <span class="n">existing</span><span class="o">.</span><span class="n">source</span> <span class="o">=</span> <span class="s2">&quot;both&quot;</span>
3719
<a id="__codelineno-0-49" name="__codelineno-0-49"></a> <span class="n">existing</span><span class="o">.</span><span class="n">descriptions</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="nb">set</span><span class="p">(</span><span class="n">existing</span><span class="o">.</span><span class="n">descriptions</span> <span class="o">+</span> <span class="n">e</span><span class="o">.</span><span class="n">descriptions</span><span class="p">))</span>
3720
<a id="__codelineno-0-50" name="__codelineno-0-50"></a> <span class="n">existing</span><span class="o">.</span><span class="n">occurrences</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">e</span><span class="o">.</span><span class="n">occurrences</span><span class="p">)</span>
3721
<a id="__codelineno-0-51" name="__codelineno-0-51"></a> <span class="k">else</span><span class="p">:</span>
3722
<a id="__codelineno-0-52" name="__codelineno-0-52"></a> <span class="n">merged</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">Entity</span><span class="p">(</span>
3723
<a id="__codelineno-0-53" name="__codelineno-0-53"></a> <span class="n">name</span><span class="o">=</span><span class="n">e</span><span class="o">.</span><span class="n">name</span><span class="p">,</span>
3724
<a id="__codelineno-0-54" name="__codelineno-0-54"></a> <span class="nb">type</span><span class="o">=</span><span class="n">e</span><span class="o">.</span><span class="n">type</span><span class="p">,</span>
3725
<a id="__codelineno-0-55" name="__codelineno-0-55"></a> <span class="n">descriptions</span><span class="o">=</span><span class="nb">list</span><span class="p">(</span><span class="n">e</span><span class="o">.</span><span class="n">descriptions</span><span class="p">),</span>
3726
<a id="__codelineno-0-56" name="__codelineno-0-56"></a> <span class="n">source</span><span class="o">=</span><span class="s2">&quot;diagram&quot;</span><span class="p">,</span>
3727
<a id="__codelineno-0-57" name="__codelineno-0-57"></a> <span class="n">occurrences</span><span class="o">=</span><span class="nb">list</span><span class="p">(</span><span class="n">e</span><span class="o">.</span><span class="n">occurrences</span><span class="p">),</span>
3728
<a id="__codelineno-0-58" name="__codelineno-0-58"></a> <span class="p">)</span>
3729
<a id="__codelineno-0-59" name="__codelineno-0-59"></a>
3730
<a id="__codelineno-0-60" name="__codelineno-0-60"></a> <span class="c1"># LLM fuzzy matching for unmatched entities</span>
3731
<a id="__codelineno-0-61" name="__codelineno-0-61"></a> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">pm</span><span class="p">:</span>
3732
<a id="__codelineno-0-62" name="__codelineno-0-62"></a> <span class="n">unmatched_t</span> <span class="o">=</span> <span class="p">[</span>
3733
<a id="__codelineno-0-63" name="__codelineno-0-63"></a> <span class="n">e</span>
3734
<a id="__codelineno-0-64" name="__codelineno-0-64"></a> <span class="k">for</span> <span class="n">e</span> <span class="ow">in</span> <span class="n">transcript_entities</span>
3735
<a id="__codelineno-0-65" name="__codelineno-0-65"></a> <span class="k">if</span> <span class="n">e</span><span class="o">.</span><span class="n">name</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">{</span><span class="n">d</span><span class="o">.</span><span class="n">name</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="k">for</span> <span class="n">d</span> <span class="ow">in</span> <span class="n">diagram_entities</span><span class="p">}</span>
3736
<a id="__codelineno-0-66" name="__codelineno-0-66"></a> <span class="p">]</span>
3737
<a id="__codelineno-0-67" name="__codelineno-0-67"></a> <span class="n">unmatched_d</span> <span class="o">=</span> <span class="p">[</span>
3738
<a id="__codelineno-0-68" name="__codelineno-0-68"></a> <span class="n">e</span>
3739
<a id="__codelineno-0-69" name="__codelineno-0-69"></a> <span class="k">for</span> <span class="n">e</span> <span class="ow">in</span> <span class="n">diagram_entities</span>
3740
<a id="__codelineno-0-70" name="__codelineno-0-70"></a> <span class="k">if</span> <span class="n">e</span><span class="o">.</span><span class="n">name</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">{</span><span class="n">t</span><span class="o">.</span><span class="n">name</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="k">for</span> <span class="n">t</span> <span class="ow">in</span> <span class="n">transcript_entities</span><span class="p">}</span>
3741
<a id="__codelineno-0-71" name="__codelineno-0-71"></a> <span class="p">]</span>
3742
<a id="__codelineno-0-72" name="__codelineno-0-72"></a>
3743
<a id="__codelineno-0-73" name="__codelineno-0-73"></a> <span class="k">if</span> <span class="n">unmatched_t</span> <span class="ow">and</span> <span class="n">unmatched_d</span><span class="p">:</span>
3744
<a id="__codelineno-0-74" name="__codelineno-0-74"></a> <span class="n">matches</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_fuzzy_match</span><span class="p">(</span><span class="n">unmatched_t</span><span class="p">,</span> <span class="n">unmatched_d</span><span class="p">)</span>
3745
<a id="__codelineno-0-75" name="__codelineno-0-75"></a> <span class="k">for</span> <span class="n">t_name</span><span class="p">,</span> <span class="n">d_name</span> <span class="ow">in</span> <span class="n">matches</span><span class="p">:</span>
3746
<a id="__codelineno-0-76" name="__codelineno-0-76"></a> <span class="n">t_key</span> <span class="o">=</span> <span class="n">t_name</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
3747
<a id="__codelineno-0-77" name="__codelineno-0-77"></a> <span class="n">d_key</span> <span class="o">=</span> <span class="n">d_name</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
3748
<a id="__codelineno-0-78" name="__codelineno-0-78"></a> <span class="k">if</span> <span class="n">t_key</span> <span class="ow">in</span> <span class="n">merged</span> <span class="ow">and</span> <span class="n">d_key</span> <span class="ow">in</span> <span class="n">merged</span><span class="p">:</span>
3749
<a id="__codelineno-0-79" name="__codelineno-0-79"></a> <span class="n">t_entity</span> <span class="o">=</span> <span class="n">merged</span><span class="p">[</span><span class="n">t_key</span><span class="p">]</span>
3750
<a id="__codelineno-0-80" name="__codelineno-0-80"></a> <span class="n">d_entity</span> <span class="o">=</span> <span class="n">merged</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="n">d_key</span><span class="p">)</span>
3751
<a id="__codelineno-0-81" name="__codelineno-0-81"></a> <span class="n">t_entity</span><span class="o">.</span><span class="n">source</span> <span class="o">=</span> <span class="s2">&quot;both&quot;</span>
3752
<a id="__codelineno-0-82" name="__codelineno-0-82"></a> <span class="n">t_entity</span><span class="o">.</span><span class="n">descriptions</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span>
3753
<a id="__codelineno-0-83" name="__codelineno-0-83"></a> <span class="nb">set</span><span class="p">(</span><span class="n">t_entity</span><span class="o">.</span><span class="n">descriptions</span> <span class="o">+</span> <span class="n">d_entity</span><span class="o">.</span><span class="n">descriptions</span><span class="p">)</span>
3754
<a id="__codelineno-0-84" name="__codelineno-0-84"></a> <span class="p">)</span>
3755
<a id="__codelineno-0-85" name="__codelineno-0-85"></a> <span class="n">t_entity</span><span class="o">.</span><span class="n">occurrences</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">d_entity</span><span class="o">.</span><span class="n">occurrences</span><span class="p">)</span>
3756
<a id="__codelineno-0-86" name="__codelineno-0-86"></a>
3757
<a id="__codelineno-0-87" name="__codelineno-0-87"></a> <span class="k">return</span> <span class="nb">list</span><span class="p">(</span><span class="n">merged</span><span class="o">.</span><span class="n">values</span><span class="p">())</span>
3758
<a id="__codelineno-0-88" name="__codelineno-0-88"></a>
3759
<a id="__codelineno-0-89" name="__codelineno-0-89"></a> <span class="k">def</span><span class="w"> </span><span class="nf">_fuzzy_match</span><span class="p">(</span>
3760
<a id="__codelineno-0-90" name="__codelineno-0-90"></a> <span class="bp">self</span><span class="p">,</span>
3761
<a id="__codelineno-0-91" name="__codelineno-0-91"></a> <span class="n">transcript_entities</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="n">Entity</span><span class="p">],</span>
3762
<a id="__codelineno-0-92" name="__codelineno-0-92"></a> <span class="n">diagram_entities</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="n">Entity</span><span class="p">],</span>
3763
<a id="__codelineno-0-93" name="__codelineno-0-93"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="n">List</span><span class="p">[</span><span class="nb">tuple</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="nb">str</span><span class="p">]]:</span>
3764
<a id="__codelineno-0-94" name="__codelineno-0-94"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Use LLM to fuzzy-match entity names across sources.&quot;&quot;&quot;</span>
3765
<a id="__codelineno-0-95" name="__codelineno-0-95"></a> <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">pm</span><span class="p">:</span>
3766
<a id="__codelineno-0-96" name="__codelineno-0-96"></a> <span class="k">return</span> <span class="p">[]</span>
3767
<a id="__codelineno-0-97" name="__codelineno-0-97"></a>
3768
<a id="__codelineno-0-98" name="__codelineno-0-98"></a> <span class="n">t_names</span> <span class="o">=</span> <span class="p">[</span><span class="n">e</span><span class="o">.</span><span class="n">name</span> <span class="k">for</span> <span class="n">e</span> <span class="ow">in</span> <span class="n">transcript_entities</span><span class="p">]</span>
3769
<a id="__codelineno-0-99" name="__codelineno-0-99"></a> <span class="n">d_names</span> <span class="o">=</span> <span class="p">[</span><span class="n">e</span><span class="o">.</span><span class="n">name</span> <span class="k">for</span> <span class="n">e</span> <span class="ow">in</span> <span class="n">diagram_entities</span><span class="p">]</span>
3770
<a id="__codelineno-0-100" name="__codelineno-0-100"></a>
3771
<a id="__codelineno-0-101" name="__codelineno-0-101"></a> <span class="n">prompt</span> <span class="o">=</span> <span class="p">(</span>
3772
<a id="__codelineno-0-102" name="__codelineno-0-102"></a> <span class="s2">&quot;Match entities that refer to the same thing across these two lists.</span><span class="se">\n\n</span><span class="s2">&quot;</span>
3773
<a id="__codelineno-0-103" name="__codelineno-0-103"></a> <span class="sa">f</span><span class="s2">&quot;Transcript entities: </span><span class="si">{</span><span class="n">t_names</span><span class="si">}</span><span class="se">\n</span><span class="s2">&quot;</span>
3774
<a id="__codelineno-0-104" name="__codelineno-0-104"></a> <span class="sa">f</span><span class="s2">&quot;Diagram entities: </span><span class="si">{</span><span class="n">d_names</span><span class="si">}</span><span class="se">\n\n</span><span class="s2">&quot;</span>
3775
<a id="__codelineno-0-105" name="__codelineno-0-105"></a> <span class="s2">&quot;Return a JSON array of matched pairs:</span><span class="se">\n</span><span class="s2">&quot;</span>
3776
<a id="__codelineno-0-106" name="__codelineno-0-106"></a> <span class="s1">&#39;[{&quot;transcript&quot;: &quot;name from list 1&quot;, &quot;diagram&quot;: &quot;name from list 2&quot;}]</span><span class="se">\n\n</span><span class="s1">&#39;</span>
3777
<a id="__codelineno-0-107" name="__codelineno-0-107"></a> <span class="s2">&quot;Only include confident matches. Return empty array if no matches.</span><span class="se">\n</span><span class="s2">&quot;</span>
3778
<a id="__codelineno-0-108" name="__codelineno-0-108"></a> <span class="s2">&quot;Return ONLY the JSON array.&quot;</span>
3779
<a id="__codelineno-0-109" name="__codelineno-0-109"></a> <span class="p">)</span>
3780
<a id="__codelineno-0-110" name="__codelineno-0-110"></a>
3781
<a id="__codelineno-0-111" name="__codelineno-0-111"></a> <span class="k">try</span><span class="p">:</span>
3782
<a id="__codelineno-0-112" name="__codelineno-0-112"></a> <span class="n">raw</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">pm</span><span class="o">.</span><span class="n">chat</span><span class="p">([{</span><span class="s2">&quot;role&quot;</span><span class="p">:</span> <span class="s2">&quot;user&quot;</span><span class="p">,</span> <span class="s2">&quot;content&quot;</span><span class="p">:</span> <span class="n">prompt</span><span class="p">}],</span> <span class="n">temperature</span><span class="o">=</span><span class="mf">0.2</span><span class="p">)</span>
3783
<a id="__codelineno-0-113" name="__codelineno-0-113"></a> <span class="n">parsed</span> <span class="o">=</span> <span class="n">parse_json_from_response</span><span class="p">(</span><span class="n">raw</span><span class="p">)</span>
3784
<a id="__codelineno-0-114" name="__codelineno-0-114"></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">parsed</span><span class="p">,</span> <span class="nb">list</span><span class="p">):</span>
3785
<a id="__codelineno-0-115" name="__codelineno-0-115"></a> <span class="k">return</span> <span class="p">[</span>
3786
<a id="__codelineno-0-116" name="__codelineno-0-116"></a> <span class="p">(</span><span class="n">item</span><span class="p">[</span><span class="s2">&quot;transcript&quot;</span><span class="p">],</span> <span class="n">item</span><span class="p">[</span><span class="s2">&quot;diagram&quot;</span><span class="p">])</span>
3787
<a id="__codelineno-0-117" name="__codelineno-0-117"></a> <span class="k">for</span> <span class="n">item</span> <span class="ow">in</span> <span class="n">parsed</span>
3788
<a id="__codelineno-0-118" name="__codelineno-0-118"></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">item</span><span class="p">,</span> <span class="nb">dict</span><span class="p">)</span> <span class="ow">and</span> <span class="s2">&quot;transcript&quot;</span> <span class="ow">in</span> <span class="n">item</span> <span class="ow">and</span> <span class="s2">&quot;diagram&quot;</span> <span class="ow">in</span> <span class="n">item</span>
3789
<a id="__codelineno-0-119" name="__codelineno-0-119"></a> <span class="p">]</span>
3790
<a id="__codelineno-0-120" name="__codelineno-0-120"></a> <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
3791
<a id="__codelineno-0-121" name="__codelineno-0-121"></a> <span class="n">logger</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Fuzzy matching failed: </span><span class="si">{</span><span class="n">e</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
3792
<a id="__codelineno-0-122" name="__codelineno-0-122"></a>
3793
<a id="__codelineno-0-123" name="__codelineno-0-123"></a> <span class="k">return</span> <span class="p">[]</span>
3794
<a id="__codelineno-0-124" name="__codelineno-0-124"></a>
3795
<a id="__codelineno-0-125" name="__codelineno-0-125"></a> <span class="k">def</span><span class="w"> </span><span class="nf">enrich_key_points</span><span class="p">(</span>
3796
<a id="__codelineno-0-126" name="__codelineno-0-126"></a> <span class="bp">self</span><span class="p">,</span>
3797
<a id="__codelineno-0-127" name="__codelineno-0-127"></a> <span class="n">key_points</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="n">KeyPoint</span><span class="p">],</span>
3798
<a id="__codelineno-0-128" name="__codelineno-0-128"></a> <span class="n">diagrams</span><span class="p">:</span> <span class="nb">list</span><span class="p">,</span>
3799
<a id="__codelineno-0-129" name="__codelineno-0-129"></a> <span class="n">transcript_text</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
3800
<a id="__codelineno-0-130" name="__codelineno-0-130"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="n">List</span><span class="p">[</span><span class="n">KeyPoint</span><span class="p">]:</span>
3801
<a id="__codelineno-0-131" name="__codelineno-0-131"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
3802
<a id="__codelineno-0-132" name="__codelineno-0-132"></a><span class="sd"> Link key points to relevant diagrams by entity overlap and temporal proximity.</span>
3803
<a id="__codelineno-0-133" name="__codelineno-0-133"></a><span class="sd"> &quot;&quot;&quot;</span>
3804
<a id="__codelineno-0-134" name="__codelineno-0-134"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">diagrams</span><span class="p">:</span>
3805
<a id="__codelineno-0-135" name="__codelineno-0-135"></a> <span class="k">return</span> <span class="n">key_points</span>
3806
<a id="__codelineno-0-136" name="__codelineno-0-136"></a>
3807
<a id="__codelineno-0-137" name="__codelineno-0-137"></a> <span class="c1"># Build diagram entity index</span>
3808
<a id="__codelineno-0-138" name="__codelineno-0-138"></a> <span class="n">diagram_entities</span><span class="p">:</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">int</span><span class="p">,</span> <span class="nb">set</span><span class="p">[</span><span class="nb">str</span><span class="p">]]</span> <span class="o">=</span> <span class="p">{}</span>
3809
<a id="__codelineno-0-139" name="__codelineno-0-139"></a> <span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">d</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">diagrams</span><span class="p">):</span>
3810
<a id="__codelineno-0-140" name="__codelineno-0-140"></a> <span class="n">elements</span> <span class="o">=</span> <span class="n">d</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;elements&quot;</span><span class="p">,</span> <span class="p">[])</span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">d</span><span class="p">,</span> <span class="nb">dict</span><span class="p">)</span> <span class="k">else</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">d</span><span class="p">,</span> <span class="s2">&quot;elements&quot;</span><span class="p">,</span> <span class="p">[])</span>
3811
<a id="__codelineno-0-141" name="__codelineno-0-141"></a> <span class="n">text</span> <span class="o">=</span> <span class="p">(</span>
3812
<a id="__codelineno-0-142" name="__codelineno-0-142"></a> <span class="n">d</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;text_content&quot;</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">)</span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">d</span><span class="p">,</span> <span class="nb">dict</span><span class="p">)</span> <span class="k">else</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">d</span><span class="p">,</span> <span class="s2">&quot;text_content&quot;</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">)</span>
3813
<a id="__codelineno-0-143" name="__codelineno-0-143"></a> <span class="p">)</span>
3814
<a id="__codelineno-0-144" name="__codelineno-0-144"></a> <span class="n">entities</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">)</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="k">for</span> <span class="n">e</span> <span class="ow">in</span> <span class="n">elements</span><span class="p">)</span>
3815
<a id="__codelineno-0-145" name="__codelineno-0-145"></a> <span class="k">if</span> <span class="n">text</span><span class="p">:</span>
3816
<a id="__codelineno-0-146" name="__codelineno-0-146"></a> <span class="n">entities</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">word</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="k">for</span> <span class="n">word</span> <span class="ow">in</span> <span class="n">text</span><span class="o">.</span><span class="n">split</span><span class="p">()</span> <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">word</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">3</span><span class="p">)</span>
3817
<a id="__codelineno-0-147" name="__codelineno-0-147"></a> <span class="n">diagram_entities</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">entities</span>
3818
<a id="__codelineno-0-148" name="__codelineno-0-148"></a>
3819
<a id="__codelineno-0-149" name="__codelineno-0-149"></a> <span class="c1"># Match key points to diagrams</span>
3820
<a id="__codelineno-0-150" name="__codelineno-0-150"></a> <span class="k">for</span> <span class="n">kp</span> <span class="ow">in</span> <span class="n">key_points</span><span class="p">:</span>
3821
<a id="__codelineno-0-151" name="__codelineno-0-151"></a> <span class="n">kp_words</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">kp</span><span class="o">.</span><span class="n">point</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span><span class="o">.</span><span class="n">split</span><span class="p">())</span>
3822
<a id="__codelineno-0-152" name="__codelineno-0-152"></a> <span class="k">if</span> <span class="n">kp</span><span class="o">.</span><span class="n">details</span><span class="p">:</span>
3823
<a id="__codelineno-0-153" name="__codelineno-0-153"></a> <span class="n">kp_words</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">kp</span><span class="o">.</span><span class="n">details</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span><span class="o">.</span><span class="n">split</span><span class="p">())</span>
3824
<a id="__codelineno-0-154" name="__codelineno-0-154"></a>
3825
<a id="__codelineno-0-155" name="__codelineno-0-155"></a> <span class="n">related</span> <span class="o">=</span> <span class="p">[]</span>
3826
<a id="__codelineno-0-156" name="__codelineno-0-156"></a> <span class="k">for</span> <span class="n">idx</span><span class="p">,</span> <span class="n">d_entities</span> <span class="ow">in</span> <span class="n">diagram_entities</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
3827
<a id="__codelineno-0-157" name="__codelineno-0-157"></a> <span class="n">overlap</span> <span class="o">=</span> <span class="n">kp_words</span> <span class="o">&amp;</span> <span class="n">d_entities</span>
3828
<a id="__codelineno-0-158" name="__codelineno-0-158"></a> <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">overlap</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="mi">2</span><span class="p">:</span>
3829
<a id="__codelineno-0-159" name="__codelineno-0-159"></a> <span class="n">related</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">idx</span><span class="p">)</span>
3830
<a id="__codelineno-0-160" name="__codelineno-0-160"></a>
3831
<a id="__codelineno-0-161" name="__codelineno-0-161"></a> <span class="k">if</span> <span class="n">related</span><span class="p">:</span>
3832
<a id="__codelineno-0-162" name="__codelineno-0-162"></a> <span class="n">kp</span><span class="o">.</span><span class="n">related_diagrams</span> <span class="o">=</span> <span class="n">related</span>
3833
<a id="__codelineno-0-163" name="__codelineno-0-163"></a>
3834
<a id="__codelineno-0-164" name="__codelineno-0-164"></a> <span class="k">return</span> <span class="n">key_points</span>
3835
</code></pre></div></td></tr></table></div>
3836
</details>
3837
3838
3839
3840
<div class="doc doc-children">
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
<div class="doc doc-object doc-function">
3852
3853
3854
<h4 id="video_processor.analyzers.content_analyzer.ContentAnalyzer.cross_reference" class="doc doc-heading">
3855
<code class="highlight language-python"><span class="n">cross_reference</span><span class="p">(</span><span class="n">transcript_entities</span><span class="p">,</span> <span class="n">diagram_entities</span><span class="p">)</span></code>
3856
3857
<a href="#video_processor.analyzers.content_analyzer.ContentAnalyzer.cross_reference" class="headerlink" title="Permanent link">&para;</a></h4>
3858
3859
3860
<div class="doc doc-contents ">
3861
3862
<p>Merge entities from transcripts and diagrams.</p>
3863
<p>Merges by exact name overlap first, then uses LLM for fuzzy matching
3864
of remaining entities. Adds source attribution.</p>
3865
3866
3867
<details class="mkdocstrings-source">
3868
<summary>Source code in <code>video_processor/analyzers/content_analyzer.py</code></summary>
3869
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-19">19</a></span>
3870
<span class="normal"><a href="#__codelineno-0-20">20</a></span>
3871
<span class="normal"><a href="#__codelineno-0-21">21</a></span>
3872
<span class="normal"><a href="#__codelineno-0-22">22</a></span>
3873
<span class="normal"><a href="#__codelineno-0-23">23</a></span>
3874
<span class="normal"><a href="#__codelineno-0-24">24</a></span>
3875
<span class="normal"><a href="#__codelineno-0-25">25</a></span>
3876
<span class="normal"><a href="#__codelineno-0-26">26</a></span>
3877
<span class="normal"><a href="#__codelineno-0-27">27</a></span>
3878
<span class="normal"><a href="#__codelineno-0-28">28</a></span>
3879
<span class="normal"><a href="#__codelineno-0-29">29</a></span>
3880
<span class="normal"><a href="#__codelineno-0-30">30</a></span>
3881
<span class="normal"><a href="#__codelineno-0-31">31</a></span>
3882
<span class="normal"><a href="#__codelineno-0-32">32</a></span>
3883
<span class="normal"><a href="#__codelineno-0-33">33</a></span>
3884
<span class="normal"><a href="#__codelineno-0-34">34</a></span>
3885
<span class="normal"><a href="#__codelineno-0-35">35</a></span>
3886
<span class="normal"><a href="#__codelineno-0-36">36</a></span>
3887
<span class="normal"><a href="#__codelineno-0-37">37</a></span>
3888
<span class="normal"><a href="#__codelineno-0-38">38</a></span>
3889
<span class="normal"><a href="#__codelineno-0-39">39</a></span>
3890
<span class="normal"><a href="#__codelineno-0-40">40</a></span>
3891
<span class="normal"><a href="#__codelineno-0-41">41</a></span>
3892
<span class="normal"><a href="#__codelineno-0-42">42</a></span>
3893
<span class="normal"><a href="#__codelineno-0-43">43</a></span>
3894
<span class="normal"><a href="#__codelineno-0-44">44</a></span>
3895
<span class="normal"><a href="#__codelineno-0-45">45</a></span>
3896
<span class="normal"><a href="#__codelineno-0-46">46</a></span>
3897
<span class="normal"><a href="#__codelineno-0-47">47</a></span>
3898
<span class="normal"><a href="#__codelineno-0-48">48</a></span>
3899
<span class="normal"><a href="#__codelineno-0-49">49</a></span>
3900
<span class="normal"><a href="#__codelineno-0-50">50</a></span>
3901
<span class="normal"><a href="#__codelineno-0-51">51</a></span>
3902
<span class="normal"><a href="#__codelineno-0-52">52</a></span>
3903
<span class="normal"><a href="#__codelineno-0-53">53</a></span>
3904
<span class="normal"><a href="#__codelineno-0-54">54</a></span>
3905
<span class="normal"><a href="#__codelineno-0-55">55</a></span>
3906
<span class="normal"><a href="#__codelineno-0-56">56</a></span>
3907
<span class="normal"><a href="#__codelineno-0-57">57</a></span>
3908
<span class="normal"><a href="#__codelineno-0-58">58</a></span>
3909
<span class="normal"><a href="#__codelineno-0-59">59</a></span>
3910
<span class="normal"><a href="#__codelineno-0-60">60</a></span>
3911
<span class="normal"><a href="#__codelineno-0-61">61</a></span>
3912
<span class="normal"><a href="#__codelineno-0-62">62</a></span>
3913
<span class="normal"><a href="#__codelineno-0-63">63</a></span>
3914
<span class="normal"><a href="#__codelineno-0-64">64</a></span>
3915
<span class="normal"><a href="#__codelineno-0-65">65</a></span>
3916
<span class="normal"><a href="#__codelineno-0-66">66</a></span>
3917
<span class="normal"><a href="#__codelineno-0-67">67</a></span>
3918
<span class="normal"><a href="#__codelineno-0-68">68</a></span>
3919
<span class="normal"><a href="#__codelineno-0-69">69</a></span>
3920
<span class="normal"><a href="#__codelineno-0-70">70</a></span>
3921
<span class="normal"><a href="#__codelineno-0-71">71</a></span>
3922
<span class="normal"><a href="#__codelineno-0-72">72</a></span>
3923
<span class="normal"><a href="#__codelineno-0-73">73</a></span>
3924
<span class="normal"><a href="#__codelineno-0-74">74</a></span>
3925
<span class="normal"><a href="#__codelineno-0-75">75</a></span>
3926
<span class="normal"><a href="#__codelineno-0-76">76</a></span>
3927
<span class="normal"><a href="#__codelineno-0-77">77</a></span>
3928
<span class="normal"><a href="#__codelineno-0-78">78</a></span>
3929
<span class="normal"><a href="#__codelineno-0-79">79</a></span>
3930
<span class="normal"><a href="#__codelineno-0-80">80</a></span>
3931
<span class="normal"><a href="#__codelineno-0-81">81</a></span>
3932
<span class="normal"><a href="#__codelineno-0-82">82</a></span>
3933
<span class="normal"><a href="#__codelineno-0-83">83</a></span>
3934
<span class="normal"><a href="#__codelineno-0-84">84</a></span>
3935
<span class="normal"><a href="#__codelineno-0-85">85</a></span>
3936
<span class="normal"><a href="#__codelineno-0-86">86</a></span>
3937
<span class="normal"><a href="#__codelineno-0-87">87</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-19" name="__codelineno-0-19"></a><span class="k">def</span><span class="w"> </span><span class="nf">cross_reference</span><span class="p">(</span>
3938
<a id="__codelineno-0-20" name="__codelineno-0-20"></a> <span class="bp">self</span><span class="p">,</span>
3939
<a id="__codelineno-0-21" name="__codelineno-0-21"></a> <span class="n">transcript_entities</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="n">Entity</span><span class="p">],</span>
3940
<a id="__codelineno-0-22" name="__codelineno-0-22"></a> <span class="n">diagram_entities</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="n">Entity</span><span class="p">],</span>
3941
<a id="__codelineno-0-23" name="__codelineno-0-23"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">List</span><span class="p">[</span><span class="n">Entity</span><span class="p">]:</span>
3942
<a id="__codelineno-0-24" name="__codelineno-0-24"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
3943
<a id="__codelineno-0-25" name="__codelineno-0-25"></a><span class="sd"> Merge entities from transcripts and diagrams.</span>
3944
<a id="__codelineno-0-26" name="__codelineno-0-26"></a>
3945
<a id="__codelineno-0-27" name="__codelineno-0-27"></a><span class="sd"> Merges by exact name overlap first, then uses LLM for fuzzy matching</span>
3946
<a id="__codelineno-0-28" name="__codelineno-0-28"></a><span class="sd"> of remaining entities. Adds source attribution.</span>
3947
<a id="__codelineno-0-29" name="__codelineno-0-29"></a><span class="sd"> &quot;&quot;&quot;</span>
3948
<a id="__codelineno-0-30" name="__codelineno-0-30"></a> <span class="n">merged</span><span class="p">:</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Entity</span><span class="p">]</span> <span class="o">=</span> <span class="p">{}</span>
3949
<a id="__codelineno-0-31" name="__codelineno-0-31"></a>
3950
<a id="__codelineno-0-32" name="__codelineno-0-32"></a> <span class="c1"># Index transcript entities</span>
3951
<a id="__codelineno-0-33" name="__codelineno-0-33"></a> <span class="k">for</span> <span class="n">e</span> <span class="ow">in</span> <span class="n">transcript_entities</span><span class="p">:</span>
3952
<a id="__codelineno-0-34" name="__codelineno-0-34"></a> <span class="n">key</span> <span class="o">=</span> <span class="n">e</span><span class="o">.</span><span class="n">name</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
3953
<a id="__codelineno-0-35" name="__codelineno-0-35"></a> <span class="n">merged</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">Entity</span><span class="p">(</span>
3954
<a id="__codelineno-0-36" name="__codelineno-0-36"></a> <span class="n">name</span><span class="o">=</span><span class="n">e</span><span class="o">.</span><span class="n">name</span><span class="p">,</span>
3955
<a id="__codelineno-0-37" name="__codelineno-0-37"></a> <span class="nb">type</span><span class="o">=</span><span class="n">e</span><span class="o">.</span><span class="n">type</span><span class="p">,</span>
3956
<a id="__codelineno-0-38" name="__codelineno-0-38"></a> <span class="n">descriptions</span><span class="o">=</span><span class="nb">list</span><span class="p">(</span><span class="n">e</span><span class="o">.</span><span class="n">descriptions</span><span class="p">),</span>
3957
<a id="__codelineno-0-39" name="__codelineno-0-39"></a> <span class="n">source</span><span class="o">=</span><span class="s2">&quot;transcript&quot;</span><span class="p">,</span>
3958
<a id="__codelineno-0-40" name="__codelineno-0-40"></a> <span class="n">occurrences</span><span class="o">=</span><span class="nb">list</span><span class="p">(</span><span class="n">e</span><span class="o">.</span><span class="n">occurrences</span><span class="p">),</span>
3959
<a id="__codelineno-0-41" name="__codelineno-0-41"></a> <span class="p">)</span>
3960
<a id="__codelineno-0-42" name="__codelineno-0-42"></a>
3961
<a id="__codelineno-0-43" name="__codelineno-0-43"></a> <span class="c1"># Merge diagram entities</span>
3962
<a id="__codelineno-0-44" name="__codelineno-0-44"></a> <span class="k">for</span> <span class="n">e</span> <span class="ow">in</span> <span class="n">diagram_entities</span><span class="p">:</span>
3963
<a id="__codelineno-0-45" name="__codelineno-0-45"></a> <span class="n">key</span> <span class="o">=</span> <span class="n">e</span><span class="o">.</span><span class="n">name</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
3964
<a id="__codelineno-0-46" name="__codelineno-0-46"></a> <span class="k">if</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">merged</span><span class="p">:</span>
3965
<a id="__codelineno-0-47" name="__codelineno-0-47"></a> <span class="n">existing</span> <span class="o">=</span> <span class="n">merged</span><span class="p">[</span><span class="n">key</span><span class="p">]</span>
3966
<a id="__codelineno-0-48" name="__codelineno-0-48"></a> <span class="n">existing</span><span class="o">.</span><span class="n">source</span> <span class="o">=</span> <span class="s2">&quot;both&quot;</span>
3967
<a id="__codelineno-0-49" name="__codelineno-0-49"></a> <span class="n">existing</span><span class="o">.</span><span class="n">descriptions</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="nb">set</span><span class="p">(</span><span class="n">existing</span><span class="o">.</span><span class="n">descriptions</span> <span class="o">+</span> <span class="n">e</span><span class="o">.</span><span class="n">descriptions</span><span class="p">))</span>
3968
<a id="__codelineno-0-50" name="__codelineno-0-50"></a> <span class="n">existing</span><span class="o">.</span><span class="n">occurrences</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">e</span><span class="o">.</span><span class="n">occurrences</span><span class="p">)</span>
3969
<a id="__codelineno-0-51" name="__codelineno-0-51"></a> <span class="k">else</span><span class="p">:</span>
3970
<a id="__codelineno-0-52" name="__codelineno-0-52"></a> <span class="n">merged</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">Entity</span><span class="p">(</span>
3971
<a id="__codelineno-0-53" name="__codelineno-0-53"></a> <span class="n">name</span><span class="o">=</span><span class="n">e</span><span class="o">.</span><span class="n">name</span><span class="p">,</span>
3972
<a id="__codelineno-0-54" name="__codelineno-0-54"></a> <span class="nb">type</span><span class="o">=</span><span class="n">e</span><span class="o">.</span><span class="n">type</span><span class="p">,</span>
3973
<a id="__codelineno-0-55" name="__codelineno-0-55"></a> <span class="n">descriptions</span><span class="o">=</span><span class="nb">list</span><span class="p">(</span><span class="n">e</span><span class="o">.</span><span class="n">descriptions</span><span class="p">),</span>
3974
<a id="__codelineno-0-56" name="__codelineno-0-56"></a> <span class="n">source</span><span class="o">=</span><span class="s2">&quot;diagram&quot;</span><span class="p">,</span>
3975
<a id="__codelineno-0-57" name="__codelineno-0-57"></a> <span class="n">occurrences</span><span class="o">=</span><span class="nb">list</span><span class="p">(</span><span class="n">e</span><span class="o">.</span><span class="n">occurrences</span><span class="p">),</span>
3976
<a id="__codelineno-0-58" name="__codelineno-0-58"></a> <span class="p">)</span>
3977
<a id="__codelineno-0-59" name="__codelineno-0-59"></a>
3978
<a id="__codelineno-0-60" name="__codelineno-0-60"></a> <span class="c1"># LLM fuzzy matching for unmatched entities</span>
3979
<a id="__codelineno-0-61" name="__codelineno-0-61"></a> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">pm</span><span class="p">:</span>
3980
<a id="__codelineno-0-62" name="__codelineno-0-62"></a> <span class="n">unmatched_t</span> <span class="o">=</span> <span class="p">[</span>
3981
<a id="__codelineno-0-63" name="__codelineno-0-63"></a> <span class="n">e</span>
3982
<a id="__codelineno-0-64" name="__codelineno-0-64"></a> <span class="k">for</span> <span class="n">e</span> <span class="ow">in</span> <span class="n">transcript_entities</span>
3983
<a id="__codelineno-0-65" name="__codelineno-0-65"></a> <span class="k">if</span> <span class="n">e</span><span class="o">.</span><span class="n">name</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">{</span><span class="n">d</span><span class="o">.</span><span class="n">name</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="k">for</span> <span class="n">d</span> <span class="ow">in</span> <span class="n">diagram_entities</span><span class="p">}</span>
3984
<a id="__codelineno-0-66" name="__codelineno-0-66"></a> <span class="p">]</span>
3985
<a id="__codelineno-0-67" name="__codelineno-0-67"></a> <span class="n">unmatched_d</span> <span class="o">=</span> <span class="p">[</span>
3986
<a id="__codelineno-0-68" name="__codelineno-0-68"></a> <span class="n">e</span>
3987
<a id="__codelineno-0-69" name="__codelineno-0-69"></a> <span class="k">for</span> <span class="n">e</span> <span class="ow">in</span> <span class="n">diagram_entities</span>
3988
<a id="__codelineno-0-70" name="__codelineno-0-70"></a> <span class="k">if</span> <span class="n">e</span><span class="o">.</span><span class="n">name</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">{</span><span class="n">t</span><span class="o">.</span><span class="n">name</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="k">for</span> <span class="n">t</span> <span class="ow">in</span> <span class="n">transcript_entities</span><span class="p">}</span>
3989
<a id="__codelineno-0-71" name="__codelineno-0-71"></a> <span class="p">]</span>
3990
<a id="__codelineno-0-72" name="__codelineno-0-72"></a>
3991
<a id="__codelineno-0-73" name="__codelineno-0-73"></a> <span class="k">if</span> <span class="n">unmatched_t</span> <span class="ow">and</span> <span class="n">unmatched_d</span><span class="p">:</span>
3992
<a id="__codelineno-0-74" name="__codelineno-0-74"></a> <span class="n">matches</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_fuzzy_match</span><span class="p">(</span><span class="n">unmatched_t</span><span class="p">,</span> <span class="n">unmatched_d</span><span class="p">)</span>
3993
<a id="__codelineno-0-75" name="__codelineno-0-75"></a> <span class="k">for</span> <span class="n">t_name</span><span class="p">,</span> <span class="n">d_name</span> <span class="ow">in</span> <span class="n">matches</span><span class="p">:</span>
3994
<a id="__codelineno-0-76" name="__codelineno-0-76"></a> <span class="n">t_key</span> <span class="o">=</span> <span class="n">t_name</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
3995
<a id="__codelineno-0-77" name="__codelineno-0-77"></a> <span class="n">d_key</span> <span class="o">=</span> <span class="n">d_name</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
3996
<a id="__codelineno-0-78" name="__codelineno-0-78"></a> <span class="k">if</span> <span class="n">t_key</span> <span class="ow">in</span> <span class="n">merged</span> <span class="ow">and</span> <span class="n">d_key</span> <span class="ow">in</span> <span class="n">merged</span><span class="p">:</span>
3997
<a id="__codelineno-0-79" name="__codelineno-0-79"></a> <span class="n">t_entity</span> <span class="o">=</span> <span class="n">merged</span><span class="p">[</span><span class="n">t_key</span><span class="p">]</span>
3998
<a id="__codelineno-0-80" name="__codelineno-0-80"></a> <span class="n">d_entity</span> <span class="o">=</span> <span class="n">merged</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="n">d_key</span><span class="p">)</span>
3999
<a id="__codelineno-0-81" name="__codelineno-0-81"></a> <span class="n">t_entity</span><span class="o">.</span><span class="n">source</span> <span class="o">=</span> <span class="s2">&quot;both&quot;</span>
4000
<a id="__codelineno-0-82" name="__codelineno-0-82"></a> <span class="n">t_entity</span><span class="o">.</span><span class="n">descriptions</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span>
4001
<a id="__codelineno-0-83" name="__codelineno-0-83"></a> <span class="nb">set</span><span class="p">(</span><span class="n">t_entity</span><span class="o">.</span><span class="n">descriptions</span> <span class="o">+</span> <span class="n">d_entity</span><span class="o">.</span><span class="n">descriptions</span><span class="p">)</span>
4002
<a id="__codelineno-0-84" name="__codelineno-0-84"></a> <span class="p">)</span>
4003
<a id="__codelineno-0-85" name="__codelineno-0-85"></a> <span class="n">t_entity</span><span class="o">.</span><span class="n">occurrences</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">d_entity</span><span class="o">.</span><span class="n">occurrences</span><span class="p">)</span>
4004
<a id="__codelineno-0-86" name="__codelineno-0-86"></a>
4005
<a id="__codelineno-0-87" name="__codelineno-0-87"></a> <span class="k">return</span> <span class="nb">list</span><span class="p">(</span><span class="n">merged</span><span class="o">.</span><span class="n">values</span><span class="p">())</span>
4006
</code></pre></div></td></tr></table></div>
4007
</details>
4008
</div>
4009
4010
</div>
4011
4012
<div class="doc doc-object doc-function">
4013
4014
4015
<h4 id="video_processor.analyzers.content_analyzer.ContentAnalyzer.enrich_key_points" class="doc doc-heading">
4016
<code class="highlight language-python"><span class="n">enrich_key_points</span><span class="p">(</span><span class="n">key_points</span><span class="p">,</span> <span class="n">diagrams</span><span class="p">,</span> <span class="n">transcript_text</span><span class="p">)</span></code>
4017
4018
<a href="#video_processor.analyzers.content_analyzer.ContentAnalyzer.enrich_key_points" class="headerlink" title="Permanent link">&para;</a></h4>
4019
4020
4021
<div class="doc doc-contents ">
4022
4023
<p>Link key points to relevant diagrams by entity overlap and temporal proximity.</p>
4024
4025
4026
<details class="mkdocstrings-source">
4027
<summary>Source code in <code>video_processor/analyzers/content_analyzer.py</code></summary>
4028
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-125">125</a></span>
4029
<span class="normal"><a href="#__codelineno-0-126">126</a></span>
4030
<span class="normal"><a href="#__codelineno-0-127">127</a></span>
4031
<span class="normal"><a href="#__codelineno-0-128">128</a></span>
4032
<span class="normal"><a href="#__codelineno-0-129">129</a></span>
4033
<span class="normal"><a href="#__codelineno-0-130">130</a></span>
4034
<span class="normal"><a href="#__codelineno-0-131">131</a></span>
4035
<span class="normal"><a href="#__codelineno-0-132">132</a></span>
4036
<span class="normal"><a href="#__codelineno-0-133">133</a></span>
4037
<span class="normal"><a href="#__codelineno-0-134">134</a></span>
4038
<span class="normal"><a href="#__codelineno-0-135">135</a></span>
4039
<span class="normal"><a href="#__codelineno-0-136">136</a></span>
4040
<span class="normal"><a href="#__codelineno-0-137">137</a></span>
4041
<span class="normal"><a href="#__codelineno-0-138">138</a></span>
4042
<span class="normal"><a href="#__codelineno-0-139">139</a></span>
4043
<span class="normal"><a href="#__codelineno-0-140">140</a></span>
4044
<span class="normal"><a href="#__codelineno-0-141">141</a></span>
4045
<span class="normal"><a href="#__codelineno-0-142">142</a></span>
4046
<span class="normal"><a href="#__codelineno-0-143">143</a></span>
4047
<span class="normal"><a href="#__codelineno-0-144">144</a></span>
4048
<span class="normal"><a href="#__codelineno-0-145">145</a></span>
4049
<span class="normal"><a href="#__codelineno-0-146">146</a></span>
4050
<span class="normal"><a href="#__codelineno-0-147">147</a></span>
4051
<span class="normal"><a href="#__codelineno-0-148">148</a></span>
4052
<span class="normal"><a href="#__codelineno-0-149">149</a></span>
4053
<span class="normal"><a href="#__codelineno-0-150">150</a></span>
4054
<span class="normal"><a href="#__codelineno-0-151">151</a></span>
4055
<span class="normal"><a href="#__codelineno-0-152">152</a></span>
4056
<span class="normal"><a href="#__codelineno-0-153">153</a></span>
4057
<span class="normal"><a href="#__codelineno-0-154">154</a></span>
4058
<span class="normal"><a href="#__codelineno-0-155">155</a></span>
4059
<span class="normal"><a href="#__codelineno-0-156">156</a></span>
4060
<span class="normal"><a href="#__codelineno-0-157">157</a></span>
4061
<span class="normal"><a href="#__codelineno-0-158">158</a></span>
4062
<span class="normal"><a href="#__codelineno-0-159">159</a></span>
4063
<span class="normal"><a href="#__codelineno-0-160">160</a></span>
4064
<span class="normal"><a href="#__codelineno-0-161">161</a></span>
4065
<span class="normal"><a href="#__codelineno-0-162">162</a></span>
4066
<span class="normal"><a href="#__codelineno-0-163">163</a></span>
4067
<span class="normal"><a href="#__codelineno-0-164">164</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-125" name="__codelineno-0-125"></a><span class="k">def</span><span class="w"> </span><span class="nf">enrich_key_points</span><span class="p">(</span>
4068
<a id="__codelineno-0-126" name="__codelineno-0-126"></a> <span class="bp">self</span><span class="p">,</span>
4069
<a id="__codelineno-0-127" name="__codelineno-0-127"></a> <span class="n">key_points</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="n">KeyPoint</span><span class="p">],</span>
4070
<a id="__codelineno-0-128" name="__codelineno-0-128"></a> <span class="n">diagrams</span><span class="p">:</span> <span class="nb">list</span><span class="p">,</span>
4071
<a id="__codelineno-0-129" name="__codelineno-0-129"></a> <span class="n">transcript_text</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
4072
<a id="__codelineno-0-130" name="__codelineno-0-130"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">List</span><span class="p">[</span><span class="n">KeyPoint</span><span class="p">]:</span>
4073
<a id="__codelineno-0-131" name="__codelineno-0-131"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
4074
<a id="__codelineno-0-132" name="__codelineno-0-132"></a><span class="sd"> Link key points to relevant diagrams by entity overlap and temporal proximity.</span>
4075
<a id="__codelineno-0-133" name="__codelineno-0-133"></a><span class="sd"> &quot;&quot;&quot;</span>
4076
<a id="__codelineno-0-134" name="__codelineno-0-134"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">diagrams</span><span class="p">:</span>
4077
<a id="__codelineno-0-135" name="__codelineno-0-135"></a> <span class="k">return</span> <span class="n">key_points</span>
4078
<a id="__codelineno-0-136" name="__codelineno-0-136"></a>
4079
<a id="__codelineno-0-137" name="__codelineno-0-137"></a> <span class="c1"># Build diagram entity index</span>
4080
<a id="__codelineno-0-138" name="__codelineno-0-138"></a> <span class="n">diagram_entities</span><span class="p">:</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">int</span><span class="p">,</span> <span class="nb">set</span><span class="p">[</span><span class="nb">str</span><span class="p">]]</span> <span class="o">=</span> <span class="p">{}</span>
4081
<a id="__codelineno-0-139" name="__codelineno-0-139"></a> <span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">d</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">diagrams</span><span class="p">):</span>
4082
<a id="__codelineno-0-140" name="__codelineno-0-140"></a> <span class="n">elements</span> <span class="o">=</span> <span class="n">d</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;elements&quot;</span><span class="p">,</span> <span class="p">[])</span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">d</span><span class="p">,</span> <span class="nb">dict</span><span class="p">)</span> <span class="k">else</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">d</span><span class="p">,</span> <span class="s2">&quot;elements&quot;</span><span class="p">,</span> <span class="p">[])</span>
4083
<a id="__codelineno-0-141" name="__codelineno-0-141"></a> <span class="n">text</span> <span class="o">=</span> <span class="p">(</span>
4084
<a id="__codelineno-0-142" name="__codelineno-0-142"></a> <span class="n">d</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;text_content&quot;</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">)</span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">d</span><span class="p">,</span> <span class="nb">dict</span><span class="p">)</span> <span class="k">else</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">d</span><span class="p">,</span> <span class="s2">&quot;text_content&quot;</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">)</span>
4085
<a id="__codelineno-0-143" name="__codelineno-0-143"></a> <span class="p">)</span>
4086
<a id="__codelineno-0-144" name="__codelineno-0-144"></a> <span class="n">entities</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">)</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="k">for</span> <span class="n">e</span> <span class="ow">in</span> <span class="n">elements</span><span class="p">)</span>
4087
<a id="__codelineno-0-145" name="__codelineno-0-145"></a> <span class="k">if</span> <span class="n">text</span><span class="p">:</span>
4088
<a id="__codelineno-0-146" name="__codelineno-0-146"></a> <span class="n">entities</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">word</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="k">for</span> <span class="n">word</span> <span class="ow">in</span> <span class="n">text</span><span class="o">.</span><span class="n">split</span><span class="p">()</span> <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">word</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">3</span><span class="p">)</span>
4089
<a id="__codelineno-0-147" name="__codelineno-0-147"></a> <span class="n">diagram_entities</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">entities</span>
4090
<a id="__codelineno-0-148" name="__codelineno-0-148"></a>
4091
<a id="__codelineno-0-149" name="__codelineno-0-149"></a> <span class="c1"># Match key points to diagrams</span>
4092
<a id="__codelineno-0-150" name="__codelineno-0-150"></a> <span class="k">for</span> <span class="n">kp</span> <span class="ow">in</span> <span class="n">key_points</span><span class="p">:</span>
4093
<a id="__codelineno-0-151" name="__codelineno-0-151"></a> <span class="n">kp_words</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">kp</span><span class="o">.</span><span class="n">point</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span><span class="o">.</span><span class="n">split</span><span class="p">())</span>
4094
<a id="__codelineno-0-152" name="__codelineno-0-152"></a> <span class="k">if</span> <span class="n">kp</span><span class="o">.</span><span class="n">details</span><span class="p">:</span>
4095
<a id="__codelineno-0-153" name="__codelineno-0-153"></a> <span class="n">kp_words</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">kp</span><span class="o">.</span><span class="n">details</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span><span class="o">.</span><span class="n">split</span><span class="p">())</span>
4096
<a id="__codelineno-0-154" name="__codelineno-0-154"></a>
4097
<a id="__codelineno-0-155" name="__codelineno-0-155"></a> <span class="n">related</span> <span class="o">=</span> <span class="p">[]</span>
4098
<a id="__codelineno-0-156" name="__codelineno-0-156"></a> <span class="k">for</span> <span class="n">idx</span><span class="p">,</span> <span class="n">d_entities</span> <span class="ow">in</span> <span class="n">diagram_entities</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
4099
<a id="__codelineno-0-157" name="__codelineno-0-157"></a> <span class="n">overlap</span> <span class="o">=</span> <span class="n">kp_words</span> <span class="o">&amp;</span> <span class="n">d_entities</span>
4100
<a id="__codelineno-0-158" name="__codelineno-0-158"></a> <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">overlap</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="mi">2</span><span class="p">:</span>
4101
<a id="__codelineno-0-159" name="__codelineno-0-159"></a> <span class="n">related</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">idx</span><span class="p">)</span>
4102
<a id="__codelineno-0-160" name="__codelineno-0-160"></a>
4103
<a id="__codelineno-0-161" name="__codelineno-0-161"></a> <span class="k">if</span> <span class="n">related</span><span class="p">:</span>
4104
<a id="__codelineno-0-162" name="__codelineno-0-162"></a> <span class="n">kp</span><span class="o">.</span><span class="n">related_diagrams</span> <span class="o">=</span> <span class="n">related</span>
4105
<a id="__codelineno-0-163" name="__codelineno-0-163"></a>
4106
<a id="__codelineno-0-164" name="__codelineno-0-164"></a> <span class="k">return</span> <span class="n">key_points</span>
4107
</code></pre></div></td></tr></table></div>
4108
</details>
4109
</div>
4110
4111
</div>
4112
4113
4114
4115
</div>
4116
4117
</div>
4118
4119
</div>
4120
4121
4122
4123
4124
</div>
4125
4126
</div>
4127
4128
</div>
4129
4130
<div class="doc doc-object doc-module">
4131
4132
4133
4134
<h2 id="video_processor.analyzers.action_detector" class="doc doc-heading">
4135
<code>video_processor.analyzers.action_detector</code>
4136
4137
4138
<a href="#video_processor.analyzers.action_detector" class="headerlink" title="Permanent link">&para;</a></h2>
4139
4140
<div class="doc doc-contents first">
4141
4142
<p>Enhanced action item detection from transcripts and diagrams.</p>
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
<div class="doc doc-children">
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
<div class="doc doc-object doc-class">
4164
4165
4166
4167
<h3 id="video_processor.analyzers.action_detector.ActionDetector" class="doc doc-heading">
4168
<code>ActionDetector</code>
4169
4170
4171
<a href="#video_processor.analyzers.action_detector.ActionDetector" class="headerlink" title="Permanent link">&para;</a></h3>
4172
4173
4174
<div class="doc doc-contents ">
4175
4176
4177
4178
<p>Detects action items from transcripts using heuristics and LLM.</p>
4179
4180
4181
4182
4183
4184
4185
4186
4187
<details class="mkdocstrings-source">
4188
<summary>Source code in <code>video_processor/analyzers/action_detector.py</code></summary>
4189
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-27"> 27</a></span>
4190
<span class="normal"><a href="#__codelineno-0-28"> 28</a></span>
4191
<span class="normal"><a href="#__codelineno-0-29"> 29</a></span>
4192
<span class="normal"><a href="#__codelineno-0-30"> 30</a></span>
4193
<span class="normal"><a href="#__codelineno-0-31"> 31</a></span>
4194
<span class="normal"><a href="#__codelineno-0-32"> 32</a></span>
4195
<span class="normal"><a href="#__codelineno-0-33"> 33</a></span>
4196
<span class="normal"><a href="#__codelineno-0-34"> 34</a></span>
4197
<span class="normal"><a href="#__codelineno-0-35"> 35</a></span>
4198
<span class="normal"><a href="#__codelineno-0-36"> 36</a></span>
4199
<span class="normal"><a href="#__codelineno-0-37"> 37</a></span>
4200
<span class="normal"><a href="#__codelineno-0-38"> 38</a></span>
4201
<span class="normal"><a href="#__codelineno-0-39"> 39</a></span>
4202
<span class="normal"><a href="#__codelineno-0-40"> 40</a></span>
4203
<span class="normal"><a href="#__codelineno-0-41"> 41</a></span>
4204
<span class="normal"><a href="#__codelineno-0-42"> 42</a></span>
4205
<span class="normal"><a href="#__codelineno-0-43"> 43</a></span>
4206
<span class="normal"><a href="#__codelineno-0-44"> 44</a></span>
4207
<span class="normal"><a href="#__codelineno-0-45"> 45</a></span>
4208
<span class="normal"><a href="#__codelineno-0-46"> 46</a></span>
4209
<span class="normal"><a href="#__codelineno-0-47"> 47</a></span>
4210
<span class="normal"><a href="#__codelineno-0-48"> 48</a></span>
4211
<span class="normal"><a href="#__codelineno-0-49"> 49</a></span>
4212
<span class="normal"><a href="#__codelineno-0-50"> 50</a></span>
4213
<span class="normal"><a href="#__codelineno-0-51"> 51</a></span>
4214
<span class="normal"><a href="#__codelineno-0-52"> 52</a></span>
4215
<span class="normal"><a href="#__codelineno-0-53"> 53</a></span>
4216
<span class="normal"><a href="#__codelineno-0-54"> 54</a></span>
4217
<span class="normal"><a href="#__codelineno-0-55"> 55</a></span>
4218
<span class="normal"><a href="#__codelineno-0-56"> 56</a></span>
4219
<span class="normal"><a href="#__codelineno-0-57"> 57</a></span>
4220
<span class="normal"><a href="#__codelineno-0-58"> 58</a></span>
4221
<span class="normal"><a href="#__codelineno-0-59"> 59</a></span>
4222
<span class="normal"><a href="#__codelineno-0-60"> 60</a></span>
4223
<span class="normal"><a href="#__codelineno-0-61"> 61</a></span>
4224
<span class="normal"><a href="#__codelineno-0-62"> 62</a></span>
4225
<span class="normal"><a href="#__codelineno-0-63"> 63</a></span>
4226
<span class="normal"><a href="#__codelineno-0-64"> 64</a></span>
4227
<span class="normal"><a href="#__codelineno-0-65"> 65</a></span>
4228
<span class="normal"><a href="#__codelineno-0-66"> 66</a></span>
4229
<span class="normal"><a href="#__codelineno-0-67"> 67</a></span>
4230
<span class="normal"><a href="#__codelineno-0-68"> 68</a></span>
4231
<span class="normal"><a href="#__codelineno-0-69"> 69</a></span>
4232
<span class="normal"><a href="#__codelineno-0-70"> 70</a></span>
4233
<span class="normal"><a href="#__codelineno-0-71"> 71</a></span>
4234
<span class="normal"><a href="#__codelineno-0-72"> 72</a></span>
4235
<span class="normal"><a href="#__codelineno-0-73"> 73</a></span>
4236
<span class="normal"><a href="#__codelineno-0-74"> 74</a></span>
4237
<span class="normal"><a href="#__codelineno-0-75"> 75</a></span>
4238
<span class="normal"><a href="#__codelineno-0-76"> 76</a></span>
4239
<span class="normal"><a href="#__codelineno-0-77"> 77</a></span>
4240
<span class="normal"><a href="#__codelineno-0-78"> 78</a></span>
4241
<span class="normal"><a href="#__codelineno-0-79"> 79</a></span>
4242
<span class="normal"><a href="#__codelineno-0-80"> 80</a></span>
4243
<span class="normal"><a href="#__codelineno-0-81"> 81</a></span>
4244
<span class="normal"><a href="#__codelineno-0-82"> 82</a></span>
4245
<span class="normal"><a href="#__codelineno-0-83"> 83</a></span>
4246
<span class="normal"><a href="#__codelineno-0-84"> 84</a></span>
4247
<span class="normal"><a href="#__codelineno-0-85"> 85</a></span>
4248
<span class="normal"><a href="#__codelineno-0-86"> 86</a></span>
4249
<span class="normal"><a href="#__codelineno-0-87"> 87</a></span>
4250
<span class="normal"><a href="#__codelineno-0-88"> 88</a></span>
4251
<span class="normal"><a href="#__codelineno-0-89"> 89</a></span>
4252
<span class="normal"><a href="#__codelineno-0-90"> 90</a></span>
4253
<span class="normal"><a href="#__codelineno-0-91"> 91</a></span>
4254
<span class="normal"><a href="#__codelineno-0-92"> 92</a></span>
4255
<span class="normal"><a href="#__codelineno-0-93"> 93</a></span>
4256
<span class="normal"><a href="#__codelineno-0-94"> 94</a></span>
4257
<span class="normal"><a href="#__codelineno-0-95"> 95</a></span>
4258
<span class="normal"><a href="#__codelineno-0-96"> 96</a></span>
4259
<span class="normal"><a href="#__codelineno-0-97"> 97</a></span>
4260
<span class="normal"><a href="#__codelineno-0-98"> 98</a></span>
4261
<span class="normal"><a href="#__codelineno-0-99"> 99</a></span>
4262
<span class="normal"><a href="#__codelineno-0-100">100</a></span>
4263
<span class="normal"><a href="#__codelineno-0-101">101</a></span>
4264
<span class="normal"><a href="#__codelineno-0-102">102</a></span>
4265
<span class="normal"><a href="#__codelineno-0-103">103</a></span>
4266
<span class="normal"><a href="#__codelineno-0-104">104</a></span>
4267
<span class="normal"><a href="#__codelineno-0-105">105</a></span>
4268
<span class="normal"><a href="#__codelineno-0-106">106</a></span>
4269
<span class="normal"><a href="#__codelineno-0-107">107</a></span>
4270
<span class="normal"><a href="#__codelineno-0-108">108</a></span>
4271
<span class="normal"><a href="#__codelineno-0-109">109</a></span>
4272
<span class="normal"><a href="#__codelineno-0-110">110</a></span>
4273
<span class="normal"><a href="#__codelineno-0-111">111</a></span>
4274
<span class="normal"><a href="#__codelineno-0-112">112</a></span>
4275
<span class="normal"><a href="#__codelineno-0-113">113</a></span>
4276
<span class="normal"><a href="#__codelineno-0-114">114</a></span>
4277
<span class="normal"><a href="#__codelineno-0-115">115</a></span>
4278
<span class="normal"><a href="#__codelineno-0-116">116</a></span>
4279
<span class="normal"><a href="#__codelineno-0-117">117</a></span>
4280
<span class="normal"><a href="#__codelineno-0-118">118</a></span>
4281
<span class="normal"><a href="#__codelineno-0-119">119</a></span>
4282
<span class="normal"><a href="#__codelineno-0-120">120</a></span>
4283
<span class="normal"><a href="#__codelineno-0-121">121</a></span>
4284
<span class="normal"><a href="#__codelineno-0-122">122</a></span>
4285
<span class="normal"><a href="#__codelineno-0-123">123</a></span>
4286
<span class="normal"><a href="#__codelineno-0-124">124</a></span>
4287
<span class="normal"><a href="#__codelineno-0-125">125</a></span>
4288
<span class="normal"><a href="#__codelineno-0-126">126</a></span>
4289
<span class="normal"><a href="#__codelineno-0-127">127</a></span>
4290
<span class="normal"><a href="#__codelineno-0-128">128</a></span>
4291
<span class="normal"><a href="#__codelineno-0-129">129</a></span>
4292
<span class="normal"><a href="#__codelineno-0-130">130</a></span>
4293
<span class="normal"><a href="#__codelineno-0-131">131</a></span>
4294
<span class="normal"><a href="#__codelineno-0-132">132</a></span>
4295
<span class="normal"><a href="#__codelineno-0-133">133</a></span>
4296
<span class="normal"><a href="#__codelineno-0-134">134</a></span>
4297
<span class="normal"><a href="#__codelineno-0-135">135</a></span>
4298
<span class="normal"><a href="#__codelineno-0-136">136</a></span>
4299
<span class="normal"><a href="#__codelineno-0-137">137</a></span>
4300
<span class="normal"><a href="#__codelineno-0-138">138</a></span>
4301
<span class="normal"><a href="#__codelineno-0-139">139</a></span>
4302
<span class="normal"><a href="#__codelineno-0-140">140</a></span>
4303
<span class="normal"><a href="#__codelineno-0-141">141</a></span>
4304
<span class="normal"><a href="#__codelineno-0-142">142</a></span>
4305
<span class="normal"><a href="#__codelineno-0-143">143</a></span>
4306
<span class="normal"><a href="#__codelineno-0-144">144</a></span>
4307
<span class="normal"><a href="#__codelineno-0-145">145</a></span>
4308
<span class="normal"><a href="#__codelineno-0-146">146</a></span>
4309
<span class="normal"><a href="#__codelineno-0-147">147</a></span>
4310
<span class="normal"><a href="#__codelineno-0-148">148</a></span>
4311
<span class="normal"><a href="#__codelineno-0-149">149</a></span>
4312
<span class="normal"><a href="#__codelineno-0-150">150</a></span>
4313
<span class="normal"><a href="#__codelineno-0-151">151</a></span>
4314
<span class="normal"><a href="#__codelineno-0-152">152</a></span>
4315
<span class="normal"><a href="#__codelineno-0-153">153</a></span>
4316
<span class="normal"><a href="#__codelineno-0-154">154</a></span>
4317
<span class="normal"><a href="#__codelineno-0-155">155</a></span>
4318
<span class="normal"><a href="#__codelineno-0-156">156</a></span>
4319
<span class="normal"><a href="#__codelineno-0-157">157</a></span>
4320
<span class="normal"><a href="#__codelineno-0-158">158</a></span>
4321
<span class="normal"><a href="#__codelineno-0-159">159</a></span>
4322
<span class="normal"><a href="#__codelineno-0-160">160</a></span>
4323
<span class="normal"><a href="#__codelineno-0-161">161</a></span>
4324
<span class="normal"><a href="#__codelineno-0-162">162</a></span>
4325
<span class="normal"><a href="#__codelineno-0-163">163</a></span>
4326
<span class="normal"><a href="#__codelineno-0-164">164</a></span>
4327
<span class="normal"><a href="#__codelineno-0-165">165</a></span>
4328
<span class="normal"><a href="#__codelineno-0-166">166</a></span>
4329
<span class="normal"><a href="#__codelineno-0-167">167</a></span>
4330
<span class="normal"><a href="#__codelineno-0-168">168</a></span>
4331
<span class="normal"><a href="#__codelineno-0-169">169</a></span>
4332
<span class="normal"><a href="#__codelineno-0-170">170</a></span>
4333
<span class="normal"><a href="#__codelineno-0-171">171</a></span>
4334
<span class="normal"><a href="#__codelineno-0-172">172</a></span>
4335
<span class="normal"><a href="#__codelineno-0-173">173</a></span>
4336
<span class="normal"><a href="#__codelineno-0-174">174</a></span>
4337
<span class="normal"><a href="#__codelineno-0-175">175</a></span>
4338
<span class="normal"><a href="#__codelineno-0-176">176</a></span>
4339
<span class="normal"><a href="#__codelineno-0-177">177</a></span>
4340
<span class="normal"><a href="#__codelineno-0-178">178</a></span>
4341
<span class="normal"><a href="#__codelineno-0-179">179</a></span>
4342
<span class="normal"><a href="#__codelineno-0-180">180</a></span>
4343
<span class="normal"><a href="#__codelineno-0-181">181</a></span>
4344
<span class="normal"><a href="#__codelineno-0-182">182</a></span>
4345
<span class="normal"><a href="#__codelineno-0-183">183</a></span>
4346
<span class="normal"><a href="#__codelineno-0-184">184</a></span>
4347
<span class="normal"><a href="#__codelineno-0-185">185</a></span>
4348
<span class="normal"><a href="#__codelineno-0-186">186</a></span>
4349
<span class="normal"><a href="#__codelineno-0-187">187</a></span>
4350
<span class="normal"><a href="#__codelineno-0-188">188</a></span>
4351
<span class="normal"><a href="#__codelineno-0-189">189</a></span>
4352
<span class="normal"><a href="#__codelineno-0-190">190</a></span>
4353
<span class="normal"><a href="#__codelineno-0-191">191</a></span>
4354
<span class="normal"><a href="#__codelineno-0-192">192</a></span>
4355
<span class="normal"><a href="#__codelineno-0-193">193</a></span>
4356
<span class="normal"><a href="#__codelineno-0-194">194</a></span>
4357
<span class="normal"><a href="#__codelineno-0-195">195</a></span>
4358
<span class="normal"><a href="#__codelineno-0-196">196</a></span>
4359
<span class="normal"><a href="#__codelineno-0-197">197</a></span>
4360
<span class="normal"><a href="#__codelineno-0-198">198</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-27" name="__codelineno-0-27"></a><span class="k">class</span><span class="w"> </span><span class="nc">ActionDetector</span><span class="p">:</span>
4361
<a id="__codelineno-0-28" name="__codelineno-0-28"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Detects action items from transcripts using heuristics and LLM.&quot;&quot;&quot;</span>
4362
<a id="__codelineno-0-29" name="__codelineno-0-29"></a>
4363
<a id="__codelineno-0-30" name="__codelineno-0-30"></a> <span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">provider_manager</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">ProviderManager</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">):</span>
4364
<a id="__codelineno-0-31" name="__codelineno-0-31"></a> <span class="bp">self</span><span class="o">.</span><span class="n">pm</span> <span class="o">=</span> <span class="n">provider_manager</span>
4365
<a id="__codelineno-0-32" name="__codelineno-0-32"></a>
4366
<a id="__codelineno-0-33" name="__codelineno-0-33"></a> <span class="k">def</span><span class="w"> </span><span class="nf">detect_from_transcript</span><span class="p">(</span>
4367
<a id="__codelineno-0-34" name="__codelineno-0-34"></a> <span class="bp">self</span><span class="p">,</span>
4368
<a id="__codelineno-0-35" name="__codelineno-0-35"></a> <span class="n">text</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
4369
<a id="__codelineno-0-36" name="__codelineno-0-36"></a> <span class="n">segments</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">List</span><span class="p">[</span><span class="n">TranscriptSegment</span><span class="p">]]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
4370
<a id="__codelineno-0-37" name="__codelineno-0-37"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="n">List</span><span class="p">[</span><span class="n">ActionItem</span><span class="p">]:</span>
4371
<a id="__codelineno-0-38" name="__codelineno-0-38"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
4372
<a id="__codelineno-0-39" name="__codelineno-0-39"></a><span class="sd"> Detect action items from transcript text.</span>
4373
<a id="__codelineno-0-40" name="__codelineno-0-40"></a>
4374
<a id="__codelineno-0-41" name="__codelineno-0-41"></a><span class="sd"> Uses LLM extraction when available, falls back to pattern matching.</span>
4375
<a id="__codelineno-0-42" name="__codelineno-0-42"></a><span class="sd"> Segments are used to attach timestamps.</span>
4376
<a id="__codelineno-0-43" name="__codelineno-0-43"></a><span class="sd"> &quot;&quot;&quot;</span>
4377
<a id="__codelineno-0-44" name="__codelineno-0-44"></a> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">pm</span><span class="p">:</span>
4378
<a id="__codelineno-0-45" name="__codelineno-0-45"></a> <span class="n">items</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_llm_extract</span><span class="p">(</span><span class="n">text</span><span class="p">)</span>
4379
<a id="__codelineno-0-46" name="__codelineno-0-46"></a> <span class="k">else</span><span class="p">:</span>
4380
<a id="__codelineno-0-47" name="__codelineno-0-47"></a> <span class="n">items</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_pattern_extract</span><span class="p">(</span><span class="n">text</span><span class="p">)</span>
4381
<a id="__codelineno-0-48" name="__codelineno-0-48"></a>
4382
<a id="__codelineno-0-49" name="__codelineno-0-49"></a> <span class="c1"># Attach timestamps from segments if available</span>
4383
<a id="__codelineno-0-50" name="__codelineno-0-50"></a> <span class="k">if</span> <span class="n">segments</span> <span class="ow">and</span> <span class="n">items</span><span class="p">:</span>
4384
<a id="__codelineno-0-51" name="__codelineno-0-51"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_attach_timestamps</span><span class="p">(</span><span class="n">items</span><span class="p">,</span> <span class="n">segments</span><span class="p">)</span>
4385
<a id="__codelineno-0-52" name="__codelineno-0-52"></a>
4386
<a id="__codelineno-0-53" name="__codelineno-0-53"></a> <span class="k">return</span> <span class="n">items</span>
4387
<a id="__codelineno-0-54" name="__codelineno-0-54"></a>
4388
<a id="__codelineno-0-55" name="__codelineno-0-55"></a> <span class="k">def</span><span class="w"> </span><span class="nf">detect_from_diagrams</span><span class="p">(</span>
4389
<a id="__codelineno-0-56" name="__codelineno-0-56"></a> <span class="bp">self</span><span class="p">,</span>
4390
<a id="__codelineno-0-57" name="__codelineno-0-57"></a> <span class="n">diagrams</span><span class="p">:</span> <span class="nb">list</span><span class="p">,</span>
4391
<a id="__codelineno-0-58" name="__codelineno-0-58"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="n">List</span><span class="p">[</span><span class="n">ActionItem</span><span class="p">]:</span>
4392
<a id="__codelineno-0-59" name="__codelineno-0-59"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
4393
<a id="__codelineno-0-60" name="__codelineno-0-60"></a><span class="sd"> Extract action items mentioned in diagram text content.</span>
4394
<a id="__codelineno-0-61" name="__codelineno-0-61"></a>
4395
<a id="__codelineno-0-62" name="__codelineno-0-62"></a><span class="sd"> Looks for action-oriented language in diagram text/elements.</span>
4396
<a id="__codelineno-0-63" name="__codelineno-0-63"></a><span class="sd"> &quot;&quot;&quot;</span>
4397
<a id="__codelineno-0-64" name="__codelineno-0-64"></a> <span class="n">items</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="n">ActionItem</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span>
4398
<a id="__codelineno-0-65" name="__codelineno-0-65"></a>
4399
<a id="__codelineno-0-66" name="__codelineno-0-66"></a> <span class="k">for</span> <span class="n">diagram</span> <span class="ow">in</span> <span class="n">diagrams</span><span class="p">:</span>
4400
<a id="__codelineno-0-67" name="__codelineno-0-67"></a> <span class="n">text</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
4401
<a id="__codelineno-0-68" name="__codelineno-0-68"></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">diagram</span><span class="p">,</span> <span class="nb">dict</span><span class="p">):</span>
4402
<a id="__codelineno-0-69" name="__codelineno-0-69"></a> <span class="n">text</span> <span class="o">=</span> <span class="n">diagram</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;text_content&quot;</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">)</span> <span class="ow">or</span> <span class="s2">&quot;&quot;</span>
4403
<a id="__codelineno-0-70" name="__codelineno-0-70"></a> <span class="n">elements</span> <span class="o">=</span> <span class="n">diagram</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;elements&quot;</span><span class="p">,</span> <span class="p">[])</span>
4404
<a id="__codelineno-0-71" name="__codelineno-0-71"></a> <span class="k">else</span><span class="p">:</span>
4405
<a id="__codelineno-0-72" name="__codelineno-0-72"></a> <span class="n">text</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">diagram</span><span class="p">,</span> <span class="s2">&quot;text_content&quot;</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">)</span> <span class="ow">or</span> <span class="s2">&quot;&quot;</span>
4406
<a id="__codelineno-0-73" name="__codelineno-0-73"></a> <span class="n">elements</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">diagram</span><span class="p">,</span> <span class="s2">&quot;elements&quot;</span><span class="p">,</span> <span class="p">[])</span>
4407
<a id="__codelineno-0-74" name="__codelineno-0-74"></a>
4408
<a id="__codelineno-0-75" name="__codelineno-0-75"></a> <span class="n">combined</span> <span class="o">=</span> <span class="n">text</span> <span class="o">+</span> <span class="s2">&quot; &quot;</span> <span class="o">+</span> <span class="s2">&quot; &quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">)</span> <span class="k">for</span> <span class="n">e</span> <span class="ow">in</span> <span class="n">elements</span><span class="p">)</span>
4409
<a id="__codelineno-0-76" name="__codelineno-0-76"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">combined</span><span class="o">.</span><span class="n">strip</span><span class="p">():</span>
4410
<a id="__codelineno-0-77" name="__codelineno-0-77"></a> <span class="k">continue</span>
4411
<a id="__codelineno-0-78" name="__codelineno-0-78"></a>
4412
<a id="__codelineno-0-79" name="__codelineno-0-79"></a> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">pm</span><span class="p">:</span>
4413
<a id="__codelineno-0-80" name="__codelineno-0-80"></a> <span class="n">diagram_items</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_llm_extract</span><span class="p">(</span><span class="n">combined</span><span class="p">)</span>
4414
<a id="__codelineno-0-81" name="__codelineno-0-81"></a> <span class="k">else</span><span class="p">:</span>
4415
<a id="__codelineno-0-82" name="__codelineno-0-82"></a> <span class="n">diagram_items</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_pattern_extract</span><span class="p">(</span><span class="n">combined</span><span class="p">)</span>
4416
<a id="__codelineno-0-83" name="__codelineno-0-83"></a>
4417
<a id="__codelineno-0-84" name="__codelineno-0-84"></a> <span class="k">for</span> <span class="n">item</span> <span class="ow">in</span> <span class="n">diagram_items</span><span class="p">:</span>
4418
<a id="__codelineno-0-85" name="__codelineno-0-85"></a> <span class="n">item</span><span class="o">.</span><span class="n">source</span> <span class="o">=</span> <span class="s2">&quot;diagram&quot;</span>
4419
<a id="__codelineno-0-86" name="__codelineno-0-86"></a> <span class="n">items</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">diagram_items</span><span class="p">)</span>
4420
<a id="__codelineno-0-87" name="__codelineno-0-87"></a>
4421
<a id="__codelineno-0-88" name="__codelineno-0-88"></a> <span class="k">return</span> <span class="n">items</span>
4422
<a id="__codelineno-0-89" name="__codelineno-0-89"></a>
4423
<a id="__codelineno-0-90" name="__codelineno-0-90"></a> <span class="k">def</span><span class="w"> </span><span class="nf">merge_action_items</span><span class="p">(</span>
4424
<a id="__codelineno-0-91" name="__codelineno-0-91"></a> <span class="bp">self</span><span class="p">,</span>
4425
<a id="__codelineno-0-92" name="__codelineno-0-92"></a> <span class="n">transcript_items</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="n">ActionItem</span><span class="p">],</span>
4426
<a id="__codelineno-0-93" name="__codelineno-0-93"></a> <span class="n">diagram_items</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="n">ActionItem</span><span class="p">],</span>
4427
<a id="__codelineno-0-94" name="__codelineno-0-94"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="n">List</span><span class="p">[</span><span class="n">ActionItem</span><span class="p">]:</span>
4428
<a id="__codelineno-0-95" name="__codelineno-0-95"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
4429
<a id="__codelineno-0-96" name="__codelineno-0-96"></a><span class="sd"> Merge action items from transcript and diagram sources.</span>
4430
<a id="__codelineno-0-97" name="__codelineno-0-97"></a>
4431
<a id="__codelineno-0-98" name="__codelineno-0-98"></a><span class="sd"> Deduplicates by checking for similar action text.</span>
4432
<a id="__codelineno-0-99" name="__codelineno-0-99"></a><span class="sd"> &quot;&quot;&quot;</span>
4433
<a id="__codelineno-0-100" name="__codelineno-0-100"></a> <span class="n">merged</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="n">ActionItem</span><span class="p">]</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">transcript_items</span><span class="p">)</span>
4434
<a id="__codelineno-0-101" name="__codelineno-0-101"></a> <span class="n">existing_actions</span> <span class="o">=</span> <span class="p">{</span><span class="n">a</span><span class="o">.</span><span class="n">action</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span> <span class="k">for</span> <span class="n">a</span> <span class="ow">in</span> <span class="n">merged</span><span class="p">}</span>
4435
<a id="__codelineno-0-102" name="__codelineno-0-102"></a>
4436
<a id="__codelineno-0-103" name="__codelineno-0-103"></a> <span class="k">for</span> <span class="n">item</span> <span class="ow">in</span> <span class="n">diagram_items</span><span class="p">:</span>
4437
<a id="__codelineno-0-104" name="__codelineno-0-104"></a> <span class="n">normalized</span> <span class="o">=</span> <span class="n">item</span><span class="o">.</span><span class="n">action</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
4438
<a id="__codelineno-0-105" name="__codelineno-0-105"></a> <span class="k">if</span> <span class="n">normalized</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">existing_actions</span><span class="p">:</span>
4439
<a id="__codelineno-0-106" name="__codelineno-0-106"></a> <span class="n">merged</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">item</span><span class="p">)</span>
4440
<a id="__codelineno-0-107" name="__codelineno-0-107"></a> <span class="n">existing_actions</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">normalized</span><span class="p">)</span>
4441
<a id="__codelineno-0-108" name="__codelineno-0-108"></a>
4442
<a id="__codelineno-0-109" name="__codelineno-0-109"></a> <span class="k">return</span> <span class="n">merged</span>
4443
<a id="__codelineno-0-110" name="__codelineno-0-110"></a>
4444
<a id="__codelineno-0-111" name="__codelineno-0-111"></a> <span class="k">def</span><span class="w"> </span><span class="nf">_llm_extract</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">text</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">List</span><span class="p">[</span><span class="n">ActionItem</span><span class="p">]:</span>
4445
<a id="__codelineno-0-112" name="__codelineno-0-112"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Extract action items using LLM.&quot;&quot;&quot;</span>
4446
<a id="__codelineno-0-113" name="__codelineno-0-113"></a> <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">pm</span><span class="p">:</span>
4447
<a id="__codelineno-0-114" name="__codelineno-0-114"></a> <span class="k">return</span> <span class="p">[]</span>
4448
<a id="__codelineno-0-115" name="__codelineno-0-115"></a>
4449
<a id="__codelineno-0-116" name="__codelineno-0-116"></a> <span class="n">prompt</span> <span class="o">=</span> <span class="p">(</span>
4450
<a id="__codelineno-0-117" name="__codelineno-0-117"></a> <span class="s2">&quot;Extract all action items, tasks, and commitments &quot;</span>
4451
<a id="__codelineno-0-118" name="__codelineno-0-118"></a> <span class="s2">&quot;from the following text.</span><span class="se">\n\n</span><span class="s2">&quot;</span>
4452
<a id="__codelineno-0-119" name="__codelineno-0-119"></a> <span class="sa">f</span><span class="s2">&quot;TEXT:</span><span class="se">\n</span><span class="si">{</span><span class="n">text</span><span class="p">[:</span><span class="mi">8000</span><span class="p">]</span><span class="si">}</span><span class="se">\n\n</span><span class="s2">&quot;</span>
4453
<a id="__codelineno-0-120" name="__codelineno-0-120"></a> <span class="s2">&quot;Return a JSON array:</span><span class="se">\n</span><span class="s2">&quot;</span>
4454
<a id="__codelineno-0-121" name="__codelineno-0-121"></a> <span class="s1">&#39;[{&quot;action&quot;: &quot;...&quot;, &quot;assignee&quot;: &quot;...&quot;, &quot;deadline&quot;: &quot;...&quot;, &#39;</span>
4455
<a id="__codelineno-0-122" name="__codelineno-0-122"></a> <span class="s1">&#39;&quot;priority&quot;: &quot;...&quot;, &quot;context&quot;: &quot;...&quot;}]</span><span class="se">\n\n</span><span class="s1">&#39;</span>
4456
<a id="__codelineno-0-123" name="__codelineno-0-123"></a> <span class="s2">&quot;Only include clear, actionable items. &quot;</span>
4457
<a id="__codelineno-0-124" name="__codelineno-0-124"></a> <span class="s2">&quot;Set fields to null if not mentioned.</span><span class="se">\n</span><span class="s2">&quot;</span>
4458
<a id="__codelineno-0-125" name="__codelineno-0-125"></a> <span class="s2">&quot;Return ONLY the JSON array.&quot;</span>
4459
<a id="__codelineno-0-126" name="__codelineno-0-126"></a> <span class="p">)</span>
4460
<a id="__codelineno-0-127" name="__codelineno-0-127"></a>
4461
<a id="__codelineno-0-128" name="__codelineno-0-128"></a> <span class="k">try</span><span class="p">:</span>
4462
<a id="__codelineno-0-129" name="__codelineno-0-129"></a> <span class="n">raw</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">pm</span><span class="o">.</span><span class="n">chat</span><span class="p">(</span>
4463
<a id="__codelineno-0-130" name="__codelineno-0-130"></a> <span class="p">[{</span><span class="s2">&quot;role&quot;</span><span class="p">:</span> <span class="s2">&quot;user&quot;</span><span class="p">,</span> <span class="s2">&quot;content&quot;</span><span class="p">:</span> <span class="n">prompt</span><span class="p">}],</span>
4464
<a id="__codelineno-0-131" name="__codelineno-0-131"></a> <span class="n">temperature</span><span class="o">=</span><span class="mf">0.3</span><span class="p">,</span>
4465
<a id="__codelineno-0-132" name="__codelineno-0-132"></a> <span class="p">)</span>
4466
<a id="__codelineno-0-133" name="__codelineno-0-133"></a> <span class="n">parsed</span> <span class="o">=</span> <span class="n">parse_json_from_response</span><span class="p">(</span><span class="n">raw</span><span class="p">)</span>
4467
<a id="__codelineno-0-134" name="__codelineno-0-134"></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">parsed</span><span class="p">,</span> <span class="nb">list</span><span class="p">):</span>
4468
<a id="__codelineno-0-135" name="__codelineno-0-135"></a> <span class="k">return</span> <span class="p">[</span>
4469
<a id="__codelineno-0-136" name="__codelineno-0-136"></a> <span class="n">ActionItem</span><span class="p">(</span>
4470
<a id="__codelineno-0-137" name="__codelineno-0-137"></a> <span class="n">action</span><span class="o">=</span><span class="n">item</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;action&quot;</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">),</span>
4471
<a id="__codelineno-0-138" name="__codelineno-0-138"></a> <span class="n">assignee</span><span class="o">=</span><span class="n">item</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;assignee&quot;</span><span class="p">),</span>
4472
<a id="__codelineno-0-139" name="__codelineno-0-139"></a> <span class="n">deadline</span><span class="o">=</span><span class="n">item</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;deadline&quot;</span><span class="p">),</span>
4473
<a id="__codelineno-0-140" name="__codelineno-0-140"></a> <span class="n">priority</span><span class="o">=</span><span class="n">item</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;priority&quot;</span><span class="p">),</span>
4474
<a id="__codelineno-0-141" name="__codelineno-0-141"></a> <span class="n">context</span><span class="o">=</span><span class="n">item</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;context&quot;</span><span class="p">),</span>
4475
<a id="__codelineno-0-142" name="__codelineno-0-142"></a> <span class="n">source</span><span class="o">=</span><span class="s2">&quot;transcript&quot;</span><span class="p">,</span>
4476
<a id="__codelineno-0-143" name="__codelineno-0-143"></a> <span class="p">)</span>
4477
<a id="__codelineno-0-144" name="__codelineno-0-144"></a> <span class="k">for</span> <span class="n">item</span> <span class="ow">in</span> <span class="n">parsed</span>
4478
<a id="__codelineno-0-145" name="__codelineno-0-145"></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">item</span><span class="p">,</span> <span class="nb">dict</span><span class="p">)</span> <span class="ow">and</span> <span class="n">item</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;action&quot;</span><span class="p">)</span>
4479
<a id="__codelineno-0-146" name="__codelineno-0-146"></a> <span class="p">]</span>
4480
<a id="__codelineno-0-147" name="__codelineno-0-147"></a> <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
4481
<a id="__codelineno-0-148" name="__codelineno-0-148"></a> <span class="n">logger</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;LLM action extraction failed: </span><span class="si">{</span><span class="n">e</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
4482
<a id="__codelineno-0-149" name="__codelineno-0-149"></a>
4483
<a id="__codelineno-0-150" name="__codelineno-0-150"></a> <span class="k">return</span> <span class="p">[]</span>
4484
<a id="__codelineno-0-151" name="__codelineno-0-151"></a>
4485
<a id="__codelineno-0-152" name="__codelineno-0-152"></a> <span class="k">def</span><span class="w"> </span><span class="nf">_pattern_extract</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">text</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">List</span><span class="p">[</span><span class="n">ActionItem</span><span class="p">]:</span>
4486
<a id="__codelineno-0-153" name="__codelineno-0-153"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Extract action items using regex pattern matching.&quot;&quot;&quot;</span>
4487
<a id="__codelineno-0-154" name="__codelineno-0-154"></a> <span class="n">items</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="n">ActionItem</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span>
4488
<a id="__codelineno-0-155" name="__codelineno-0-155"></a> <span class="n">sentences</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="sa">r</span><span class="s2">&quot;[.!?]\s+&quot;</span><span class="p">,</span> <span class="n">text</span><span class="p">)</span>
4489
<a id="__codelineno-0-156" name="__codelineno-0-156"></a>
4490
<a id="__codelineno-0-157" name="__codelineno-0-157"></a> <span class="k">for</span> <span class="n">sentence</span> <span class="ow">in</span> <span class="n">sentences</span><span class="p">:</span>
4491
<a id="__codelineno-0-158" name="__codelineno-0-158"></a> <span class="n">sentence</span> <span class="o">=</span> <span class="n">sentence</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
4492
<a id="__codelineno-0-159" name="__codelineno-0-159"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">sentence</span> <span class="ow">or</span> <span class="nb">len</span><span class="p">(</span><span class="n">sentence</span><span class="p">)</span> <span class="o">&lt;</span> <span class="mi">10</span><span class="p">:</span>
4493
<a id="__codelineno-0-160" name="__codelineno-0-160"></a> <span class="k">continue</span>
4494
<a id="__codelineno-0-161" name="__codelineno-0-161"></a>
4495
<a id="__codelineno-0-162" name="__codelineno-0-162"></a> <span class="k">for</span> <span class="n">pattern</span> <span class="ow">in</span> <span class="n">_ACTION_PATTERNS</span><span class="p">:</span>
4496
<a id="__codelineno-0-163" name="__codelineno-0-163"></a> <span class="k">if</span> <span class="n">pattern</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="n">sentence</span><span class="p">):</span>
4497
<a id="__codelineno-0-164" name="__codelineno-0-164"></a> <span class="n">items</span><span class="o">.</span><span class="n">append</span><span class="p">(</span>
4498
<a id="__codelineno-0-165" name="__codelineno-0-165"></a> <span class="n">ActionItem</span><span class="p">(</span>
4499
<a id="__codelineno-0-166" name="__codelineno-0-166"></a> <span class="n">action</span><span class="o">=</span><span class="n">sentence</span><span class="p">,</span>
4500
<a id="__codelineno-0-167" name="__codelineno-0-167"></a> <span class="n">source</span><span class="o">=</span><span class="s2">&quot;transcript&quot;</span><span class="p">,</span>
4501
<a id="__codelineno-0-168" name="__codelineno-0-168"></a> <span class="p">)</span>
4502
<a id="__codelineno-0-169" name="__codelineno-0-169"></a> <span class="p">)</span>
4503
<a id="__codelineno-0-170" name="__codelineno-0-170"></a> <span class="k">break</span> <span class="c1"># One match per sentence is enough</span>
4504
<a id="__codelineno-0-171" name="__codelineno-0-171"></a>
4505
<a id="__codelineno-0-172" name="__codelineno-0-172"></a> <span class="k">return</span> <span class="n">items</span>
4506
<a id="__codelineno-0-173" name="__codelineno-0-173"></a>
4507
<a id="__codelineno-0-174" name="__codelineno-0-174"></a> <span class="k">def</span><span class="w"> </span><span class="nf">_attach_timestamps</span><span class="p">(</span>
4508
<a id="__codelineno-0-175" name="__codelineno-0-175"></a> <span class="bp">self</span><span class="p">,</span>
4509
<a id="__codelineno-0-176" name="__codelineno-0-176"></a> <span class="n">items</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="n">ActionItem</span><span class="p">],</span>
4510
<a id="__codelineno-0-177" name="__codelineno-0-177"></a> <span class="n">segments</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="n">TranscriptSegment</span><span class="p">],</span>
4511
<a id="__codelineno-0-178" name="__codelineno-0-178"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
4512
<a id="__codelineno-0-179" name="__codelineno-0-179"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Attach timestamps to action items by finding matching segments.&quot;&quot;&quot;</span>
4513
<a id="__codelineno-0-180" name="__codelineno-0-180"></a> <span class="k">for</span> <span class="n">item</span> <span class="ow">in</span> <span class="n">items</span><span class="p">:</span>
4514
<a id="__codelineno-0-181" name="__codelineno-0-181"></a> <span class="n">action_lower</span> <span class="o">=</span> <span class="n">item</span><span class="o">.</span><span class="n">action</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
4515
<a id="__codelineno-0-182" name="__codelineno-0-182"></a> <span class="n">best_overlap</span> <span class="o">=</span> <span class="mi">0</span>
4516
<a id="__codelineno-0-183" name="__codelineno-0-183"></a> <span class="n">best_segment</span> <span class="o">=</span> <span class="kc">None</span>
4517
<a id="__codelineno-0-184" name="__codelineno-0-184"></a>
4518
<a id="__codelineno-0-185" name="__codelineno-0-185"></a> <span class="k">for</span> <span class="n">seg</span> <span class="ow">in</span> <span class="n">segments</span><span class="p">:</span>
4519
<a id="__codelineno-0-186" name="__codelineno-0-186"></a> <span class="n">seg_lower</span> <span class="o">=</span> <span class="n">seg</span><span class="o">.</span><span class="n">text</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
4520
<a id="__codelineno-0-187" name="__codelineno-0-187"></a> <span class="c1"># Check word overlap</span>
4521
<a id="__codelineno-0-188" name="__codelineno-0-188"></a> <span class="n">action_words</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">action_lower</span><span class="o">.</span><span class="n">split</span><span class="p">())</span>
4522
<a id="__codelineno-0-189" name="__codelineno-0-189"></a> <span class="n">seg_words</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">seg_lower</span><span class="o">.</span><span class="n">split</span><span class="p">())</span>
4523
<a id="__codelineno-0-190" name="__codelineno-0-190"></a> <span class="n">overlap</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">action_words</span> <span class="o">&amp;</span> <span class="n">seg_words</span><span class="p">)</span>
4524
<a id="__codelineno-0-191" name="__codelineno-0-191"></a>
4525
<a id="__codelineno-0-192" name="__codelineno-0-192"></a> <span class="k">if</span> <span class="n">overlap</span> <span class="o">&gt;</span> <span class="n">best_overlap</span><span class="p">:</span>
4526
<a id="__codelineno-0-193" name="__codelineno-0-193"></a> <span class="n">best_overlap</span> <span class="o">=</span> <span class="n">overlap</span>
4527
<a id="__codelineno-0-194" name="__codelineno-0-194"></a> <span class="n">best_segment</span> <span class="o">=</span> <span class="n">seg</span>
4528
<a id="__codelineno-0-195" name="__codelineno-0-195"></a>
4529
<a id="__codelineno-0-196" name="__codelineno-0-196"></a> <span class="k">if</span> <span class="n">best_segment</span> <span class="ow">and</span> <span class="n">best_overlap</span> <span class="o">&gt;=</span> <span class="mi">3</span><span class="p">:</span>
4530
<a id="__codelineno-0-197" name="__codelineno-0-197"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">item</span><span class="o">.</span><span class="n">context</span><span class="p">:</span>
4531
<a id="__codelineno-0-198" name="__codelineno-0-198"></a> <span class="n">item</span><span class="o">.</span><span class="n">context</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;at </span><span class="si">{</span><span class="n">best_segment</span><span class="o">.</span><span class="n">start</span><span class="si">:</span><span class="s2">.0f</span><span class="si">}</span><span class="s2">s&quot;</span>
4532
</code></pre></div></td></tr></table></div>
4533
</details>
4534
4535
4536
4537
<div class="doc doc-children">
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
<div class="doc doc-object doc-function">
4549
4550
4551
<h4 id="video_processor.analyzers.action_detector.ActionDetector.detect_from_diagrams" class="doc doc-heading">
4552
<code class="highlight language-python"><span class="n">detect_from_diagrams</span><span class="p">(</span><span class="n">diagrams</span><span class="p">)</span></code>
4553
4554
<a href="#video_processor.analyzers.action_detector.ActionDetector.detect_from_diagrams" class="headerlink" title="Permanent link">&para;</a></h4>
4555
4556
4557
<div class="doc doc-contents ">
4558
4559
<p>Extract action items mentioned in diagram text content.</p>
4560
<p>Looks for action-oriented language in diagram text/elements.</p>
4561
4562
4563
<details class="mkdocstrings-source">
4564
<summary>Source code in <code>video_processor/analyzers/action_detector.py</code></summary>
4565
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-55">55</a></span>
4566
<span class="normal"><a href="#__codelineno-0-56">56</a></span>
4567
<span class="normal"><a href="#__codelineno-0-57">57</a></span>
4568
<span class="normal"><a href="#__codelineno-0-58">58</a></span>
4569
<span class="normal"><a href="#__codelineno-0-59">59</a></span>
4570
<span class="normal"><a href="#__codelineno-0-60">60</a></span>
4571
<span class="normal"><a href="#__codelineno-0-61">61</a></span>
4572
<span class="normal"><a href="#__codelineno-0-62">62</a></span>
4573
<span class="normal"><a href="#__codelineno-0-63">63</a></span>
4574
<span class="normal"><a href="#__codelineno-0-64">64</a></span>
4575
<span class="normal"><a href="#__codelineno-0-65">65</a></span>
4576
<span class="normal"><a href="#__codelineno-0-66">66</a></span>
4577
<span class="normal"><a href="#__codelineno-0-67">67</a></span>
4578
<span class="normal"><a href="#__codelineno-0-68">68</a></span>
4579
<span class="normal"><a href="#__codelineno-0-69">69</a></span>
4580
<span class="normal"><a href="#__codelineno-0-70">70</a></span>
4581
<span class="normal"><a href="#__codelineno-0-71">71</a></span>
4582
<span class="normal"><a href="#__codelineno-0-72">72</a></span>
4583
<span class="normal"><a href="#__codelineno-0-73">73</a></span>
4584
<span class="normal"><a href="#__codelineno-0-74">74</a></span>
4585
<span class="normal"><a href="#__codelineno-0-75">75</a></span>
4586
<span class="normal"><a href="#__codelineno-0-76">76</a></span>
4587
<span class="normal"><a href="#__codelineno-0-77">77</a></span>
4588
<span class="normal"><a href="#__codelineno-0-78">78</a></span>
4589
<span class="normal"><a href="#__codelineno-0-79">79</a></span>
4590
<span class="normal"><a href="#__codelineno-0-80">80</a></span>
4591
<span class="normal"><a href="#__codelineno-0-81">81</a></span>
4592
<span class="normal"><a href="#__codelineno-0-82">82</a></span>
4593
<span class="normal"><a href="#__codelineno-0-83">83</a></span>
4594
<span class="normal"><a href="#__codelineno-0-84">84</a></span>
4595
<span class="normal"><a href="#__codelineno-0-85">85</a></span>
4596
<span class="normal"><a href="#__codelineno-0-86">86</a></span>
4597
<span class="normal"><a href="#__codelineno-0-87">87</a></span>
4598
<span class="normal"><a href="#__codelineno-0-88">88</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-55" name="__codelineno-0-55"></a><span class="k">def</span><span class="w"> </span><span class="nf">detect_from_diagrams</span><span class="p">(</span>
4599
<a id="__codelineno-0-56" name="__codelineno-0-56"></a> <span class="bp">self</span><span class="p">,</span>
4600
<a id="__codelineno-0-57" name="__codelineno-0-57"></a> <span class="n">diagrams</span><span class="p">:</span> <span class="nb">list</span><span class="p">,</span>
4601
<a id="__codelineno-0-58" name="__codelineno-0-58"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">List</span><span class="p">[</span><span class="n">ActionItem</span><span class="p">]:</span>
4602
<a id="__codelineno-0-59" name="__codelineno-0-59"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
4603
<a id="__codelineno-0-60" name="__codelineno-0-60"></a><span class="sd"> Extract action items mentioned in diagram text content.</span>
4604
<a id="__codelineno-0-61" name="__codelineno-0-61"></a>
4605
<a id="__codelineno-0-62" name="__codelineno-0-62"></a><span class="sd"> Looks for action-oriented language in diagram text/elements.</span>
4606
<a id="__codelineno-0-63" name="__codelineno-0-63"></a><span class="sd"> &quot;&quot;&quot;</span>
4607
<a id="__codelineno-0-64" name="__codelineno-0-64"></a> <span class="n">items</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="n">ActionItem</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span>
4608
<a id="__codelineno-0-65" name="__codelineno-0-65"></a>
4609
<a id="__codelineno-0-66" name="__codelineno-0-66"></a> <span class="k">for</span> <span class="n">diagram</span> <span class="ow">in</span> <span class="n">diagrams</span><span class="p">:</span>
4610
<a id="__codelineno-0-67" name="__codelineno-0-67"></a> <span class="n">text</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
4611
<a id="__codelineno-0-68" name="__codelineno-0-68"></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">diagram</span><span class="p">,</span> <span class="nb">dict</span><span class="p">):</span>
4612
<a id="__codelineno-0-69" name="__codelineno-0-69"></a> <span class="n">text</span> <span class="o">=</span> <span class="n">diagram</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;text_content&quot;</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">)</span> <span class="ow">or</span> <span class="s2">&quot;&quot;</span>
4613
<a id="__codelineno-0-70" name="__codelineno-0-70"></a> <span class="n">elements</span> <span class="o">=</span> <span class="n">diagram</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;elements&quot;</span><span class="p">,</span> <span class="p">[])</span>
4614
<a id="__codelineno-0-71" name="__codelineno-0-71"></a> <span class="k">else</span><span class="p">:</span>
4615
<a id="__codelineno-0-72" name="__codelineno-0-72"></a> <span class="n">text</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">diagram</span><span class="p">,</span> <span class="s2">&quot;text_content&quot;</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">)</span> <span class="ow">or</span> <span class="s2">&quot;&quot;</span>
4616
<a id="__codelineno-0-73" name="__codelineno-0-73"></a> <span class="n">elements</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">diagram</span><span class="p">,</span> <span class="s2">&quot;elements&quot;</span><span class="p">,</span> <span class="p">[])</span>
4617
<a id="__codelineno-0-74" name="__codelineno-0-74"></a>
4618
<a id="__codelineno-0-75" name="__codelineno-0-75"></a> <span class="n">combined</span> <span class="o">=</span> <span class="n">text</span> <span class="o">+</span> <span class="s2">&quot; &quot;</span> <span class="o">+</span> <span class="s2">&quot; &quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">)</span> <span class="k">for</span> <span class="n">e</span> <span class="ow">in</span> <span class="n">elements</span><span class="p">)</span>
4619
<a id="__codelineno-0-76" name="__codelineno-0-76"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">combined</span><span class="o">.</span><span class="n">strip</span><span class="p">():</span>
4620
<a id="__codelineno-0-77" name="__codelineno-0-77"></a> <span class="k">continue</span>
4621
<a id="__codelineno-0-78" name="__codelineno-0-78"></a>
4622
<a id="__codelineno-0-79" name="__codelineno-0-79"></a> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">pm</span><span class="p">:</span>
4623
<a id="__codelineno-0-80" name="__codelineno-0-80"></a> <span class="n">diagram_items</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_llm_extract</span><span class="p">(</span><span class="n">combined</span><span class="p">)</span>
4624
<a id="__codelineno-0-81" name="__codelineno-0-81"></a> <span class="k">else</span><span class="p">:</span>
4625
<a id="__codelineno-0-82" name="__codelineno-0-82"></a> <span class="n">diagram_items</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_pattern_extract</span><span class="p">(</span><span class="n">combined</span><span class="p">)</span>
4626
<a id="__codelineno-0-83" name="__codelineno-0-83"></a>
4627
<a id="__codelineno-0-84" name="__codelineno-0-84"></a> <span class="k">for</span> <span class="n">item</span> <span class="ow">in</span> <span class="n">diagram_items</span><span class="p">:</span>
4628
<a id="__codelineno-0-85" name="__codelineno-0-85"></a> <span class="n">item</span><span class="o">.</span><span class="n">source</span> <span class="o">=</span> <span class="s2">&quot;diagram&quot;</span>
4629
<a id="__codelineno-0-86" name="__codelineno-0-86"></a> <span class="n">items</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">diagram_items</span><span class="p">)</span>
4630
<a id="__codelineno-0-87" name="__codelineno-0-87"></a>
4631
<a id="__codelineno-0-88" name="__codelineno-0-88"></a> <span class="k">return</span> <span class="n">items</span>
4632
</code></pre></div></td></tr></table></div>
4633
</details>
4634
</div>
4635
4636
</div>
4637
4638
<div class="doc doc-object doc-function">
4639
4640
4641
<h4 id="video_processor.analyzers.action_detector.ActionDetector.detect_from_transcript" class="doc doc-heading">
4642
<code class="highlight language-python"><span class="n">detect_from_transcript</span><span class="p">(</span><span class="n">text</span><span class="p">,</span> <span class="n">segments</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span></code>
4643
4644
<a href="#video_processor.analyzers.action_detector.ActionDetector.detect_from_transcript" class="headerlink" title="Permanent link">&para;</a></h4>
4645
4646
4647
<div class="doc doc-contents ">
4648
4649
<p>Detect action items from transcript text.</p>
4650
<p>Uses LLM extraction when available, falls back to pattern matching.
4651
Segments are used to attach timestamps.</p>
4652
4653
4654
<details class="mkdocstrings-source">
4655
<summary>Source code in <code>video_processor/analyzers/action_detector.py</code></summary>
4656
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-33">33</a></span>
4657
<span class="normal"><a href="#__codelineno-0-34">34</a></span>
4658
<span class="normal"><a href="#__codelineno-0-35">35</a></span>
4659
<span class="normal"><a href="#__codelineno-0-36">36</a></span>
4660
<span class="normal"><a href="#__codelineno-0-37">37</a></span>
4661
<span class="normal"><a href="#__codelineno-0-38">38</a></span>
4662
<span class="normal"><a href="#__codelineno-0-39">39</a></span>
4663
<span class="normal"><a href="#__codelineno-0-40">40</a></span>
4664
<span class="normal"><a href="#__codelineno-0-41">41</a></span>
4665
<span class="normal"><a href="#__codelineno-0-42">42</a></span>
4666
<span class="normal"><a href="#__codelineno-0-43">43</a></span>
4667
<span class="normal"><a href="#__codelineno-0-44">44</a></span>
4668
<span class="normal"><a href="#__codelineno-0-45">45</a></span>
4669
<span class="normal"><a href="#__codelineno-0-46">46</a></span>
4670
<span class="normal"><a href="#__codelineno-0-47">47</a></span>
4671
<span class="normal"><a href="#__codelineno-0-48">48</a></span>
4672
<span class="normal"><a href="#__codelineno-0-49">49</a></span>
4673
<span class="normal"><a href="#__codelineno-0-50">50</a></span>
4674
<span class="normal"><a href="#__codelineno-0-51">51</a></span>
4675
<span class="normal"><a href="#__codelineno-0-52">52</a></span>
4676
<span class="normal"><a href="#__codelineno-0-53">53</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-33" name="__codelineno-0-33"></a><span class="k">def</span><span class="w"> </span><span class="nf">detect_from_transcript</span><span class="p">(</span>
4677
<a id="__codelineno-0-34" name="__codelineno-0-34"></a> <span class="bp">self</span><span class="p">,</span>
4678
<a id="__codelineno-0-35" name="__codelineno-0-35"></a> <span class="n">text</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
4679
<a id="__codelineno-0-36" name="__codelineno-0-36"></a> <span class="n">segments</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">List</span><span class="p">[</span><span class="n">TranscriptSegment</span><span class="p">]]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
4680
<a id="__codelineno-0-37" name="__codelineno-0-37"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">List</span><span class="p">[</span><span class="n">ActionItem</span><span class="p">]:</span>
4681
<a id="__codelineno-0-38" name="__codelineno-0-38"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
4682
<a id="__codelineno-0-39" name="__codelineno-0-39"></a><span class="sd"> Detect action items from transcript text.</span>
4683
<a id="__codelineno-0-40" name="__codelineno-0-40"></a>
4684
<a id="__codelineno-0-41" name="__codelineno-0-41"></a><span class="sd"> Uses LLM extraction when available, falls back to pattern matching.</span>
4685
<a id="__codelineno-0-42" name="__codelineno-0-42"></a><span class="sd"> Segments are used to attach timestamps.</span>
4686
<a id="__codelineno-0-43" name="__codelineno-0-43"></a><span class="sd"> &quot;&quot;&quot;</span>
4687
<a id="__codelineno-0-44" name="__codelineno-0-44"></a> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">pm</span><span class="p">:</span>
4688
<a id="__codelineno-0-45" name="__codelineno-0-45"></a> <span class="n">items</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_llm_extract</span><span class="p">(</span><span class="n">text</span><span class="p">)</span>
4689
<a id="__codelineno-0-46" name="__codelineno-0-46"></a> <span class="k">else</span><span class="p">:</span>
4690
<a id="__codelineno-0-47" name="__codelineno-0-47"></a> <span class="n">items</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_pattern_extract</span><span class="p">(</span><span class="n">text</span><span class="p">)</span>
4691
<a id="__codelineno-0-48" name="__codelineno-0-48"></a>
4692
<a id="__codelineno-0-49" name="__codelineno-0-49"></a> <span class="c1"># Attach timestamps from segments if available</span>
4693
<a id="__codelineno-0-50" name="__codelineno-0-50"></a> <span class="k">if</span> <span class="n">segments</span> <span class="ow">and</span> <span class="n">items</span><span class="p">:</span>
4694
<a id="__codelineno-0-51" name="__codelineno-0-51"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_attach_timestamps</span><span class="p">(</span><span class="n">items</span><span class="p">,</span> <span class="n">segments</span><span class="p">)</span>
4695
<a id="__codelineno-0-52" name="__codelineno-0-52"></a>
4696
<a id="__codelineno-0-53" name="__codelineno-0-53"></a> <span class="k">return</span> <span class="n">items</span>
4697
</code></pre></div></td></tr></table></div>
4698
</details>
4699
</div>
4700
4701
</div>
4702
4703
<div class="doc doc-object doc-function">
4704
4705
4706
<h4 id="video_processor.analyzers.action_detector.ActionDetector.merge_action_items" class="doc doc-heading">
4707
<code class="highlight language-python"><span class="n">merge_action_items</span><span class="p">(</span><span class="n">transcript_items</span><span class="p">,</span> <span class="n">diagram_items</span><span class="p">)</span></code>
4708
4709
<a href="#video_processor.analyzers.action_detector.ActionDetector.merge_action_items" class="headerlink" title="Permanent link">&para;</a></h4>
4710
4711
4712
<div class="doc doc-contents ">
4713
4714
<p>Merge action items from transcript and diagram sources.</p>
4715
<p>Deduplicates by checking for similar action text.</p>
4716
4717
4718
<details class="mkdocstrings-source">
4719
<summary>Source code in <code>video_processor/analyzers/action_detector.py</code></summary>
4720
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-90"> 90</a></span>
4721
<span class="normal"><a href="#__codelineno-0-91"> 91</a></span>
4722
<span class="normal"><a href="#__codelineno-0-92"> 92</a></span>
4723
<span class="normal"><a href="#__codelineno-0-93"> 93</a></span>
4724
<span class="normal"><a href="#__codelineno-0-94"> 94</a></span>
4725
<span class="normal"><a href="#__codelineno-0-95"> 95</a></span>
4726
<span class="normal"><a href="#__codelineno-0-96"> 96</a></span>
4727
<span class="normal"><a href="#__codelineno-0-97"> 97</a></span>
4728
<span class="normal"><a href="#__codelineno-0-98"> 98</a></span>
4729
<span class="normal"><a href="#__codelineno-0-99"> 99</a></span>
4730
<span class="normal"><a href="#__codelineno-0-100">100</a></span>
4731
<span class="normal"><a href="#__codelineno-0-101">101</a></span>
4732
<span class="normal"><a href="#__codelineno-0-102">102</a></span>
4733
<span class="normal"><a href="#__codelineno-0-103">103</a></span>
4734
<span class="normal"><a href="#__codelineno-0-104">104</a></span>
4735
<span class="normal"><a href="#__codelineno-0-105">105</a></span>
4736
<span class="normal"><a href="#__codelineno-0-106">106</a></span>
4737
<span class="normal"><a href="#__codelineno-0-107">107</a></span>
4738
<span class="normal"><a href="#__codelineno-0-108">108</a></span>
4739
<span class="normal"><a href="#__codelineno-0-109">109</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-90" name="__codelineno-0-90"></a><span class="k">def</span><span class="w"> </span><span class="nf">merge_action_items</span><span class="p">(</span>
4740
<a id="__codelineno-0-91" name="__codelineno-0-91"></a> <span class="bp">self</span><span class="p">,</span>
4741
<a id="__codelineno-0-92" name="__codelineno-0-92"></a> <span class="n">transcript_items</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="n">ActionItem</span><span class="p">],</span>
4742
<a id="__codelineno-0-93" name="__codelineno-0-93"></a> <span class="n">diagram_items</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="n">ActionItem</span><span class="p">],</span>
4743
<a id="__codelineno-0-94" name="__codelineno-0-94"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">List</span><span class="p">[</span><span class="n">ActionItem</span><span class="p">]:</span>
4744
<a id="__codelineno-0-95" name="__codelineno-0-95"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
4745
<a id="__codelineno-0-96" name="__codelineno-0-96"></a><span class="sd"> Merge action items from transcript and diagram sources.</span>
4746
<a id="__codelineno-0-97" name="__codelineno-0-97"></a>
4747
<a id="__codelineno-0-98" name="__codelineno-0-98"></a><span class="sd"> Deduplicates by checking for similar action text.</span>
4748
<a id="__codelineno-0-99" name="__codelineno-0-99"></a><span class="sd"> &quot;&quot;&quot;</span>
4749
<a id="__codelineno-0-100" name="__codelineno-0-100"></a> <span class="n">merged</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="n">ActionItem</span><span class="p">]</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">transcript_items</span><span class="p">)</span>
4750
<a id="__codelineno-0-101" name="__codelineno-0-101"></a> <span class="n">existing_actions</span> <span class="o">=</span> <span class="p">{</span><span class="n">a</span><span class="o">.</span><span class="n">action</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span> <span class="k">for</span> <span class="n">a</span> <span class="ow">in</span> <span class="n">merged</span><span class="p">}</span>
4751
<a id="__codelineno-0-102" name="__codelineno-0-102"></a>
4752
<a id="__codelineno-0-103" name="__codelineno-0-103"></a> <span class="k">for</span> <span class="n">item</span> <span class="ow">in</span> <span class="n">diagram_items</span><span class="p">:</span>
4753
<a id="__codelineno-0-104" name="__codelineno-0-104"></a> <span class="n">normalized</span> <span class="o">=</span> <span class="n">item</span><span class="o">.</span><span class="n">action</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
4754
<a id="__codelineno-0-105" name="__codelineno-0-105"></a> <span class="k">if</span> <span class="n">normalized</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">existing_actions</span><span class="p">:</span>
4755
<a id="__codelineno-0-106" name="__codelineno-0-106"></a> <span class="n">merged</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">item</span><span class="p">)</span>
4756
<a id="__codelineno-0-107" name="__codelineno-0-107"></a> <span class="n">existing_actions</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">normalized</span><span class="p">)</span>
4757
<a id="__codelineno-0-108" name="__codelineno-0-108"></a>
4758
<a id="__codelineno-0-109" name="__codelineno-0-109"></a> <span class="k">return</span> <span class="n">merged</span>
4759
</code></pre></div></td></tr></table></div>
4760
</details>
4761
</div>
4762
4763
</div>
4764
4765
4766
4767
</div>
4768
4769
</div>
4770
4771
</div>
4772
4773
4774
4775
4776
</div>
4777
4778
</div>
4779
4780
</div><hr />
4781
<h2 id="overview">Overview<a class="headerlink" href="#overview" title="Permanent link">&para;</a></h2>
4782
<p>The analyzers module contains the core content extraction logic for PlanOpticon. These analyzers process video frames and transcripts to extract structured knowledge: diagrams, key points, action items, and cross-referenced entities.</p>
4783
<p>All analyzers accept an optional <code>ProviderManager</code> instance. When provided, they use LLM capabilities for richer extraction. Without one, they fall back to heuristic/pattern-based methods where possible.</p>
4784
<hr />
4785
<h2 id="diagramanalyzer">DiagramAnalyzer<a class="headerlink" href="#diagramanalyzer" title="Permanent link">&para;</a></h2>
4786
<div class="highlight"><pre><span></span><code><a id="__codelineno-0-1" name="__codelineno-0-1" href="#__codelineno-0-1"></a><span class="kn">from</span><span class="w"> </span><span class="nn">video_processor.analyzers.diagram_analyzer</span><span class="w"> </span><span class="kn">import</span> <span class="n">DiagramAnalyzer</span>
4787
</code></pre></div>
4788
<p>Vision model-based diagram detection and analysis. Classifies video frames as diagrams, slides, screenshots, or other content, then performs full extraction on high-confidence frames.</p>
4789
<h3 id="constructor">Constructor<a class="headerlink" href="#constructor" title="Permanent link">&para;</a></h3>
4790
<div class="highlight"><pre><span></span><code><a id="__codelineno-1-1" name="__codelineno-1-1" href="#__codelineno-1-1"></a><span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span>
4791
<a id="__codelineno-1-2" name="__codelineno-1-2" href="#__codelineno-1-2"></a> <span class="bp">self</span><span class="p">,</span>
4792
<a id="__codelineno-1-3" name="__codelineno-1-3" href="#__codelineno-1-3"></a> <span class="n">provider_manager</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">ProviderManager</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
4793
<a id="__codelineno-1-4" name="__codelineno-1-4" href="#__codelineno-1-4"></a> <span class="n">confidence_threshold</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="mf">0.3</span><span class="p">,</span>
4794
<a id="__codelineno-1-5" name="__codelineno-1-5" href="#__codelineno-1-5"></a><span class="p">)</span>
4795
</code></pre></div>
4796
<table>
4797
<thead>
4798
<tr>
4799
<th>Parameter</th>
4800
<th>Type</th>
4801
<th>Default</th>
4802
<th>Description</th>
4803
</tr>
4804
</thead>
4805
<tbody>
4806
<tr>
4807
<td><code>provider_manager</code></td>
4808
<td><code>Optional[ProviderManager]</code></td>
4809
<td><code>None</code></td>
4810
<td>LLM provider (creates a default if not provided)</td>
4811
</tr>
4812
<tr>
4813
<td><code>confidence_threshold</code></td>
4814
<td><code>float</code></td>
4815
<td><code>0.3</code></td>
4816
<td>Minimum confidence to process a frame at all</td>
4817
</tr>
4818
</tbody>
4819
</table>
4820
<h3 id="classify_frame">classify_frame()<a class="headerlink" href="#classify_frame" title="Permanent link">&para;</a></h3>
4821
<div class="highlight"><pre><span></span><code><a id="__codelineno-2-1" name="__codelineno-2-1" href="#__codelineno-2-1"></a><span class="k">def</span><span class="w"> </span><span class="nf">classify_frame</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">image_path</span><span class="p">:</span> <span class="n">Union</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Path</span><span class="p">])</span> <span class="o">-&gt;</span> <span class="nb">dict</span>
4822
</code></pre></div>
4823
<p>Classify a single frame using a vision model. Determines whether the frame contains a diagram, slide, or other visual content worth extracting.</p>
4824
<p><strong>Parameters:</strong></p>
4825
<table>
4826
<thead>
4827
<tr>
4828
<th>Parameter</th>
4829
<th>Type</th>
4830
<th>Description</th>
4831
</tr>
4832
</thead>
4833
<tbody>
4834
<tr>
4835
<td><code>image_path</code></td>
4836
<td><code>Union[str, Path]</code></td>
4837
<td>Path to the frame image file</td>
4838
</tr>
4839
</tbody>
4840
</table>
4841
<p><strong>Returns:</strong> <code>dict</code> with the following keys:</p>
4842
<table>
4843
<thead>
4844
<tr>
4845
<th>Key</th>
4846
<th>Type</th>
4847
<th>Description</th>
4848
</tr>
4849
</thead>
4850
<tbody>
4851
<tr>
4852
<td><code>is_diagram</code></td>
4853
<td><code>bool</code></td>
4854
<td>Whether the frame contains extractable content</td>
4855
</tr>
4856
<tr>
4857
<td><code>diagram_type</code></td>
4858
<td><code>str</code></td>
4859
<td>One of: <code>flowchart</code>, <code>sequence</code>, <code>architecture</code>, <code>whiteboard</code>, <code>chart</code>, <code>table</code>, <code>slide</code>, <code>screenshot</code>, <code>unknown</code></td>
4860
</tr>
4861
<tr>
4862
<td><code>confidence</code></td>
4863
<td><code>float</code></td>
4864
<td>Detection confidence from 0.0 to 1.0</td>
4865
</tr>
4866
<tr>
4867
<td><code>content_type</code></td>
4868
<td><code>str</code></td>
4869
<td>Content category: <code>slide</code>, <code>diagram</code>, <code>document</code>, <code>screen_share</code>, <code>whiteboard</code>, <code>chart</code>, <code>person</code>, <code>other</code></td>
4870
</tr>
4871
<tr>
4872
<td><code>brief_description</code></td>
4873
<td><code>str</code></td>
4874
<td>One-sentence description of the frame content</td>
4875
</tr>
4876
</tbody>
4877
</table>
4878
<p><strong>Important:</strong> Frames showing people, webcam feeds, or video conference participant views return <code>confidence: 0.0</code>. The classifier is tuned to detect only shared/presented content.</p>
4879
<div class="highlight"><pre><span></span><code><a id="__codelineno-3-1" name="__codelineno-3-1" href="#__codelineno-3-1"></a><span class="n">analyzer</span> <span class="o">=</span> <span class="n">DiagramAnalyzer</span><span class="p">()</span>
4880
<a id="__codelineno-3-2" name="__codelineno-3-2" href="#__codelineno-3-2"></a><span class="n">result</span> <span class="o">=</span> <span class="n">analyzer</span><span class="o">.</span><span class="n">classify_frame</span><span class="p">(</span><span class="s2">&quot;/path/to/frame_042.jpg&quot;</span><span class="p">)</span>
4881
<a id="__codelineno-3-3" name="__codelineno-3-3" href="#__codelineno-3-3"></a><span class="k">if</span> <span class="n">result</span><span class="p">[</span><span class="s2">&quot;confidence&quot;</span><span class="p">]</span> <span class="o">&gt;=</span> <span class="mf">0.7</span><span class="p">:</span>
4882
<a id="__codelineno-3-4" name="__codelineno-3-4" href="#__codelineno-3-4"></a> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Diagram detected: </span><span class="si">{</span><span class="n">result</span><span class="p">[</span><span class="s1">&#39;diagram_type&#39;</span><span class="p">]</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
4883
</code></pre></div>
4884
<h3 id="analyze_diagram_single_pass">analyze_diagram_single_pass()<a class="headerlink" href="#analyze_diagram_single_pass" title="Permanent link">&para;</a></h3>
4885
<div class="highlight"><pre><span></span><code><a id="__codelineno-4-1" name="__codelineno-4-1" href="#__codelineno-4-1"></a><span class="k">def</span><span class="w"> </span><span class="nf">analyze_diagram_single_pass</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">image_path</span><span class="p">:</span> <span class="n">Union</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Path</span><span class="p">])</span> <span class="o">-&gt;</span> <span class="nb">dict</span>
4886
</code></pre></div>
4887
<p>Full single-pass diagram analysis. Extracts description, text content, elements, relationships, Mermaid syntax, and chart data in a single LLM call.</p>
4888
<p><strong>Returns:</strong> <code>dict</code> with the following keys:</p>
4889
<table>
4890
<thead>
4891
<tr>
4892
<th>Key</th>
4893
<th>Type</th>
4894
<th>Description</th>
4895
</tr>
4896
</thead>
4897
<tbody>
4898
<tr>
4899
<td><code>diagram_type</code></td>
4900
<td><code>str</code></td>
4901
<td>Diagram classification</td>
4902
</tr>
4903
<tr>
4904
<td><code>description</code></td>
4905
<td><code>str</code></td>
4906
<td>Detailed description of the visual content</td>
4907
</tr>
4908
<tr>
4909
<td><code>text_content</code></td>
4910
<td><code>str</code></td>
4911
<td>All visible text, preserving structure</td>
4912
</tr>
4913
<tr>
4914
<td><code>elements</code></td>
4915
<td><code>list[str]</code></td>
4916
<td>Identified elements/components</td>
4917
</tr>
4918
<tr>
4919
<td><code>relationships</code></td>
4920
<td><code>list[str]</code></td>
4921
<td>Relationships in <code>"A -&gt; B: label"</code> format</td>
4922
</tr>
4923
<tr>
4924
<td><code>mermaid</code></td>
4925
<td><code>str</code></td>
4926
<td>Valid Mermaid diagram syntax</td>
4927
</tr>
4928
<tr>
4929
<td><code>chart_data</code></td>
4930
<td><code>dict \| None</code></td>
4931
<td>Chart data with <code>labels</code>, <code>values</code>, <code>chart_type</code> (only for data charts)</td>
4932
</tr>
4933
</tbody>
4934
</table>
4935
<p>Returns an empty <code>dict</code> on failure.</p>
4936
<h3 id="caption_frame">caption_frame()<a class="headerlink" href="#caption_frame" title="Permanent link">&para;</a></h3>
4937
<div class="highlight"><pre><span></span><code><a id="__codelineno-5-1" name="__codelineno-5-1" href="#__codelineno-5-1"></a><span class="k">def</span><span class="w"> </span><span class="nf">caption_frame</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">image_path</span><span class="p">:</span> <span class="n">Union</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Path</span><span class="p">])</span> <span class="o">-&gt;</span> <span class="nb">str</span>
4938
</code></pre></div>
4939
<p>Get a brief 1-2 sentence caption for a frame. Used as a fallback when full diagram analysis is not warranted.</p>
4940
<p><strong>Returns:</strong> <code>str</code> -- a brief description of the frame content.</p>
4941
<h3 id="process_frames">process_frames()<a class="headerlink" href="#process_frames" title="Permanent link">&para;</a></h3>
4942
<div class="highlight"><pre><span></span><code><a id="__codelineno-6-1" name="__codelineno-6-1" href="#__codelineno-6-1"></a><span class="k">def</span><span class="w"> </span><span class="nf">process_frames</span><span class="p">(</span>
4943
<a id="__codelineno-6-2" name="__codelineno-6-2" href="#__codelineno-6-2"></a> <span class="bp">self</span><span class="p">,</span>
4944
<a id="__codelineno-6-3" name="__codelineno-6-3" href="#__codelineno-6-3"></a> <span class="n">frame_paths</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="n">Union</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Path</span><span class="p">]],</span>
4945
<a id="__codelineno-6-4" name="__codelineno-6-4" href="#__codelineno-6-4"></a> <span class="n">diagrams_dir</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">Path</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
4946
<a id="__codelineno-6-5" name="__codelineno-6-5" href="#__codelineno-6-5"></a> <span class="n">captures_dir</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">Path</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
4947
<a id="__codelineno-6-6" name="__codelineno-6-6" href="#__codelineno-6-6"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Tuple</span><span class="p">[</span><span class="n">List</span><span class="p">[</span><span class="n">DiagramResult</span><span class="p">],</span> <span class="n">List</span><span class="p">[</span><span class="n">ScreenCapture</span><span class="p">]]</span>
4948
</code></pre></div>
4949
<p>Process a batch of extracted video frames through the full classification and analysis pipeline.</p>
4950
<p><strong>Parameters:</strong></p>
4951
<table>
4952
<thead>
4953
<tr>
4954
<th>Parameter</th>
4955
<th>Type</th>
4956
<th>Default</th>
4957
<th>Description</th>
4958
</tr>
4959
</thead>
4960
<tbody>
4961
<tr>
4962
<td><code>frame_paths</code></td>
4963
<td><code>List[Union[str, Path]]</code></td>
4964
<td><em>required</em></td>
4965
<td>Paths to frame images</td>
4966
</tr>
4967
<tr>
4968
<td><code>diagrams_dir</code></td>
4969
<td><code>Optional[Path]</code></td>
4970
<td><code>None</code></td>
4971
<td>Output directory for diagram files (images, mermaid, JSON)</td>
4972
</tr>
4973
<tr>
4974
<td><code>captures_dir</code></td>
4975
<td><code>Optional[Path]</code></td>
4976
<td><code>None</code></td>
4977
<td>Output directory for screengrab fallback files</td>
4978
</tr>
4979
</tbody>
4980
</table>
4981
<p><strong>Returns:</strong> <code>Tuple[List[DiagramResult], List[ScreenCapture]]</code></p>
4982
<p><strong>Confidence thresholds:</strong></p>
4983
<table>
4984
<thead>
4985
<tr>
4986
<th>Confidence Range</th>
4987
<th>Action</th>
4988
</tr>
4989
</thead>
4990
<tbody>
4991
<tr>
4992
<td>&gt;= 0.7</td>
4993
<td>Full diagram analysis -- extracts elements, relationships, Mermaid syntax</td>
4994
</tr>
4995
<tr>
4996
<td>0.3 to 0.7</td>
4997
<td>Screengrab fallback -- saves frame with a brief caption</td>
4998
</tr>
4999
<tr>
5000
<td>&lt; 0.3</td>
5001
<td>Skipped entirely</td>
5002
</tr>
5003
</tbody>
5004
</table>
5005
<p><strong>Output files (when directories are provided):</strong></p>
5006
<p>For diagrams (<code>diagrams_dir</code>):</p>
5007
<ul>
5008
<li><code>diagram_N.jpg</code> -- original frame image</li>
5009
<li><code>diagram_N.mermaid</code> -- Mermaid source (if generated)</li>
5010
<li><code>diagram_N.json</code> -- full DiagramResult as JSON</li>
5011
</ul>
5012
<p>For screen captures (<code>captures_dir</code>):</p>
5013
<ul>
5014
<li><code>capture_N.jpg</code> -- original frame image</li>
5015
<li><code>capture_N.json</code> -- ScreenCapture metadata as JSON</li>
5016
</ul>
5017
<div class="highlight"><pre><span></span><code><a id="__codelineno-7-1" name="__codelineno-7-1" href="#__codelineno-7-1"></a><span class="kn">from</span><span class="w"> </span><span class="nn">pathlib</span><span class="w"> </span><span class="kn">import</span> <span class="n">Path</span>
5018
<a id="__codelineno-7-2" name="__codelineno-7-2" href="#__codelineno-7-2"></a><span class="kn">from</span><span class="w"> </span><span class="nn">video_processor.analyzers.diagram_analyzer</span><span class="w"> </span><span class="kn">import</span> <span class="n">DiagramAnalyzer</span>
5019
<a id="__codelineno-7-3" name="__codelineno-7-3" href="#__codelineno-7-3"></a><span class="kn">from</span><span class="w"> </span><span class="nn">video_processor.providers.manager</span><span class="w"> </span><span class="kn">import</span> <span class="n">ProviderManager</span>
5020
<a id="__codelineno-7-4" name="__codelineno-7-4" href="#__codelineno-7-4"></a>
5021
<a id="__codelineno-7-5" name="__codelineno-7-5" href="#__codelineno-7-5"></a><span class="n">analyzer</span> <span class="o">=</span> <span class="n">DiagramAnalyzer</span><span class="p">(</span>
5022
<a id="__codelineno-7-6" name="__codelineno-7-6" href="#__codelineno-7-6"></a> <span class="n">provider_manager</span><span class="o">=</span><span class="n">ProviderManager</span><span class="p">(),</span>
5023
<a id="__codelineno-7-7" name="__codelineno-7-7" href="#__codelineno-7-7"></a> <span class="n">confidence_threshold</span><span class="o">=</span><span class="mf">0.3</span><span class="p">,</span>
5024
<a id="__codelineno-7-8" name="__codelineno-7-8" href="#__codelineno-7-8"></a><span class="p">)</span>
5025
<a id="__codelineno-7-9" name="__codelineno-7-9" href="#__codelineno-7-9"></a>
5026
<a id="__codelineno-7-10" name="__codelineno-7-10" href="#__codelineno-7-10"></a><span class="n">frame_paths</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">Path</span><span class="p">(</span><span class="s2">&quot;output/frames&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">glob</span><span class="p">(</span><span class="s2">&quot;*.jpg&quot;</span><span class="p">))</span>
5027
<a id="__codelineno-7-11" name="__codelineno-7-11" href="#__codelineno-7-11"></a><span class="n">diagrams</span><span class="p">,</span> <span class="n">captures</span> <span class="o">=</span> <span class="n">analyzer</span><span class="o">.</span><span class="n">process_frames</span><span class="p">(</span>
5028
<a id="__codelineno-7-12" name="__codelineno-7-12" href="#__codelineno-7-12"></a> <span class="n">frame_paths</span><span class="p">,</span>
5029
<a id="__codelineno-7-13" name="__codelineno-7-13" href="#__codelineno-7-13"></a> <span class="n">diagrams_dir</span><span class="o">=</span><span class="n">Path</span><span class="p">(</span><span class="s2">&quot;output/diagrams&quot;</span><span class="p">),</span>
5030
<a id="__codelineno-7-14" name="__codelineno-7-14" href="#__codelineno-7-14"></a> <span class="n">captures_dir</span><span class="o">=</span><span class="n">Path</span><span class="p">(</span><span class="s2">&quot;output/captures&quot;</span><span class="p">),</span>
5031
<a id="__codelineno-7-15" name="__codelineno-7-15" href="#__codelineno-7-15"></a><span class="p">)</span>
5032
<a id="__codelineno-7-16" name="__codelineno-7-16" href="#__codelineno-7-16"></a>
5033
<a id="__codelineno-7-17" name="__codelineno-7-17" href="#__codelineno-7-17"></a><span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Found </span><span class="si">{</span><span class="nb">len</span><span class="p">(</span><span class="n">diagrams</span><span class="p">)</span><span class="si">}</span><span class="s2"> diagrams, </span><span class="si">{</span><span class="nb">len</span><span class="p">(</span><span class="n">captures</span><span class="p">)</span><span class="si">}</span><span class="s2"> screengrabs&quot;</span><span class="p">)</span>
5034
<a id="__codelineno-7-18" name="__codelineno-7-18" href="#__codelineno-7-18"></a><span class="k">for</span> <span class="n">d</span> <span class="ow">in</span> <span class="n">diagrams</span><span class="p">:</span>
5035
<a id="__codelineno-7-19" name="__codelineno-7-19" href="#__codelineno-7-19"></a> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot; [</span><span class="si">{</span><span class="n">d</span><span class="o">.</span><span class="n">diagram_type</span><span class="o">.</span><span class="n">value</span><span class="si">}</span><span class="s2">] </span><span class="si">{</span><span class="n">d</span><span class="o">.</span><span class="n">description</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
5036
</code></pre></div>
5037
<hr />
5038
<h2 id="contentanalyzer">ContentAnalyzer<a class="headerlink" href="#contentanalyzer" title="Permanent link">&para;</a></h2>
5039
<div class="highlight"><pre><span></span><code><a id="__codelineno-8-1" name="__codelineno-8-1" href="#__codelineno-8-1"></a><span class="kn">from</span><span class="w"> </span><span class="nn">video_processor.analyzers.content_analyzer</span><span class="w"> </span><span class="kn">import</span> <span class="n">ContentAnalyzer</span>
5040
</code></pre></div>
5041
<p>Cross-references transcript and diagram entities for richer knowledge extraction. Merges entities found in different sources and enriches key points with diagram links.</p>
5042
<h3 id="constructor_1">Constructor<a class="headerlink" href="#constructor_1" title="Permanent link">&para;</a></h3>
5043
<div class="highlight"><pre><span></span><code><a id="__codelineno-9-1" name="__codelineno-9-1" href="#__codelineno-9-1"></a><span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">provider_manager</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">ProviderManager</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">)</span>
5044
</code></pre></div>
5045
<table>
5046
<thead>
5047
<tr>
5048
<th>Parameter</th>
5049
<th>Type</th>
5050
<th>Default</th>
5051
<th>Description</th>
5052
</tr>
5053
</thead>
5054
<tbody>
5055
<tr>
5056
<td><code>provider_manager</code></td>
5057
<td><code>Optional[ProviderManager]</code></td>
5058
<td><code>None</code></td>
5059
<td>Required for LLM-based fuzzy matching</td>
5060
</tr>
5061
</tbody>
5062
</table>
5063
<h3 id="cross_reference">cross_reference()<a class="headerlink" href="#cross_reference" title="Permanent link">&para;</a></h3>
5064
<div class="highlight"><pre><span></span><code><a id="__codelineno-10-1" name="__codelineno-10-1" href="#__codelineno-10-1"></a><span class="k">def</span><span class="w"> </span><span class="nf">cross_reference</span><span class="p">(</span>
5065
<a id="__codelineno-10-2" name="__codelineno-10-2" href="#__codelineno-10-2"></a> <span class="bp">self</span><span class="p">,</span>
5066
<a id="__codelineno-10-3" name="__codelineno-10-3" href="#__codelineno-10-3"></a> <span class="n">transcript_entities</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="n">Entity</span><span class="p">],</span>
5067
<a id="__codelineno-10-4" name="__codelineno-10-4" href="#__codelineno-10-4"></a> <span class="n">diagram_entities</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="n">Entity</span><span class="p">],</span>
5068
<a id="__codelineno-10-5" name="__codelineno-10-5" href="#__codelineno-10-5"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">List</span><span class="p">[</span><span class="n">Entity</span><span class="p">]</span>
5069
</code></pre></div>
5070
<p>Merge entities from transcripts and diagrams into a unified list with source attribution.</p>
5071
<p><strong>Merge strategy:</strong></p>
5072
<ol>
5073
<li>Index all transcript entities by lowercase name, marked with <code>source="transcript"</code></li>
5074
<li>Merge diagram entities: if a name matches, set <code>source="both"</code> and combine descriptions/occurrences; otherwise add as <code>source="diagram"</code></li>
5075
<li>If a <code>ProviderManager</code> is available, use LLM fuzzy matching to find additional matches among unmatched entities (e.g., "PostgreSQL" from transcript matching "Postgres" from diagram)</li>
5076
</ol>
5077
<p><strong>Parameters:</strong></p>
5078
<table>
5079
<thead>
5080
<tr>
5081
<th>Parameter</th>
5082
<th>Type</th>
5083
<th>Description</th>
5084
</tr>
5085
</thead>
5086
<tbody>
5087
<tr>
5088
<td><code>transcript_entities</code></td>
5089
<td><code>List[Entity]</code></td>
5090
<td>Entities extracted from transcript</td>
5091
</tr>
5092
<tr>
5093
<td><code>diagram_entities</code></td>
5094
<td><code>List[Entity]</code></td>
5095
<td>Entities extracted from diagrams</td>
5096
</tr>
5097
</tbody>
5098
</table>
5099
<p><strong>Returns:</strong> <code>List[Entity]</code> -- merged entity list with <code>source</code> attribution.</p>
5100
<div class="highlight"><pre><span></span><code><a id="__codelineno-11-1" name="__codelineno-11-1" href="#__codelineno-11-1"></a><span class="kn">from</span><span class="w"> </span><span class="nn">video_processor.analyzers.content_analyzer</span><span class="w"> </span><span class="kn">import</span> <span class="n">ContentAnalyzer</span>
5101
<a id="__codelineno-11-2" name="__codelineno-11-2" href="#__codelineno-11-2"></a><span class="kn">from</span><span class="w"> </span><span class="nn">video_processor.models</span><span class="w"> </span><span class="kn">import</span> <span class="n">Entity</span>
5102
<a id="__codelineno-11-3" name="__codelineno-11-3" href="#__codelineno-11-3"></a>
5103
<a id="__codelineno-11-4" name="__codelineno-11-4" href="#__codelineno-11-4"></a><span class="n">analyzer</span> <span class="o">=</span> <span class="n">ContentAnalyzer</span><span class="p">(</span><span class="n">provider_manager</span><span class="o">=</span><span class="n">pm</span><span class="p">)</span>
5104
<a id="__codelineno-11-5" name="__codelineno-11-5" href="#__codelineno-11-5"></a>
5105
<a id="__codelineno-11-6" name="__codelineno-11-6" href="#__codelineno-11-6"></a><span class="n">transcript_entities</span> <span class="o">=</span> <span class="p">[</span>
5106
<a id="__codelineno-11-7" name="__codelineno-11-7" href="#__codelineno-11-7"></a> <span class="n">Entity</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s2">&quot;PostgreSQL&quot;</span><span class="p">,</span> <span class="nb">type</span><span class="o">=</span><span class="s2">&quot;technology&quot;</span><span class="p">),</span>
5107
<a id="__codelineno-11-8" name="__codelineno-11-8" href="#__codelineno-11-8"></a> <span class="n">Entity</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s2">&quot;Alice&quot;</span><span class="p">,</span> <span class="nb">type</span><span class="o">=</span><span class="s2">&quot;person&quot;</span><span class="p">),</span>
5108
<a id="__codelineno-11-9" name="__codelineno-11-9" href="#__codelineno-11-9"></a><span class="p">]</span>
5109
<a id="__codelineno-11-10" name="__codelineno-11-10" href="#__codelineno-11-10"></a><span class="n">diagram_entities</span> <span class="o">=</span> <span class="p">[</span>
5110
<a id="__codelineno-11-11" name="__codelineno-11-11" href="#__codelineno-11-11"></a> <span class="n">Entity</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s2">&quot;Postgres&quot;</span><span class="p">,</span> <span class="nb">type</span><span class="o">=</span><span class="s2">&quot;technology&quot;</span><span class="p">),</span>
5111
<a id="__codelineno-11-12" name="__codelineno-11-12" href="#__codelineno-11-12"></a> <span class="n">Entity</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s2">&quot;Redis&quot;</span><span class="p">,</span> <span class="nb">type</span><span class="o">=</span><span class="s2">&quot;technology&quot;</span><span class="p">),</span>
5112
<a id="__codelineno-11-13" name="__codelineno-11-13" href="#__codelineno-11-13"></a><span class="p">]</span>
5113
<a id="__codelineno-11-14" name="__codelineno-11-14" href="#__codelineno-11-14"></a>
5114
<a id="__codelineno-11-15" name="__codelineno-11-15" href="#__codelineno-11-15"></a><span class="n">merged</span> <span class="o">=</span> <span class="n">analyzer</span><span class="o">.</span><span class="n">cross_reference</span><span class="p">(</span><span class="n">transcript_entities</span><span class="p">,</span> <span class="n">diagram_entities</span><span class="p">)</span>
5115
<a id="__codelineno-11-16" name="__codelineno-11-16" href="#__codelineno-11-16"></a><span class="c1"># &quot;PostgreSQL&quot; and &quot;Postgres&quot; may be fuzzy-matched and merged</span>
5116
</code></pre></div>
5117
<h3 id="enrich_key_points">enrich_key_points()<a class="headerlink" href="#enrich_key_points" title="Permanent link">&para;</a></h3>
5118
<div class="highlight"><pre><span></span><code><a id="__codelineno-12-1" name="__codelineno-12-1" href="#__codelineno-12-1"></a><span class="k">def</span><span class="w"> </span><span class="nf">enrich_key_points</span><span class="p">(</span>
5119
<a id="__codelineno-12-2" name="__codelineno-12-2" href="#__codelineno-12-2"></a> <span class="bp">self</span><span class="p">,</span>
5120
<a id="__codelineno-12-3" name="__codelineno-12-3" href="#__codelineno-12-3"></a> <span class="n">key_points</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="n">KeyPoint</span><span class="p">],</span>
5121
<a id="__codelineno-12-4" name="__codelineno-12-4" href="#__codelineno-12-4"></a> <span class="n">diagrams</span><span class="p">:</span> <span class="nb">list</span><span class="p">,</span>
5122
<a id="__codelineno-12-5" name="__codelineno-12-5" href="#__codelineno-12-5"></a> <span class="n">transcript_text</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
5123
<a id="__codelineno-12-6" name="__codelineno-12-6" href="#__codelineno-12-6"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">List</span><span class="p">[</span><span class="n">KeyPoint</span><span class="p">]</span>
5124
</code></pre></div>
5125
<p>Link key points to relevant diagrams by entity overlap. Examines word overlap between key point text and diagram elements/text content.</p>
5126
<p><strong>Parameters:</strong></p>
5127
<table>
5128
<thead>
5129
<tr>
5130
<th>Parameter</th>
5131
<th>Type</th>
5132
<th>Description</th>
5133
</tr>
5134
</thead>
5135
<tbody>
5136
<tr>
5137
<td><code>key_points</code></td>
5138
<td><code>List[KeyPoint]</code></td>
5139
<td>Key points to enrich</td>
5140
</tr>
5141
<tr>
5142
<td><code>diagrams</code></td>
5143
<td><code>list</code></td>
5144
<td>List of <code>DiagramResult</code> objects or dicts</td>
5145
</tr>
5146
<tr>
5147
<td><code>transcript_text</code></td>
5148
<td><code>str</code></td>
5149
<td>Full transcript text (reserved for future use)</td>
5150
</tr>
5151
</tbody>
5152
</table>
5153
<p><strong>Returns:</strong> <code>List[KeyPoint]</code> -- key points with <code>related_diagrams</code> indices populated.</p>
5154
<p>A key point is linked to a diagram when they share 2 or more words (excluding short words) between the key point text/details and the diagram's elements/text content.</p>
5155
<hr />
5156
<h2 id="actiondetector">ActionDetector<a class="headerlink" href="#actiondetector" title="Permanent link">&para;</a></h2>
5157
<div class="highlight"><pre><span></span><code><a id="__codelineno-13-1" name="__codelineno-13-1" href="#__codelineno-13-1"></a><span class="kn">from</span><span class="w"> </span><span class="nn">video_processor.analyzers.action_detector</span><span class="w"> </span><span class="kn">import</span> <span class="n">ActionDetector</span>
5158
</code></pre></div>
5159
<p>Detects action items from transcripts and diagram content using LLM extraction with a regex pattern fallback.</p>
5160
<h3 id="constructor_2">Constructor<a class="headerlink" href="#constructor_2" title="Permanent link">&para;</a></h3>
5161
<div class="highlight"><pre><span></span><code><a id="__codelineno-14-1" name="__codelineno-14-1" href="#__codelineno-14-1"></a><span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">provider_manager</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">ProviderManager</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">)</span>
5162
</code></pre></div>
5163
<table>
5164
<thead>
5165
<tr>
5166
<th>Parameter</th>
5167
<th>Type</th>
5168
<th>Default</th>
5169
<th>Description</th>
5170
</tr>
5171
</thead>
5172
<tbody>
5173
<tr>
5174
<td><code>provider_manager</code></td>
5175
<td><code>Optional[ProviderManager]</code></td>
5176
<td><code>None</code></td>
5177
<td>Required for LLM-based extraction</td>
5178
</tr>
5179
</tbody>
5180
</table>
5181
<h3 id="detect_from_transcript">detect_from_transcript()<a class="headerlink" href="#detect_from_transcript" title="Permanent link">&para;</a></h3>
5182
<div class="highlight"><pre><span></span><code><a id="__codelineno-15-1" name="__codelineno-15-1" href="#__codelineno-15-1"></a><span class="k">def</span><span class="w"> </span><span class="nf">detect_from_transcript</span><span class="p">(</span>
5183
<a id="__codelineno-15-2" name="__codelineno-15-2" href="#__codelineno-15-2"></a> <span class="bp">self</span><span class="p">,</span>
5184
<a id="__codelineno-15-3" name="__codelineno-15-3" href="#__codelineno-15-3"></a> <span class="n">text</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
5185
<a id="__codelineno-15-4" name="__codelineno-15-4" href="#__codelineno-15-4"></a> <span class="n">segments</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">List</span><span class="p">[</span><span class="n">TranscriptSegment</span><span class="p">]]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
5186
<a id="__codelineno-15-5" name="__codelineno-15-5" href="#__codelineno-15-5"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">List</span><span class="p">[</span><span class="n">ActionItem</span><span class="p">]</span>
5187
</code></pre></div>
5188
<p>Detect action items from transcript text.</p>
5189
<p><strong>Parameters:</strong></p>
5190
<table>
5191
<thead>
5192
<tr>
5193
<th>Parameter</th>
5194
<th>Type</th>
5195
<th>Default</th>
5196
<th>Description</th>
5197
</tr>
5198
</thead>
5199
<tbody>
5200
<tr>
5201
<td><code>text</code></td>
5202
<td><code>str</code></td>
5203
<td><em>required</em></td>
5204
<td>Transcript text to analyze</td>
5205
</tr>
5206
<tr>
5207
<td><code>segments</code></td>
5208
<td><code>Optional[List[TranscriptSegment]]</code></td>
5209
<td><code>None</code></td>
5210
<td>Transcript segments for timestamp attachment</td>
5211
</tr>
5212
</tbody>
5213
</table>
5214
<p><strong>Returns:</strong> <code>List[ActionItem]</code> -- detected action items with <code>source="transcript"</code>.</p>
5215
<p><strong>Extraction modes:</strong></p>
5216
<ul>
5217
<li><strong>LLM mode</strong> (when <code>provider_manager</code> is set): Sends the transcript to the LLM with a structured extraction prompt. Extracts action, assignee, deadline, priority, and context.</li>
5218
<li><strong>Pattern mode</strong> (fallback): Matches sentences against regex patterns for action-oriented language.</li>
5219
</ul>
5220
<p><strong>Pattern matching</strong> detects sentences containing:</p>
5221
<ul>
5222
<li>"need/needs to", "should/must/shall"</li>
5223
<li>"will/going to", "action item/todo/follow-up"</li>
5224
<li>"assigned to/responsible for", "deadline/due by"</li>
5225
<li>"let's/let us", "make sure/ensure"</li>
5226
<li>"can you/could you/please"</li>
5227
</ul>
5228
<p><strong>Timestamp attachment:</strong> When <code>segments</code> are provided, each action item is matched to the most relevant transcript segment (by word overlap, minimum 3 matching words), and a timestamp is added to <code>context</code>.</p>
5229
<h3 id="detect_from_diagrams">detect_from_diagrams()<a class="headerlink" href="#detect_from_diagrams" title="Permanent link">&para;</a></h3>
5230
<div class="highlight"><pre><span></span><code><a id="__codelineno-16-1" name="__codelineno-16-1" href="#__codelineno-16-1"></a><span class="k">def</span><span class="w"> </span><span class="nf">detect_from_diagrams</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">diagrams</span><span class="p">:</span> <span class="nb">list</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">List</span><span class="p">[</span><span class="n">ActionItem</span><span class="p">]</span>
5231
</code></pre></div>
5232
<p>Extract action items from diagram text content and elements. Processes each diagram's combined text using either LLM or pattern extraction.</p>
5233
<p><strong>Parameters:</strong></p>
5234
<table>
5235
<thead>
5236
<tr>
5237
<th>Parameter</th>
5238
<th>Type</th>
5239
<th>Description</th>
5240
</tr>
5241
</thead>
5242
<tbody>
5243
<tr>
5244
<td><code>diagrams</code></td>
5245
<td><code>list</code></td>
5246
<td>List of <code>DiagramResult</code> objects or dicts</td>
5247
</tr>
5248
</tbody>
5249
</table>
5250
<p><strong>Returns:</strong> <code>List[ActionItem]</code> -- action items with <code>source="diagram"</code>.</p>
5251
<h3 id="merge_action_items">merge_action_items()<a class="headerlink" href="#merge_action_items" title="Permanent link">&para;</a></h3>
5252
<div class="highlight"><pre><span></span><code><a id="__codelineno-17-1" name="__codelineno-17-1" href="#__codelineno-17-1"></a><span class="k">def</span><span class="w"> </span><span class="nf">merge_action_items</span><span class="p">(</span>
5253
<a id="__codelineno-17-2" name="__codelineno-17-2" href="#__codelineno-17-2"></a> <span class="bp">self</span><span class="p">,</span>
5254
<a id="__codelineno-17-3" name="__codelineno-17-3" href="#__codelineno-17-3"></a> <span class="n">transcript_items</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="n">ActionItem</span><span class="p">],</span>
5255
<a id="__codelineno-17-4" name="__codelineno-17-4" href="#__codelineno-17-4"></a> <span class="n">diagram_items</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="n">ActionItem</span><span class="p">],</span>
5256
<a id="__codelineno-17-5" name="__codelineno-17-5" href="#__codelineno-17-5"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">List</span><span class="p">[</span><span class="n">ActionItem</span><span class="p">]</span>
5257
</code></pre></div>
5258
<p>Merge action items from multiple sources, deduplicating by action text (case-insensitive, whitespace-normalized).</p>
5259
<p><strong>Returns:</strong> <code>List[ActionItem]</code> -- deduplicated merged list.</p>
5260
<h3 id="usage-example">Usage example<a class="headerlink" href="#usage-example" title="Permanent link">&para;</a></h3>
5261
<div class="highlight"><pre><span></span><code><a id="__codelineno-18-1" name="__codelineno-18-1" href="#__codelineno-18-1"></a><span class="kn">from</span><span class="w"> </span><span class="nn">video_processor.analyzers.action_detector</span><span class="w"> </span><span class="kn">import</span> <span class="n">ActionDetector</span>
5262
<a id="__codelineno-18-2" name="__codelineno-18-2" href="#__codelineno-18-2"></a><span class="kn">from</span><span class="w"> </span><span class="nn">video_processor.providers.manager</span><span class="w"> </span><span class="kn">import</span> <span class="n">ProviderManager</span>
5263
<a id="__codelineno-18-3" name="__codelineno-18-3" href="#__codelineno-18-3"></a>
5264
<a id="__codelineno-18-4" name="__codelineno-18-4" href="#__codelineno-18-4"></a><span class="n">detector</span> <span class="o">=</span> <span class="n">ActionDetector</span><span class="p">(</span><span class="n">provider_manager</span><span class="o">=</span><span class="n">ProviderManager</span><span class="p">())</span>
5265
<a id="__codelineno-18-5" name="__codelineno-18-5" href="#__codelineno-18-5"></a>
5266
<a id="__codelineno-18-6" name="__codelineno-18-6" href="#__codelineno-18-6"></a><span class="c1"># From transcript</span>
5267
<a id="__codelineno-18-7" name="__codelineno-18-7" href="#__codelineno-18-7"></a><span class="n">transcript_items</span> <span class="o">=</span> <span class="n">detector</span><span class="o">.</span><span class="n">detect_from_transcript</span><span class="p">(</span>
5268
<a id="__codelineno-18-8" name="__codelineno-18-8" href="#__codelineno-18-8"></a> <span class="n">text</span><span class="o">=</span><span class="s2">&quot;Alice needs to update the API docs by Friday. &quot;</span>
5269
<a id="__codelineno-18-9" name="__codelineno-18-9" href="#__codelineno-18-9"></a> <span class="s2">&quot;Bob should review the PR before merging.&quot;</span><span class="p">,</span>
5270
<a id="__codelineno-18-10" name="__codelineno-18-10" href="#__codelineno-18-10"></a> <span class="n">segments</span><span class="o">=</span><span class="n">transcript_segments</span><span class="p">,</span>
5271
<a id="__codelineno-18-11" name="__codelineno-18-11" href="#__codelineno-18-11"></a><span class="p">)</span>
5272
<a id="__codelineno-18-12" name="__codelineno-18-12" href="#__codelineno-18-12"></a>
5273
<a id="__codelineno-18-13" name="__codelineno-18-13" href="#__codelineno-18-13"></a><span class="c1"># From diagrams</span>
5274
<a id="__codelineno-18-14" name="__codelineno-18-14" href="#__codelineno-18-14"></a><span class="n">diagram_items</span> <span class="o">=</span> <span class="n">detector</span><span class="o">.</span><span class="n">detect_from_diagrams</span><span class="p">(</span><span class="n">diagram_results</span><span class="p">)</span>
5275
<a id="__codelineno-18-15" name="__codelineno-18-15" href="#__codelineno-18-15"></a>
5276
<a id="__codelineno-18-16" name="__codelineno-18-16" href="#__codelineno-18-16"></a><span class="c1"># Merge and deduplicate</span>
5277
<a id="__codelineno-18-17" name="__codelineno-18-17" href="#__codelineno-18-17"></a><span class="n">all_items</span> <span class="o">=</span> <span class="n">detector</span><span class="o">.</span><span class="n">merge_action_items</span><span class="p">(</span><span class="n">transcript_items</span><span class="p">,</span> <span class="n">diagram_items</span><span class="p">)</span>
5278
<a id="__codelineno-18-18" name="__codelineno-18-18" href="#__codelineno-18-18"></a>
5279
<a id="__codelineno-18-19" name="__codelineno-18-19" href="#__codelineno-18-19"></a><span class="k">for</span> <span class="n">item</span> <span class="ow">in</span> <span class="n">all_items</span><span class="p">:</span>
5280
<a id="__codelineno-18-20" name="__codelineno-18-20" href="#__codelineno-18-20"></a> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;[</span><span class="si">{</span><span class="n">item</span><span class="o">.</span><span class="n">priority</span><span class="w"> </span><span class="ow">or</span><span class="w"> </span><span class="s1">&#39;unset&#39;</span><span class="si">}</span><span class="s2">] </span><span class="si">{</span><span class="n">item</span><span class="o">.</span><span class="n">action</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
5281
<a id="__codelineno-18-21" name="__codelineno-18-21" href="#__codelineno-18-21"></a> <span class="k">if</span> <span class="n">item</span><span class="o">.</span><span class="n">assignee</span><span class="p">:</span>
5282
<a id="__codelineno-18-22" name="__codelineno-18-22" href="#__codelineno-18-22"></a> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot; Assignee: </span><span class="si">{</span><span class="n">item</span><span class="o">.</span><span class="n">assignee</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
5283
<a id="__codelineno-18-23" name="__codelineno-18-23" href="#__codelineno-18-23"></a> <span class="k">if</span> <span class="n">item</span><span class="o">.</span><span class="n">deadline</span><span class="p">:</span>
5284
<a id="__codelineno-18-24" name="__codelineno-18-24" href="#__codelineno-18-24"></a> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot; Deadline: </span><span class="si">{</span><span class="n">item</span><span class="o">.</span><span class="n">deadline</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
5285
</code></pre></div>
5286
<h3 id="pattern-fallback-no-llm">Pattern fallback (no LLM)<a class="headerlink" href="#pattern-fallback-no-llm" title="Permanent link">&para;</a></h3>
5287
<div class="highlight"><pre><span></span><code><a id="__codelineno-19-1" name="__codelineno-19-1" href="#__codelineno-19-1"></a><span class="c1"># Works without any API keys</span>
5288
<a id="__codelineno-19-2" name="__codelineno-19-2" href="#__codelineno-19-2"></a><span class="n">detector</span> <span class="o">=</span> <span class="n">ActionDetector</span><span class="p">()</span> <span class="c1"># No provider_manager</span>
5289
<a id="__codelineno-19-3" name="__codelineno-19-3" href="#__codelineno-19-3"></a><span class="n">items</span> <span class="o">=</span> <span class="n">detector</span><span class="o">.</span><span class="n">detect_from_transcript</span><span class="p">(</span>
5290
<a id="__codelineno-19-4" name="__codelineno-19-4" href="#__codelineno-19-4"></a> <span class="s2">&quot;We need to finalize the database schema. &quot;</span>
5291
<a id="__codelineno-19-5" name="__codelineno-19-5" href="#__codelineno-19-5"></a> <span class="s2">&quot;Please update the deployment scripts.&quot;</span>
5292
<a id="__codelineno-19-6" name="__codelineno-19-6" href="#__codelineno-19-6"></a><span class="p">)</span>
5293
<a id="__codelineno-19-7" name="__codelineno-19-7" href="#__codelineno-19-7"></a><span class="c1"># Returns ActionItems matched by regex patterns</span>
5294
</code></pre></div>
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304
5305
5306
5307
5308
</article>
5309
</div>
5310
5311
5312
<script>var tabs=__md_get("__tabs");if(Array.isArray(tabs))e:for(var set of document.querySelectorAll(".tabbed-set")){var labels=set.querySelector(".tabbed-labels");for(var tab of tabs)for(var label of labels.getElementsByTagName("label"))if(label.innerText.trim()===tab){var input=document.getElementById(label.htmlFor);input.checked=!0;continue e}}</script>
5313
5314
<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script>
5315
</div>
5316
5317
<button type="button" class="md-top md-icon" data-md-component="top" hidden>
5318
5319
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8z"/></svg>
5320
Back to top
5321
</button>
5322
5323
</main>
5324
5325
<footer class="md-footer">
5326
5327
<div class="md-footer-meta md-typeset">
5328
<div class="md-footer-meta__inner md-grid">
5329
<div class="md-copyright">
5330
5331
<div class="md-copyright__highlight">
5332
Copyright &copy; 2026 CONFLICT LLC
5333
</div>
5334
5335
5336
Made with
5337
<a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener">
5338
Material for MkDocs
5339
</a>
5340
5341
</div>
5342
5343
5344
<div class="md-social">
5345
5346
5347
5348
5349
5350
5351
5352
5353
<a href="https://github.com/ConflictHQ/PlanOpticon" target="_blank" rel="noopener" title="github.com" class="md-social__link">
5354
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d="M173.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M252.8 8C114.1 8 8 113.3 8 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C436.2 457.8 504 362.9 504 252 504 113.3 391.5 8 252.8 8M105.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2"/></svg>
5355
</a>
5356
5357
</div>
5358
5359
</div>
5360
</div>
5361
</footer>
5362
5363
</div>
5364
<div class="md-dialog" data-md-component="dialog">
5365
<div class="md-dialog__inner md-typeset"></div>
5366
</div>
5367
5368
5369
5370
5371
5372
<script id="__config" type="application/json">{"annotate": null, "base": "../..", "features": ["navigation.instant", "navigation.tabs", "navigation.sections", "navigation.expand", "navigation.top", "search.suggest", "search.highlight", "content.code.copy", "content.tabs.link", "header.autohide"], "search": "../../assets/javascripts/workers/search.2c215733.min.js", "tags": null, "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": null}</script>
5373
5374
5375
<script src="../../assets/javascripts/bundle.79ae519e.min.js"></script>
5376
5377
5378
</body>
5379
</html>

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button